Create simple repetitive macro with optional argument

Using xparse (with options):

enter image description here

\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}

Reference: Repeat characters n times


Just use one of David Kastrup's good old \replicate-macros that are described here:

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

Example:

\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}  

result from compiling the example

If it is only about dashes/hyphens and if you don't want dashes/hyphens to be broken across lines, you can probably also fill a horizontal box of predetermined width with horizontal \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}

result of compiling the example


You might enjoy this generalization:

\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}

You describe a pattern by a comma separated list of items: X means “print one copy of X”, while [5]Y means “print five copies of Y). The additional braces make TeX into not adding automatic spacing between atoms, because all are treated as ordinary atoms. Items can be more than one token.

enter image description here

Tags:

Macros