I often need to check what a length expression like "20pt + 2 cm" would resolve to -- and of course, I'd rather do something quick on the command line / shell / terminal, than typing \documentclass{article} ... in a file, and running Latex on that.

Is there anything like that out there?

  • 3
    I would just type etex \showthe\dimexpr 20pt+2cm\relax on the command line and see: > 76.9055pt. – Dan Jul 3 '14 at 19:36
$ pdftex '\relax\showthe\dimexpr20pt + 2 cm\relax\bye'
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014) (preloaded format=pdftex)
 restricted \write18 enabled.
entering extended mode
> 76.9055pt.

The quoting with ' assumes bash syntax, other commandlines may need different quotes, or no quotes.

  • 2
    or etex '...' for a minimal example :-) – user2478 Jul 3 '14 at 19:38
  • Hah! This is, indeed, much more basic and straightforward, and so warrants an accept. However, if you'd need printouts in cm, then you need \converttocm, and then you need a library which you should \input, and then you may as well think about a shell wrapper (which is what I ended up doing below). Many thanks, @ DavidCarlisle - cheers! – sdaau Jul 3 '14 at 19:43

Well, there may have been; a search for texcalc returns: CTAN: texcalc from 1988 (with a binary .ins file!); also zem/texcalc · GitHub which is a Python calculator you -shell-escape to use in a Latex document (and TexCalc on the App Store on iTunes, which "converts units for yarns from SI to Anglo-American Units and vice versa").

But, I'd like to present something else: I'm pretty sure someone already did this decades ago on comp.text.tex - but I just got this idea recently, and I'm amazed that it works at all :) Basically, here we'll use the *nix shebang functionality, to make an executable Latex script (with actual executable Latex in the shebang).

Recall first that: If a script /path/to/foo begins with #!/bin/bash, then executing /path/to/foo arg1 arg2 is equivalent to executing /bin/bash /path/too/foo arg1 arg2. If the shebang line is #!/bin/bash -ex, it is equivalent to executing /bin/bash -ex /path/too/foo arg1 arg2. This feature is managed by the kernel.. Thus, if we have a shebang line like:

#!/path/to/pdflatex "\catcode`\#=14\batchmode\gdef\cmd{\gdef\mcmd}\gdef\e{\input"

... and we call with (note single quote characters, so the shell doesn't interpret backslash ):

./script.tex '} ___SOMETHING___ \e'

... the resulting call is:

/path/to/pdflatex "\catcode`\#=14\batchmode\gdef\cmd{\gdef\mcmd}\gdef\e{\input" ./script.tex '} ___SOMETHING___ \e'

... or just the arguments pdflatex sees, resolve to:

\batchmode% go silent here
\gdef\e{\input ./script.tex } %
\e % ... which is \input ./script.tex

Thus, we'll have Latex re-read script.tex - but skip the shebang character (number sign / hash / sharp), and thus not crash on it -- since we've changed it's catcode to "comment" in time. Then once inside the script, we can restore that catcode, and do some stuff. The only nuissance is that you have to have the arguments in format } __WHATEVER__ \e, and some technique for propagating actual commands to Latex. Gosh, I feel like such an 80's hacker now :)

So, below is a script, called cmdcalc.tex (good, I avoided the texcalc disambiguation :)), which basically works with pgfmath, and allows you to do stuff like this:

$ ./cmdcalc.tex '} \cmd{ \pgfmathparse{20pt+2cm} } \e'
This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011)
 restricted \write18 enabled.
entering extended mode
LaTeX2e <2011/06/27>
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, lo

 RESULT: '76.9055' 
 (for command: 'macro:-> \pgfmathparse {20pt+2cm} ')


$ ./cmdcalc.tex "}\
        \\converttou{cm}{\\pgfmathresult pt}\
This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011)
 restricted \write18 enabled.
entering extended mode
LaTeX2e <2011/06/27>
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, lo


 RESULT: '76.9055' 
 (for command: 'macro:-> \pgfmathparse {20pt+2cm} \typeout { \converttou {cm}{\
pgfmathresult pt} } ')

