0

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.

2
  • What do you have in mind? Do you have plots, datatables etc. and want to include them into your document?
    – Bubaya
    Feb 25, 2019 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, 2019 at 5:23

3 Answers 3

1

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 :).

2
  • I like this for the simplicity and it also works with equations!
    – Robin
    Feb 26, 2019 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, 2019 at 11:51
3

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
  • +1 for this nice solution since the data are available for all projects...
    – AndiW
    Feb 26, 2019 at 10:19
2

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{%
  \@ifpackageloaded{hyperref}{%
    \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}
2
  • +1: Neet solution! Feb 26, 2019 at 13:48
  • 1
    @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... :-( Feb 26, 2019 at 13:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .