# Cross-referencing external data

Is there an existing module which can be used to reference external data. For example I would like to add the result of my analysis to some kind of library and give it a citation key which I can use throughout my text. The idea is to avoid mistakes/constancy issues by using a citation key and be able to quickly update the data throughout my manuscript if the analysis is modified.

• What do you have in mind? Do you have plots, datatables etc. and want to include them into your document? – Bubaya Feb 25 at 9:58
• I was more thinking just numerical data. Say for example I do an analysis and find the groundwater flux is 10 m/s. I would write about that intext probably in multiple locations throughout the text. Now say I find a mistake in my analysis and recomplete it I would need to find every instance where I wrote 10 m/s and change it to the new value. If I am doing it for many values in a big document it is easy to forget to update in some spots. So I was thinking it would be handy to have a library where I can store my data with a label (say "gw_flux") to make it easy to update throughout. – Robin Feb 26 at 5:23

I would provide an external file, e. g. myData.txt with the following content:

% Content of myData.txt
\newcommand{\myVariablePi}{3.14}
\newcommand{\myVariableEuler}{2.71}


In your main document, you can import this file with \input{myData.txt}. Then you can use \myVariablePi as a variable in the document.

Side note 1: You may need a \myVariablePi{} ({} at the end) if you want to have a space after the variable (or use xspace package).

Side note 2: Make sure, that your statements are still true after you update variables :).

• I like this for the simplicity and it also works with equations! – Robin Feb 26 at 11:17
• @Robin Both work for equations (or arbitrary stuff). If you want to share your data file among several documents, see my answer where to place it. – Bubaya Feb 26 at 11:51

In the light of the comment, you could do the following: Create a file my-variables.sty containing e.g.

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{my-variables}
\RequirePackage{siunitx}

% Commands for setting and getting variables
\newcommand{\setvariable}[2]{
\expandafter\def\csname myv@riable@#1\endcsname{#2}
}
\newcommand{\getvariable}[1]{%
\csname myv@riable@#1\endcsname
}

% My variable variable definitions
\setvariable{speed-of-light}{\SI{299 792 458}{m/s}}


and place in your home texmf-tree. For me on a Linux computer, this is ~/texmf/tex/latex/local. The correct directory for you should be found out by running kpsewhich -var-value TEXMFHOME on the terminal.

Now, you can make use of your “library”, e.g. by writing the following tex file:

\documentclass{article}
\usepackage{my-variables}
\begin{document}
The speed of light is \getvariable{speed-of-light}.
\end{document}


This should the correct speed of light as saved in your my-variables.sty file.

Side note: Imagine that you want to highlight all variables that are read from your library file. A use case for this I could imagine is that you want to quickly skim through a document and make sure that all quantities are indeed read from your library. With my suggested solution, you can just do

\renewcommand{\getvariable}[1]{%
\colorbox{yellow!50}{\csname myv@riable@#1\endcsname}
}


or whatever you want to do to highlight equations.

• +1 for this nice solution since the data are available for all projects... – AndiW Feb 26 at 10:19

Elaborating on the solution of Bubaya one could add a bit of error-management in case one erroneously, e.g., due to a typo, tries to obtain values that are not defined or tries to define values that are already defined.

I put the code where macros for setting and retrieving values are defined into a .sty-file on their own whose name is SetValues.sty.
I put the code where these macros are used for setting the values into another .sty-file on their own whose name is MyValues.sty.

When compiling the example below, these .sty-files will be created automatically due to the filecontents*-environments.

If you wish you can merge the two .sty-files.

I did not because one might wish to use these macros also with other projects and other sets of values. ;-)

\documentclass{article}

% Let LaTeX create the file SetValues.sty in case it does not already exist
% on the system:
\begin{filecontents*}{SetValues.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{SetValues}
\newcommand\SetValues@Exchange[2]{#2#1}%
\newcommand\SetValues@Name{}%
\long\def\SetValues@Name#1#{\romannumeral0\SetValues@@Name{#1}}%
\newcommand\SetValues@@Name[2]{%
\expandafter\SetValues@Exchange\expandafter{\csname#2\endcsname}{ #1}%
}%
\DeclareRobustCommand\GetValue[1]{%
\@ifundefined{SetValues@@@#1}%
{%
\SetValues@UndefText
\GenericError{\space\@spaces\@spaces}%
{Error: Value #1' not defined}%
{Source for further information on this error is neither available nor needed.}%
{It was attempted to obtain a value with name #1'\MessageBreak%
although such a value is not defined.\MessageBreak%
Either the intended value has another name (typo or the like?)\MessageBreak%
or it needs to be defined.%
}%
}{%
\SetValues@Name{SetValues@@@#1}%
}%
}%
\DeclareRobustCommand\SetValue[1]{%
\@ifundefined{SetValues@@@#1}%
{\SetValues@Name\newcommand*{SetValues@@@#1}}%
{%
\GenericError{\space\@spaces\@spaces}%
{Error: Value #1' already defined}%
{Source for further information on this error is neither available nor needed.}%
{A value with name #1' is already defined.\MessageBreak%
Either choose another name for the value\MessageBreak%
or modify the existing definition.%
}%
}%
}%
\@onlypreamble\SetValue
\AtBeginDocument{%
\DeclareRobustCommand\SetValues@UndefText{%
\texorpdfstring{\nfss@text{\reset@font\bfseries ??}}{??}%
}%
}{%
\DeclareRobustCommand\SetValues@UndefText{%
\nfss@text{\reset@font\bfseries ??}%
}%
}%
}%
\endinput
\end{filecontents*}

% Let LaTeX create the file MyValues.sty in case it does not already exist
% on the system:
\begin{filecontents*}{MyValues.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyValues}
\RequirePackage{SetValues}
%
% At this place you can require whatever additional packages you
% need for having LaTeX typeset your values nicely:
\RequirePackage{siunitx}
%\RequirePackage ...
%
% Now do a sequence of calls to \SetValue for defining values:
\SetValue{ApproxPi}{\num{3.1415927}}%
%\SetValue...
%
\endinput
\end{filecontents*}

%\usepackage{SetValues} % Actually you don't need to require the
% SetValues-package as it is also required
% by the MyValues-package.
\usepackage{MyValues}

\begin{document}

$\pi$ is approximately \GetValue{ApproxPi}

\end{document}

• +1: Neet solution! – Dr. Manuel Kuehner Feb 26 at 13:48
• @Dr.ManuelKuehner Thanks, but of course I had to do an edit as in the first rouud I overlooked to insert questionmarks in case of undefined values... :-( – Ulrich Diez Feb 26 at 13:51