LaTeX3 RenewDocumentCommand 用于引用带有可选标点符号参数

LaTeX3 RenewDocumentCommand 用于引用带有可选标点符号参数

处理引文时,有许多不同的方式必须将引文纳入文本中。即使您只使用数字格式(此示例不包括作者年份样式的引文)。

虽然只使用数字报告系统,但我必须反复更改的两种最常见风格包括

  • 行内、句内、方括号内、句子标点符号内的数字(IEEE)
  • 空格吞噬了标点符号外的上标数字

natbib 很好地让我能够非常快速地在这些格式之间切换,并将格式重定向到不同的 bst 文件。

不幸的是,我必须手动浏览我的文本并将标点符号移到参考文献的另一侧。

我不得不一直这样做,因为合作者们就是拿不定主意,最终我不得不写一个修改版的 cite 命令,如果引用中有标点符号,我只需将其作为参数添加,全局分配到引用本身之前或之后的位置。

在我的完整文档中(唯一的主要例外是它包含 bibunits),这可以很好地编译,但它无法将 [.] 识别为参数,它只是将其附加在引用之后。以下 MWE 将无法完全编译,但我无法确定它是否因为缺少包而失败,还是因为我的LaTeX3命令有问题。

我之前已经写过很多DeclareDocumentCommands,没有任何参数问题m+ o,所以我不知道为什么RenewDocumentCommand会失败。

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@article{greenwade93,
    author  = "George D. Greenwade",
    title   = "The {C}omprehensive {T}ex {A}rchive {N}etwork ({CTAN})",
    year    = "1993",
    journal = "TUGBoat",
    volume  = "14",
    number  = "3",
    pages   = "342--351"
}

@book{goossens93,
    author    = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
    title     = "The LaTeX Companion",
    year      = "1993",
    publisher = "Addison-Wesley",
    address   = "Reading, Massachusetts"
}
\end{filecontents}


\usepackage{expl3}
\usepackage{xparse}
\usepackage{xpatch}  % can exclude etoolbox. xpatch loads it anyway, since xpatch extends etoolbox
\usepackage{letltxmacro}

\usepackage[numbers,super,comma,sort&compress]{natbib}

