21

How to read a variable from a file, lets say textfile var.txt that contains the following:

foo = 10
bar = 20

Now I am looking for a command \missingcommand that scans the file and it can be used in my Latex code like this:

The first value \missingcommand{foo} and the second value \missingcommand{bar}.

Compiles to:

The first value 10 and the second value 20.

Any help would be kindly appreciated

  • What should it return if it can't be used? – Hugh Aug 3 '16 at 16:35
20

This uses my readarray package. It relies on there being space separators between fields, and exactly 3 fields in each row: <variable> = <value>. See ADDENDUM for improved version.

EDITED (12/2016) to use preferred syntax of upgraded readarray package, namely, \MyDat[\arabic{datacount},3] in lieu of deprecated \arrayij{MyDat}{\arabic{datacount}}{3}. Likewise, \readarray\data\MyDat[-,3] in lieu of \readArrayij{\data}{MyDat}{3}.

Note also that \value{datacount} of original answer was necessarily revised to \arabic{datacount}, as well.

\documentclass{article}
\usepackage{readarray}[2016-11-07]
\usepackage{filecontents}
\begin{filecontents*}{mydata.dat}
foo = 10
bar = 20
\end{filecontents*}
\newcommand\missingcommand[1]{\csname DATA#1\endcsname}
\begin{document}
\readdef{mydata.dat}{\data}
\readarray\data\MyDat[-,3]
\MyDatROWS{} rows of data read.

\newcounter{datacount}
\setcounter{datacount}{0}%
\whiledo{\value{datacount} < \MyDatROWS}{%
  \stepcounter{datacount}%
  \expandafter\xdef\csname DATA\MyDat[\arabic{datacount},1]\endcsname{%
    \MyDat[\arabic{datacount},3]}%
}

The first value \missingcommand{foo} and the second value \missingcommand{bar}.
\end{document}

enter image description here

ADDENDUM

Note that with latest readarray package version, the field separator can be set to other characters or strings. Thus, for this application, it would be preferable to set the field separator as the = character (using \readarraysepchar{=}), so that spaces around the = sign are not a requirement. Then, using the starred version of the new/improved \readarray, leading/trailing spaces can be excised automatically from the data. Thus, the best version of the above code, producing identical results, can be given as

\documentclass{article}
\usepackage{readarray}[2016-11-07]
\usepackage{filecontents}
\begin{filecontents*}{mydata.dat}
foo = 10
bar=20
\end{filecontents*}
\newcommand\missingcommand[1]{\csname DATA#1\endcsname}
\readarraysepchar{=}
\begin{document}
\readdef{mydata.dat}{\data}
\readarray*\data\MyDat[-,2]
\MyDatROWS{} rows of data read.

\newcounter{datacount}
\setcounter{datacount}{0}%
\whiledo{\value{datacount} < \MyDatROWS}{%
  \stepcounter{datacount}%
  \expandafter\xdef\csname DATA\MyDat[\arabic{datacount},1]\endcsname{%
    \MyDat[\arabic{datacount},2]}%
}

The first value \missingcommand{foo} and the second value \missingcommand{bar}.
\end{document}
| improve this answer | |
15

You could use datatool. Its made for database structures inside LaTeX. I use this in a similar context as you like to.

\documentclass{article}
\usepackage{datatool, filecontents}
\DTLsetseparator{ = }% Set the separator between the columns. Could be
% anything you like. Whitespaces are not trimmed, so you have to set
%them as part of the separator.

\begin{filecontents*}{mydata.dat}
foo = 10
bar = 20
"x" = 30
\end{filecontents*}

\begin{document}
\DTLloaddb[noheader, keys={thekey,thevalue}]{mydata}{mydata.dat}
% Loads mydata.dat with column headers 'thekey' and 'thevalue'

\newcommand{\missingcommand}[1]{\DTLfetch{mydata}{thekey}{#1}{thevalue}}

The first value \missingcommand{foo} and the second value \missingcommand{bar}.

\end{document}

If thekey is a single character, it has to be sourrounded by quotation marks.

Read Values

| improve this answer | |
  • 2
    I was waiting for someone to post a datatool solution. +1 – Steven B. Segletes Aug 3 '16 at 15:01
  • This doesn't seem to work if thekey is only one character. – Azor Ahai -- he him May 23 '17 at 3:56
  • 1
    @Azor-Ahai: If thekey is only one character, you have to place it between quotation marks, e.g. "f" = 10. I have to say that I do not really now why you have to do it. – Michael P Jun 16 '17 at 11:31

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.