使用 xstring 用不同的宏替换宏

使用 xstring 用不同的宏替换宏

xstring 员工……

目标

我想在特定文本的开头和结尾分别创建两个标签。我已经成功编写了一些代码来执行此操作,请参阅以下代码:

\usepackage{xstring}
\usepackage{lineno}
\linenumbers
\usepackage{hyperref}
\newcommand{\hlabel}[1]{\label{#1}\hypertarget{#1}{\linelabel{line:#1}}}

\makeatother
\newcommand{\clab}[2]{%
\protected@write \@auxout {}{\string \newlabel {r:#1}{{#2}{}}}\hlabel{#1}#2\hlabel{#1end}}
\makeatother

我可以用

\clab{lab1}{some text, some text, more text...}

创建两个标签,分别指向文本的开头和结尾“一些文本,一些文本,更多文本......”

有些错误

\clab{lab}{text...}如果像这样使用,该函数将会出错:

  \clab{lab1}{some text, some text, more text..., \clab{lab2}{other text, other text, more other text...}, even more text...}

我失败的解决方案

我从一个示例中找到了一些代码xstring包(第 18-19 页)可以用另一个函数替换该函数。我的想法是使用包将内部函数替换\clab{lab2}{text...}为另一个空函数。\elab{lab2}{text...}xstring

首先定义模式并替换函数名称:
\expandarg
\def\pattern{\clab}
\def\replace{\elab}
然后定义两个函数\clab\elab
 % define a empty function to replace the function \clab
 \newcommand{\elab}[2]{#2}  

 % define a function \clab{label}{texts, texts, blabla}
 \newcommand{\clab}[2]{%
 \protected@write \@auxout {}{\string \newlabel {r:#1}{{#2}{}}}\hlabel{#1}#2\hlabel{#1end}}
最后,我使用 xstring 包将 \clab 函数替换为 \elab 函数:

修改#2----->\StrSubstitute[2]{#2}{\pattern}{\replace}

\protected@write \@auxout {}{\string \newlabel {r:#1}{{#2}{}}}\hlabel{#1}#2\hlabel{#1end}}

具体如下:

\protected@write \@auxout {}{\string \newlabel {r:#1}{{#2}{}}}\hlabel{#1}\StrSubstitute[2]{#2}{\pattern}{\replace}\hlabel{#1end}}

还是错误,请帮忙!

可执行的 LaTeX 代码在这里:

LaTeX 代码

请阅读以下代码并帮助我解决问题

\documentclass{article}
\usepackage{xstring}
\usepackage{lineno}
\linenumbers
\usepackage{hyperref}
\newcommand{\hlabel}[1]{\label{#1}\hypertarget{#1}{\linelabel{line:#1}}}

% learn from a example of xstring package (page 18-19, xstring.pdf)
\expandarg
\def\pattern{\clab}
\def\replace{\elab}

\makeatletter
  % define a empty function to replace the function \clab
  \newcommand{\elab}[2]{#2}  

 % define a function \clab{label}{texts, texts, blabla}
  % to create two labels, one is at the beginning of the texts
  % the other is at the end of the texts
  \newcommand{\clab}[2]{%
    % I use the following line to do the job,
    % it is fine to do 
    % \clab{lab1}{texts texts} texts, \clab{lab2}{texts texts} texts, 
    % but it goes wrong with
    % \clab{lab1}{texts texts texts, \clab{lab2}{texts texts} texts}, 
  %\protected@write \@auxout {}{\string \newlabel {r:#1}{{#2}{}}}\hlabel{#1}#2\hlabel{#1end}}
    %so I tried to find the solution,
    % the idea is using xstring function to replace the \clab{lab2}{texts texts texts} by a empty function
    % \elab{lab2}{texts texts texts},
    % I use the following code to do the job, but it still goes wrong!!
    % \expandarg
    % \def\pattern{\clab}
    % \def\replace{\elab}
    % \StrSubstitute[2]{#2}{\pattern}{\replace}
  \protected@write \@auxout {}{\string \newlabel {r:#1}{{#2}{}}}\hlabel{#1}\StrSubstitute[2]{#2}{\pattern}{\replace}\hlabel{#1end}}
\makeatother


\begin{document}

THis one not work:
% please uncomment the following line to see the error messages

 % \clab{lab1}{one two three four \clab{lab2}{five six seven eigth} nine ten}.

THis one works:

\clab{lab1}{one two three four}, \clab{lab2}{five six seven eigth} nine ten.

\end{document}
% end of file template.tex

答案1

\documentclass{article}
\usepackage{xstring}
\usepackage{lineno}
\linenumbers
\usepackage{hyperref}
\newcommand{\hlabel}[1]{\label{#1}\hypertarget{#1}{\linelabel{line:#1}}}

\makeatletter
\newcommand{\clab}[2]{%
  \protected@write\@auxout{\let\clab\@secondoftwo}{\string\newlabel{r:#1}{{#2}{}}}%
  \hlabel{#1}#2\hlabel{#1end}}

\makeatother
\begin{document}
  \clab{lab1}{one two three four \clab{lab2}{five six seven eigth} nine ten}.
\end{document}

相关内容