# Read YAML field from LaTeX

Let me explain my problem. I have a simple YAML file automatically generated with a series of experiments that looks like as follows

error-metric1:
method1: value
method2: value
method3: value

error-metric2:
method1: value
method2: value
method3: value


What I would like to do is to - somehow - retrieve values automatically from the file during compilation and insert them in text and/or tables. For example, I'm looking to do something like:

The error rate for the method1 is \readYAML{file}{error-metric1}{method1}


First question: do you think it is possible? Do you have any suggestions on how it can be done?

BTW, if this might help, my workflow is based on LuaLaTeX. Thanks!

• Welcome to TeX.SX! – Bobyandbob Aug 9 '18 at 9:52
• Will each metric always have the same number of methods, or might the number of methods vary with the metric? Also, are the words "error-metric" and "method" standard words that actually appear in the file, or are you only using them as placeholder words? – Steven B. Segletes Aug 9 '18 at 10:49

Not a complete YAML parser, but this should be sufficient for your specific need. I used \jobname just not to clobber my files, you can use your own files.

\begin{filecontents*}{\jobname.yaml}
error-metric1:
method1: 1
method2: 2
method3: 3

error-metric2:
method1: 4
method2: 5
method3: 6
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

{% #1 = file (no .yaml extension)
% #2 = section
% #3 = key
\sr_readyaml:nnn { #1 } { #2 } { #3 }
}

\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\cs_generate_variant:Nn \prop_gput:Nnn { cxx }
\prg_generate_conditional_variant:Nnn \tl_if_blank:n { f } { TF }

{
{
}
\prop_item:cn { g_sr_readyaml_#1_prop } { #2@#3 }
}

{
{
\__sr_readyaml_line:nn { #1 } { ##1 }
}
}

{% #1 is the file name, #2 the current line
\tl_if_blank:nF { #2 }
{
\seq_set_split:NVn \l__sr_readyaml_line_seq \c_colon_str { #2 }
\tl_if_blank:fTF { \seq_item:Nn \l__sr_readyaml_line_seq { 2 } }
{% nothing after the colon, set the current section
}
{% value after the colon, add to the property list
\prop_gput:cxx
% prop name
% key
% value
{ \seq_item:Nn \l__sr_readyaml_line_seq { 2 } }
}
}
}

\ExplSyntaxOff

\begin{document}

\end{document}


You might want to split off the reading phase from the data retrieving phase, in order to get an expandable macro.

\begin{filecontents*}{\jobname.yaml}
error-metric1:
method1: 1
method2: 2
method3: 3

error-metric2:
method1: 4
method2: 5
method3: 6
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

{% #1 = file (no .yaml extension)
}
\NewExpandableDocumentCommand{\getfromYAML}{mmm}
{% #1 = file (no .yaml extension)
% #2 = section
% #3 = key
\prop_item:cn { g_sr_readyaml_#1_prop } { #2@#3 }
}

\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\cs_generate_variant:Nn \prop_gput:Nnn { cxx }
\prg_generate_conditional_variant:Nnn \tl_if_blank:n { f } { TF }

{
{
}
}

{
{
\__sr_readyaml_line:nn { #1 } { ##1 }
}
}

{% #1 is the file name, #2 the current line
\tl_if_blank:nF { #2 }
{
\seq_set_split:NVn \l__sr_readyaml_line_seq \c_colon_str { #2 }
\tl_if_blank:fTF { \seq_item:Nn \l__sr_readyaml_line_seq { 2 } }
{% nothing after the colon, set the current section
}
{% value after the colon, add to the property list
\prop_gput:cxx
% prop name
% key
% value
{ \seq_item:Nn \l__sr_readyaml_line_seq { 2 } }
}
}
}

\ExplSyntaxOff

\begin{document}