# How to import data from a CSV file in a figure caption using csvsimple?

I have made a pretty report that gets all the data from CSV files data.csv like this :

Images,Infos,Bayer,BilineaireA,BilineaireB,TeinteA,TeinteB,ContourA,ContourB,Forme

img1(illusion),Temps (en ms),0,4,5,7,6,6,7,442
img1(illusion),Erreur MSE,152.44,34.44,34.44,24.04,24.04,24.06,25.99,32.90
img1(illusion),Erreur DeltaE,17.70,4.92,4.92,4.58,4.58,4.39,4.30,5.24
img1(illusion),Erreur PSNR (en dB),26.30,32.76,32.76,34.32,34.32,34.32,33.98,32.96

img2(points1),Temps (en ms),0,1,4,3,3,2,3,123
img2(points1),Erreur MSE,6.28,3.83,3.83,3.24,3.28,2.69,2.36,2.56
img2(points1),Erreur DeltaE,0.79,1.09,1.09,0.72,0.72,0.63,0.34,0.60
img2(points1),Erreur PSNR (en dB),40.15,42.30,42.30,43.02,42.97,43.83,44.41,44.05
...


I've written many macros like the one below which reads the MSE error for an image #1 generated using a given algorithm #2 (be gentle, it's the first time I write my own macro !) :

\newcommand{\MSE}[2]{%
before filter=\ifthenelse{ \equal{\Images}{#1} }{%
\ifthenelse{ \equal{\Infos}{Erreur MSE} }{\csvfilteraccept}{\csvfilterreject}%
}{\csvfilterreject}]%
{data.csv}{}{#2}%
}


Nevertheless, it seems that I can't use my macros inside captions of figures (and subfigures too). Here is a minimal example that fails :

\begin{filecontents*}{data.csv}
Images,Infos,Bayer,BilineaireA,BilineaireB,TeinteA,TeinteB,ContourA,ContourB,Forme

img1(illusion),Temps (en ms),0,4,5,7,6,6,7,442
img1(illusion),Erreur MSE,152.44,34.44,34.44,24.04,24.04,24.06,25.99,32.90
img1(illusion),Erreur DeltaE,17.70,4.92,4.92,4.58,4.58,4.39,4.30,5.24
img1(illusion),Erreur PSNR (en dB),26.30,32.76,32.76,34.32,34.32,34.32,33.98,32.96
\end{filecontents*}
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{csvsimple}

\newcommand{\MSE}[2]{%
before filter=\ifthenelse{ \equal{\Images}{#1} }{%
\ifthenelse{ \equal{\Infos}{Erreur MSE} }{\csvfilteraccept}{\csvfilterreject}%
}{\csvfilterreject}]%
{data.csv}{}{#2}%
}

\begin{document}
\listoffigures
\begin{figure}
\centering
My Image
\caption{A caption \MSE{img1(illusion)}{\BilineaireA} }
\end{figure}
\end{document}


I can read ! TeX capacity exceeded. If I put my command inside a minipage environment, I get the following error :

Argument of \@caption has an extra }


Thank you for your help !

-
More information is needed: a sample of the CSV file, for instance. However you might try with \protect\MSE{...}{...} –  egreg Nov 22 '12 at 16:03
This is just perfect ! It will be my accepted answer if you write your solution below. –  remjg Nov 22 '12 at 16:23
Please, add the info I requested, so that both the question and the answers can be more complete. –  egreg Nov 22 '12 at 16:24
I didn't know the filecontents environment, it's very convenient. –  remjg Nov 22 '12 at 20:18

An error message such as

Argument of \@caption has an extra }


usually means that a command in the argument of \caption needs protection. In this case the command is surely \MSE. Thus

\caption{A caption \protect\MSE{img1(illusion)}{\BilineaireA}}


might solve the problem.

However, in this particular application \protect is not sufficient. We need something that contains the value we need, so a different road can be taken. Define a similar \MSEset macro, that takes also an optional argument (default value \MSEresult:

\begin{filecontents*}{data.csv}
Images,Infos,Bayer,BilineaireA,BilineaireB,TeinteA,TeinteB,ContourA,ContourB,Forme

img1(illusion),Temps (en ms),0,4,5,7,6,6,7,442
img1(illusion),Erreur MSE,152.44,34.44,34.44,24.04,24.04,24.06,25.99,32.90
img1(illusion),Erreur DeltaE,17.70,4.92,4.92,4.58,4.58,4.39,4.30,5.24
img1(illusion),Erreur PSNR (en dB),26.30,32.76,32.76,34.32,34.32,34.32,33.98,32.96
\end{filecontents*}
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{csvsimple}

\newcommand{\MSE}[2]{%
before filter=\ifthenelse{ \equal{\Images}{#1} }{%
\ifthenelse{ \equal{\Infos}{Erreur MSE} }{\csvfilteraccept}{\csvfilterreject}%
}{\csvfilterreject}]%
{data.csv}{}{#2}%
}
\newcommand{\MSEset}[3][\MSEresult]{%
before filter=\ifthenelse{ \equal{\Images}{#2} }{%
\ifthenelse{ \equal{\Infos}{Erreur MSE} }{\csvfilteraccept}{\csvfilterreject}%
}{\csvfilterreject}]%
{data.csv}{}{\xdef#1{#3}}%
}
\newbox{\remibox}

\begin{document}
\listoffigures
\begin{figure}
\centering
My Image
\MSEset{img1(illusion)}{\BilineaireA}
\caption{A caption \MSEresult}
\end{figure}
\end{document}


You set the macro before typing the \caption and use \result to stand for the value. You can also say

\MSEset[\MSEresultA]{img1(illusion)}{\BilineaireA}


or any control sequence you want if you need more than one of these numbers. Take care of using control sequence names that are not used elsewhere (a common prefix such as MSE should do).

This will print the correct value also in the List of Figures, should you need it.

-
Finally I found a solution. I need to add a second \protect command like this : \protect\MSE{img1(illusion)}{\protect\BilineaireA} –  remjg Nov 22 '12 at 17:30
@RémiG. The second \protect might work, but it won't do any good if you want a list of figures. I've added a more robust solution. –  egreg Nov 22 '12 at 18:19
Thank you, I've understood ! I think I'll have to buy a LaTeX book if I want to go deeper and automate more things... –  remjg Nov 22 '12 at 20:06

Have you tried saving your caption in a lrbox and then call from your caption with a \usebox command?

Here's some sample code:

\newsavebox{\mycaption}
\begin{lrbox}{\mycaption}
\begin{minipage}{1in}
\MSE{img1(illusion)}{\BilineaireA}
\end{minipage}
\end{lrbox}

\begin{figure}
\centering
My Image
\caption{\usebox{\mycaption}}
\end{figure}

-
Thank you very much, it works perfectly ! –  remjg Nov 22 '12 at 16:20
Why the minipage and lrbox? Wouldn't \sbox{\mycaption}{\MSE{...}{...}} work? –  egreg Nov 22 '12 at 16:22
Indeed, the minipage environment is useless. I don't get a correct output with the \sbox command (letters instead of numbers). –  remjg Nov 22 '12 at 16:30
I didn't have the cvs data at the time. Something seemed to be fragile and I figured the minipage might get around this. –  A.Ellett Nov 22 '12 at 16:35