替换具有特定参数的 \cite 实例

替换具有特定参数的 \cite 实例

在 LaTeX 中,有没有办法定义一个宏(或其他东西)来替换每个实例

\cite{a_literal_string}

\ref{appendix:a_different_literal_string}

无需触及\cite没有参数的实例a_literal_string?我想对几种不同的可能替代品进行同样的操作。

这里的想法是,我将一些模块化文档纳入一个更大的项目,并希望将其中一些用作附录。我不想只是查找/替换,因为当子文档未在更大的项目中使用时,它们需要能够相互引用。

答案1

expl3以下是使用和的实现xparse

\begin{filecontents*}{\jobname.bib}
@article{cite:a,
 author={A. Uthor},
 title={Title a},
 journal={J. A},
 year={2014},
}
@article{cite:b,
 author={B. Athor},
 title={Title b},
 journal={J. B},
 year={2014},
}
@article{cite:c,
 author={C. Ethor},
 title={Title c},
 journal={J. C},
 year={2014},
}
\end{filecontents*}

\documentclass{article}
\usepackage{xparse,letltxmacro}
\LetLtxMacro{\latexcite}{\cite}

\ExplSyntaxOn
\RenewDocumentCommand{\cite}{om}
 {
  \IfNoValueTF{#1}
   { \daniel_cite_or_ref:n { #2 } }
   { \latexcite[#1]{#2} }
 }
\NewDocumentCommand{\addsubstitution}{mm}
 {
  \tl_gput_right:Nn \g_daniel_changes_tl { {#1}{\ref{#2}} }
 }

\tl_new:N \g_daniel_changes_tl

\cs_new_protected:Npn \daniel_cite_or_ref:n #1
 {
  \str_case:nVTF { #1 } \g_daniel_changes_tl
  {
   % \nocite{#1} %%%% <---- uncomment this line if you want \nocite
  }
  {
   \latexcite{#1}
  }
 }

\cs_generate_variant:Nn \str_case:nnTF { nV }
\ExplSyntaxOff

\addsubstitution{cite:a}{ref:a}
\addsubstitution{cite:b}{ref:b}

\begin{document}

\section{Something}\label{sec:some}

Here we do the citations: \cite{cite:a}, \cite{cite:b}, 
\cite{cite:c} and \cite[p.~42]{cite:c}

\appendix

\section{First appendix}\label{ref:a}

Text

\section{Second appendix}\label{ref:b}

Text

\bibliographystyle{plain}
\bibliography{\jobname}

\end{document}

您应该在\cite命令中只使用一个项目;考虑替换的多个引用是可能的,但它需要对最终格式做出决定。

使用\addsubstitution命令添加您想要执行的替换:第一个参数是引用键,第二个参数是标签。

在参考文献中仅插入实际引用的项目;如果您还想添加替换的项目,只需取消\nocite上面宏的注释即可。

在此处输入图片描述

实施注意事项

expl3函数\str_case:nnTF有四个参数:

  1. 要检查的字符串;
  2. 一组对{<string>}{<action>}
  3. 如果找到匹配项该怎么办?
  4. 如果没有找到匹配项该怎么办。

对于变体\str_case:nVTF,第二个参数是包含对集的标记列表变量。

如果给出了可选参数,则新\cite命令将使用原始命令;否则,它将控制权传递给检查参数是否符合存储在中的一组对的命令;此变量由任意数量的命令填充。\cite\daniel_cite_or_ref:n\g_daniel_changes_tl\addsubstitution

添加其他功能虽然不简单,但很容易,例如在参数中接受多个键,\cite并决定当键需要替换时该做什么。

答案2

如果您愿意使用 LuaLaTeX,那么您可以使用 Lua 的强大string.gsub函数来实现您的目标。在下面的示例中,Lua 端代码存储在名为 的文件中string_replacements.lua。(除了最简单的情况外,通常最简单的方法是将 Lua 代码存储在单独的文件中并使用指令调用它\directlua{ require("string_replacements.lua")}。)该函数replace_string可以执行多个字符串替换。Is 被分配给process_input_buffer回调,它会完成其工作LaTeX 进行任何处理;输入文件的内容不会被修改。

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luatexbase}
\directlua{require("string_replacements.lua")}

\begin{document}
\section{Hello}
Here's a cross-reference to Appendix \cite{a_literal_string}. 
And here's a cross-reference to abcdefuvwxyz.

\appendix
\section{Good-bye} \label{appendix:a_different_literal_string}
\begin{equation} \label{eq:pyth}
a^2+b^2=c^2
\end{equation}
\end{document}

其内容string_replacements.lua为:

-- string_replacements.lua
   local function replace_string ( line )
       line = string.gsub ( line, 
           "\\cite{a_literal_string}" , 
           "\\ref{appendix:a_different_literal_string}" )
       line = string.gsub ( line,
           "abcdefuvwxyz",
           "equation~(\\ref{eq:pyth})" )
       return line
   end
   luatexbase.add_to_callback( "process_input_buffer", 
       replace_string, "replace_string" )

答案3

也许你需要这样的东西:

\def\speclabel#1#2{\expandafter\def\csname slab:#1\endcsname{#2}}
\let\citeOri=\cite
\def\cite#1{\expandafter\ifx\csname slab:#1\endcsname\relax\citeOri{#1}%
   \else \expandafter\expandafter\expandafter\ref
         \expandafter\expandafter\expandafter{\csname slab:#1\endcsname}\fi
}
\speclabel {a_literal_string}       {a_different_literal_string}
\speclabel {another_literal_strig}  {another_different_litral_string}

Now \cite{normal} behaves normal but \cite{a_literal_string} expands
to \ref{a_different_literal_string}.

您必须通过\speclabel宏声明转换,然后才能使用正常的\cite

相关内容