% % Copyright (C) 2016-2026 Zeping Lee % Released under the LaTeX Project Public License v1.3c or later versions. % Repository: https://github.com/zepinglee/gbt7714-bibtex-style % \NeedsTeXFormat{LaTeX2e}[2020-10-01] % 检查 LaTeXe kernel 版本 \providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} \IfFormatAtLeastTF{2020-10-01}{} {\PackageError{gbt7714}{TeX Live 2021 or later version is required.}{}} \ProvidesExplPackage {gbt7714} {2026-05-03} {2.2.0} {GB/T 7714 BibTeX style} % 控制著者-出版年的符号使用全角/半角 \newif \ifgbt@cite@punct@full % 控制连续两个序号是否使用连接号。 \newif \ifgbt@min@compress@two % 控制引注的样式,true 为上标式,false 为行内式。 \bool_new:N \l__gbt_cite_inline_bool \cs_new:Npn \__gbt_set_cite_inline: { } % 控制引注的页码在括号内还是在括号外。 \newif \ifgbt@locator@in@brackets \bool_new:N \l__gbt_align_left_bool % 控制 bst 的格式。 \prop_new:N \l__gbt_bst_control_prop % 用于兼容 v1.x.x 过时的接口 % TODO: v3.0.0 remove these \bool_new:N \l__gbt_legacy_interface_bool \bool_new:N \l__gbt_legacy_mmxv_bool \bool_new:N \l__gbt_legacy_numeric_bool \bool_new:N \l__gbt_legacy_super_bool \bool_set_false:N \l__gbt_legacy_interface_bool \bool_set_true:N \l__gbt_legacy_mmxv_bool \bool_set_true:N \l__gbt_legacy_numeric_bool \bool_set_true:N \l__gbt_legacy_super_bool % 设置选项 \NewDocumentCommand \gbtsetup { m } { \keys_set:nn { gbt7714 } { #1 } } % 参考文献列表的标签左对齐 \keys_define:nn { gbt7714 } { citepunct .choice: , citepunct / full .code:n = { \gbt@cite@punct@fulltrue } , citepunct / half .code:n = { \gbt@cite@punct@fullfalse } , mincompress .choice: , mincompress / 2 .code:n = { \gbt@min@compress@twotrue } , mincompress / 3 .code:n = { \gbt@min@compress@twofalse } , inline .choice: , inline / true .code:n = { \bool_set_true:N \l__gbt_cite_inline_bool \__gbt_set_cite_inline: } , inline / false .code:n = { \bool_set_false:N \l__gbt_cite_inline_bool \__gbt_set_cite_inline: } , inline .default:n = true , locator-in-brackets .choice: , locator-in-brackets / true .code:n = { \gbt@locator@in@bracketstrue } , locator-in-brackets / false .code:n = { \gbt@locator@in@bracketsfalse } , locator-in-brackets .default:n = true , % For compatibility locator-inside-brackets .choice: , locator-inside-brackets / true .code:n = { \gbt@locator@in@bracketstrue } , locator-inside-brackets / false .code:n = { \gbt@locator@in@bracketsfalse } , locator-inside-brackets .default:n = true , % % 参考文献表的选项 align .choice: , align / left .code:n = { \bool_set_true:N \l__gbt_align_left_bool } , align / right .code:n = { \bool_set_false:N \l__gbt_align_left_bool } , % % 控制 .bst 的选项 bibpunct .choice: , bibpunct / GB .code:n = { \prop_put:Nnn \l__gbt_bst_control_prop { CTL_bib_punct } { GB } } , bibpunct / half .code:n = { \prop_put:Nnn \l__gbt_bst_control_prop { CTL_bib_punct } { half } } , bibpunct / bylanguage .code:n = { \prop_put:Nnn \l__gbt_bst_control_prop { CTL_bib_punct } { bylanguage } } , convertpunct .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_convert_punct } \l_keys_choice_tl } , convertpunct .default:n = true , maxbibnames .code:n = { \prop_put:Nne \l__gbt_bst_control_prop { CTL_max_bib_names } {#1} } , minbibnames .code:n = { \prop_put:Nne \l__gbt_bst_control_prop { CTL_min_bib_names } {#1} } , maxcitenames .code:n = { \prop_put:Nne \l__gbt_bst_control_prop { CTL_max_cite_names } {#1} } , mincitenames .code:n = { \prop_put:Nne \l__gbt_bst_control_prop { CTL_min_cite_names } {#1} } , uppercasefamily .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_uppercase_family } \l_keys_choice_tl } , uppercasefamily .default:n = true , initializewithhyphen .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_initialize_with_hyphen } \l_keys_choice_tl } , initializewithhyphen .default:n = true , checkpinyin .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_check_pinyin } \l_keys_choice_tl } , checkpinyin .default:n = true , initializepinyin .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_initialize_pinyin } \l_keys_choice_tl } , initializepinyin .default:n = true , bibfinaland .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_bib_final_and } \l_keys_choice_tl } , bibfinaland .default:n = true , citefinaland .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_cite_final_and } \l_keys_choice_tl } , citefinaland .default:n = true , citelang .choices:nn = { byentry, macro, chinese, english } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_cite_lang } \l_keys_choice_tl } , spacebeforeetal .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_space_before_et_al } \l_keys_choice_tl } , spacebeforeetal .default:n = true , yearbeforetitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_year_before_title } \l_keys_choice_tl } , yearbeforetitle .default:n = true , nameyeardelim .choices:nn = { comma , period } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_name_year_delim } \l_keys_choice_tl } , sentencecase .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_sentence_case } \l_keys_choice_tl } , sentencecase .default:n = true , sentencecasetitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_sentence_case_title } \l_keys_choice_tl } , sentencecasetitle .default:n = true , sentencecasebooktitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_sentence_case_booktitle } \l_keys_choice_tl } , sentencecasebooktitle .default:n = true , sentencecasejournal .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_sentence_case_journal } \l_keys_choice_tl } , sentencecasejournal .default:n = true , capitalizesubtitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_capitalize_subtitle } \l_keys_choice_tl } , capitalizesubtitle .default:n = true , linktitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_link_title } \l_keys_choice_tl } , linktitle .default:n = true , articletitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_article_title } \l_keys_choice_tl } , articletitle .default:n = true , patentcountry .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_patent_country } \l_keys_choice_tl } , patentcountry .default:n = true , entrytypeid .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_entry_type_id } \l_keys_choice_tl } , entrytypeid .default:n = true , spacebeforetypeid .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_space_before_type_id } \l_keys_choice_tl } , spacebeforetypeid .default:n = true , entrymediumid .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_entry_medium_id } \l_keys_choice_tl } , entrymediumid .default:n = true , slash .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_slash } \l_keys_choice_tl } , slash .default:n = true , in .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_in } \l_keys_choice_tl } , in .default:n = true , emphbooktitle .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_emph_booktitle } \l_keys_choice_tl } , emphbooktitle .default:n = true , emphjournal .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_emph_journal } \l_keys_choice_tl } , emphjournal .default:n = true , shortjournal .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_short_journal } \l_keys_choice_tl } , shortjournal .default:n = true , journaldots .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_journal_dots } \l_keys_choice_tl } , journaldots .default:n = true , linkjournal .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_link_journal } \l_keys_choice_tl } , linkjournal .default:n = true , boldvolume .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_bold_volume } \l_keys_choice_tl } , boldvolume .default:n = true , unknownpublisher .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_unknown_publisher } \l_keys_choice_tl } , unknownpublisher .default:n = true , spacebeforepages .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_space_before_pages } \l_keys_choice_tl } , spacebeforepages .default:n = true , pageranges .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_page_ranges } \l_keys_choice_tl } , pageranges .default:n = true , pagerangedelim .code:n = { \prop_put:Nne \l__gbt_bst_control_prop { CTL_page_range_delim } {#1} } , urldate .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_urldate } \l_keys_choice_tl } , urldate .default:n = true , url .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_url } \l_keys_choice_tl } , url .default:n = true , doi .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_doi } \l_keys_choice_tl } , doi .default:n = true , eprint .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_eprint } \l_keys_choice_tl } , eprint .default:n = true , note .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_note } \l_keys_choice_tl } , note .default:n = true , enddot .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_end_dot } \l_keys_choice_tl } , enddot .default:n = true , bibwarn .choices:nn = { true, false } { \prop_put:NnV \l__gbt_bst_control_prop { CTL_warn_empty_field } \l_keys_choice_tl } , bibwarn .default:n = true , % % 兼容 v1.x.x 过时的接口 % TODO: v3.0.0 remove these 2015 .code:n = { \msg_warning:nnn { gbt7714 } { obsolete-option } { 2015 } \bool_set_true:N \l__gbt_legacy_interface_bool \bool_set_true:N \l__gbt_legacy_mmxv_bool } , 2005 .code:n = { \msg_warning:nnn { gbt7714 } { obsolete-option } { 2005 } \bool_set_true:N \l__gbt_legacy_interface_bool \bool_set_false:N \l__gbt_legacy_mmxv_bool } , super .code:n = { \msg_warning:nnn { gbt7714 } { obsolete-option } { super } \bool_set_true:N \l__gbt_legacy_interface_bool \bool_set_true:N \l__gbt_legacy_numeric_bool \bool_set_true:N \l__gbt_legacy_super_bool } , numbers .code:n = { \msg_warning:nnn { gbt7714 } { obsolete-option } { numbers } \bool_set_true:N \l__gbt_legacy_interface_bool \bool_set_true:N \l__gbt_legacy_numeric_bool \bool_set_false:N \l__gbt_legacy_super_bool } , authoryear .code:n = { \msg_warning:nnn { gbt7714 } { obsolete-option } { authoryear } \bool_set_true:N \l__gbt_legacy_interface_bool \bool_set_false:N \l__gbt_legacy_numeric_bool } , % 将选项传递给 \pkg{natbib} unknown .code:n = { \PassOptionsToPackage { \CurrentOption } { natbib } } , } \msg_new:nnn { gbt7714 } { obsolete-option } { The~ option~ "#1"~ is~ obsolete. } \keys_set:nn { gbt7714 } { % TODO: v3.0.0 将默认值改为 auto。 citepunct = half , mincompress = 2 , locator-in-brackets = false , align = left , } \PassOptionsToPackage { compress } { natbib } \ProcessKeyOptions [ gbt7714 ] \keys_define:nn { gbt7714 } { unknown .undefine: } % 调用宏包。 \RequirePackage { natbib } \RequirePackage { url } % 处理过时的样式名称 \cs_set_eq:NN \__gbt_original_bib_style:n \bibliographystyle \prop_const_from_keyval:Nn \c__gbt_deprecated_style_name_prop { gbt7714-2005-author-year = gbt7714-2005-authoryear , gbt7714-2005-numerical = gbt7714-2005-numeric , gbt7714-author-year = gbt7714-authoryear , gbt7714-numerical = gbt7714-numeric , } \cs_set_nopar:Npn \bibliographystyle #1 { \prop_get:NnNTF \c__gbt_deprecated_style_name_prop {#1} \l_tmpa_tl { \msg_warning:nnnV { gbt7714 } { deprecated-style-name } {#1} \l_tmpa_tl \file_if_exist:nTF { #1 .bst } { \__gbt_original_bib_style:n {#1} } { \exp_args:NV \__gbt_original_bib_style:n \l_tmpa_tl } } { \__gbt_original_bib_style:n {#1} } } \msg_new:nnn { gbt7714 } { deprecated-style-name } { Bibliography~ style~ name~ '#1'~ is~ deprecated.~ Use~ '#2'~ instead. } % 默认使用顺序编码制 \NAT@numberstrue \NAT@supertrue \cs_gset_nopar:Npn \NAT@open { [ } \cs_gset_nopar:Npn \NAT@close { ] } \cs_gset_nopar:Npn \NAT@sep { , } \cs_gset_nopar:Npn \NAT@aysep { , } \cs_gset_nopar:Npn \NAT@yrsep { \textsuperscript { , } } % 定义接口切换引用文献的标注法,可用 \cs{citestyle} 调用 \opt{numerical} % 或 \opt{authoryear},参见 \pkg{natbib}。 \cs_new:Npn \bibstyle@super { \bibpunct { [ } { ] } { , } { s } { , } { \textsuperscript { , } } \cs_set:Npn \NAT@spacechar { \ } } \cs_new:Npn \bibstyle@inline { \bibpunct { [ } { ] } { , } { n } { , } { , } \cs_set:Npn \NAT@spacechar { \ } } \cs_new:Npn \bibstyle@authoryear { \bibpunct % \NAT@cmt: The delimiter preceding a post-note [ \ifgbt@cite@punct@full , \else ,~ \fi ] { \ifgbt@cite@punct@full ( \else ( \fi } { \ifgbt@cite@punct@full ) \else ) \fi } % \NAT@sep: The delimiter between multiple cites { \ifgbt@cite@punct@full ; \else ; \fi } { a } % \NAT@aysep: The delimiter between author and year { \ifgbt@cite@punct@full , \else , \fi } % \NAT@yrsep: The delimiter between years with same author { \ifgbt@cite@punct@full , \else , \fi } \cs_set:Npn \NAT@spacechar { \ifgbt@cite@punct@full \else \ \fi } } \cs_new:Npn \bibstyle@numeric { \bool_if:NTF \l__gbt_cite_inline_bool { \bibstyle@inline } { \bibstyle@super } } \cs_new:Npn \bibstyle@numbers { \bibstyle@inline } \AtBeginDocument { \cs_set:Npn \__gbt_set_cite_inline: { \ifNAT@numbers \bool_if:NTF \l__gbt_cite_inline_bool { \bibstyle@inline } { \bibstyle@super } \fi } } % 在使用 \cs{bibliographystyle} 时自动切换引用文献的标注的样式。 \cs_new:cpn { bibstyle@gbt7714-numeric } { \bibstyle@numeric } \cs_new:cpn { bibstyle@gbt7714-authoryear } { \bibstyle@authoryear } \cs_new:cpn { bibstyle@gbt7714-2025-numeric } { \bibstyle@numeric } \cs_new:cpn { bibstyle@gbt7714-2025-authoryear } { \bibstyle@authoryear } \cs_new:cpn { bibstyle@gbt7714-2015-numeric } { \bibstyle@numeric } \cs_new:cpn { bibstyle@gbt7714-2015-authoryear } { \bibstyle@authoryear } \cs_new:cpn { bibstyle@gbt7714-2005-numeric } { \bibstyle@numeric } \cs_new:cpn { bibstyle@gbt7714-2005-authoryear } { \bibstyle@authoryear } % 兼容过时的样式名称 \cs_new:cpn { bibstyle@gbt7714-numerical } { \bibstyle@numeric } \cs_new:cpn { bibstyle@gbt7714-author-year } { \bibstyle@authoryear } % 下面修改 \pkg{natbib} 的引用格式。 % 为了减少依赖的宏包,这里直接重定义命令不使用 \pkg{etoolbox} 的 \cs{patchcmd}。 \cs_new_nopar:Npn \bibrangedash { - } \cs_new_nopar:Npn \multiciterangedelim { \bibrangedash } \ExplSyntaxOff % 顺序编码制的页码在方括号外。 % TODO: 最好处理上标式后与中文之间多余的空格,以及断行规则。 % % \renewcommand\NAT@citesuper[3]{% \ifNAT@swa \if*#2*\else #2\NAT@spacechar \fi \unskip\kern\p@ % \textsuperscript{\NAT@@open#1\NAT@@close}% % \if*#3*\else\NAT@spacechar#3\fi \textsuperscript{% \NAT@@open #1% \ifgbt@locator@in@brackets \if*#3*\else \NAT@cmt#3% \fi \NAT@@close \else \NAT@@close #3% \fi }% \else #1% \fi \endgroup } % 将 numbers 样式的 \cs{citep} 的页码置于括号外。 \renewcommand\NAT@citenum[3]{% \ifNAT@swa \NAT@@open \if*#2*\else #2\NAT@spacechar \fi #1% % \if*#3*\else\NAT@cmt#3\fi\NAT@@close \ifgbt@locator@in@brackets \if*#3*\else \NAT@cmt#3% \fi \NAT@@close \else \NAT@@close \if*#3*\else \textsuperscript{#3}% \fi \fi \else #1% \fi \endgroup } % Numeric 的 \cs{@citex} \def\NAT@citexnum[#1][#2]#3{% \NAT@reset@parser \NAT@sort@cites{#3}% \NAT@reset@citea \@cite{\def\NAT@num{-1}\let\NAT@last@yr\relax\let\NAT@nm\@empty \@for\@citeb:=\NAT@cite@list\do {\@safe@activestrue \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}% \@safe@activesfalse \@ifundefined{b@\@citeb\@extra@b@citeb}{% {\reset@font\bfseries?} \NAT@citeundefined\PackageWarning{natbib}% {Citation `\@citeb' on page \thepage \space undefined}}% {\let\NAT@last@num\NAT@num\let\NAT@last@nm\NAT@nm \NAT@parse{\@citeb}% \ifNAT@longnames\@ifundefined{bv@\@citeb\@extra@b@citeb}{% \let\NAT@name=\NAT@all@names \global\@namedef{bv@\@citeb\@extra@b@citeb}{}}{}% \fi \ifNAT@full\let\NAT@nm\NAT@all@names\else \let\NAT@nm\NAT@name\fi \ifNAT@swa \@ifnum{\NAT@ctype>\@ne}{% \@citea \NAT@hyper@{\@ifnum{\NAT@ctype=\tw@}{\NAT@test{\NAT@ctype}}{\NAT@alias}}% }{% \@ifnum{\NAT@cmprs>\z@}{% \NAT@ifcat@num\NAT@num {\let\NAT@nm=\NAT@num}% {\def\NAT@nm{-2}}% \NAT@ifcat@num\NAT@last@num {\@tempcnta=\NAT@last@num\relax}% {\@tempcnta\m@ne}% \@ifnum{\NAT@nm=\@tempcnta}{% \@ifnum{\NAT@merge>\@ne}{}{\NAT@last@yr@mbox}% }{% \advance\@tempcnta by\@ne \@ifnum{\NAT@nm=\@tempcnta}{% % \ifx\NAT@last@yr\relax % \def@NAT@last@yr{\@citea}% % \else % \def@NAT@last@yr{--\NAT@penalty}% % \fi % % \pkg{natbib} 默认在三个以上连续序号才会使用连接号, % 按照国标要求改为连续两个序号使用连接号。 % 参考 \url{https://tex.stackexchange.com/a/86991/82731}。 \ifgbt@min@compress@two \def@NAT@last@yr{\multiciterangedelim\NAT@penalty}% \else \ifx\NAT@last@yr\relax \def@NAT@last@yr{\@citea}% \else \def@NAT@last@yr{\multiciterangedelim\NAT@penalty}% \fi \fi }{% \NAT@last@yr@mbox }% }% }{% \@tempswatrue \@ifnum{\NAT@merge>\@ne}{\@ifnum{\NAT@last@num=\NAT@num\relax}{\@tempswafalse}{}}{}% \if@tempswa\NAT@citea@mbox\fi }% }% \NAT@def@citea \else \ifcase\NAT@ctype \ifx\NAT@last@nm\NAT@nm \NAT@yrsep\NAT@penalty\NAT@space\else \@citea \NAT@test{\@ne}\NAT@spacechar\NAT@mbox{\NAT@super@kern\NAT@@open}% \fi \if*#1*\else#1\NAT@spacechar\fi \NAT@mbox{\NAT@hyper@{{\citenumfont{\NAT@num}}}}% \NAT@def@citea@box \or \NAT@hyper@citea@space{\NAT@test{\NAT@ctype}}% \or \NAT@hyper@citea@space{\NAT@test{\NAT@ctype}}% \or \NAT@hyper@citea@space\NAT@alias \fi \fi }% }% \@ifnum{\NAT@cmprs>\z@}{\NAT@last@yr}{}% \ifNAT@swa\else % \@ifnum{\NAT@ctype=\z@}{% % \if*#2*\else\NAT@cmt#2\fi % }{}% % \NAT@mbox{\NAT@@close}% % % 将页码放在括号外边,并且置于上标。 \ifgbt@locator@in@brackets % \citeauthor 也会使用此命令生成, % 但是在 super 模式下会生成空的 \textsuperscript{} % 由于其底层是用数学实现的,导致后续的汉字前会插入多余空白。 % % 这里判断放入上标的是否为空。 \edef\NAT@tmp{% \@ifnum{\NAT@ctype=\z@}{#2}{}% \NAT@@close }% \if*\NAT@tmp*\else \NAT@mbox{% \@ifnum{\NAT@ctype=\z@}{% \if*#2*\else\NAT@cmt#2\fi }{}% \NAT@@close}% \fi \else \ifNAT@super \edef\NAT@tmp{% \NAT@@close \@ifnum{\NAT@ctype=\z@}{#2}{}% }% \if*\NAT@tmp*\else \NAT@mbox{% \NAT@@close \@ifnum{\NAT@ctype=\z@}{#2}{}% }% \fi \else \ifNAT@par \NAT@mbox{\NAT@@close}% \fi \@ifnum{\NAT@ctype=\z@}{% \if*#2*\else % 仿照 super 模式的 \NAT@mbox \unskip\nobreak\textsuperscript{#2}% \fi }{}% \fi \fi \fi }{#1}{#2}% }% % Author-year 模式以角标的形式著录引文页码。 \renewcommand\NAT@cite[3]{% \ifNAT@swa \NAT@@open \if*#2*\else#2\NAT@spacechar\fi #1% % \if*#3*\else\NAT@cmt#3\fi\NAT@@close \ifgbt@locator@in@brackets \if*#3*\else\NAT@cmt#3\fi\NAT@@close \else \NAT@@close \if*#3*\else \unskip\kern\p@ \textsuperscript{#3}% \fi \fi \else #1% \fi \endgroup } % Author-year 模式的 \cs{citet} 的页码: \def\NAT@citex% [#1][#2]#3{% \NAT@reset@parser \NAT@sort@cites{#3}% \NAT@reset@citea \@cite{\let\NAT@nm\@empty\let\NAT@year\@empty \@for\@citeb:=\NAT@cite@list\do {\@safe@activestrue \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}% \@safe@activesfalse \@ifundefined{b@\@citeb\@extra@b@citeb}{\@citea% {\reset@font\bfseries ?}\NAT@citeundefined \PackageWarning{natbib}% {Citation `\@citeb' on page \thepage \space undefined}\def\NAT@date{}}% {\let\NAT@last@nm=\NAT@nm\let\NAT@last@yr=\NAT@year \NAT@parse{\@citeb}% \ifNAT@longnames\@ifundefined{bv@\@citeb\@extra@b@citeb}{% \let\NAT@name=\NAT@all@names \global\@namedef{bv@\@citeb\@extra@b@citeb}{}}{}% \fi \ifNAT@full\let\NAT@nm\NAT@all@names\else \let\NAT@nm\NAT@name\fi \ifNAT@swa\ifcase\NAT@ctype \if\relax\NAT@date\relax \@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}\NAT@date}% \else \ifx\NAT@last@nm\NAT@nm\NAT@yrsep \ifx\NAT@last@yr\NAT@year \def\NAT@temp{{?}}% \ifx\NAT@temp\NAT@exlab\PackageWarningNoLine{natbib}% {Multiple citation on page \thepage: same authors and year\MessageBreak without distinguishing extra letter,\MessageBreak appears as question mark}\fi \NAT@hyper@{\NAT@exlab}% \else % \unskip % % 如果用全角符号,\unksip 会破坏“(张三,1984,1985)” 年份之间逗号后的空白 \ifgbt@cite@punct@full\else \unskip \fi \NAT@spacechar \NAT@hyper@{\NAT@date}% \fi \else \@citea\NAT@hyper@{% \NAT@nmfmt{\NAT@nm}% \hyper@natlinkbreak{% \NAT@aysep\NAT@spacechar}{\@citeb\@extra@b@citeb }% \NAT@date }% \fi \fi \or\@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}}% \or\@citea\NAT@hyper@{\NAT@date}% \or\@citea\NAT@hyper@{\NAT@alias}% \fi \NAT@def@citea \else \ifcase\NAT@ctype \if\relax\NAT@date\relax \@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}}% \else \ifx\NAT@last@nm\NAT@nm\NAT@yrsep \ifx\NAT@last@yr\NAT@year \def\NAT@temp{{?}}% \ifx\NAT@temp\NAT@exlab\PackageWarningNoLine{natbib}% {Multiple citation on page \thepage: same authors and year\MessageBreak without distinguishing extra letter,\MessageBreak appears as question mark}\fi \NAT@hyper@{\NAT@exlab}% \else % \unskip % % 如果用全角符号,\unksip 会破坏“张三(1984,1985)” 年份之间逗号后的空白 \ifgbt@cite@punct@full\else \unskip \fi \NAT@spacechar \NAT@hyper@{\NAT@date}% \fi \else \@citea\NAT@hyper@{% \NAT@nmfmt{\NAT@nm}% \hyper@natlinkbreak{\NAT@spacechar\NAT@@open\if*#1*\else#1\NAT@spacechar\fi}% {\@citeb\@extra@b@citeb}% \NAT@date }% \fi \fi \or\@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}}% \or\@citea\NAT@hyper@{\NAT@date}% \or\@citea\NAT@hyper@{\NAT@alias}% \fi \if\relax\NAT@date\relax \NAT@def@citea \else \NAT@def@citea@close \fi \fi }}% \ifNAT@swa\else % \if*#2*\else\NAT@cmt#2\fi % \if\relax\NAT@date\relax\else\NAT@@close\fi % % 在括号外边,以上标的形式著录引文页码。 \ifgbt@locator@in@brackets \if*#2*\else\NAT@cmt#2\fi \if\relax\NAT@date\relax\else\NAT@@close\fi \else \if\relax\NAT@date\relax\else \NAT@@close \fi \if*#2*\else \unskip\kern\p@ \textsuperscript{#2}% \fi \fi \fi}{#1}{#2}} % 如果使用全角符号则不加空格 \def\NAT@spacechar{\ifgbt@cite@punct@full\else\ \fi}% \DeclareRobustCommand\parencite {\begingroup\NAT@swatrue\let\NAT@ctype\z@\NAT@partrue \NAT@superfalse \let\NAT@mbox=\mbox \let\@cite\NAT@citenum \let\NAT@space\NAT@spacechar \let\NAT@super@kern\relax \@ifstar{\NAT@fulltrue\NAT@citetp}{\NAT@fullfalse\NAT@citetp}} % 兼容 RevTeX 的 \cs{onlinecite} 命令。 \DeclareRobustCommand\onlinecite {\begingroup\NAT@swatrue\let\NAT@ctype\z@\NAT@partrue \NAT@superfalse \let\NAT@mbox=\mbox \let\@cite\NAT@citenum \let\NAT@space\NAT@spacechar \let\NAT@super@kern\relax \@ifstar{\NAT@fulltrue\NAT@citetp}{\NAT@fullfalse\NAT@citetp}} \DeclareRobustCommand\inlinecite {\begingroup\NAT@swatrue\let\NAT@ctype\z@\NAT@partrue \NAT@superfalse \let\NAT@mbox=\mbox \let\@cite\NAT@citenum \let\NAT@space\NAT@spacechar \let\NAT@super@kern\relax \@ifstar{\NAT@fulltrue\NAT@citetp}{\NAT@fullfalse\NAT@citetp}} \DeclareRobustCommand\textcite {\begingroup\NAT@swafalse\let\NAT@ctype\z@\NAT@partrue \@ifstar{\NAT@fulltrue\NAT@citetp}{\NAT@fullfalse\NAT@citetp}} % 控制参考文献表的格式 \renewenvironment{thebibliography}[1]{% \bibsection \parindent\z@ \bibpreamble % 参考文献表的设置 \gbt@bib@setup \bibfont \list{\@biblabel{\the\c@NAT@ctr}}{\@bibsetup{#1}\global\c@NAT@ctr\z@}% \ifNAT@openbib \renewcommand\newblock{\par}% \else \renewcommand\newblock{\hskip .11em \@plus.33em \@minus.07em}% \fi % \sloppy\clubpenalty4000\widowpenalty4000 \sfcode`\.\@m \let\NAT@bibitem@first@sw\@firstoftwo \let\citeN\cite \let\shortcite\cite \let\citeasnoun\cite }{% \bibitem@fin \bibpostamble \def\@noitemerr{% \PackageWarning{natbib}{Empty `thebibliography' environment}% }% \endlist \bibcleanup } \ExplSyntaxOn % 控制参考文献表的标签格式对齐方式 \cs_set_nopar:Npn \@biblabel #1 { \hbox:n { [ #1 ] } \bool_if:NT \l__gbt_align_left_bool { \hfill } } \cs_new:Npn \gbt@bib@setup { % \__gbt_set_square_bracket_font: \__gbt_bib_url_setup: } % % 设置半角方括号使用中文字体。 % \cs_new:Npn \__gbt_set_square_bracket_font: { } % \hook_gput_code:nnn { begindocument / before } { . } % { % \@ifpackageloaded { xeCJK } % { % \cs_set:Npn \__gbt_set_square_bracket_font: % { % \xeCJKDeclareCharClass { FullLeft } { "005B } % \xeCJKDeclareCharClass { FullRight } { "005D } % } % } % { % % TODO: LuaTeXja 应该如何处理? % % \@ifpackageloaded { luatexja } % % { % % \cs_set:Npn \__gbt_set_square_bracket_font: % % { % % \ltjdefcharrange { 6 } { "005B } % % } % % } % % { } % } % } % 设置参考文献表的 URL 断行 % 参考 `biblatex` 的 \biburlsetup % \int_new:N \l__gbt_url_num_penalty_int \int_new:N \l__gbt_url_uc_penalty_int \int_new:N \l__gbt_url_lc_penalty_int \int_set:Nn \l__gbt_url_num_penalty_int { 9000 } \int_set:Nn \l__gbt_url_uc_penalty_int { 9000 } \int_set:Nn \l__gbt_url_lc_penalty_int { 9000 } \cs_new:Npn \__gbt_bib_url_setup: { \urlstyle { same } \muskip_set:Nn \Urlmuskip { 0 mu plus 3 mu } \mathchardef \UrlBigBreakPenalty = 100 \relax \mathchardef \UrlBreakPenalty = 200 \relax \cs_set_nopar:Npn \UrlBigBreaks { \do \: \do \- } \cs_set_nopar:Npn \UrlBreaks { \do \. \do \@ \do \/ \do \\ \do \! \do \_ \do \| \do \; \do \> \do \] \do \) \do \} \do \, \do \? \do \' \do \+ \do \= \do \# \do \$ \do \& \do \* \do \^ \do \" } \int_compare:nNnT { \l__gbt_url_num_penalty_int } > { 0 } { \clist_map_inline:nn { \1 , \2 , \3 , \4 , \5 , \6 , \7 , \8 , \9 , \0 } { \tl_put_right:Nn \UrlSpecials { \do ##1 { \mathchar `##1 \mskip 0 mu \relax \penalty \l__gbt_url_num_penalty_int } } } } \int_compare:nNnT { \l__gbt_url_uc_penalty_int } > { 0 } { \clist_map_inline:nn { \A , \B , \C , \D , \E , \F , \G , \H , \I , \J , \K , \L , \M , \N , \O , \P , \Q , \R , \S , \T , \U , \V , \W , \X , \Y , \Z } { \tl_put_right:Nn \UrlSpecials { \do ##1 { \mathchar `##1 \mskip 0 mu \relax \penalty \l__gbt_url_uc_penalty_int } } } } \int_compare:nNnT { \l__gbt_url_lc_penalty_int } > { 0 } { \clist_map_inline:nn { \a , \b , \c , \d , \e , \f , \g , \h , \i , \j , \k , \l , \m , \n , \o , \p , \q , \r , \s , \t , \u , \v , \w , \x , \y , \z } { \tl_put_right:Nn \UrlSpecials { \do ##1 { \mathchar`##1 \mskip 0 mu \relax \penalty \l__gbt_url_lc_penalty_int } } } } \cs_set_eq:NN \do \exp_not:N } % 修改 \cs{bibliography} 以处理 bst 格式控制文件。 \cs_set_eq:NN \__gbt_original_bibliography:n \bibliography \cs_set:Npn \bibliography #1 { \prop_if_empty:NTF \l__gbt_bst_control_prop { \__gbt_original_bibliography:n {#1} } { \__gbt_write_bst_control_file: \tl_set:Ne \l_tmpa_tl { \jobname \c__gbt_bst_control_file_suffix_tl } \tl_put_right:Nn \l_tmpa_tl { , #1 } \exp_args:NV \__gbt_original_bibliography:n \l_tmpa_tl } } \tl_const:Nn \c__gbt_bst_control_file_suffix_tl { -BSTcontrol } \tl_const:Nn \c__gbt_bst_control_entry_type_tl { GBT7714BSTCTL } \tl_const:Nn \c__gbt_bst_control_entry_key_tl { GBT7714:BSTcontrol } \iow_new:N \l__gbt_bst_control_iow \cs_new:Npn \__gbt_write_bst_control_file: { \iow_open:Nn \l__gbt_bst_control_iow { \jobname \c__gbt_bst_control_file_suffix_tl .bib } \iow_now:Ne \l__gbt_bst_control_iow { @ \c__gbt_bst_control_entry_type_tl \c_left_brace_str \c__gbt_bst_control_entry_key_tl , } \prop_map_inline:Nn \l__gbt_bst_control_prop { \iow_now:Ne \l__gbt_bst_control_iow { \c_space_tl \c_space_tl ##1 \c_space_tl = \c_space_tl {##2} , } } \iow_now:Ne \l__gbt_bst_control_iow { \c_right_brace_str } \iow_close:N \l__gbt_bst_control_iow \if@filesw \iow_now:Ne \@auxout { \token_to_str:N \citation { \c__gbt_bst_control_entry_key_tl } } \fi } % 兼容 v1.x.x 过时的接口: % TODO: v3.0.0 remove these \bool_if:NT \l__gbt_legacy_interface_bool { \foo \bool_if:NTF \l__gbt_legacy_mmxv_bool { \tl_set:Nn \l_tmpa_tl { 2015 } } { \tl_set:Nn \l_tmpa_tl { 2005 } } \bool_if:NTF \l__gbt_legacy_numeric_bool { \tl_set:Nn \l_tmpb_tl { numeric } \bool_if:NF \l__gbt_legacy_super_bool { \gbtsetup { inline = true } } } { \tl_set:Nn \l_tmpb_tl { authoryear } } \exp_args:Ne \bibliographystyle { gbt7714- \tl_use:N \l_tmpa_tl - \tl_use:N \l_tmpb_tl } } \ExplSyntaxOff % Patch \pkg{natbib} 内部命令,以支持 \cs{noopsort}。 % 参考 \url{https://tex.stackexchange.com/a/39718/82731}。 \let\NAT@bare@aux\NAT@bare \def\NAT@bare#1(#2){% \begingroup\edef\x{\endgroup \unexpanded{\NAT@bare@aux#1}(\@firstofone#2)}\x}