\global\let\originalcite\cite
\ExplSyntaxOn
\RenewDocumentCommand{\cite}{ m+ o }
{
    % two arguments, the citation string, and an optional argument of the punctuation
    \tl_if_blank:VTF{#2}{\originalcite{#1}}%
    {%
        {\gobble}{#2}{\originalcite{#1}}
    }%
}
\ExplSyntaxOff


\begin{document}

The original cite command \originalcite{goossens93}.

Depending on the style I work with I will have to change everything manually to:  The original cite command.\originalcite{goossens93}

But if I can create a macro, I only have to add a toggle, or change the order manually.  Of course increasing the complexity of the logic is possible to work for different types of punctuation, but this is a MWE after all.  The modified cite command I am trying to produce is \cite{goossens93}[.]


\bibliographystyle{plainnat}
\bibliography{\jobname}

\end{document}

更新

为了简化问题,我尝试删除一些内容,bibunits以便其他人更容易编译。结果发现,bibunits这是我的最初罪魁祸首,导致原本应该是参数的内容被文字排版。使用解决方案建议更新了下面的 MWE。

\begin{filecontents}{\jobname.bib}
@article{greenwade93,
    author  = "George D. Greenwade",
    title   = "The {C}omprehensive {T}ex {A}rchive {N}etwork ({CTAN})",
    year    = "1993",
    journal = "TUGBoat",
    volume  = "14",
    number  = "3",
    pages   = "342--351"
}

@book{goossens93,
    author    = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
    title     = "The LaTeX Companion",
    year      = "1993",
    publisher = "Addison-Wesley",
    address   = "Reading, Massachusetts"
}
\end{filecontents}

\documentclass{article}

\usepackage{xparse}
\usepackage{xpatch}
\usepackage{letltxmacro}

\usepackage[numbers,super,comma,sort&compress]{natbib}
\usepackage{bibunits}
\defaultbibliographystyle{plainnat}
\defaultbibliography{\jobname}

\LetLtxMacro\originalcite\cite

\ExplSyntaxOn % just not to worry about spaces and end-of-lines
\RenewDocumentCommand{\cite}{ m o }
 {
  \IfValueT { #2 }{ \unskip #2 }
  \originalcite { #1 }
 }
\ExplSyntaxOff


\begin{document}

\begin{bibunit}
The original cite command \originalcite{goossens93}.

Depending on the style I work with I will have to change everything 
manually to:  The original cite command.\originalcite{goossens93}

But if I can create a macro, I only have to add a toggle, or change 
the order manually.  Of course increasing the complexity of the logic 
is possible to work for different types of punctuation, but this is 
a MWE after all.  The modified cite command I am trying to produce 
is \cite{goossens93}[.]
\end{bibunit}

\end{document}

答案1

如果我正确理解了你的问题,你希望将尾随的可选参数打印在上标之前。

  1. \tl_if_blank:VTF是错误的函数,因为这V意味着需要一个变量;

  2. {\gobble}{#2}{\originalcite{#1}}是没有意义的;

  3. m+o意味着最后一个(可选)参数是“长”的,也就是说,它接受\par它;它应该读作m +o,而不是m+ o,但你不希望\par在任何一个参数中。

正确解决方案:如果可选参数不存在,则不执行任何操作,否则执行“ \unskip”并在引用前打印。使用xparse处理参数的功能,而不是像 这样的低级函数\tl_if_blank:nTF

\begin{filecontents}{\jobname.bib}
@article{greenwade93,
    author  = "George D. Greenwade",
    title   = "The {C}omprehensive {T}ex {A}rchive {N}etwork ({CTAN})",
    year    = "1993",
    journal = "TUGBoat",
    volume  = "14",
    number  = "3",
    pages   = "342--351"
}

@book{goossens93,
    author    = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
    title     = "The LaTeX Companion",
    year      = "1993",
    publisher = "Addison-Wesley",
    address   = "Reading, Massachusetts"
}
\end{filecontents}

\documentclass{article}

%\usepackage{expl3} % xparse loads it
\usepackage{xparse}
\usepackage{xpatch}
\usepackage{letltxmacro}

\usepackage[numbers,super,comma,sort&compress]{natbib}

\LetLtxMacro\originalcite\cite

\ExplSyntaxOn % just not to worry about spaces and end-of-lines
\RenewDocumentCommand{\cite}{ m o }
 {
  \IfValueT { #2 }{ \unskip #2 }
  \originalcite { #1 }
 }
\ExplSyntaxOff


\begin{document}

The original cite command \originalcite{goossens93}.

Depending on the style I work with I will have to change everything 
manually to:  The original cite command.\originalcite{goossens93}

But if I can create a macro, I only have to add a toggle, or change 
the order manually.  Of course increasing the complexity of the logic 
is possible to work for different types of punctuation, but this is 
a MWE after all.  The modified cite command I am trying to produce 
is \cite{goossens93}[.]

\bibliographystyle{plainnat}
\bibliography{\jobname}

\end{document}

在此处输入图片描述

使用时bibunits,必须在加载之前重新定义\cite,因为包会\cite在每个环境开始时重新定义bibunit。或者更简单地说,必须更新\std@cite才能使用重新定义的\cite命令。

\begin{filecontents}{\jobname.bib}
@article{greenwade93,
    author  = "George D. Greenwade",
    title   = "The {C}omprehensive {T}ex {A}rchive {N}etwork ({CTAN})",
    year    = "1993",
    journal = "TUGBoat",
    volume  = "14",
    number  = "3",
    pages   = "342--351"
}

@book{goossens93,
    author    = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
    title     = "The LaTeX Companion",
    year      = "1993",
    publisher = "Addison-Wesley",
    address   = "Reading, Massachusetts"
}
\end{filecontents}

\documentclass{article}

\usepackage{xparse}
\usepackage{xpatch}
\usepackage{letltxmacro}

\usepackage[numbers,super,comma,sort&compress]{natbib}
\usepackage{bibunits}
\defaultbibliographystyle{plainnat}
\defaultbibliography{\jobname}

\ExplSyntaxOn % just not to worry about spaces and end-of-lines
\LetLtxMacro\originalcite\cite
\RenewDocumentCommand{\cite}{ m o }
 {
  \IfValueT { #2 }{ \unskip #2 }
  \originalcite { #1 }
 }
\ExplSyntaxOff

% update the command bibunits uses for the original \cite
\makeatletter
\let\std@cite\cite
\makeatother

\begin{document}

\begin{bibunit}[plainnat]
The original cite command \originalcite{goossens93}.

Depending on the style I work with I will have to change everything 
manually to:  The original cite command.\originalcite{goossens93}

But if I can create a macro, I only have to add a toggle, or change 
the order manually.  Of course increasing the complexity of the logic 
is possible to work for different types of punctuation, but this is 
a MWE after all.  The modified cite command I am trying to produce 
is \cite{goossens93}[.]

\putbib

\end{bibunit}

\end{document}

输出与以前相同。

答案2

一个可能的解决方案(如果我理解正确的话):

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@article{greenwade93,
    author  = "George D. Greenwade",
    title   = "The {C}omprehensive {T}ex {A}rchive {N}etwork ({CTAN})",
    year    = "1993",
    journal = "TUGBoat",
    volume  = "14",
    number  = "3",
    pages   = "342--351"
}

@book{goossens93,
    author    = "Michel Goossens and Frank Mittelbach and Alexander Samarin",
    title     = "The LaTeX Companion",
    year      = "1993",
    publisher = "Addison-Wesley",
    address   = "Reading, Massachusetts"
}
\end{filecontents}


\usepackage{letltxmacro}

%\usepackage[numbers,super,comma,sort&compress]{natbib}% Toggle this line
\usepackage[numbers,comma,sort&compress]{natbib}% Toggle this line

\global\let\originalcite\cite

\makeatletter
\def\cite#1{\Cite{#1}}
\def\Cite#1{\@ifnextchar[{\@Cite#1}{\@Cite#1[]}}
\def\@Cite#1[#2]{\ifNAT@super\unskip#2\originalcite{#1}\else\originalcite{#1}\unskip#2\fi}%
\makeatother


\begin{document}

The original cite command \originalcite{goossens93}.

Depending on the style I work with I will have to change everything
manually to:  The original cite command.\originalcite{goossens93}

But if I can create a macro, I only have to add a toggle, or change the
order manually.  Of course increasing the complexity of the logic is
possible to work for different types of punctuation, but this is a MWE
after all.  The modified cite command I am trying to produce is
\cite{goossens93}[.]


\bibliographystyle{plainnat}
\bibliography{\jobname}

\end{document}

相关内容