将默认参数包含到 \def 中

将默认参数包含到 \def 中

我正在使用经典论题使用 \graffito 命令设置样式(例如这里)。我如何修改下面的命令以在文本前添加一些垂直间距,该间距默认设置为标准值,但可以通过包含参数来更改?

% Graffiti as in GKP's book "Concrete Mathematics"
% thanks to Lorenzo Pantieri and Enrico Gregorio
\def\graffito@setup{%
    \vspace{0.7em}
%   \slshape\footnotesize% this was due to \slhape in above book
   \itshape\footnotesize\leavevmode\color{Black}%
   \parindent=0pt \lineskip=0pt \lineskiplimit=0pt %
   \tolerance=2000 \hyphenpenalty=300 \exhyphenpenalty=300%
   \doublehyphendemerits=100000%
   \finalhyphendemerits=\doublehyphendemerits}

我的第一个方法是在开头添加 \vspace{#1},但我不知道如何 (i) 将这个参数 #1 包含到定义中;(ii) 为该参数包含一个默认值。我也没有设法将下面的代码片段转换为 \newcommand 定义,据我所知,它支持默认参数。

答案1

只需\graffito使用可选参数定义:

\documentclass{article}
\usepackage{lipsum}

\makeatletter
\newcommand{\graffito}[2][0.7em]{%
  \marginpar
    [\graffito@setup{#1}\raggedleft\hspace{0pt}#2]
    {\graffito@setup{#1}\raggedright\hspace{0pt}#2}%
}
\newcommand\graffito@setup[1]{%
   \vspace{#1}%
   \parindent=0pt \lineskip=0pt \lineskiplimit=0pt
   \tolerance=2000 \hyphenpenalty=300 \exhyphenpenalty=300
   \doublehyphendemerits=100000
   \finalhyphendemerits=\doublehyphendemerits
   \itshape\footnotesize
   \leavevmode\color{Black}%
}
\makeatother

\begin{document}

This has a graffito\graffito{This is a standard graffito}
\lipsum[1][1-5]

This has a graffito\graffito[-0.7em]{This is a moved up graffito}
\lipsum[1][1-5]

This has a graffito\graffito[1cm]{This is a moved down graffito}
\lipsum[1][1-5]

\end{document}

在此处输入图片描述

附注:原始代码在和%之后有:它们是300100000错误的

答案2

由于您无论如何都要使用 LaTeX 语法,因此您可以使用 LaTeX 命令\newcommand设置默认参数:\newcommand\graffito@setup[1][0.7em]{\vspace{#1}...}。如果您不想出于教育目的使用 LaTeX 语法,可以执行以下操作:

我们需要第一个宏来检查可选参数是否跟在后面。为此,我们使用\futurelet\protected因为这里需要赋值,所以进行了定义):

\protected\def\mycmd{\futurelet\next\mycmd@a}

我们需要检查下一个标记是否是一个括号,如果是,则下一个宏读取它的参数,否则我们给它默认值。

\def\mycmd@a
  {%
    \ifx[\next
      \afterelsefi{\mycmd@b}%
    \else
      \afterfi{\mycmd@b[0.7em]}%
    \fi
  }

这里我使用宏\afterelsefi\afterfi进行一些逻辑分支。它们吃掉它们的参数并将其放在后面\fi

\long\def\afterelsefi#1\else#2\fi{\fi#1}
\long\def\afterfi#1\fi{\fi#1}

最后是所需的最后一个宏,它是生成输出的宏:

\long\def\mycmd@b[#1]%
  {%
    Argument was: \texttt{\detokenize{#1}}%
  }

完成 MWE:

\documentclass[]{article}

\makeatletter
\long\def\afterelsefi#1\else#2\fi{\fi#1}
\long\def\afterfi#1\fi{\fi#1}
\protected\def\mycmd{\futurelet\next\mycmd@a}
\def\mycmd@a
  {%
    \ifx[\next
      \afterelsefi{\mycmd@b}%
    \else
      \afterfi{\mycmd@b[0.7em]}%
    \fi
  }
\long\def\mycmd@b[#1]%
  {%
    Argument was: \texttt{\detokenize{#1}}%
  }
\makeatother

\begin{document}
\mycmd

\mycmd[1em]
\end{document}

相关内容