3

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]{%
\csvreader[ head to column names,%
            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]{%
\csvreader[ head to column names,%
            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 !

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

2 Answers 2

4

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]{%
\csvreader[ head to column names,%
            before filter=\ifthenelse{ \equal{\Images}{#1} }{%
                          \ifthenelse{ \equal{\Infos}{Erreur MSE} }{\csvfilteraccept}{\csvfilterreject}%
                           }{\csvfilterreject}]% 
          {data.csv}{}{#2}%
}
\newcommand{\MSEset}[3][\MSEresult]{%
\csvreader[ head to column names,%
            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.

3
  • Finally I found a solution. I need to add a second \protect command like this : \protect\MSE{img1(illusion)}{\protect\BilineaireA}
    – remjg
    Nov 22, 2012 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, 2012 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, 2012 at 20:06
1

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}
3
  • Why the minipage and lrbox? Wouldn't \sbox{\mycaption}{\MSE{...}{...}} work?
    – egreg
    Nov 22, 2012 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, 2012 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, 2012 at 16:35

You must log in to answer this question.

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