分析

分析

我正在尝试定义一个简写命令,以便更快地编写一些引用。到目前为止,我能做的最好的事情是

\newcommand{\apologien}[2]{#1\textit{A} #2}
\newcommand{\apo}[1]{\apologien{1}{#1}}
\newcommand{\apoz}[1]{\apologien{2}{#1}}

例如,它很适合\apo{65.1}。但是,如果要引用整个文本而不仅仅是特定的章节或诗句,我会使用例如\apo。这会给我留下一个不必要的尾随空格。

除此以外,我还尝试了以下方法:

\usepackage{xparse}
\DeclareDocumentCommand{\apologien}{mo}
  {%
    #1\textit{A}\IfValueT{#2}{ {#2}}
  }

或者

\usepackage{ifthen}
\newcommand{\apologien}[2]{#1\textit{A}\ifthenelse{\isundefined{#2}}{}{ #2}}

或者

\usepackage{ifthen}
\newcommand{\apologien}[2][]{#1\textit{A}\ifthenelse{\equal{#2}{}}{}{ #2}}

我终于让它为 \apo{} 工作了

\usepackage{trimspaces}

\makeatletter
\newcommand{\apologien}[2]{\trim@spaces{#1\textit{A} #2}}
\makeatother

不过,我真的很想知道为什么我的其他尝试没有成功。

示例文档:

%!TEX TS-program = xelatex
%!TEX encoding = UTF-8 Unicode

\documentclass[
        fontsize=12pt,
        paper=a4,
        titlepage,
        twoside,
]{scrartcl}

\usepackage{trimspaces}

\makeatletter
\newcommand{\apologien}[2]{\trim@spaces{#1\textit{A} #2}}
\makeatother

\newcommand{\apo}[1]{\apologien{1}{#1}}
\newcommand{\apoz}[1]{\apologien{2}{#1}}

\begin{document}
\begin{tabular}{ll}
\hline
Commmand & Wanted\\
\hline
\apologien{1}.        & 1\textit{A}.\\
\apologien{1}{}.      & 1\textit{A}.\\
\apologien{1}{65.1}.  & 1\textit{A} 65.1.\\
\apo{65.1}.           & 1\textit{A} 65.1.\\
\apo.                 & 1\textit{A}.\\
\apo{}.               & 1\textit{A}.\\
\apoz{5.1}.           & 2\textit{A} 5.1\\
\hline
\end{tabular}
\end{document}

答案1

我认为您的问题是,当您重写宏以便它们使用可选参数时,您并没有更改宏,因此它们使用了可选参数。

更明确地说,如果你定义

\usepackage{xparse}
\DeclareDocumentCommand{\apologien}{mo}
  {%
    #1\textit{A}\IfValueT{#2}{ {#2}}
  }

那么您必须使用可选参数,以便和\apologien的定义也必须更改为\apo\apoz

\newcommand{\apo}[1]{\apologien{1}[#1}]}
\newcommand{\apoz}[1]{\apologien{2}[#1]}

实际上,您在“现在正在工作的” MWE 中也遇​​到了类似的问题,因为您使用了\apo.\apo{}。其中第一个扩展为\apologien{1}{.},第二个扩展为\apologien{1}{},因此您可能偶然得到了想要的结果。如果您希望此语法起作用,那么\apo\apoz还必须接受可选参数。

据我所知,你不需要使用修剪空间包并可以改用:

\documentclass[
        fontsize=12pt,
        paper=a4,
        titlepage,
        twoside,
]{scrartcl}

\usepackage{xparse}

\NewDocumentCommand\apologien{ mo }{#1\textit{A}\IfValueT{#2}{\space #2}}
\NewDocumentCommand{\apo}{o}{\IfValueTF{#1}{\apologien{1}[#1]}{\apologien{1}}}
\NewDocumentCommand{\apoz}{o}{\IfValueTF{#1}{\apologien{2}[#1]}{\apologien{1}}}

\begin{document}
  \begin{tabular}{ll}
    \hline
    Commmand & Wanted\\
    \hline
    \apologien{1}.        & 1\textit{A}.\\
    \apologien{1}{}.      & 1\textit{A}.\\
    \apologien{1}[65.1].  & 1\textit{A} 65.1.\\
    \apo[65.1].           & 1\textit{A} 65.1.\\
    \apo.                 & 1\textit{A}.\\
    \apo{}.               & 1\textit{A}.\\
    \apoz[5.1].           & 2\textit{A} 5.1\\
    \hline
  \end{tabular}
\end{document}

当然,这会产生您预期的输出:

在此处输入图片描述

但请注意,当需要可选参数时,您需要使用它们!

最后一条评论:LaTeX 中的通常做法是将可选参数放在首位。当然,你不需要这样做,但至少对我来说,这样写更自然:

\NewDocumentCommand\apologien{ om }{#2\textit{A}\IfValueT{#1}{\space #1}}
\NewDocumentCommand{\apo}{o}{\IfValueTF{#1}{\apologien[#1]{1}}{\apologien{1}}}
\NewDocumentCommand{\apoz}{o}{\IfValueTF{#1}{\apologien[#1]{2}}{\apologien{1}}}

答案2

你特别需要区分 和\apo{something}\apo其中{不 跟在后面。然后\futurelet需要使用 TeX 原语:

\def\apo  {1{\it A}\futurelet\next\apoA}
\def\apoz {2{\it A}\futurelet\next\apoA}
\def\apoA{\ifx\next\bgroup \space \fi}

Test:

\apo {65.1}, \apo.

\apoz {65.1}, \apoz.

\bye

答案3

分析

让我们考虑一下代码

\newcommand{\apologien}[2]{#1\textit{A} #2}
\newcommand{\apo}[1]{\apologien{1}{#1}}
\newcommand{\apoz}[1]{\apologien{2}{#1}}

如果你在示例中调用\apo.或类似,则参数在前一种情况下是句点,在后一种情况下是空,从而导致\apo{}.#1

\apologien{1}{.}
\apologien{1}{}.

在这两种情况下,你最终都会得到

1\textit{A} .

建议的解决方案

由于章节部分似乎是可选的,因此这样处理是有意义的:

\NewDocumentCommand{\apologien}{mo}{%
  #1\textit{A}%
  \IfValueT{#2}{~#2}%
}
\NewDocumentCommand{\apo}{}{\apologien{1}}
\NewDocumentCommand{\apoz}{}{\apologien{2}}

你应该调用如下命令

\apologien{1}.
\apologien{1}[65.1].
\apo[65.1].
\apo.
\apoz[5.1].

语法一致。即使你使用\apo{}(可能是为了保护后面的空格),结果也会如指定的那样。

替代(但不推荐)解决方案

只是为了完整性,但这是一个我完全不推荐的方法,你可以

\NewDocumentCommand{\apologien}{mg}{%
  #1\textit{A}%
  \IfValueT{#2}{~#2}%
}
\NewDocumentCommand{\apo}{}{\apologien{1}}
\NewDocumentCommand{\apoz}{}{\apologien{2}}

并将上述代码中[...]的括号改为。然而,这仍然会导致不必要的空格,并且还需要做更多的工作{...}\apo{}

\ExplSyntaxOn
\NewDocumentCommand{\apologien}{mg}
 {
  #1\textit{A}
  \IfValueT { #2 } { \tl_if_blank:nF { #2 } { \nobreakspace #2 } }
}
\ExplSyntaxOff

相关内容