使用可选参数创建简单的重复宏

使用可选参数创建简单的重复宏

我想要以最简单的方式(就字符长度而言)创建一个执行某项操作或可选地执行 n 次操作的宏。

事实上,我想要做的就是创建类似 --------X 的东西,其中 -`s 从 1 到 n。我不想必须向宏提供 1,因为这是默认的,也是最常用的情况。

所以

\dash{X} gives -X
\dash[3]{X} gives ---X
or
\dash{X}[3] gives ---X
or 
\dash{X}{3} gives ---X
or
\dash{3}{X} gives ---X

我不在乎语法。只要它简短、按预期工作并且应该高效就行。我可能不想使用嵌套组,因为这样做毫无意义,而且效率低下,但无论哪种方式都无所谓。

我希望尽可能少地使用额外的包,除非某些包可以很好地做到这一点以使其非常简短。

就像是

\newcommand{\dash}[2][1]{\directlua{for i=1,#1 do tex.print('-') end}#2}%

与 LuaLaTeX 一起使用,但tex.print似乎在每个破折号之后/之前添加了一个空格,导致 - - - -X。

答案1

使用xparse(带选项):

在此处输入图片描述

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\dash}{O{1} O{-} m}{%
  \prg_replicate:nn {#1} {#2}#3
}
\ExplSyntaxOff

\begin{document}

\dash{X}

\dash[2]{X}

\dash[15][{{-}}]{X}

\dash[7][a]{X}

\end{document}

参考:重复字符 n 次

答案2

\replicate只需使用这里描述的David Kastrup 的一个旧宏即可:

http://www.gust.org.pl/projects/pearls/2005p/david-kastrup/bachotex2005-david-kastrup-pearl3.pdf

例子:

\documentclass{article}

\makeatletter
\newcommand\xii[2]{\if#2m#1\expandafter\xii\else\expandafter\@gobble\fi{#1}}
\newcommand\xiii{}\long\def\xiii#1\relax#2{\xii{#2}#1\relax}
\newcommand\replicate[1]{\expandafter\xiii\romannumeral\number\number#1 000\relax}
%
\newcommand\dash[1][1]{\replicate{#1}{-}\@firstofone}
%
% You can avoid consecutive dashes yielding en-dash-ligatures and em-dash-ligatures
% by wrapping the single dash into braces---\hyphendash yields hyphens:
%
\newcommand\hyphendash[1][1]{\replicate{#1}{{-}}\@firstofone}
\makeatother

\begin{document}

\verb|\dash[0]{X}| should yield X and indeed yields \dash[0]{X}

\verb|\dash{X}| should yield -X and indeed yields \dash{X}

\verb|\dash[1]{X}| should yield -X and indeed yields \dash[1]{X}

\verb|\dash[2]{X}| should yield --X and indeed yields \dash[2]{X}

\verb|\dash[3]{X}| should yield ---X and indeed yields \dash[3]{X}

\leavevmode\leaders\hbox{-}\hfill\null

\verb|\hyphendash[0]{X}| should yield X and indeed yields \hyphendash[0]{X}

\verb|\hyphendash{X}| should yield {-}X and indeed yields \hyphendash{X}

\verb|\hyphendash[1]{X}| should yield {-}X and indeed yields \hyphendash[1]{X}

\verb|\hyphendash[2]{X}| should yield {-}{-}X and indeed yields \hyphendash[2]{X}

\verb|\hyphendash[3]{X}| should yield {-}{-}{-}X and indeed yields \hyphendash[3]{X}

\end{document}  

编译示例的结果

如果它仅涉及破折号/连字符,并且如果您不希望破折号/连字符跨行断开,则可能还可以用水平填充预定宽度的水平框\leaders

\documentclass{article}

\makeatletter
\newbox\mytempbox
\newcommand\nobreakhyphendash[1][1]{%
  \begingroup
  \setbox\mytempbox\hbox{-}%
  \vbox{\hbox to#1\wd\mytempbox{\leaders\box\mytempbox\hfill}}%
  \endgroup 
  \@firstofone
}
\makeatother

\begin{document}

\verb|\nobreakhyphendash[0]{X}| should yield X and indeed yields \nobreakhyphendash[0]{X}

\verb|\nobreakhyphendash{X}| should yield {-}X and indeed yields \nobreakhyphendash{X}

\verb|\nobreakhyphendash[1]{X}| should yield {-}X and indeed yields \nobreakhyphendash[1]{X}

\verb|\nobreakhyphendash[2]{X}| should yield {-}{-}X and indeed yields \nobreakhyphendash[2]{X}

\verb|\nobreakhyphendash[3]{X}| should yield {-}{-}{-}X and indeed yields \nobreakhyphendash[3]{X}

\verb|\nobreakhyphendash[15]{X}| should yield {-}{-}{-}{-}{-}{-}{-}{-}{-}{-}{-}{-}{-}{-}{-}X and indeed yields \nobreakhyphendash[15]{X}

\end{document}

示例的编译结果

答案3

你可能会喜欢这个概括:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\pattern}{>{\SplitList{,}}m}
 {
  \ProcessList{#1}{\MakePattern}
 }
\NewDocumentCommand{\MakePattern}{m}
 {
  \MakePatternAux #1 \MakePatternAux
 }
\NewDocumentCommand{\MakePatternAux}{O{1}u{\MakePatternAux}}
 {
  \prg_replicate:nn { #1 } { {#2} }
 }
\ExplSyntaxOff

\begin{document}

\pattern{[3]-,X,-,Y,[5]abc}

$\pattern{[3]-,X,-,Y,[5]+}$

\end{document}

你可以用逗号分隔的项目列表来描述模式:X表示“打印一份X”,而[5]Y表示“打印五份Y”。额外的括号使得 TeX 不会在原子之间添加自动间距,因为所有原子都被视为普通原子。项目可以是多个标记。

在此处输入图片描述

相关内容