2009-07-11 23 views
7

W T E X, jak można podzielić ciąg znaków, taki jak \mana{X1 2W/UB R /G} na części i podać je do innego makra (w tym przypadku, aby zastąpić wywołanie makra przez coś podobnego \m{X}\m{12}\m{W/U}\m{B}\m{R/G}), grupując według bardzo prostych reguł, a mianowicie: a) kolejne cyfry tworzą grupę, b) ukośnik tworzy grupę dwóch pobliskich znaków, c) spacje mają zostać całkowicie usunięte?TeX: parsowanie ciągów i usuwanie białych znaków

Wypróbowałem pakiet substr, ale nie był zbyt pomocny, pozwalając tylko znaleźć pewne podciągi. pętle ręcznie napisany takie jak

\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 

nie działa, gdy kończy się ciąg spacji, ani ja sukces z \futurelet.

Ogólnie, jak podejść do zadania analizy łańcuchów w T E X? Na przykład pakiet texmate pozwala pisać takie rzeczy, jak |1 e4 e5 Nf3 Nc6| i automatycznie rysuje odpowiednie pozycje w szachach. Jak to robi? Co mogę przeczytać o zapętlaniu znaków w ciągu znaków i innych hackach takich jak ten?

Odpowiedz

3

Oto co w końcu zrobił wejść MTG mana w TeX/LaTeX:


% http://www.tug.org/TUGboat/Articles/tb28-1/tb88glister.pdf 

\newif\[email protected]@digit 

\def\@[email protected]#1{% lame, I know, but nothing else worked 
    \@[email protected]% 
    \def\@[email protected]{0}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{1}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{2}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{3}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{4}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{5}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{6}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{7}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{8}\ifx\@[email protected]#1\@[email protected]\fi% 
    \def\@[email protected]{9}\ifx\@[email protected]#1\@[email protected]\fi% 
    } 


\catcode`\^^G=12 

\newcommand*{\@[email protected]}[2]{% 
    \let\@[email protected]=#1% 
    \def\@[email protected]{#2}% 
    \ifx\@[email protected]\@empty% 
    \else% 
     \@@[email protected]#2^^G% 
    \fi% 
} 

\def\@@[email protected]#1#2^^G{% 
    \def\@[email protected]{#1}% 
    \def\@[email protected]{#2}% 
    \ifx\@[email protected]\@empty% 
     \let\@[email protected]=\@gobble% 
    \else% 
     \@[email protected]{#1}% 
     \ifx\@[email protected]\@empty% 
      \let\@[email protected]=\@gobble% 
     \else% 
      \let\@[email protected]=\@@[email protected]% 
     \fi% 
    \fi% 
    \@[email protected]#2^^G% 
} 

\catcode`\^^G=15 

% these are meant to be redefined 
\def\[email protected]#1{(\MakeUppercase{#1})} 
\def\[email protected]@colored#1{\[email protected]{#1}} 
\def\[email protected]@colorless#1#2{\[email protected]{#1#2}} 
\def\[email protected]@hybrid#1#2{\[email protected]{#1/#2}} 

\gdef\@[email protected]{.} 
\gdef\@[email protected]{/} 
\let\@[email protected]=\@[email protected] 
\let\@[email protected]=\@[email protected] 

\def\@[email protected]#1{% 
    \gdef\@[email protected]{#1}% 
    \ifx\@[email protected]\@[email protected]% 
    \else% 
     \ifx\@[email protected]\@[email protected]% 
      \[email protected]@hybrid{\@[email protected]}{\@[email protected]}% 
      \let\@[email protected]=\@[email protected]% 
      \let\@[email protected]=\@[email protected]% 
     \else% 
      \@[email protected]\@[email protected]\[email protected]@digit% 
       \@[email protected]\@[email protected]\[email protected]@digit% 
        \ifx\@[email protected]\@[email protected]% 
         \[email protected]@colorless{}{\@[email protected]}% 
        \else% 
         \[email protected]@colorless{\@[email protected]}{\@[email protected]}% 
         \let\@[email protected]=\@[email protected]% 
        \fi% 
       \else% 
        \[email protected]@colorless{}{\@[email protected]}% 
       \fi% 
      \else% 
       \[email protected]@colored{\@[email protected]}% 
      \fi% 
     \fi% 
    \fi% 
    \let\@[email protected]=\@[email protected]% 
    \let\@[email protected]=\@[email protected]% 
} 

\newcommand{\mana}[1]{% 
\let\@[email protected]=\@[email protected]% 
\let\@[email protected]=\@[email protected]% 
\@[email protected]{\@[email protected]}{#1\@[email protected]\@[email protected]}} 
+0

Co nie tak z moją odpowiedź? Wygląda na mniejszy. –

+0

Nic nie jest nie tak, ale udało mi się wymyślić to rozwiązanie, zanim zdążyłem spojrzeć na twoje. –

3

Jak to często bywa, dobrze zadane pytanie stanowi połowę rozwiązania. Oto co znalazłem po napisaniu powyższego posta:

http://www.tug.org/TUGboat/Articles/tb28-1/tb88glister.pdf

„Jeden niefortunny własnością \allchars jest to, że odrzuca wszystkie spacje w oryginalnej ciąg,” mówi. Ha ha.

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 
Powiązane problemy