Я хочу иметь специальную команду для печати физических размеров. Что-то вроде \phydimen{M2L-3T-1}
. Это должно вывести то же самое, что и $\textrm{M}^2\textrm{L}^{-3}\textrm{T}^{-1}$
.
Я нахожу, что \ce
команда mhchem
package вполне подходит. Поэтому я хакаю ее, чтобы сделать это \newcommand{\phydimen}[1]{\ce{#1}}
, а затем даю команду \phydimen{ML^2T^{-2}}
на печать измерения. Однако мне все еще приходится использовать надоедливые ^
и { }
. \ce
Поведение по умолчанию — помещать числа в качестве нижнего индекса.
Я хочу \phydimen
автоматически определять, когда в аргументе есть (положительное или отрицательное) целое число, и возводить его в "степень". Также \phydimen
должна быть возможность принимать больше символов, чем M, L, T. Также, если указан нижний регистр, он должен автоматически преобразовывать его в верхний.
Как мне проанализировать аргументы посимвольно и решить, являются ли они буквой, положительным или отрицательным целым числом?
МВЭ:
\documentclass{article}
\usepackage{mhchem}
\newcommand{\phydimen}[1]{\ce{#1}}
\begin{document}
$\textrm{M}^2\textrm{L}^{-3}\textrm{T}^{-1}$
\phydimen{ML^2T^{-2}} % instead I want \phydimen{ML2T-2}
\end{document}
решение1
Вы можете использовать регулярные выражения:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\phydimen}{m}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_all:nnN { (\-?\d+) } { \cU\^\cB\{\1\cE\} } \l_tmpa_tl
\ensuremath { \mathrm { \tl_use:N \l_tmpa_tl } }
}
\ExplSyntaxOff
\begin{document}
\phydimen{ML2T-2}
\end{document}
Выражение поиска соответствует возможному целому числу со знаком, выражение замены указывает «символ верхнего индекса, левая фигурная скобка, совпадение, правая фигурная скобка».
решение2
Здесь я listofitems
провожу двухуровневый анализ, на первом уровне ищу цифры, а negative
на втором — знак.
\documentclass{article}
\usepackage{listofitems}
\newcommand\phydimen[1]{%
\setsepchar{0||1||2||3||4||5||6||7||8||9/-}%
\greadlist\Dim{#1}%
\foreachitem\i\in\Dim{%
\textrm{\Dim[\icnt,1]}\ensuremath{^{\Dimsep[\icnt,1]\Dimsep[\icnt]}}}%
}
\begin{document}
\phydimen{ML2T-2}
\end{document}
решение3
Разбор побуквенно — сложная штука в LaTeX. Вы можете открыть mhchem.sty и посмотреть, как это делается. Или см.Основы парсингаилиКак можно разобрать первое слово в потоке токенов, токен за токеном?.
Я бы не рекомендовал использовать \ce
внутри вашей команды. Он делает гораздо больше, чем просто меняет шрифт. Он будет дважды анализировать ввод, я думаю, это будет неэффективно.
Команда, которую вы хотите создать, уже существует в mhchem для MathJax. Почему ее нет для LaTeX, объясняется в вопросеКак использовать команду `MathJax mhchem \pu{}` в LaTex?, включая причины использования другой команды.