41

I would like a command \egreg which produces “egreg”. However, there is no reason to limit yourself to one “reg”. Who knows, maybe one day you just feel like writing “egregregregreg" for some reason. So the command should also take an optional argument, specifying the number of “reg”’s you want.

I know there are easy solutions involving loops, but given that it’s April 1, the most ridiculous solution will be accepted.

\documentclass{article}

\NewDocumentCommand\egreg{o}{% % something }

\begin{document}

\egreg % should produce "egreg" \egreg[0] % should produce "eg" \egreg[1] % should produce "egreg" \egreg[2] % should produce "egregreg" \egreg[5] % should produce "egregregregregreg"

Perhaps we might also want to allow negative values:

\egreg[-1] % should produce "regeg" \egreg[-2] % should produce "regregeg"

Maybe also complex values?

\egreg[i] % perhaps "$\text{eg} + i\text{reg}$"?

Perhaps someone can also figure out what to do with quaternionic values?

\end{document}

Gaussler
  • 12,801
  • 12
    Great April 1st post! I'm sure egreg will answer :D – CarLaTeX Apr 01 '23 at 07:59
  • 9
    I first thought that this was about a macro that outputs marvellous solutions to (or even just magically solve on-the-fly) tricky TeX problems whenever being used in your code ... – Jasper Habicht Apr 01 '23 at 08:02
  • 4
    @JasperHabicht I promise that if you can come up with a command that can do that consistently, your answer will also be accepted and appropriately awarded. But \newcommand\egreg[1]{Ask ChatGPT about #1} doesn’t count. – Gaussler Apr 01 '23 at 08:04
  • 4
    I think, on April 1st, the macro should output variations of the string april instead of egreg ... – Jasper Habicht Apr 01 '23 at 10:51
  • 4
    @JasperHabicht “aprilprilprilprilprilprilprilprilprilpril 1”? – Gaussler Apr 01 '23 at 10:58
  • 17
    How very egregious. – JonathanZ Apr 01 '23 at 18:17
  • 3
    For a moment I parsed that command as \egrep and started wondering what the application of the egrep *NIX command in a LaTeX document could be. I opted for an April's fools joke, but the wrong joke! So you fooled me twice! :-) – LorenzoDonati4Ukraine-OnStrike Apr 02 '23 at 19:24

9 Answers9

34

I think the image-inary part should be drawn with TikZlings:

\documentclass{article}
\usepackage{xstring}
\usepackage{etoolbox}
\usepackage{tikzlings}
\newcommand{\egregnum}[1]{%
  \begin{tikzpicture}[
    every node/.style={inner sep=0pt}, 
    baseline=(a0.base)
    ]
    \node (a0) {eg};
    \ifnumgreater{#1}{0}{%
    \foreach \x [count=\prev from 0] in {1,...,#1}
        \node[anchor=west] (a\x) at (a\prev.east){reg};
        }{%
    \ifnumless{#1}{0}{%
        \foreach \x [evaluate=\x as \numpos using int(\x * -1),
                    evaluate=\x as \prev using int((\x * -1)-1)] 
                    in {-1,...,#1}                  
                \node[anchor=east] (a\numpos) at (a\prev.west){reg};            
            }{}%
        }%
    \end{tikzpicture}
    }

\newcommand{\egregimm}{% \raisebox{-.3cm}{\begin{tikzpicture} \tikzling[ scale=0.5,signpost={reg} ] \end{tikzpicture} }}

\newcommand{\egreg}[1][1]{% \IfDecimal{#1}{% \egregnum{#1}% }{% \StrDel{#1}{ }[\complesso]% \StrSubstitute{\complesso}{-}{+}[\contasegni]% \StrCount{\contasegni}{+}[\numsegni]% \StrPosition[\numsegni]{\contasegni}{+}[\signposition]% \StrChar{\complesso}{\signposition}[\segno]% \IfStrEq{\segno}{-}{%immaginario negativo \StrBehind[\numsegni]{#1}{-}[\partei]% \StrSubstitute{\partei}{ }{}[\parteimm]% \StrSubstitute{\parteimm}{i}{}[\immaginario]% \IfDecimal{\immaginario}{% \foreach \cifreimm in {1,...,\immaginario}{\egregimm} }{% \egregimm }% \StrBefore[\numsegni]{\complesso}{-}[\reale]% \IfDecimal{\reale}{% \egregnum{\reale} }{% \egregnum{0} }% }{% immaginario positivo \StrBefore{\complesso}{+}[\reale]% \IfDecimal{\reale}{% \egregnum{\reale} }{% \egregnum{0} }% \StrBehind{#1}{+}[\partei]% \StrSubstitute{\partei}{ }{}[\parteimm]% \StrSubstitute{\parteimm}{i}{}[\immaginario]% \IfDecimal{\immaginario}{% \foreach \cifreimm in {1,...,\immaginario}{\egregimm} }{% \egregimm }% }% } }

\begin{document} \verb|\egreg|: \egreg % should produce "egreg"

\verb|\egreg[0]|: \egreg[0] % should produce "eg"

\verb|\egreg[1]|: \egreg[1] % should produce "egreg"

\verb|\egreg[2]|: \egreg[2] % should produce "egregreg"

\verb|\egreg[5]|: \egreg[5] % should produce "egregregregregreg"

\verb|\egreg[-1]|: \egreg[-1] % should produce "regeg"

\verb|\egreg[-2]|: \egreg[-2] % should produce "regregeg"

\verb|\egreg[i]|: \egreg[i] % perhaps "$\text{eg} + i\text{reg}$"?

    \verb|\egreg[3+2i]|: \egreg[3+2i] 

    \verb|\egreg[2 + 3i]|: \egreg[2 + 3i]

    \verb|\egreg[-2 + 4i]|: \egreg[-2 + 4i]

    \verb|\egreg[1 - 2i]|: \egreg[1 - 2i]

    \verb|\egreg[-2 - i]|: \egreg[-2 - i]

    \verb|\egreg[-i]|: \egreg[-i]

\end{document}

enter image description here

CarLaTeX
  • 62,716
20

Out of competition, of course. The most ridiculous answers will be rewarded with bounty points.

Since you don't want expandability, as witnessed by the proposed syntax, here's my version. Note how most endlines are not masked with % and the abundance of unneeded spaces.

\documentclass{article}

\NewDocumentCommand{\egreg}{o}{% \IfNoValueTF{#1}{\printegreg{1}}{\printegreg{#1}}% }

\NewDocumentCommand{\printegreg}{m}{% $ \begingroup\uccode~ =m \uppercase{\endgroup\def~}{\hbox{reg}} \mathcode`m = "8000 \ifnum#1<0 \romannumeral-\number\number#1 000 \fi \hbox{eg} \ifnum#1>0 \romannumeral\number\number#1 000 \fi $% }

\newcounter{egreg} \newcount\plainegreg

\begin{document}

\egreg \ should produce ``egreg''

\egreg[0] should produce ``eg''

\egreg[1] should produce ``egreg''

\egreg[2] should produce ``egregreg''

\egreg[5] should produce ``egregregregregreg''

\egreg[-1] should produce ``regeg''

\egreg[-2] should produce ``regregeg''

\setcounter{egreg}{4}

\egreg[\value{egreg}]

\plainegreg=-3

\egreg[\plainegreg]

\end{document}

enter image description here

egreg
  • 1,121,712
18

I think the best way to thank egreg for all the help was to solve this exercise using a code roughly as readable as most LaTeX code I can read on this forum (in particular yours egreg, but it's not your fault if LaTeX is not really readable :-P)… but a bit prettified (I took the liberty to modify the minus version to actually be a true inverse, i.e. equal when reading backward).

\documentclass[a4paper]{article}
\usepackage{bxbluf} % See below, from https://gist.github.com/zr-tex8r/7527995

\procbf{\egregBF}{ +>,----- --------
------------ ------------
--------[<[-]> ++++++++++++++
++++++++++++++++ +++++++++++++++[
>[>++++++++++<-]> [-<+>]<<---------
------------------ ------------------
---[>+<-],]++++++++ +++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++.++.
[-]>[->++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++.-
------------.++.[-]<],[--------------
-------------------------------]]<[
[-]>,[>[>++++++++++<-]>[-<+>]<<--
-------------------------------
---------------[>+<-],]>[->++
+++++++++++++++++++++++++++++
+++++++++++++++++++++++++++
+++++++++++++++++++++++++
++++++++++++++++++++.--
.+++++++++++++.[-]<]+
+++++++++++++++++++
+++++++++++++++++
+++++++++++++++
+++++++++++++++
+++++++++++++
+++++++++++
+++++++++
+++.--.
[-]]♥
♥♥♥


}

\NewDocumentCommand{\egreg}{O{1}}{\egregBF{#1}} \begin{document} \begin{itemize} \item \texttt{\textbackslash egreg}: \egreg \item \texttt{\textbackslash egreg[12]}: \egreg[12] \item \texttt{\textbackslash egreg[-2]}: \egreg[-2] \end{itemize}

\end{document}

enter image description here

Note that you need to create also a bxbluf.sty file to interpret the Brainfuck in the above code (from https://gist.github.com/zr-tex8r/7527995, slighty improved to remove unwanted space):

% bxbluf.sty

%% package declaration \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{bxbluf}[2013/11/11 v0.2]

%% preparations \def\bxbf@pkgname{bxbluf} \def\bxbf@error{\PackageError\bxbf@pkgname} \def\bxbf@warn{\PackageWarningNoLine\bxbf@pkgname} \def\bxbf@err@umbgr{% \bxbf@error{Unmatched [ found}@ehc } \def\bxbf@err@umegr{% \bxbf@error{Unmatched ] found}@ehc } \def\bxbf@warn@hichr{% \bxbf@warn{Non 8-bit character found}% } \def\bxbf@warn@ineof{% \bxbf@warn{End-of-input reached}% } % \newif\ifbxbf@inloop \newif\ifbxbf@g@error \newif\ifbxbf@optok \providecommand*\bxDebug[1]{}

%--------------------------------------- base

%% variables \newcount\bxbf@count \let\bxbf@prcode@empty

%% \bxbf@op@list : operator list \def\bxbf@op@list{% \do\bxbf@AP\do\bxbf@AV\do\bxbf@ID\do\bxbf@OD\do\bxbf@LP \do\bxbf@RP\do\bxbf@RV\do\bxbf@AX\do\bxbf@RX\do\bxbf@SF }

%% \bxbf@op@frozen \let\bxbf@op@frozen\relax

%% \bxbf@op@noop \def\bxbf@op@noop#1{}

%% \bxbf@switch@all@op\CS \def\bxbf@switch@all@op#1{% \let\bxbf@tmpa#1% \let\do\bxbf@switch@all@op@do \bxbf@op@list } \def\bxbf@switch@all@op@do#1{% \let#1\bxbf@tmpa }

%% \bxbf@modulo{<num>} \def\bxbf@modulo#1{% @tempcnta=#1\relax \bxbf@count@tempcnta \divide@tempcnta\bxbf@rbase \multiply@tempcnta\bxbf@rbase \advance\bxbf@count-@tempcnta }

%% \bxbf@show % for debug \def\bxbf@show{% \bxbf@switch@all@op\bxbf@op@frozen \bxDebug{prog:\bxbf@prcode}% }

%--------------------------------------- \scantokens emulation \ifx\scantokens@undefined % when \scantokens is unavailable \newwrite\bxbf@tempfile \def\bxbf@tempfilename{\bxbf@pkgname.out}

\def\bxbf@scantokens#1{% \begingroup \toks@={#1}% \immediate\openout\bxbf@tempfile=\bxbf@tempfilename\relax \immediate\write\bxbf@tempfile{\the\toks@}% \immediate\closeout\bxbf@tempfile \endgroup \input{\bxbf@tempfilename}% }%

\else % uses \scantokens if available \let\bxbf@scantokens\scantokens \fi %--------------------------------------- LaTeX interface

%% variables \newcount\bxbf@proc@maxid \let\bxbf@decl@mode\relax \let\bxbf@out@verbatim\relax \let\bxbf@eofval=*

%%<> \execbf[] / \execbfwithinput[*] / \procbf[*] \DeclareRobustCommand\execbf{% @ifstar{\bxbf@procbf{n}{1}}{\bxbf@procbf{n}{0}}% } \DeclareRobustCommand\execbfwithinput{% @ifstar{\bxbf@procbf{i}{1}}{\bxbf@procbf{i}{0}}% } \DeclareRobustCommand*\procbf{% @ifstar{\bxbf@procbf{p}{1}}{\bxbf@procbf{p}{0}}% } \def\bxbf@procbf#1#2{% \let\bxbf@decl@mode=#1\relax \chardef\bxbf@out@verbatim=#2\relax \def\bxbf@proc@id{0}% \if i\bxbf@decl@mode \let\bxbf@tmpa\bxbf@procbf@winput \else\if p\bxbf@decl@mode \advance\bxbf@proc@maxid@ne \edef\bxbf@proc@id{\the\bxbf@proc@maxid}% \let\bxbf@tmpa\bxbf@procbf@wproc \else \let\bxbf@input@empty \let\bxbf@tmpa\bxbf@procbf@a \fi\fi \bxbf@tmpa } \def\bxbf@procbf@winput#1{% <input> \def\bxbf@input{#1}% \bxbf@procbf@a } \def\bxbf@procbf@wproc#1{% \ProcCS \def\bxbf@proc@cs{\noexpand#1}% \bxbf@procbf@a } \def\bxbf@procbf@a#1{% <program> \begingroup \global\expandafter\chardef\csname bxbf@OutVerb/\bxbf@proc@id\endcsname =\bxbf@out@verbatim \bxbf@parse{#1}% \bxbf@optimize \global\expandafter\let\csname bxbf@PrArray/\bxbf@proc@id\endcsname =\bxbf@prcode \endgroup \ifnum\bxbf@proc@id>0 \edef\bxbf@tmpa{% \gdef\bxbf@proc@cs{\noexpand\bxbf@invoke@proc{\bxbf@proc@id}}% }% \bxbf@tmpa \else % immediate execution \bxbf@invoke@proc{\bxbf@proc@id}{\bxbf@input}% \fi }

%% \bxbf@invoke@proc{<id>}{<input>} \def\bxbf@invoke@proc#1#2{% \begingroup \bxbf@stringify\bxbf@input{#2}% \expandafter\let\expandafter\bxbf@prcode \csname bxbf@PrArray/#1\endcsname \bxbf@execute \xdef\bxbf@g@tmpa{\noexpand\bxbf@process@str {\csname bxbf@OutVerb/#1\endcsname}{\bxbf@output}}% \endgroup \bxbf@g@tmpa } \def\bxbf@process@str#1#2{% \ifnum#1>\z@ \begingroup \let\bxbfLF\newline \let\bxbfSP\ % #2\relax \endgroup \else \begingroup \def\bxbfLF{^^J}\def\bxbfSP{ }% \xdef\bxbf@g@tmpa{\noexpand\bxbf@scantokens{#2}}% \endgroup \bxbf@g@tmpa \fi }

%% \bxbf@stringify\CS{<text>} \def\bxbf@stringify#1#2{% \edef\bxbf@tmpa{#2}% \expandafter\bxbf@stringify@a\meaning\bxbf@tmpa\bxbf@end#1% } \def\bxbf@stringify@a#1->#2\bxbf@end#3{% \def#3{#2}% }

%%<> \bfeofvalue{<val>} \newcommand\bfeofvalue[1]{% \def\bxbf@tmpa{#1}% \ifx\bxbf@tmpa\bxbf@@star \let\bxbf@eofval=\relax \else\ifx\bxbf@tmpa\bxbf@@bang \let\bxbf@eofval=!\relax \else \afterassignment\bxbf@eofvalue@a\bxbf@count=\bxbf@tmpa\bxbf@tn \fi\fi } \def\bxbf@eofvalue@a#1\bxbf@tn{% \def\bxbf@tmpa{#1}% \ifx\bxbf@tmpa@empty \bxbf@modulo\bxbf@count \ifnum\bxbf@count<\z@ \advance\bxbf@count\bxbf@rbase \fi \chardef\bxbf@eofval\bxbf@count \else \bxbf@count=\bxbf@tn \fi } \let\bxbf@tn\relax \def\bxbf@@star{} \def\bxbf@@bang{!}

%--------------------------------------- parse

%% variables \let\bxbf@block@empty \let\bxbf@prev@op@empty \let\bxbf@source@rest@empty \mathchardef\bxbf@rbase=256 \mathchardef\bxbf@mcmax="7FFF

%% \bxbf@chk \def\bxbf@chk{\space}

%% \bxbf@parse \long\def\bxbf@parse#1{% \bxbf@switch@all@op\bxbf@op@frozen \bxbf@inloopfalse \global\bxbf@g@errorfalse \edef\bxbf@tmpa{% \noexpand\bxbf@parse@block{#1\noexpand\bxbf@chk}}% \bxbf@tmpa \ifbxbf@g@error \let\bxbf@prcode@empty \else \let\bxbf@prcode\bxbf@block \fi }

%% \bxbf@parse@block \long\def\bxbf@parse@block#1{% \let\bxbf@prev@op@empty \bxbf@count\z@ \let\bxbf@block@empty \bxbf@parse@loop@a#1\bxbf@end }

%% \bxbf@parse@loop \def\bxbf@parse@loop{% \futurelet\bxbf@tmpa\bxbf@parse@loop@a } \def\bxbf@parse@loop@a{% \ifx\bxbf@tmpa\bgroup \expandafter\bxbf@parse@loop@b \else \expandafter\bxbf@parse@loop@ab \fi } \def\bxbf@parse@loop@ab{% \ifx\bxbf@tmpa@sptoken \expandafter\bxbf@parse@loop@ac \else \expandafter\bxbf@parse@loop@c \fi } \expandafter\def\expandafter\bxbf@parse@loop@ac\space{% \bxbf@parse@loop } \long\def\bxbf@parse@loop@b#1{% \bxbf@parse@loop#1% } \long\def\bxbf@parse@loop@c#1{% \csname bxbf@p@h/\string#1\endcsname \bxbf@parse@loop } %% \bxbf@aprse@flush \def\bxbf@parse@flush{% \ifnum\bxbf@count=\z@\else \edef\bxbf@block{\bxbf@block\bxbf@prev@op{\the\bxbf@count}}% \fi } %% \bxbf@aprse@nonaccum \def\bxbf@parse@nonaccum#1{% \bxbf@parse@flush \def\bxbf@prev@op{#1}\bxbf@count@ne } %% \bxbf@aprse@accum \def\bxbf@parse@accum#1#2{% \def\bxbf@tmpa{#1}% \ifx\bxbf@prev@op\bxbf@tmpa \advance\bxbf@count#2% \else \bxbf@parse@flush \bxbf@count#2\def\bxbf@prev@op{#1} \fi } %% \bxbf@aprse@new@block \long\def\bxbf@parse@new@block#1#2\bxbf@end{% #1 gobbled \bxbf@parse@flush %\bxDebug{new:\bxbf@block}% \begingroup \bxbf@inlooptrue \bxbf@parse@block{#2}% \global\let\bxbf@g@tmpa\bxbf@block \global\let\bxbf@g@tmpb\bxbf@source@rest \endgroup \let\bxbf@source@rest\bxbf@g@tmpb \edef\bxbf@block{\bxbf@block\bxbf@LP{\bxbf@g@tmpa}}% %\bxDebug{back:\bxbf@block}% \let\bxbf@prev@op@empty \bxbf@count\z@ \expandafter\bxbf@parse@loop\bxbf@source@rest\bxbf@end } %% \bxbf@aprse@end@block \long\def\bxbf@parse@end@block#1#2\bxbf@end{% #1 gobbled \bxbf@parse@flush \ifbxbf@inloop \def\bxbf@source@rest{#2}% \else \bxbf@err@umegr \global\bxbf@g@errortrue \let\bxbf@source@rest@empty \fi } %% \bxbf@aprse@finale \long\def\bxbf@parse@finale#1#2\bxbf@end{% #1 gobbled \bxbf@parse@flush \ifbxbf@inloop \bxbf@err@umbgr \global\bxbf@g@errortrue \def\bxbf@source@rest{\bxbf@chk}% \fi }

%% \bxbf@decl@handler{<token>}{<body>} \def\bxbf@decl@handler#1{% \expandafter\def\csname bxbf@p@h/#1\endcsname } \bxbf@decl@handler{+}{\bxbf@parse@accum\bxbf@AV@ne} \bxbf@decl@handler{-}{\bxbf@parse@accum\bxbf@AV\m@ne} \bxbf@decl@handler{>}{\bxbf@parse@accum\bxbf@AP@ne} \bxbf@decl@handler{<}{\bxbf@parse@accum\bxbf@AP\m@ne} \bxbf@decl@handler{,}{\bxbf@parse@nonaccum\bxbf@ID} \bxbf@decl@handler{.}{\bxbf@parse@nonaccum\bxbf@OD} \bxbf@decl@handler{[}{\bxbf@parse@new@block} \bxbf@decl@handler{]}{\bxbf@parse@end@block} \bxbf@decl@handler{\string\bxbf@chk}{\bxbf@parse@finale}

%--------------------------------------- optimize

%% variables \let\bxbf@g@block@empty

%% \bxbf@g@addto@block \def\bxbf@g@addto@block{\g@addto@macro\bxbf@g@block}

%% \bxbf@opt@addop \def\bxbf@opt@addop#1#2{% \bxbf@g@addto@block{#1#2}% }

%% \bxbf@intern{<num>}\cont \edef\bxbf@H{\expandafter@gobble\string#} \def\bxbf@intern#1{% \expandafter\bxbf@intern@a\csname\bxbf@H\number#1% \expandafter\endcsname\number#1\relax } \def\bxbf@intern@a#1#2\relax#3{% \ifx#1\relax \ifnum#2>\bxbf@mcmax \gdef#1{#2 }% \else \global\mathchardef#1=#2\relax \fi \fi #3#1% }

%% \bxbf@intern@red{<num>}\cont \def\bxbf@intern@red#1{% \bxbf@modulo{#1}% \bxbf@intern\bxbf@count }

%% \bxbf@optimize \def\bxbf@optimize{% \bxbf@switch@opt \global\let\bxbf@g@block@empty \bxbf@prcode \let\bxbf@prcode\bxbf@g@block }

%% \bxbf@switch@opt \def\bxbf@switch@opt{% \let\bxbf@AP\bxbf@opt@AP\let\bxbf@AV\bxbf@opt@AV \let\bxbf@ID\bxbf@opt@ID\let\bxbf@OD\bxbf@opt@OD \let\bxbf@LP\bxbf@opt@LP \let\bxbf@RP\bxbf@op@error\let\bxbf@RV\bxbf@op@error \let\bxbf@AX\bxbf@opt@AX\let\bxbf@RX\bxbf@op@error \let\bxbf@SF\bxbf@op@error }

%% \bxbf@opt@ID / \bxbf@opt@OD \def\bxbf@tmpa#1{% \def\bxbf@opt@ID##1{\bxbf@g@addto@block{\bxbf@ID#1}}% \def\bxbf@opt@OD##1{\bxbf@g@addto@block{\bxbf@OD#1}}% } \bxbf@intern{1}\bxbf@tmpa

%% \bxbf@opt@AP \def\bxbf@opt@AP#1{% \ifnum#1<\z@ \bxbf@intern{-#1}{\bxbf@opt@addop\bxbf@RP}% \else \bxbf@intern{+#1}{\bxbf@opt@addop\bxbf@AP}% \fi } %% \bxbf@opt@AV \def\bxbf@opt@AV#1{% \ifnum#1<\z@ \bxbf@intern@red{-#1}{\bxbf@opt@addop\bxbf@RV}% \else \bxbf@intern@red{+#1}{\bxbf@opt@addop\bxbf@AV}% \fi } %% \bxbf@opt@AX \def\bxbf@opt@AX#1{% \ifnum#1<\z@ \bxbf@intern@red{-#1}{\bxbf@opt@addop\bxbf@RX}% \else \bxbf@intern@red{+#1}{\bxbf@opt@addop\bxbf@AX}% \fi }

%% \bxbf@opt@check \def\bxbf@opt@check#1{% \bxbf@optokfalse \begingroup \bxbf@switch@all@op\bxbf@opt@check@ng \let\bxbf@AV\bxbf@opt@check@AV \let\bxbf@AP\bxbf@opt@check@AP \bxbf@count\z@ @tempcntb\z@ #1\bxbf@opt@check@fin \endgroup } \def\bxbf@opt@check@ng#1\bxbf@opt@check@fin{} \def\bxbf@opt@check@AP#1{% \advance\bxbf@count#1\relax } \def\bxbf@opt@check@AV#1{% \ifnum\bxbf@count=\z@ \advance@tempcntb#1\relax \fi }

%% \bxbf@opt@check@fin \def\bxbf@opt@check@fin{% \ifnum\bxbf@count=\z@ \ifnum@tempcntb=\m@ne \aftergroup\bxbf@optoktrue \fi\fi }

%% \bxbf@opt@LP \def\bxbf@opt@LP#1{% \begingroup \bxbf@opt@check{#1}% \let\bxbf@save@block\bxbf@g@block \global\let\bxbf@g@block@empty \ifbxbf@optok \let\bxbf@AV\bxbf@AX \fi #1% \expandafter\bxbf@opt@LP@a\expandafter{\bxbf@g@block}% \endgroup } \def\bxbf@opt@LP@a#1{% \let\bxbf@g@block\bxbf@save@block \ifbxbf@optok \g@addto@macro\bxbf@g@block{\bxbf@SF{#1}}% \else \g@addto@macro\bxbf@g@block{\bxbf@LP{#1}}% \fi }

%% \bxbf@opt@add\CS{<arg>} \def\bxbf@opt@add#1#2{% \g@addto@macro\bxbf@g@block{#1{#2}}% }

%--------------------------------------- execute \edef\bxbf@restorecc{\catcode127=\the\catcode127\relax} \catcode127=12

%% variables \newcount\bxbf@dptr \let\bxbf@str@in@empty \let\bxbf@str@out@empty \chardef\bxbf@zero=0 \chardef\bxbf@lctr=0

%% \bxbf@execute \def\bxbf@execute{% %\bxbf@show \bxbf@switch@exec \global\let\bxbf@str@in\bxbf@input \global\let\bxbf@str@out@empty \global\bxbf@g@errorfalse \bxbf@dptr\z@ \bxbf@prcode\bxbf@exec@fin \ifbxbf@g@error \let\bxbf@output@empty \else \let\bxbf@output\bxbf@str@out \fi } \let\bxbf@exec@fin\relax

%% \bxbf@exec@halt % NB. This is not counted as error. \def\bxbf@exec@halt#1\bxbf@exec@fin{}

%% \bxbf@swtich@exec \def\bxbf@switch@exec{% \let\bxbf@AP\bxbf@exec@AP\let\bxbf@AV\bxbf@exec@AV \let\bxbf@ID\bxbf@exec@ID\let\bxbf@OD\bxbf@exec@OD \let\bxbf@LP\bxbf@exec@LP \let\bxbf@RP\bxbf@exec@RP\let\bxbf@RV\bxbf@exec@RV \let\bxbf@AX\bxbf@exec@AX\let\bxbf@RX\bxbf@exec@RX \let\bxbf@SF\bxbf@exec@SF }

%% bxbf@exec@AP \def\bxbf@exec@AP#1{% \advance\bxbf@dptr#1% %\bxDebug{AP:\number#1;\number\bxbf@dptr}% } %% bxbf@exec@RP \def\bxbf@exec@RP#1{% \advance\bxbf@dptr-#1% %\bxDebug{RP:\number#1;\number\bxbf@dptr}% }

%% bxbf@exec@AV \def\bxbf@exec@AV{% \expandafter\bxbf@exec@AV@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@AV@a#1#2{% \ifx#1\relax \chardef#1#2% \else \bxbf@count#1\advance\bxbf@count#2% \ifnum\bxbf@count<\bxbf@rbase\else \advance\bxbf@count-\bxbf@rbase \fi \chardef#1\bxbf@count \fi %\bxDebug{AV:#1:\the#2;\the#1}% } %% bxbf@exec@RV \def\bxbf@exec@RV{% \expandafter\bxbf@exec@RV@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@RV@a#1#2{% \ifx#1\relax \chardef#1\bxbf@zero \fi \bxbf@count#1\advance\bxbf@count-#2% \ifnum\bxbf@count<\z@ \advance\bxbf@count\bxbf@rbase \fi \chardef#1\bxbf@count %\bxDebug{RV:#1:\the#2;\the#1}% }

%% bxbf@exec@ID \def\bxbf@exec@ID{% \expandafter\bxbf@exec@ID@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@ID@a#1#2{% \ifx#1\relax \chardef#1\bxbf@zero \fi \bxbf@count#1% \bxbf@get@char \ifnum\bxbf@count<\z@ \expandafter\bxbf@exec@halt \fi \chardef#1\bxbf@count %\bxDebug{ID:#1;\the#1}% }

%% bxbf@exec@OD \def\bxbf@exec@OD{% \expandafter\bxbf@exec@OD@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@OD@a#1#2{% \ifx#1\relax \chardef#1\bxbf@zero\fi% \bxbf@count#1% \bxbf@put@char% %\bxDebug{OD:#1;\the#1}% }

%% bxbf@exec@OD \def\bxbf@exec@LP{% \expandafter\bxbf@exec@LP@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@LP@a#1{% \ifx#1\relax \chardef#1\bxbf@zero\fi% %\bxDebug{LP:#1;\the#1}% \ifnum#1=\z@ \expandafter@gobble% \else\expandafter\bxbf@exec@LP@b% \fi% } \def\bxbf@exec@LP@b#1{% #1\bxbf@exec@LP{#1}% }

%% bxbf@exec@SF \def\bxbf@exec@SF{% \expandafter\bxbf@exec@SF@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@SF@a#1#2{% \ifx#1\relax \chardef#1\bxbf@zero\fi% \chardef\bxbf@lctr#1% #2% }

%% bxbf@exec@AX \def\bxbf@exec@AX{% \expandafter\bxbf@exec@AX@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@AX@a#1#2{% \ifx#1\relax \chardef#1\bxbf@zero\fi \bxbf@count#2\multiply\bxbf@count\bxbf@lctr\advance\bxbf@count#1% \ifnum\bxbf@count<\bxbf@rbase\else\bxbf@modulo\bxbf@count\fi% \chardef#1\bxbf@count% %\bxDebug{AX:#1:\the#2;\the#1}% } %% bxbf@exec@RX \def\bxbf@exec@RX{% \expandafter\bxbf@exec@RX@a\csname ^^?\the\bxbf@dptr\endcsname} \def\bxbf@exec@RX@a#1#2{% \ifx#1\relax% \chardef#1\bxbf@zero\fi% \bxbf@count#2\multiply\bxbf@count-\bxbf@lctr\advance\bxbf@count#1% \ifnum\bxbf@count<\z@ \bxbf@modulo\bxbf@count\fi% \ifnum\bxbf@count<\z@ \advance\bxbf@count\bxbf@rbase\fi% \chardef#1\bxbf@count% %\bxDebug{RX:#1:\the#2;\the#1}% }

\bxbf@restorecc %--------------------------------------- virtual I/O

%% variables \chardef\bxbfLF=10 \chardef\bxbfSP=32

%% \bxbf@get@char \def\bxbf@get@char{% \ifx\bxbf@str@in@empty \bxbf@get@char@mt% \else% \expandafter\bxbf@get@char@a\bxbf@str@in\bxbf@end% \fi% } \def\bxbf@get@char@a{% % don't discard spaces! \futurelet\bxbf@tmpa\bxbf@get@char@b% } \def\bxbf@get@char@b{% \ifx\bxbf@tmpa@sptoken% \expandafter\bxbf@get@char@d% \else% \expandafter\bxbf@get@char@c% \fi% } \def\bxbf@get@char@c#1#2\bxbf@end{% \bxbf@count`#1\relax \gdef\bxbf@str@in{#2}% \ifnum\bxbf@count>@cclv% \expandafter\bxbf@invalid@char% \fi } \def\bxbf@get@char@d{% \afterassignment\bxbf@get@char@e \let\bxbf@tmpa=% } \def\bxbf@get@char@e#1\bxbf@end{% \bxbf@count\bxbfSP \gdef\bxbf@str@in{#1}% } \def\bxbf@invalid@char{% \bxbf@warn@hichr% \bxbf@count\z@% non 8-bit char is replaced by zero } \def\bxbf@get@char@mt{% \ifx!\bxbf@eofval% \bxbf@warn@ineof% \bxbf@count\m@ne% \else\ifx*\bxbf@eofval\else% \bxbf@count\bxbf@eofval% \fi\fi% }

%% \bxbf@put@char \def\bxbf@put@char{% \lccode`!=\bxbf@count% \lowercase{% \xdef\bxbf@str@out{\bxbf@str@out% \ifnum\bxbf@count=\bxbfLF \bxbfLF% \else\ifnum\bxbf@count=\bxbfSP \bxbfSP% \else !\fi\fi}% }% %\bxDebug{OUT:\bxbf@str@out:\the\bxbf@count}% }

%--------------------------------------- all done \endinput %% EOF

tobiasBora
  • 8,684
  • 1
    Excellent ridiculous solution! You are right about the minus sign, that is the logical behaviour, but I only realized that after the answers had started coming in, so we're stuck with the original question. – Gaussler Apr 04 '23 at 06:03
  • 7
    This is worth another bounty! – egreg Apr 04 '23 at 12:53
  • @egreg Ahah thanks, I'm happy to see that you like it, I would never have expected to ever receive a bounty from you ^^ (the fact that you have never asked a single question does not help! https://tex.stackexchange.com/users/4427/egreg?tab=questions) – tobiasBora Apr 04 '23 at 13:52
  • 1
    Yes, @egreg is usually the one who receives bounties. Still, I hope that some day, just for fun, he will ask some question in here. – Gaussler Apr 04 '23 at 16:01
17

What we can do in OpTeX:

\optdef\wipet[1]{\if i\the\opt ${\rm wi}+i{\rm pet}$%
   \else
      \tmpnum=\the\opt\relax
      \ifnum\tmpnum<0 \fornum 1..-\tmpnum \do{pet}\fi
      wi%
      \ifnum\tmpnum>0 \fornum 1..\tmpnum \do{pet}\fi
   \fi
}

\wipet\ should produce ``wipet''

\wipet[0]\ should produce ``wi''

\wipet[1]\ should produce ``wipet''

\wipet[2]\ should produce ``wipetpet''

\wipet[5]\ should produce ``wipetpetpetpetpet''

\wipet[-1]\ should produce ``petwi''

\wipet[-2]\ should produce ``petpetwi''

\wipet[i]\ perhaps "${\rm wi} + i{\rm pet}$"

\bye

wipet
  • 74,238
15

Just for comparison, here is a version in Metapost (with apologies for being so far from the brief, apart from the "ridiculous" bit).

enter image description here

Compile with lualatex. (Here be dragons...)

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
picture payload; 
payload = textext("$\vcenter{\hbox{egreg}}\;$");
payload := payload scaled (1/abs(lrcorner payload - llcorner payload));
vardef dragon(expr level, a, b, r) = 
    if level = 0:
        draw a--b withcolor 3/4;
        draw payload zscaled (b-a) shifted a;
    else:
        save p; pair p;
        p = 0.7071067811865476[a, b] rotatedabout(a, r);
    dragon(level-1, a, p, +abs(r));
    dragon(level-1, p, b, -abs(r)); 
fi

enddef; beginfig(1); dragon(11, origin, 600 right, 45); endfig; \end{mplibcode} \end{document}

Thruston
  • 42,268
14

I like recursions:

\documentclass{article}

\NewDocumentCommand\egreg{O{1}}{% \ifnum #1>0 eg\reg{#1}\else\ifnum #1<0 \reg{-#1}\fi eg\fi } \newcommand*{\reg}[1]{% \ifnum #1>0 -reg\reg{\numexpr #1-1\relax}\fi }

\begin{document}

\raggedright

\egreg{} should produce ``egreg"

\egreg[0] should produce ``eg"

\egreg[1] should produce ``egreg"

\egreg[2] should produce ``egregreg"

\egreg[5] should produce ``egregregregregreg"

\medskip Perhaps we might also want to allow negative values:

\egreg[-1] should produce ``regeg"

\egreg[-2] should produce ``regregeg"

\medskip And also with hyphenation: \egreg[100]

\end{document}

Yes, handling of complex values is missing.

cabohah
  • 11,455
  • 1
    Good, in case I want to write “egregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregregreg”. – Gaussler Apr 01 '23 at 12:03
  • In general, isn’t it safer to use '' (two apostrophes) instead of " (quotation mark), especially since babel has a tendency to make the latter active? – Gaussler Apr 02 '23 at 12:54
  • 1
    @Gaussler Generally it would be safer and better to use csquotes. But IMHO the question was not about safer and better solutions. ;-) (But honestly, I was simply too lazy to replace all the quotes.) – cabohah Apr 03 '23 at 06:48
10

The following, LuaLaTeX-based solution probably won't qualify as being completely ridiculous, since it doesn't actually employ any loop-type control structures; it is left as an exercise to the motivated reader to replace Lua's string.rep function with a suitable for, while, or repeat .. until loop. Also, to keep @egreg's blood pressure from spiking up, I use \mathrm instead of \text directives...

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}

\begin{luacode*}

function egreg ( n )
  if n=="" then
    tex.sprint ("egreg")
  elseif n=="i" then
    tex.sprint ( "\\ensuremath{\\mathrm{eg}+i\\mathrm{reg}}" )
  else
    n = tonumber ( n )
    if n<0 then
      tex.sprint (        string.rep ( "reg",-n) .. "eg" )
    else
      tex.sprint ( "e" .. string.rep ( "gre", n) .. "g" )
    end
  end
end
\end{luacode*}
%% LaTeX-side code:
\newcommand\egreg[1][]{\directlua{egreg("#1")}}

\begin{document}

\obeylines % just for this example
\egreg 
\egreg[0] 
\egreg[1] 
\egreg[5] 
\egreg[-1] 
\egreg[-2]
\egreg[i] 

\end{document}
Mico
  • 506,678
4

An expl3 abstraction, to a certain approximation:

egreg

carlisle

Besides being ridiculous in coding, style, design, purpose, outcome, background colour, submission time, some imaginable items, and other things, what this shows is that: egreg is, simultaneously, equivalent to, and not equivalent to, carlisle. Mirabile dictu!

And utterly ridiculous!!

MWE

\documentclass{article}
\usepackage{xcolor}
\usepackage{fontspec}
\setmainfont{NotoSerif}
\pagecolor{blue!5}

\ExplSyntaxOn

\tl_new:c {c_texta_tl} \tl_set:cn {c_texta_tl} { ~ produces ~}

\tl_new:N \l_tmpc_tl

\tl_new:N \l_egreg_oarg_tl \newcommand{\egregnodelength}{2} \int_new:N \l_enl_loop_int

%------------------------------------------------------------------

\cs_new:Npn \setegreg:n #1 { \exp_args:Nc \NewDocumentCommand { #1 } { o } {

\tl_if_novalue:nTF { ##1 }
    { 
        \int_set:Nn \l_tmpa_int { 0 }
        }
    {
        \tl_set:Nn \l_egreg_oarg_tl { ##1 }
        \tl_if_eq:NnTF \l_egreg_oarg_tl { i } { \int_set:Nn \l_tmpa_int { 9999 }    }
        {\tl_if_eq:NnTF \l_egreg_oarg_tl { zzz } { \int_set:Nn \l_tmpa_int { 9998 }     }
        {\tl_if_eq:NnTF \l_egreg_oarg_tl { egreg } { \int_set:Nn \l_tmpa_int { 9997 }   }
            { 
                \int_set:Nn \l_tmpa_int { ##1 }
            }
        }}
        }

\tl_set:Nn \l_tmpa_tl { #1 } %***********

% \tl_show:N \l_tmpa_tl

\tl_if_exist:cF { g_ \l_tmpa_tl _head_tl }
    {%%%%%%%%%%%
        \tl_new:c { g_ \l_tmpa_tl _head_tl }
        }
\tl_if_exist:cF { g_ \l_tmpa_tl _tail_tl }
    {
        \tl_new:c { g_ \l_tmpa_tl _tail_tl }
        }

\seq_set_split:NnV  \l_tmpa_seq {  } { \l_tmpa_tl } 

% \tl_show:N \l_tmpa_tl % \seq_show:N \l_tmpa_seq

\tl_clear:N \l_tmpb_tl
\int_set:Nn \l_enl_loop_int { 0 }
\int_do_until:nNnn { \l_enl_loop_int } = { \egregnodelength } 
{

\seq_pop_left:NN
    \l_tmpa_seq
    \l_tmpc_tl 
\tl_put_right:NV
    \l_tmpb_tl
    \l_tmpc_tl      

    \int_incr:N \l_enl_loop_int
}

\tl_gset_eq:cN { g_ \l_tmpa_tl _head_tl } \l_tmpb_tl 

\tl_gset:cn 
    { g_ \l_tmpa_tl _tail_tl } 
    { \seq_use:Nnnn
        \l_tmpa_seq
        {}{}{}
     }



    \int_case:nnTF
        { \l_tmpa_int }
        {
            { 9999 } { 
                    \tl_use:c { g_ \l_tmpa_tl _head_tl }
                    $ + i $
                    \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                         }
            { 9998 } { 
                        \showegreg{#1}
                         }
            { 9997 } { 
    \textcolor{blue}{
    \texttt{
    \textbackslash
    #1[#1]
    }}
    \tl_use:N \c_texta_tl 
    ``carlisle''.
                         }
        }
        {}{ %%%%%%%%%%%%%%%%%%%
    \int_case:nnTF
        { \int_sign:n { \l_tmpa_int } }
        {
            { 0 } {

% \tl_use:c { g_ \l_tmpa_tl head_tl } % \tl_use:c { g \l_tmpa_tl _tail_tl }

                        \int_until_do:nNnn
                            { \l_tmpb_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpb_int
                            }
                                \tl_use:c { g_ \l_tmpa_tl _head_tl }
                        \int_until_do:nNnn
                            { \l_tmpa_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpa_int
                            }

                        \tl_if_novalue:nT { ##1 }
                            { 
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                            }
                    }
            { -1 } {
                        \int_set:Nn \l_tmpb_int { \int_abs:n { \l_tmpa_int } }
                        \int_until_do:nNnn
                            { \l_tmpb_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpb_int
                            }
                                \tl_use:c { g_ \l_tmpa_tl _head_tl }
                    }
            { 1 } {
                        \tl_use:c { g_ \l_tmpa_tl _head_tl }
                        \int_until_do:nNnn
                            { \l_tmpa_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpa_int
                            }
                    }
        }
        {}{}            

    } %%%%%%%%%%%%%%%%%%%
} % end-NDC


}

%------------------------------------------------------------------

\NewDocumentCommand{\makeegreg} { m } { \setegreg:n { #1 } }

%------------------------------------------------------------------

\NewDocumentCommand { \egregX } { o } {

\tl_if_novalue:nTF { #1 }
    { 
        \int_set:Nn \l_tmpa_int { 0 }
        }
    {
        \tl_set:Nn \l_egreg_oarg_tl { #1 }
        \tl_if_eq:NnTF \l_egreg_oarg_tl { i } { \int_set:Nn \l_tmpa_int { 9999 }    }
        {\tl_if_eq:NnTF \l_egreg_oarg_tl { zzz } { \int_set:Nn \l_tmpa_int { 9998 }     }
        {\tl_if_eq:NnTF \l_egreg_oarg_tl { egreg } { \int_set:Nn \l_tmpa_int { 9997 }   }
            { 
                \int_set:Nn \l_tmpa_int { #1 }
            }
        }}
        }

\tl_set:Nn \l_tmpa_tl { egreg } %***********

% \tl_show:N \l_tmpa_tl

\tl_if_exist:cF { g_ \l_tmpa_tl _head_tl }
    {%%%%%%%%%%%
        \tl_new:c { g_ \l_tmpa_tl _head_tl }
        }
\tl_if_exist:cF { g_ \l_tmpa_tl _tail_tl }
    {
        \tl_new:c { g_ \l_tmpa_tl _tail_tl }
        }

\seq_set_split:NnV  \l_tmpa_seq {  } { \l_tmpa_tl } 

% \tl_show:N \l_tmpa_tl % \seq_show:N \l_tmpa_seq

\tl_clear:N \l_tmpb_tl
\int_set:Nn \l_enl_loop_int { 0 }
\int_do_until:nNnn { \l_enl_loop_int } &gt; { \egregnodelength } 
{

\seq_pop_left:NN
    \l_tmpa_seq
    \l_tmpc_tl 
\tl_put_right:NV
    \l_tmpb_tl
    \l_tmpc_tl      

    \int_incr:N \l_enl_loop_int
}


\tl_gset_eq:cN { g_ \l_tmpa_tl _head_tl } \l_tmpb_tl 

\tl_gset:cn 
    { g_ \l_tmpa_tl _tail_tl } 
    { \seq_use:Nnnn
        \l_tmpa_seq
        {}{}{}
     }



    \int_case:nnTF
        { \l_tmpa_int }
        {
            { 9999 } { 
                    \tl_use:c { g_ \l_tmpa_tl _head_tl }
                    $ + i $
                    \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                         }
            { 9998 } { 
                        \showegreg{egreg}
                         }
            { 9997 } { 
    \textcolor{blue}{
    \texttt{
    \textbackslash
    egreg[egreg]
    }}
    \tl_use:N \c_texta_tl 
    ``carlisle''.
                         }
        }
        {}{ %%%%%%%%%%%%%%%%%%%
    \int_case:nnTF
        { \int_sign:n { \l_tmpa_int } }
        {
            { 0 } {

% \tl_use:c { g_ \l_tmpa_tl head_tl } % \tl_use:c { g \l_tmpa_tl _tail_tl }

                        \int_until_do:nNnn
                            { \l_tmpb_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpb_int
                            }
                                \tl_use:c { g_ \l_tmpa_tl _head_tl }
                        \int_until_do:nNnn
                            { \l_tmpa_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpa_int
                            }

                        \tl_if_novalue:nT { #1 }
                            { 
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                            }
                    }
            { -1 } {
                        \int_set:Nn \l_tmpb_int { \int_abs:n { \l_tmpa_int } }
                        \int_until_do:nNnn
                            { \l_tmpb_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpb_int
                            }
                                \tl_use:c { g_ \l_tmpa_tl _head_tl }
                    }
            { 1 } {
                        \tl_use:c { g_ \l_tmpa_tl _head_tl }
                        \int_until_do:nNnn
                            { \l_tmpa_int }
                            =
                            { \c_zero_int }
                            {
                                \tl_use:c { g_ \l_tmpa_tl _tail_tl }
                                \int_decr:N \l_tmpa_int
                            }
                    }
        }
        {}{}            

    } %%%%%%%%%%%%%%%%%%%
} % end-NDC


%------------------------------------------------------------------

\NewDocumentCommand { \showegreg } { m o } {

\tl_if_novalue:nTF { #2 } { \tl_set:Nn \l_tmpa_tl { \textcolor{blue}{ \texttt{ \textbackslash #1 }} \tl_use:N \c_texta_tl \use:c {#1}''. } } { \tl_set:Nn \l_tmpa_tl { \textcolor{blue}{ \texttt{ \textbackslash #1[#2] }} \tl_use:N \c_texta_tl\use:c {#1}[#2]''. } }
\tl_use:N \l_tmpa_tl }

\NewDocumentCommand { \showegregall } { m } {

\tex_par:D \showegreg{#1} ~

\tex_par:D \showegreg{#1}[0]

\tex_par:D \showegreg{#1}[1]

\tex_par:D \showegreg{#1}[-1]

\tex_par:D \showegreg{#1}[-5]

\tex_par:D \showegreg{#1}[i]

\tex_par:D \showegreg{#1}[zzz]

\tex_par:D \showegreg{#1}[egreg]

\renewcommand{\egregnodelength}{3} \tex_par:D \showegreg{#1}[-5]

\renewcommand{\egregnodelength}{1} \tex_par:D \showegreg{#1}[-5]

\renewcommand{\egregnodelength}{2} \tex_par:D \showegreg{#1}[-5]

}

\ExplSyntaxOff

\begin{document}

\makeegreg{egreg} \egreg \showegregall{egreg}

\newpage \makeegreg{carlisle} \carlisle

\showegregall{carlisle} % %\showegreg{carlisle}[4] % %\showegreg{carlisle}[i]

\end{document}

Cicada
  • 10,129
3

Nobody remember multido?

enter image description here

\documentclass[a5paper]{article}
\usepackage{xstring}
\usepackage{multido}
\usepackage{xcolor}
\usepackage{graphicx}
\parindent0pt\parskip0pt
\newcommand\egreg[1][1]{%
\IfInteger{#1}{%
\ifnum #1<0 \multido{}{#1}{\reflectbox{reg}}\reflectbox{eg}\else
\ifnum #1>0 
{\bfseries{eg}\multido{}{#1}{reg}}\par
\else  eg\par\fi\fi}{{eg\emph{reg}}\par}}
\centering
\begin{document}
\sffamily
\multido{}{9}{\egreg[i]}  
\egreg [-4] \egreg [4]
\egreg [-3] \egreg [3]
\egreg [-2] \egreg [2]
\egreg[-1] \egreg [1]
\egreg[0]
\huge \egreg 
\end{document}
Fran
  • 80,769