我想要一个\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}