(Yeah, I too wish I could get rid of the extra blurb messages; I could live with just the first one though).

Basically, you put your code inside a \cmd{ } inside the command argument delimiter } \e - basically: } \cmd{ YOUR CODE HERE} \e; you can use pgfmath expressions; \pgfmathresult is automatically printed, else you have to \typeout yourself.

Anyways - I'm sure this could be done a lot better, unfortunately I don't have the time for it; so I thought I'd post while I remember it :) Here is the script (of course, make sure you've put your actual path to pdflatex in the shebang - and you've made it executable chmod +x cmdcalc.tex in your shell):


#!/path/to/texlive/2011/bin/i386-linux/pdflatex "\catcode`\#=14\batchmode\gdef\cmd{\gdef\mcmd}\gdef\e{\input"

% cmdcalc.tex; copyleft sdaau, 2014 / LPPL, GPL, or whatever suitable :)

% at entry, shebang already did \make#comment
% now that we have entered here, restore (\make#parameter)

% enable messages here, if we need to debug package loading
% \errorstopmode

% "preamble" - load packages;
% since we haven't begun{document} yet,
% should use \RequirePackage/\input:

% \makeatletter
\input pgfutil-common.tex
\input pgfmathutil.code.tex
% \makeatother

% set a debug flag, if needed, here:
% (if not wanted, simply keep commented=undefined)
% \def\dbg{1}
  \RequirePackage{trace}% debug

% some Latex utility functions/macros:
% http://tex.stackexchange.com/a/8337/2595
\def\convertto#1#2{\strip@pt\dimexpr #2*65536/\number\dimexpr 1#1}
% with units at end:
\def\converttou#1#2{\strip@pt\dimexpr #2*65536/\number\dimexpr 1#1 #1}
  \typeout{ gettikzcmxy: x \the\pgf@x #2 cm, y \the\pgf@y #3 cm}

% initialize \pgfmathresult, so it's not "! Undefined control sequence."

% stop the quiet batchmode, and halt on errors
% (if we want terminal interaction upon error)
% \errorstopmode
% % (or)
% stop the quiet batchmode, and just report errors and exit

% run the set \cmd{} by user:
% %\expandafter\edef\expandafter\mrescmd{\mcmd} % bad!
% just run directly:
% \ifx\dbg\empty\else\traceon\fi% (if debug)
  \typeout{The \string\cmd is undefined!}

% convenience result variable - \pmr (short for \pgfmathresult);
% check it after running of command:
% (do not handle \ifx\pmr\empty - maybe it's a valid outcome)

% print out \pg
\typeout{^^J RESULT: '\pmr' }
\typeout{ (for command: '\meaning\mcmd')}

% go silent again:

% forced exit:

% other possibilities: with luatex:
% \directlua0{io.stderr:write("Error: what do you thing you are doing^^J")}

% we don't need to begin document; we've already exited :)
% \begin{document}
  • Mostly unrelated—why don't you use /usr/bin/env latex instead of the full pdflatex path? (Also, plain-old latex is noticeably faster in my experience. I don't think pgf would have a problem with that, hopefully…) – Sean Allred Jul 4 '14 at 4:20
  • @SeanAllred Shebangs don't pass more than one argument (e.g. #!/usr/bin/env pdflatex blah). The defined behaviour is to smash it all into one argument, so env would attempt to locate pdflatex blah, which would fail; and even if pdflatex was somehow run, it wouldn't get blah as an argument. – michaelb958 Jul 4 '14 at 10:40

From the terminal it's actually quite easy:

> tex
** \relax
* \newdimen\calc
* \calc 20pt
* \advance \calc 2cm
* \showthe\calc
> 76.9055pt.
  • My answer showed the "all on the command line variant but dropping to the * prompt as here is easier for longer calculations. – David Carlisle Jul 4 '14 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.