在T E X中,如何将诸如\mana{X1 2W/UB R /G}
之类的字符串拆分成部分并将它们提供给另一个宏(在这种情况下,通过以下方式替换宏调用)像\m{X}\m{12}\m{W/U}\m{B}\m{R/G}
这样的东西,按照非常简单的规则进行分组,即:a)连续数字组成一个组,b)斜线创建一组两个附近的字符,c)空格要被完全剥离?
我尝试了substr
包,但它没有太大帮助,只允许找到某些子串。手写循环,如
\def\lcpass#1.{}
\def\lcloop#1#2.{%
\ifempty{#2}%
#1%
\let\continue=\lcpass%
\else%
\let\continue=\lcloop%
\fi%
\continue#2.}
\def\lastchar#1{\lcloop#1.} % returns the last character of a string
当字符串以空格结尾时,无法工作,\futurelet
我也没有成功。
一般来说,如何解决在T E X中解析字符串的任务?例如,texmate
包允许用户编写|1 e4 e5 Nf3 Nc6|
之类的内容并自动绘制相应的国际象棋位置。它是如何做到的?关于循环字符串中的字符以及其他T E X这样的黑客,我能读到什么?
答案 0 :(得分:6)
\def\m#1{\par$m$({\tt #1})}% Any macros
\def\removespaces{\catcode`\ =9 }% Ignore all spaces`
\let\manaNext\relax % aux def
\let\manaLastChar\relax % aux def
\newtoks\manaToks % aux toks
\newif\ifDigitProcessing
\def\mana#{\afterassignment \manaA \let\next= }% always next = {
\def\manaA{\bgroup \removespaces \let\manaNext\manaB \manaNext}% algorithm init: ignore spaces
\def\manaB{\futurelet\next\manaC}% algorithm start
\def\manaC{\ifx\next\egroup \def\nnext{\manaFlush\aftergroup\manaNext}\else\let\nnext\manaD\fi\nnext}% check for \egroup
\def\manaD{\ifx\next/\let\nnext\manaSlash\else \ifcat\next 1\let\nnext\manaDigit \else \let\nnext\manaE \fi\fi \nnext}% cases
\def\manaE#1{\manaFlush\DigitProcessingfalse\let\manaLastChar\next\manaNext}% Letters A-Z and a-z case
\def\manaFlush{\ifx\manaLastChar\relax\else\m{\manaLastChar}\fi\let\manaLastChar\relax
\ifDigitProcessing\expandafter\m\expandafter{\the\manaToks}\fi\manaToks{}}% transform to \m{...}
\def\manaSlash#1#2{\m{\manaLastChar/#2}\let\manaLastChar\relax\manaNext}%#1=/, #2=next letter
\def\manaDigit#1{\ifDigitProcessing\else\manaFlush\fi
\manaToks=\expandafter{\the\manaToks#1}\DigitProcessingtrue\manaNext}% 0-9 case
\hrule\medskip
\mana{X1 2W/UB R /G}
\medskip\hrule\medskip
\mana{X1 2W/UB s/SS 14 1 R /G XZ}
\medskip\hrule\medskip
答案 1 :(得分:3)
通常情况下,一个好的问题只是解决方案的一半。这是我在写完上述帖子后发现的:
http://www.tug.org/TUGboat/Articles/tb28-1/tb88glister.pdf
“\allchars
的一个不幸之处在于它丢弃了原始字符串中的所有空格,”它说。哈哈。
答案 2 :(得分:3)
这是我最终在TeX / LaTeX中输入MTG法术力的方法:
% http://www.tug.org/TUGboat/Articles/tb28-1/tb88glister.pdf
\newif\if@mtg@digit
\def\@mtg@testdigit#1{% lame, I know, but nothing else worked
\@mtg@digitfalse%
\def\@mtg@tmp{0}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{1}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{2}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{3}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{4}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{5}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{6}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{7}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{8}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
\def\@mtg@tmp{9}\ifx\@mtg@tmp#1\@mtg@digittrue\fi%
}
\catcode`\^^G=12
\newcommand*{\@mtg@loop}[2]{%
\let\@mtg@callback=#1%
\def\@mtg@string{#2}%
\ifx\@mtg@string\@empty%
\else%
\@@mtg@loop#2^^G%
\fi%
}
\def\@@mtg@loop#1#2^^G{%
\def\@mtg@car{#1}%
\def\@mtg@cdr{#2}%
\ifx\@mtg@car\@empty%
\let\@mtg@next=\@gobble%
\else%
\@mtg@callback{#1}%
\ifx\@mtg@cdr\@empty%
\let\@mtg@next=\@gobble%
\else%
\let\@mtg@next=\@@mtg@loop%
\fi%
\fi%
\@mtg@next#2^^G%
}
\catcode`\^^G=15
% these are meant to be redefined
\def\mtg@mana#1{(\MakeUppercase{#1})}
\def\mtg@mana@colored#1{\mtg@mana{#1}}
\def\mtg@mana@colorless#1#2{\mtg@mana{#1#2}}
\def\mtg@mana@hybrid#1#2{\mtg@mana{#1/#2}}
\gdef\@mtg@terminator{.}
\gdef\@mtg@slash{/}
\let\@mtg@a=\@mtg@terminator
\let\@mtg@b=\@mtg@terminator
\def\@mtg@doChar#1{%
\gdef\@mtg@c{#1}%
\ifx\@mtg@a\@mtg@terminator%
\else%
\ifx\@mtg@b\@mtg@slash%
\mtg@mana@hybrid{\@mtg@a}{\@mtg@c}%
\let\@mtg@b=\@mtg@terminator%
\let\@mtg@c=\@mtg@terminator%
\else%
\@mtg@testdigit\@mtg@a\if@mtg@digit%
\@mtg@testdigit\@mtg@b\if@mtg@digit%
\ifx\@mtg@c\@mtg@slash%
\mtg@mana@colorless{}{\@mtg@a}%
\else%
\mtg@mana@colorless{\@mtg@a}{\@mtg@b}%
\let\@mtg@b=\@mtg@terminator%
\fi%
\else%
\mtg@mana@colorless{}{\@mtg@a}%
\fi%
\else%
\mtg@mana@colored{\@mtg@a}%
\fi%
\fi%
\fi%
\let\@mtg@a=\@mtg@b%
\let\@mtg@b=\@mtg@c%
}
\newcommand{\mana}[1]{%
\let\@mtg@a=\@mtg@terminator%
\let\@mtg@b=\@mtg@terminator%
\@mtg@loop{\@mtg@doChar}{#1\@mtg@terminator\@mtg@terminator}}