23

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

Stefan Pinnow
  • 29,535
Steff80
  • 231

2 Answers2

21

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

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

Michael P
  • 596