使用 LaTeX3 泛化宏

使用 LaTeX3 泛化宏

我正在尝试增加我的 LaTeX3-fu,但是在文档开始之前遇到打印输出的错误。

我正在尝试概括如何通过章节编号获取章节标题?

我也知道 LaTeX3 的强大功能是(主要)废除\expandafter,但我不知道是否存在一对一关系的等效语法。(我​​真的只是想在这里学习 :-)。)

这是我的代码:

\documentclass{article}

\usepackage{xparse}

% Macro to insert labels at the end of other macros
\ExplSyntaxOn
\NewDocumentCommand{\labelize}{mm}{
  % Automatically inserts a label of the form \label{#2:\the#1}for
  % referencing after every #1

  % For example:
  % \labelize{section}{auto-section}
  % ...
  % \begin{document}
  % \section{something}
  % -->\label{auto-section:1}
  % \section{something else}
  % -->\label{auto-section:2}
  % \end{document}


  % #1 : Macro to labelize
  % #2 : Prefix for label

  % Store the old macro
  \let\expandafter\csname old#1\endcsname\expandafter\csname #1\endcsname

  % Adapted from https://tex.stackexchange.com/questions/76078/
               % how-to-get-the-section-title-by-section-number
  \expandafter\renewcommand\csname #1\endcsname[2]{
    \ifx##1\relax
      \csname old#1\endcsname{##2}
    \else
      \csname old#1\endcsname[##1]{##2}
    \fi
    \label{#2:\csname the#1\endcsname}%
  }
}
\ExplSyntaxOff

\labelize{section}{auto@section}

\begin{document}
Hi
\end{document}

答案1

我不知道xparseLaTeX3 与此有什么关系。你几乎所有的\expandafter命令都放错了地方。

这有效,但您将失去使用的能力\section*

\documentclass{article}

% Macro to insert labels at the end of other macros
\newcommand{\labelize}[2]{%
  % Automatically inserts a label of the form \label{#2:\the#1}for
  % referencing after every #1
  % For example:
  % \labelize{section}{auto-section}
  % ...
  % \begin{document}
  % \section{something}
  % -->\label{auto-section:1}
  % \section{something else}
  % -->\label{auto-section:2}
  % \end{document}
  % #1 : Macro to labelize
  % #2 : Prefix for label
  % Store the old macro
  \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname
  % Adapted from http://tex.stackexchange.com/questions/76078/
               % how-to-get-the-section-title-by-section-number
  \expandafter\renewcommand\csname #1\endcsname[2][]{
    \if\relax\detokenize{##1}\relax
      \csname old#1\endcsname{##2}%
    \else
      \csname old#1\endcsname[##1]{##2}%
    \fi
    \label{#2: \csname the#1\endcsname}%
  }
}

\labelize{section}{auto@section}

\begin{document}
\section{Test}
Hi

\ref{auto@section:1}
\end{document}

当然使用\ref{auto@section:1}是没有意义的,但如果要通过某些宏使用自动生成的标签,那么它就会很有用。

这是允许\section*以及可选参数的 LaTeX3 版本。但请注意,第一个参数应该\labelize是命令(带反斜杠)。可以使用与以前相同的语法,但我认为这更清楚。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% Macro to insert labels at the end of other macros
\NewDocumentCommand{\labelize}{mm}
 {
  \sean_labelize:Nn #1 { #2 }
 }

\cs_new_protected:Npn \sean_labelize:Nn #1 #2
 {
  \cs_set_eq:cN { original_ \cs_to_str:N #1 } #1
  \RenewDocumentCommand #1 { som }
   {
    \IfBooleanTF{##1}
     {
      \use:c { original_ \cs_to_str:N #1 }*{##3}
     }
     {
      \IfNoValueTF{##2}
       {
        \use:c { original_ \cs_to_str:N #1 } {##3}
       }
       {
        \use:c { original_ \cs_to_str:N #1 } [##2]{##3}
       }
      \label{#2: \use:c{the\cs_to_str:N #1} }%
     }
   }
 }
\ExplSyntaxOff

\labelize{\section}{auto@section}

\begin{document}
\section{Test}
Hi

\ref{auto@section:1}

\section*{Star}

Hi
\end{document}

相关内容