如何创建 \egreg 命令?

如何创建 \egreg 命令?

我想要一个\egreg生成“egreg”的命令。但是,没有理由将自己限制为一个“reg”。谁知道呢,也许有一天你出于某种原因只想写“egregregreg”。因此,该命令还应采用可选参数,指定所需的“reg”数量。

我知道有一些涉及循环的简单解决方案,但考虑到今天是 4 月 1 日,最荒谬的解决方案将被接受。

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

答案1

我认为图像部分应该用 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}

在此处输入图片描述

答案2

当然是在比赛之外。最荒谬的答案将获得赏金积分。

由于您不想要可扩展性(如建议的语法所示),因此这是我的版本。请注意,大多数结束行都没有被掩盖,%并且有大量不需要的空格。

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

在此处输入图片描述

答案3

我认为感谢 egreg 提供的所有帮助的最好方式是使用与我在这个论坛上读到的大多数 LaTeX 代码一样易读的代码来解决这个练习(特别是你的 egreg,但如果 LaTeX 不是真正可读的,那不是你的错:-P)...但有点美化(我擅自将减号版本修改为真正的逆,即向后读时相等)。

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

在此处输入图片描述

请注意,您还需要创建一个bxbluf.sty文件来解释上述代码中的 Brainfuck(来自https://gist.github.com/zr-tex8r/7527995,略微改进以删除不需要的空间):

% 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{\[email protected]}

  \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

答案4

仅供比较,以下是元帖子(除了“荒谬”的部分,我对离简报还有点距离表示歉意)。

在此处输入图片描述

使用 进行编译lualatex。(这里有龙……)

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

相关内容