我想要以最简单的方式(就字符长度而言)创建一个执行某项操作或可选地执行 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
答案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 不会在原子之间添加自动间距,因为所有原子都被视为普通原子。项目可以是多个标记。