# Is it possible to call a latex macro at the command line in order to return a string, not create a document?

I'm curious as to whether there is a way to pass a small amount of LaTeX code to a compiler at the command line and return the string corresponding to the value of a variable or length.

For instance I would like to pass this code

\usepackage{calc}
\def\contnt{\tt{I wish I knew how much space was occupied by this string when typeset...}
\settowidth{\contntwdth}{\contnt}


and I'd like to indicate that the string output I'm after is the width of the content e.g.

\the\contntwdth


Any suggestions are greatly appreciated.

-
As TeX's output tends to be in files, the most obvious place to put the string is in the .log or a dedicated text file. The latter avoids needing to parse the log: does that sound about right? –  Joseph Wright Dec 29 '12 at 14:49
Welcome to TeX.SX. We like to avoid greetings and closing lines here. Your (user-)name is already added automatically at the bottom of all your posts. You might want to rename the generic user name you currently have. –  Martin Scharrer Dec 29 '12 at 14:49
The tool texdef written by me does something very similar, i.e. returning the definition of macros and also values, but your example might be already be to complicated. (Also, your use of \tt is incorrect and \tt is outdated altogether, use {\ttfamily ..} or \texttt{..} instead.) –  Martin Scharrer Dec 29 '12 at 14:51
If needed, the printlen package can be used to convert to display the length in different units. –  Peter Grill Dec 29 '12 at 14:52

The texdef tool written by me can be used to display the definition of macros and the value of dimension and other registers. It also allows to add arbitrary other code before (-b) and after the definition/value is printed.

Your example would be (code got refactored):

$texdef -t latex -p calc -b '\newdimen\mydim \settowidth{\mydim}{\texttt{I wish I knew how much space was occupied by this string when typeset...}}' -v mydim \the\mydim: 377.9967pt  If required a wrapper script could be written which inserts the actual text in the position and removes unwanted lines in the output. - Why should calc be required? – egreg Dec 29 '12 at 15:26 @egreg: Well, it is indeed not required. I blindly copied it from the original code. I will let it stay as an example how to include packages in texdef. – Martin Scharrer Dec 29 '12 at 15:35 Here's a simple Bash script, say getdim #!/bin/bash latex << EOF | sed -n -e '/^\*\*\*\*/s///p' \documentclass{article} \nofiles \begin{document} \settowidth{\dimen0}{\ttfamily$1}\typeout{***\the\dimen0}
\stop
EOF


If you run

bash getdim "test of script"


you get the following output

73.49936pt


(Thanks to Marc van Dongen for suggesting an improvement in the usage of sed.)

-
latex << EOF | sed -n -e '/^\*\*\*\*/s///p' .... also does the trick and saves a grep and a pipe. The -n is for no-print. The p forces the printing. –  Marc van Dongen Dec 30 '12 at 1:22
@MarcvanDongen Thanks; this shows how little I know sed. :) –  egreg Dec 30 '12 at 11:37
You're being too modest. Most people wouldn't know sed at all and the -n flag isn't used much. –  Marc van Dongen Dec 30 '12 at 13:56

You can use \immediate\write18 to output the length. The MWE below yields:

The content width is 377.9967pt.

The same code can be used to evaluate lengths of different strings. Saving the code below as GetLength.tex, and running it from the command line as:

pdflatex -shell-escape "\def\contnt{\tt{Here is a different string}}\input{GetLength.tex}"  | grep "content width"


yields:

The content width is 136.49881pt.

## Code:

\ifdefined\contnt
\else
\def\contnt{\texttt{I wish I knew how much space was occupied by this string when typeset...}}
\fi

\documentclass{article}

\newlength{\contntwdth}
\settowidth{\contntwdth}{\contnt}
\begin{document}
\immediate\write18{echo ""; echo "The content width is \the\contntwdth."}
\end{document}

-

Yes you can pass commands on the commandline without using any auxiliary files.

For example the following just outputs 377.9967pt The | sed -e "1,/loaded/d" at the end just deletes the startup banner and list of hyphenation patterns, if you don't have sed then just omit that bit.

\$ pdflatex '\batchmode\newlength\contntwdth\def\contnt{\texttt{I wish I knew how much space was occupied by this string when typeset...}}\settowidth{\contntwdth}{\contnt}\scrollmode\typeout{\the\contntwdth}\batchmode\stop' | sed -e "1,/loaded/d"

377.9967pt


Note I changed \tt to \texttt as \tt is not defined in the LaTeX format, if you use the string as given in the question the output is

! Undefined control sequence.
\contnt ->\tt


(In classes where \tt is defined the usage is not as used in the MWE, the syntax is {\tt text} not \tt{text} but in the base LaTeX format it is not defined at all.)

-

it is not clear to me what do you really want. However, here is a solution mit a savebox:

\documentclass{article}
\newsavebox\TBox
\newlength\TLength
\def\contnt#1{\savebox\TBox{#1}\setlength\TLength{\wd\TBox}}

\begin{document}

\contnt{\ttfamily I wish I knew how much space was occupied by this string when typeset \ldots}
The contents has a width of \the\TLength

\end{document}


-
As I understand it the OP wants to get the value in the command line without actual going over a document. –  Martin Scharrer Dec 29 '12 at 14:49