Создание команды для Физического измерения — посимвольный разбор

Создание команды для Физического измерения — посимвольный разбор

Я хочу иметь специальную команду для печати физических размеров. Что-то вроде \phydimen{M2L-3T-1}. Это должно вывести то же самое, что и $\textrm{M}^2\textrm{L}^{-3}\textrm{T}^{-1}$.

Я нахожу, что \ceкоманда mhchempackage вполне подходит. Поэтому я хакаю ее, чтобы сделать это \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?, включая причины использования другой команды.

Связанный контент