Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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 !

share|improve this question
1  
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

2 Answers 2

up vote 4 down vote accepted

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.

share|improve this answer
    
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}
share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.