2

I wish to have a dedicated command for printing physical dimension. Something like \phydimen{M2L-3T-1}. This should output the same as $\textrm{M}^2\textrm{L}^{-3}\textrm{T}^{-1}$.

I find that the \ce command of mhchem package is quite suitable. So I hack it to do \newcommand{\phydimen}[1]{\ce{#1}} and then issue a command \phydimen{ML^2T^{-2}} to print the dimension. However I still have to use the pesky ^ and { }. The default \ce behavior is to push the numbers as subscript.

I want \phydimen to automatically detect when a (positive or negative) integer is in the argument and push it to "power". Also \phydimen should be able to accept more characters than M,L,T. Also if lowercase is supplied, it should automatically convert it to uppercase.

How do I parse the arguments character by character and decide whether it is a letter or positive integer or negative integer?

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} 

3 Answers 3

2

You can use regular expressions:

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

The search expression matches a possibly signed integer, the replacement expression specifies “superscript character, left brace, the match, right brace”.

enter image description here

1
  • Thanks a lot. This is exactly what I wanted. After @mhchem's comment, I was digging regex manipulation of l3regex to figure out. Commented Feb 16, 2018 at 11:58
2

Here I use listofitems to conduct a 2-tier parsing, looking for digits at the first level and for the negative sign at the second level.

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

enter image description here

1

Parsing letter by letter is a complicated thing in LaTeX. You could open mhchem.sty and look how this is done. Or see Basics of parsing or How can I parse the first word in a token stream, token by token?.

I would not recommend using \ce inside your command. It does way more stuff than just changing the font. It would double-parse the input, I think this will not be efficient.

The command you want to create already exists within mhchem for MathJax. Why it does not exist for LaTeX is explained in the question How to use `MathJax mhchem \pu{}` command in LaTex?, including reasons to use another command instead.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.