10

https://tex.stackexchange.com/a/227862/6865 explains how to convert Roman into Arabic numerals, but when compiling

\documentclass{article}
\usepackage{etoolbox}
\xdef\test{VII}
\begin{document}
\rmntonum{VII} corresponds to \test\par
\rmntonum{\test} should not be -1!
\end{document}

it results in:

7 corresponds to VII -1 should not be -1!

Probably \rmntonum sees \test instead of VII, but even \expandafter\rmntonum{\test} did not work. How can I "feed" some variable to \rmntonum (or how can I convert it otherwise)?

3
  • 4
    You've got your \expandafter in the wrong place: you are trying to expand {! \expandafter\rmntonum\expandafter{\test}
    – Joseph Wright
    Commented May 28, 2017 at 16:57
  • @JosephWright: Yes: \expandafter\rmntonum\expandafter{\test} works fine. Please turn your comment into an answer (and please add a line to the etoolbox manual for people as stupid as me...). And thanks and +1!
    – Stephen
    Commented May 28, 2017 at 17:04
  • I didn't post as an answer as really this is nothing to do with the specific case here: it's the general issue of misunderstanding how \expandafter works.
    – Joseph Wright
    Commented May 28, 2017 at 18:12

2 Answers 2

8

\expandafter\rmntonum{\test} expands to \rmntonum{\test} since \expandafter applies to { (skipping over \rmntonum, as the name implies). What you're after is \expandafter\rmntonum\expandafter{\test} in order to expand \test. You can update \rmntonum to do this by default:

7 corresponds to VII
7 should not be -1!

\documentclass{article}

\usepackage{etoolbox}

\def\test{VII}
\let\oldrmntonum\rmntonum
\renewcommand{\rmntonum}[1]{\expandafter\oldrmntonum\expandafter{#1}}

\begin{document}

\rmntonum{VII} corresponds to \test

\rmntonum{\test} should not be -1!

\end{document}

You could save some keystrokes

\let\oldrmntonum\rmntonum
\renewcommand{\rmntonum}{\expandafter\oldrmntonum\expandafter}

but it requires you to explicitly brace the argument to \rmntonum (rather than, say, \rmntonum\test). Of course, this is not a bad idea in general.

1
  • You can allow \rmntonum\test by using an intermediate macro: \def\rmntonum#1{\rmntonumaux{#1}} and \def\rmntonumaux#1{\expandafter\oldrmntonum\expandafter{#1}}
    – egreg
    Commented May 28, 2017 at 20:18
7

It's a matter of turning a kernel function into a user level command, with expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\romantoarabic}{m}
 {
  \int_from_roman:f { #1 }
 }
\cs_generate_variant:Nn \int_from_roman:n { f }
\ExplSyntaxOff

\begin{document}

\romantoarabic{VII}

\newcommand{\seven}{VII}

\romantoarabic{\seven}

\end{document}

This prints two 7’s.

You can even do

\romantoarabic\seven

(but I wouldn't recommend it).

If you are using LuaLaTeX, there's a slicker definition:

\documentclass{article}

\usepackage{etoolbox}

\let\etoolboxrmntonum\rmntonum
\renewcommand{\rmntonum}[1]{%
  \expanded{\noexpand\etoolboxrmntonum{#1}}%
}

\newcommand\test{VII}
\newcommand\another{X\test}

\begin{document}

\rmntonum{VII} corresponds to \test

\rmntonum{\test} should not be -1!

\rmntonum\test{} should not be -1!

\rmntonum{C\another} should not be -1!

\end{document}

enter image description here

1
  • Thanks and +1, although I accepted Werner's answer (because it is not possible to accept more than one answer).
    – Stephen
    Commented May 30, 2017 at 20:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .