¿Cómo puedo crear una macro?
\split{ABC}
que produce
donde el formateo de los caracteres se realiza con otra macro, es decir
\formatchar{A}
dónde
\def\formatchar#1{{\color{red}#1}}
¿Para cualquier longitud de cuerda?
Intenté modificar el código en Dividir una cadena de caracteres n por n
\documentclass{article}
\usepackage{xstring}
\def\split#1#2{%
\StrSplit{#2}{1}\tempa\tempb
x%
\tempa\let\tempa\empty
\unless\ifx\tempb\empty\def\tempa{|\split{1}\tempb}\fi
y%
\tempa
}
\begin{document}
\split{1}{ABCD}
\end{document}
Y obtengo x e y antes y después (ya que no pude limitar con un comando y }) pero no puedo formatearlo correctamente. También me gustaría evitar el {1} en la llamada y usar
\split{ABCD}
solo. Siempre son divisiones de 1 carácter.
¡Cualquier ayuda es muy apreciada!
Respuesta1
Si no se garantiza que su entrada sea "solo ASCII", \seq_set_split:Nnn
es posible que un enfoque no funcione.
Cambié el nombre a \splitchars
porque \split
está ocupado por amsmath
.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\NewDocumentCommand{\formatchar}{m}{%
\textcolor{red!90!yellow}{#1}% <--- or whatever you like
}
\ExplSyntaxOn
\NewDocumentCommand{\splitchars}{O{|}m}
{% #1 = optional separator, default |
% #2 = text to split
\mflxvii_split:nn { #1 } { #2 }
}
\seq_new:N \l__mflxvii_split_items_seq
\cs_new_protected:Nn \mflxvii_split:nn
{
\seq_clear:N \l__mflxvii_split_items_seq
\text_map_inline:nn { #2 }
{
\seq_put_right:Nn \l__mflxvii_split_items_seq { \formatchar{##1} }
}
\seq_use:Nn \l__mflxvii_split_items_seq { #1 }
}
\ExplSyntaxOff
\begin{document}
\splitchars{ABC}
\splitchars[--]{ABC}
\splitchars{ábç}
\splitchars{ÅÄÖ}
\end{document}
Para obtener un resultado similar a una lista, aquí hay una extensión que permite un separador diferente entre los dos últimos elementos.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\NewDocumentCommand{\formatchar}{m}{%
\textcolor{red!90!yellow}{#1}% <--- or whatever you like
}
\ExplSyntaxOn
\NewDocumentCommand{\splitchars}{O{|}O{#1}m}
{% #1 = optional separator, default |
% #2 = optional separator between last two
% #3 = text to split
\mflxvii_split:nnn { #1 } { #2 } { #3 }
}
\seq_new:N \l__mflxvii_split_items_seq
\cs_new_protected:Nn \mflxvii_split:nnn
{
\seq_clear:N \l__mflxvii_split_items_seq
\text_map_inline:nn { #3 }
{
\seq_put_right:Nn \l__mflxvii_split_items_seq { \formatchar{##1} }
}
\seq_use:Nnnn \l__mflxvii_split_items_seq { #2 } { #1 } { #2 }
}
\ExplSyntaxOff
\begin{document}
\splitchars{ABC}
\splitchars[--]{ABC}
\splitchars{ábç}
\splitchars{ÅÄÖ}
\splitchars[, ][ and ]{ÅÄÖ}
\splitchars[, ][ and ]{ÅÄ}
\end{document}
Respuesta2
Aquí hay una solución basada en LuaLaTeX, que utiliza las funciones integradas de gsub
Lua sub
. En realidad, el código utiliza versiones de funciones gsub
y sub
que pueden manejar caracteres codificados en utf8 directamente.
La macro principal a nivel de usuario se llama \splitstring
en lugar de \split
, porque lamatemáticasEl paquete define un entorno llamado split
junto con macros llamadas \split
y \endsplit
.
Observe que (a) el argumento de \splitstring
puede contener espacios en blanco y (b) formatchar
se implementa como una función Lua en lugar de como una macro LaTeX.
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{xcolor} % for '\textcolor' macro
% Lua-side code
\directlua{
function formatchar ( c )
return ( '\\textcolor{red}{\\textbf{' .. c .. '}}|' )
end
function split ( s )
s = unicode.utf8.gsub ( s , '.' , formatchar )
return ( unicode.utf8.sub ( s , 1 , -2 ) ) % delete final '|'
end
}
% LaTeX-side code
\newcommand\splitstring[1]{\directlua{tex.sprint(split('#1'))}}
\begin{document}
\obeylines % just for this example
\splitstring{ABC}
\splitstring{123abc}
\splitstring{Hello World}
\end{document}
Respuesta3
Aquí está mi intento de solución usando ExplSyntax:
\documentclass{article}
\usepackage{xcolor}
\ExplSyntaxOn
\seq_new:N \l__my_split_seq
\NewDocumentCommand { \split } { m } { \__my_split:n { #1 } }
\cs_new_protected:Npn \__my_split:n #1
{
\seq_set_split:Nnn \l__my_split_seq {} { #1 }
\seq_set_map:NNn \l__my_split_seq \l__my_split_seq
{ \__my_split_fn:n { ##1 } }
% \seq_log:N \l__my_split_seq
\seq_use:Nn \l__my_split_seq { | }
}
\cs_new_protected:Npn \__my_split_fn:n #1 { { \color { red } #1 } }
\ExplSyntaxOff
\begin{document}
\split{ABCD}
\split{1234}
\end{document}
Respuesta4
Como no se ofrecen soluciones LaTeX2e, les doy una aquí. Utilizo un ciclo de token para tomar caracteres uno por uno del argumento. Esta solución supone que el argumento no tiene macros ni grupos. Los omití porque no se dio ninguna orientación sobre cómo deben manejarse, aunque se pueden manejar según sea necesario.
Si es necesario manejar caracteres Unicode, la compilación debe realizarse en xelatex o lualatex.
\documentclass{article}
\usepackage{tokcycle,xcolor}
\newcommand\formatchar[1]{\textcolor{red}{#1}}
\def\split#1{%
\tokencycle{\formatchar{##1}\splitchar}
{}{}{##1\splitchar}#1\endtokencycle}
\newcommand\splitchar{\tcpeek\z\ifx\empty\z\else$\mid$\fi}
\begin{document}
\split{ABCD}
\split{Å ÄÖ}
\end{document}