%%
%% ---------------------------------------------------------------
%% biblatex-gb7714-2015 --- A biblatex implementation of the
%% GBT7714-2015 citation style,numerical sequence
%% Maintained by huzhenzhen
%% E-mail: hzzmail@163.com
%% Released under the LaTeX Project Public License v1.3c or later
%% ---------------------------------------------------------------
%%
\ProvidesFile{gb7714-2015.cbx}[a biblatex citation style for GB/T 7714-2015]

%
%   加载标准样式
%
\RequireCitationStyle{numeric-comp} %numeric


%
%   选项设置
%
\ExecuteBibliographyOptions{
  %autocite  = superscript ,
  %autopunct = true       ,
  %sorting   = none        ,
  maxcitenames=1,
  mincitenames=1,
  uniquename=init,%因为使用了名字缩写选项，所以需要设置uniquename=init而不是full避免冲突
  uniquelist=minyear,
  labeldateparts,
  sortcites,
}

\newrobustcmd{\mkbibleftborder}{\gbleftbracket}
\newrobustcmd{\mkbibrightborder}{\gbrightbracket}

%修改\mkbibsuperscript宏在最后加上一个空白使得xeCJK不会自动在引用标签后面加上中英文之间的空白
%hzz,v1.0w,2021-0401
\renewrobustcmd{\mkbibsuperscript}[1]{%
  \unspace\allowhyphens\textsuperscript{%
    \begingroup
    \protected\long\def\mkbibsuperscript##1{%
      \blx@warning{Nested superscript}%
      \mkbibbrackets{##1}}%
    #1\endgroup}\kern\z@}

%
%   定义一个上标方括号wrapper
%
\newcommand*\mkbibsuperbracket[1]{%
  \mkbibsuperscript{\mkbibbrackets{#1}}%
}

%   修改postnote的输出格式
\DeclareFieldFormat{postnote}{#1}

%
%   重定义cite命令
%
%   方法:\DeclareCiteCommand{\cite}[\mkbibparens]{precode}{loopcode}{sepcode}{postcode}
%    v1.0p版后将cite的处理方式修改为类似pagescite，而不再使用biblatex的标准方式
\DeclareCiteCommand{\cite}[\mkbibsuperscript]%利用mkbibsuperbracket添加方括号
  {\mkbibleftborder\usebibmacro{cite:init}%
   \usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite:comp}}
  {}
  {\usebibmacro{cite:dump}\mkbibrightborder%
   \printfield{postnote}}
%   v1.0p 以前用的方式
%\DeclareCiteCommand{\cite}[\mkbibsuperbracket]%利用mkbibsuperbracket添加方括号
%  {\usebibmacro{cite:init}%
%   \usebibmacro{prenote}}
%  {\usebibmacro{citeindex}%
%   \usebibmacro{cite:comp}}
%  {}
%  {\usebibmacro{cite:dump}%
%   \usebibmacro{postnote}}

%
%   定义upcite命令
%   20180604，v1.0l，hzz
%   20190409，v1.0r，hzz
%   方法:对supercite增加[]
\newrobustcmd*{\upcite}{%
    \cite}

%
%   重定义parencite命令，以满足标签带页码的国标要求
%
\DeclareCiteCommand{\parencite}%[\mkbibbrackets]
  {\mkbibleftborder\usebibmacro{cite:init}%]
   \usebibmacro{prenote}}%
  {\usebibmacro{citeindex}%
   \usebibmacro{cite:comp}}
  {}
  {%[
  \usebibmacro{cite:dump}\mkbibrightborder%
   \mkbibsuperscript{\printfield{postnote}}}

%
%   新定义pagescite命令，以满足标签带页码的国标要求
%
%   原理方法:
%   1.新增页码输出宏
\newbibmacro*{postpages}{%
  \iffieldundef{postnote}
    {\printfield[postnote]{pages}}
    {\printfield{postnote}}}
%   2.新增\pagescite引用命令
\DeclareCiteCommand{\pagescite}[\mkbibsuperscript]%\mkbibbrackets,仍然用上标
  {\mkbibleftborder\usebibmacro{cite:init}%]直接添加方括号
   \usebibmacro{prenote}%
   }
  {\usebibmacro{citeindex}%
   \usebibmacro{cite:comp}}
  {}
  {\usebibmacro{cite:dump}\mkbibrightborder%
   \usebibmacro{postpages}}

%
%   定义yearpagescite，为与ay样式兼容，等同于\pagescite
%
\DeclareCiteCommand{\yearpagescite}[\mkbibsuperscript]%\mkbibbrackets,仍然用上标
  {\mkbibleftborder\usebibmacro{cite:init}%]直接添加方括号
   \usebibmacro{prenote}%
   }
  {\usebibmacro{citeindex}%
   \usebibmacro{cite:comp}}
  {}
  {\usebibmacro{cite:dump}\mkbibrightborder%
   \usebibmacro{postpages}}

%
%   定义\yearcite命令，为与ay样式兼容，且提供不输出页码的标签格式，
%
%   原理方法:等同于\pagescite，但不要页码
\DeclareCiteCommand{\yearcite}[\mkbibsuperscript]%\mkbibbrackets,仍然用上标
  {\mkbibleftborder\usebibmacro{cite:init}%]直接添加方括号
   \usebibmacro{prenote}%
   }
  {\usebibmacro{citeindex}%
   \usebibmacro{cite:comp}}
  {}
  {\usebibmacro{cite:dump}\mkbibrightborder}

%
%   定义\authornumcite命令，输出作者信息，然后在后面带上顺序编码
%   20180427，v1.0k，增加，hzz
%   gb7714样式新定义的命令都把cite放到最后，比如前面的pagescite，yearcite，这里的\authornumcite
%   区别于biblatex定义的命令都把cite放到前面，比如citeauthor等。
%见numeric.CBX
\newbibmacro*{cite}{%
  \printtext[bibhyperref]{%
    \printfield{labelprefix}%
    \printfield{labelnumber}%
    \ifbool{bbx:subentry}
      {\printfield{entrysetcount}}
      {}}}
%见numeric.CBX，\DeclareCiteCommand{\cite},
\DeclareCiteCommand{\authornumcite}%[\mkbibsuperscript]
  {\usebibmacro{prenote}}
  {\iffieldequalstr{userf}{cn}{\renewcommand*{\andothersdelim}{\addthinspace}}%\addthinspace
  {\renewcommand*{\andothersdelim}{\addspace}}%
  \printnames{labelname}\mkbibsuperscript{\mkbibbrackets{\usebibmacro{citeindex}%
   \usebibmacro{cite}}}}
  {\multicitedelim}
  {\mkbibsuperscript{\printfield{postnote}}}


%
%   增加如下多个命令
%   20190409，v1.0r，hzz
%   方法:利用newcommand或newrobustcmd命令进行定义
%   注意\citet和\citep命令之所以不用newrobustcmd，是为避免加载natbib模块后产生冲突
\DeclareCiteCommand{\citet}%
  {\usebibmacro{prenote}}
  {\iffieldequalstr{userf}{cn}{\renewcommand*{\andothersdelim}{\addthinspace}}%\addthinspace
  {\renewcommand*{\andothersdelim}{\addspace}}%
  \printnames{labelname}\mkbibsuperscript{\mkbibbrackets{\usebibmacro{citeindex}%
   \usebibmacro{cite}}}}
  {\multicitedelim}
  {\mkbibsuperscript{\printfield{postnote}}}


\DeclareCiteCommand{\citep}[\mkbibsuperscript]%利用mkbibsuperbracket添加方括号
  {\mkbibleftborder\usebibmacro{cite:init}%
   \usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite:comp}}
  {}
  {\usebibmacro{cite:dump}\mkbibrightborder%
   \printfield{postnote}}

\newrobustcmd*{\citetns}%
    {\textcite}

\newrobustcmd*{\citepns}%
    {\parencite}

\newrobustcmd*{\inlinecite}%
    {\parencite}


%textcite标注命令中的标点设置
%\DeclareDelimFormat[textcite]{andothersdelim}{\addspace}%

%textcite标注命令中的标点设置，注意只针对textcite命令。
\DeclareDelimFormat[textcite]{nameyeardelim}{}%\addcomma\space
\DeclareDelimFormat[textcite]{andothersdelim}{\iffieldequalstr{userf}{chinese}{\addthinspace}{\addspace}}%
\AtEveryCitekey{%
\iffieldequalstr{userf}{chinese}{\renewcommand*{\andothersdelim}{\addthinspace}}%\addthinspace
  {\renewcommand*{\andothersdelim}{\addspace}}%
}

%
%
%
\apptocmd{\refsection}{

%\edef\gb@refsecnum{\number\c@refsection}
\edef\gb@refsecnum{\number\c@refsection}%
\ifcsundef{gb@aystyle@section\gb@refsecnum}%
{}%
{

\renewcommand*{\iffinalcitedelim}{%
  \ifnumequal{\value{textcitecount}}{\value{textcitetotal}-1}}

\newbibmacro*{cite:init}{%
  \ifnumless{\value{multicitecount}}{2}
    {\global\boolfalse{cbx:parens}%
     \global\undef\cbx@lasthash
     \global\undef\cbx@lastyear}
    {\iffieldundef{prenote}
       {}
       {\global\undef\cbx@lasthash
        \global\undef\cbx@lastyear}}}

\newbibmacro*{cite:reinit}{%
  \global\undef\cbx@lasthash
  \global\undef\cbx@lastyear}

\newbibmacro*{cite}{%
  \iffieldundef{shorthand}
    {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
       {\usebibmacro{cite:label}%
        \setunit{\printdelim{nonameyeardelim}}%
        \usebibmacro{cite:labeldate+extradate}%
        \usebibmacro{cite:reinit}}
       {\iffieldequals{namehash}{\cbx@lasthash}
          {\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
                       \(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
             {\setunit{\addcomma}%
              \usebibmacro{cite:extradate}}
             {\setunit{\compcitedelim}%
              \usebibmacro{cite:labeldate+extradate}%
              \savefield{labelyear}{\cbx@lastyear}}}
          {\printnames{labelname}%
           \setunit{\printdelim{nameyeardelim}}%
           \usebibmacro{cite:labeldate+extradate}%
           \savefield{namehash}{\cbx@lasthash}%
           \savefield{labelyear}{\cbx@lastyear}}}}
    {\usebibmacro{cite:shorthand}%
     \usebibmacro{cite:reinit}}%
  \setunit{\multicitedelim}}

\newbibmacro*{citeyear}{%
  \iffieldundef{shorthand}
    {\iffieldundef{labelyear}
       {\usebibmacro{cite:label}%
        \usebibmacro{cite:reinit}}
       {\iffieldequals{namehash}{\cbx@lasthash}
          {\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
                       \(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
             {\setunit{\addcomma}%
              \usebibmacro{cite:extradate}}
             {\setunit{\compcitedelim}%
              \usebibmacro{cite:labeldate+extradate}%
              \savefield{labelyear}{\cbx@lastyear}}}
          {\usebibmacro{cite:labeldate+extradate}%
           \savefield{namehash}{\cbx@lasthash}%
           \savefield{labelyear}{\cbx@lastyear}}}}
    {\usebibmacro{cite:shorthand}%
     \usebibmacro{cite:reinit}}%
  \setunit{\multicitedelim}}

\newbibmacro*{textcite}{%
  \iffieldequals{namehash}{\cbx@lasthash}
    {\iffieldundef{shorthand}
       {\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
                    \(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
          {\setunit{\addcomma}%
           \usebibmacro{cite:extradate}}
          {\setunit{\compcitedelim}%
           \usebibmacro{cite:labeldate+extradate}%
           \savefield{labelyear}{\cbx@lastyear}}}
       {\setunit{\compcitedelim}%
        \usebibmacro{cite:shorthand}%
        \global\undef\cbx@lastyear}}
    {\ifnameundef{labelname}
       {\iffieldundef{shorthand}
          {\usebibmacro{cite:label}%
           \setunit{%
             \global\booltrue{cbx:parens}%
             \printdelim{nonameyeardelim}\bibopenparen}%
           \ifnumequal{\value{citecount}}{1}
             {\usebibmacro{prenote}}
             {}%
           \usebibmacro{cite:labeldate+extradate}}
          {\usebibmacro{cite:shorthand}}}
       {\printnames{labelname}%
        \setunit{%
          \global\booltrue{cbx:parens}%
          \printdelim{nameyeardelim}\bibopenparen}%
        \ifnumequal{\value{citecount}}{1}
          {\usebibmacro{prenote}}
          {}%
        \iffieldundef{shorthand}
          {\iffieldundef{labelyear}
             {\usebibmacro{cite:label}}
             {\usebibmacro{cite:labeldate+extradate}}%
           \savefield{labelyear}{\cbx@lastyear}}
          {\usebibmacro{cite:shorthand}%
           \global\undef\cbx@lastyear}}%
     \stepcounter{textcitecount}%
     \savefield{namehash}{\cbx@lasthash}}%
  \setunit{%
    \ifbool{cbx:parens}
      {\bibcloseparen\global\boolfalse{cbx:parens}}
      {}%
    \textcitedelim}}

\newbibmacro*{cite:shorthand}{%
  \printtext[bibhyperref]{\printfield{shorthand}}}

%
%   重定义cite:label，针对biblatex3.8以上版本set条目集的标注(引用)标签
%
%   原理方法:当条目是set时，v3.8以上版本，都没有有用的信息(区别于3.7以下版本set复制第一个成员的信息)，
%   于是利用entrykey来给出标签，那么就要set的条目关键字是需要的字符串，注意字符串中间不能有空格
\renewbibmacro*{cite:label}{%
  \iffieldundef{label}%
    {\iffieldundef{labeltitle}{\printtext[bibhyperref]{\printfield{entrykey}}}%entrykey
    {\printtext[bibhyperref]{\printfield[citetitle]{labeltitle}}}}%
    {\printtext[bibhyperref]{\printfield{label}}}}

\newbibmacro*{cite:labeldate+extradate}{%
  \iffieldundef{labelyear}
    {}
    {\printtext[bibhyperref]{\printlabeldateextra}}}

\newbibmacro*{cite:extradate}{%
  \iffieldundef{extradate}
    {}
    {\printtext[bibhyperref]{\printfield{extradate}}}}



%
%   重定义cite:label，针对biblatex3.8以上版本set条目集的标注(引用)标签
%
%   原理方法:当条目是set时，v3.8以上版本，都没有有用的信息(区别于3.7以下版本set复制第一个成员的信息)，
%   于是利用entrykey来给出标签，那么就要set的条目关键字是需要的字符串，注意字符串中间不能有空格
\renewbibmacro*{cite:label}{%
  \iffieldundef{label}%
    {\iffieldundef{labeltitle}{\printtext[bibhyperref]{\printfield{entrykey}}}%entrykey
    {\printtext[bibhyperref]{\printfield[citetitle]{labeltitle}}}}%
    {\printtext[bibhyperref]{\printfield{label}}}}

%
%   重定义cite命令
%
%   方法:\DeclareCiteCommand{\cite}[\mkbibparens]{precode}{loopcode}{sepcode}{postcode}
%    v1.0p版后将cite的处理方式修改为类似pagescite，而不再使用biblatex的标准方式
\DeclareCiteCommand{\cite}
  {\usebibmacro{cite:init}%
  \renewbibmacro*{postnote}{%
  \iffieldundef{postnote}%
    {}%
    {\thefield{postnote}}}%
    \gbleftparen\usebibmacro{prenote}}%)
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {}
  {\gbrightparen\mkbibsuperscript{\usebibmacro{postnote}}%\usebibmacro{postnote}
  }

\DeclareCiteCommand{\parencite}[\mkbibparens]
  {\usebibmacro{cite:init}%
   \usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {}
  {\usebibmacro{postnote}}

%
%   定义\authornumcite命令，输出作者信息，然后在后面带上顺序编码
%   20180427，v1.0k，增加，hzz
%   20190409，v1.0r，hzz
%   为与顺序编码制兼容，增加了命令，定义与citet相同
\newbibmacro*{citet}{%
  \iffieldundef{shorthand}
    {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
       {\usebibmacro{cite:label}%
        \setunit{\printdelim{nonameyeardelim}}%
        \usebibmacro{cite:labeldate+extradate}%
        \usebibmacro{cite:reinit}}
       {\iffieldequals{namehash}{\cbx@lasthash}
          {\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
                       \(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
             {\setunit{\addcomma}%
              \usebibmacro{cite:extradate}}
             {\setunit{\compcitedelim}%
              \usebibmacro{cite:labeldate+extradate}%
              \savefield{labelyear}{\cbx@lastyear}}}
          {\printnames{labelname}%
           %\setunit{\printdelim{nameyeardelim}}%
           \gbleftparen\usebibmacro{cite:labeldate+extradate}\gbrightparen%
           \savefield{namehash}{\cbx@lasthash}%
           \savefield{labelyear}{\cbx@lastyear}}}}
    {\usebibmacro{cite:shorthand}%
     \usebibmacro{cite:reinit}}%
  \setunit{\multicitedelim}}

\DeclareCiteCommand{\authornumcite}%
  {\usebibmacro{cite:init}%
  \renewbibmacro*{postnote}{%
  \iffieldundef{postnote}%
    {}%
    {\thefield{postnote}}}%
    \usebibmacro{prenote}}%
  {\usebibmacro{citeindex}%
   \usebibmacro{citet}}
  {}
  {\mkbibsuperscript{\usebibmacro{postnote}}%\usebibmacro{postnote}
  }

%
%   增加如下多个命令
%   20190409，v1.0r，hzz
%   方法:利用newcommand或newrobustcmd命令进行定义
%   注意\citet和\citep命令之所以不用newrobustcmd，是为避免加载natbib模块后产生冲突

%同\authornumcite
\DeclareCiteCommand{\citet}%
  {\usebibmacro{cite:init}%
  \renewbibmacro*{postnote}{%
  \iffieldundef{postnote}%
    {}%
    {\thefield{postnote}}}%
    \usebibmacro{prenote}}%
  {\usebibmacro{citeindex}%
   \usebibmacro{citet}}
  {}
  {\mkbibsuperscript{\usebibmacro{postnote}}%\usebibmacro{postnote}
  }

%同cite
\DeclareCiteCommand{\citep}
  {\usebibmacro{cite:init}%
  \renewbibmacro*{postnote}{%
  \iffieldundef{postnote}%
    {}%
    {\thefield{postnote}}}%
    \gbleftparen\usebibmacro{prenote}}%
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {}
  {\gbrightparen\mkbibsuperscript{\usebibmacro{postnote}}%\usebibmacro{postnote}
  }


}
}{}{}
