Construindo um comando para Dimensão Física - analisando caractere por caractere

Construindo um comando para Dimensão Física - analisando caractere por caractere

Desejo ter um comando dedicado para imprimir dimensões físicas. Algo como \phydimen{M2L-3T-1}. Isso deve produzir o mesmo que $\textrm{M}^2\textrm{L}^{-3}\textrm{T}^{-1}$.

Acho que o \cecomando do mhchempacote é bastante adequado. Então eu faço isso \newcommand{\phydimen}[1]{\ce{#1}}e emito um comando \phydimen{ML^2T^{-2}}para imprimir a dimensão. No entanto, ainda tenho que usar o incômodo ^e { }. O comportamento padrão \ceé enviar os números como subscritos.

Quero \phydimendetectar automaticamente quando um número inteiro (positivo ou negativo) está no argumento e colocá-lo em "potência". Também \phydimendeve ser capaz de aceitar mais caracteres do que M, L, T. Além disso, se forem fornecidas letras minúsculas, ele deverá convertê-las automaticamente para maiúsculas.

Como analiso os argumentos caractere por caractere e decido se é uma letra, um número inteiro positivo ou um número inteiro negativo?

MWE:

\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}

Responder1

Você pode usar expressões regulares:

\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}

A expressão de pesquisa corresponde a um número inteiro possivelmente assinado, a expressão de substituição especifica “caractere sobrescrito, chave esquerda, a correspondência, chave direita”.

insira a descrição da imagem aqui

Responder2

Aqui eu costumo listofitemsrealizar uma análise de 2 níveis, procurando dígitos no primeiro nível e sinais negativeno segundo nível.

\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}

insira a descrição da imagem aqui

Responder3

Analisar letra por letra é uma coisa complicada no LaTeX. Você poderia abrir mhchem.sty e ver como isso é feito. Ou vejaNoções básicas de análiseouComo posso analisar a primeira palavra em um fluxo de token, token por token?.

Eu não recomendaria usar \cedentro do seu comando. Faz muito mais coisas do que apenas alterar a fonte. Seria uma análise dupla da entrada, acho que isso não será eficiente.

O comando que você deseja criar já existe no mhchem para MathJax. Por que não existe para LaTeX é explicado na perguntaComo usar o comando `MathJax mhchem \pu{}` em LaTex?, incluindo motivos para usar outro comando.

informação relacionada