Как создать макрос
\split{ABC}
что выводит
где форматирование символов производится с помощью другого макроса, т.е.
\formatchar{A}
где
\def\formatchar#1{{\color{red}#1}}
для любой длины строки?
Я попытался изменить код в Разделить строку символов n на 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}
И я получаю x и y до и после (так как я не смог ограничиться командой и }), но я не могу заставить его правильно отформатироваться. Также я хотел бы избежать {1} в вызове и использовать
\split{ABCD}
только. Всегда разделяется на 1 символ.
Буду признателен за любую оказанную помощь!
решение1
Если нет гарантии, что ваши входные данные будут содержать только символы ASCII, подход с использованием \seq_set_split:Nnn
может не сработать.
Я изменил название на , \splitchars
потому что \split
оно занято 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}
Чтобы получить вывод в виде списка, вот расширение, которое позволяет использовать другой разделитель между двумя последними элементами.
\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}
решение2
Вот решение на основе LuaLaTeX, которое использует встроенные функции Lua gsub
и . На самом деле, код использует версии функций и , которые могут напрямую обрабатывать символы в кодировке utf8.sub
gsub
sub
Основной макрос пользовательского уровня называется , \splitstring
а не \split
, потому чтоамсматПакет определяет среду, называемую split
вместе с макросами, называемыми \split
и \endsplit
.
Обратите внимание, что (а) аргумент \splitstring
может содержать пробелы и (б) formatchar
реализован как функция Lua, а не как макрос 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}
решение3
Вот моя попытка решения с использованием 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}
решение4
Поскольку не предлагается никаких решений LaTeX2e, я привожу одно здесь. Я использую цикл токенов для извлечения символов по одному из аргумента. Это решение предполагает, что аргумент не имеет макросов и групп. Я их опустил, потому что не было дано никаких указаний о том, как с ними следует обращаться, хотя с ними можно обращаться по мере необходимости.
Если необходимо обрабатывать символы Unicode, компиляция должна выполняться под xelatex или 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}