2009-07-11 11 views
7

En E X, ¿cómo es posible dividir una cadena como \mana{X1 2W/UB R /G} en partes y alimentarlas a otra macro (en este caso, para reemplazar la macro invocación por algo así como \m{X}\m{12}\m{W/U}\m{B}\m{R/G}), agrupando por reglas muy simples, a saber: a) los dígitos consecutivos forman un grupo, b) una barra inclinada crea un grupo de dos caracteres cercanos, c) los espacios deben ser eliminados por completo?TeX: cadena de análisis y eliminación de espacio en blanco

Probé el paquete substr pero no fue demasiado útil, solo permitía encontrar ciertas subcadenas. bucles escritos a mano como

\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 

no funcionan cuando la cadena termina en el espacio en blanco, ni soy exitoso con \futurelet.

En general, ¿cómo se aborda la tarea de analizar cadenas en T E X? Por ejemplo, el paquete texmate le permite a uno escribir cosas como |1 e4 e5 Nf3 Nc6| y dibuja automáticamente las posiciones de ajedrez correspondientes. ¿Cómo lo hace? ¿Qué puedo leer sobre el bucle de caracteres en una cadena y otros T E X hacks como este?

Respuesta

3

Esto es lo que finalmente hice para entrar MTG maná en 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][email protected]{}{\@[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

¿Qué pasa con mi respuesta? Se ve más pequeño. –

+0

No pasa nada, pero pude descifrar esta solución antes de poder ver la tuya. –

3

Como suele ser el caso, una pregunta bien formulada es la mitad de la solución. Esto es lo que encontré después de escribir el post anterior:

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

“Una desafortunada propiedad de \allchars es que descarta todos los espacios en la cadena original”, dice. Jaja.

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 
Cuestiones relacionadas