6

I have this piece of code:

\documentclass{scrartcl}
\usepackage{pbox,calc}

\makeatletter
\newcommand*{\strippt}[1]{\strip@pt#1}
\makeatother

\newlength{\pointsExo}
\setlength{\pointsExo}{4pt}
\newlength{\pointsSousTotal}
\setlength{\pointsSousTotal}{0pt}

\newlength{\souspointsExo}
\newcommand{\sousPoints}[1]{
    \setlength{\souspointsExo}{#1pt}
    \setlength{\pointsSousTotal}{\pointsSousTotal + #1pt}
    {\scriptsize{(#1~\ifdim#1pt=1pt point\else points\fi/\strippt\pointsExo)}}
}

\newcommand{\subexo}[2]{
    \textsf{ %%If I comment these two lines, the sub-total is correct
        #1\hfill\sousPoints{#2}% Points
    }        %%If I comment these two lines, the sub-total is correct
    \medskip
}

\newcommand{\exercice}[2]{
    \setlength{\pointsExo}{#2pt}
    \setlength{\pointsSousTotal}{0pt}
    \medskip
    #1\hfill#2 Points% Points
    \medskip
}

\begin{document}
\exercice{A first one}{2.5}
\subexo{Anything}{2}

\subexo{Something}{0.5}

Sub-Total: \strippt\pointsSousTotal %should display 2.5

\exercice{A title}{4}
\subexo{another thing}{2.5}

\subexo{and a thing}{1.5}

Sub-Total: \strippt\pointsSousTotal %should display 4

\end{document} 

The problem with this is that it should display something like this:

A first one 2.5 Points

Anything (2 points/2.5)

Something (0.5 points/2.5)

Sub-Total: 2.5

A title

another thing (2.5 points/4)

and a thing (1.5 points/4)

Sub-Total: 4

But, unless I comment the two indicated lines (currently, an enclosing \textsf{...}, but the problem is the same as soon as I enclose the \sousPoints{#2} between two curly braces), I get this:

A first one 2.5 Points

Anything (2 points/2.5)

Something (0.5 points/2.5)

Sub-Total: 0

A title

another thing (2.5 points/4)

and a thing (1.5 points/4)

Sub-Total: 0

What is wrong with using length inside an enclosing brace {...} ? Is it a bug ? A bad understanding of how commands work ?

5
  • your \setlength are local settings so the values are restored at the end of a group. (Also you are missing % from the ends of lots of lines.) Apr 15, 2014 at 23:16
  • @HarishKumar but if it's not grouped the OP had better use \normalfont or some such to restore things afterwards Apr 15, 2014 at 23:18
  • @DavidCarlisle You are right. :)
    – user11232
    Apr 15, 2014 at 23:19
  • @DavidCarlisle Thanks, is there a way to workaround this ? Should I add % to all lines of a command ? Are there documentation or short tutorial about this ?
    – lauhub
    Apr 15, 2014 at 23:19
  • 1
    On % see tex.stackexchange.com/questions/7453/… Apr 15, 2014 at 23:25

2 Answers 2

7

You need a global assignment for the effects to be seen outside the group:

\documentclass{scrartcl}
\usepackage{pbox,calc}

\makeatletter
\newcommand*{\strippt}[1]{\strip@pt#1}
\makeatother

\newlength{\pointsExo}
\setlength{\pointsExo}{4pt}
\newlength{\pointsSousTotal}
\setlength{\pointsSousTotal}{0pt}

\newlength{\souspointsExo}
\newcommand{\sousPoints}[1]{% don't let egreg get points for missing %
    \setlength{\souspointsExo}{#1pt}% don't let egreg get points for missing %
    \setlength{\pointsSousTotal}{\pointsSousTotal + #1pt}% don't let egreg get points for missing %
     \global\souspointsExo=\souspointsExo % a bit costly of save stack but unlikely to have 1000s of these.
     \global\pointsSousTotal=\pointsSousTotal
    {\scriptsize{(#1~\ifdim#1pt=1pt point\else points\fi/\strippt\pointsExo)}}% don't let egreg get points for missing %
}

\newcommand{\subexo}[2]{% don't let egreg get points for missing %
    \textsf{%%If I comment these two lines, the sub-total is correct
        #1\hfill\sousPoints{#2}% Points
    }%%If I comment these two lines, the sub-total is correct
    \medskip
}

\newcommand{\exercice}[2]{% don't let egreg get points for missing %
    \setlength{\pointsExo}{#2pt}% don't let egreg get points for missing %
    \setlength{\pointsSousTotal}{0pt}% don't let egreg get points for missing %
    \medskip
    #1\hfill#2 Points% Points
    \medskip
}

\begin{document}
\exercice{A first one}{2.5}
\subexo{Anything}{2}

\subexo{Something}{0.5}

Sub-Total: \strippt\pointsSousTotal %should display 2.5

\exercice{A title}{4}
\subexo{another thing}{2.5}

\subexo{and a thing}{1.5}

Sub-Total: \strippt\pointsSousTotal %should display 4

\end{document} 
1
  • 1
    % don't let egreg get points for missing % brilliant :)
    – cmhughes
    Apr 15, 2014 at 23:27
0

I post here is a supplemental test I made. I post it to demonstrate the effect of \setlength when it is inside or outside a group (a possible workaround to my problem that David Carlisle suggested in its first comment to my question).

However, I prefer David Carlisle 's answer with \global. It allows to display and set the value within one single command (since I will never a document with more than 50 calls to this command, so it will not consume so much resources).

\documentclass{scrartcl}
\usepackage{pbox,calc}

\makeatletter
\newcommand*{\strippt}[1]{\strip@pt#1}
\makeatother

\newlength{\pointsTotal}
\setlength{\pointsTotal}{0pt}


\newcounter{numExercice}
\newlength{\pointsExo}
\setlength{\pointsExo}{4pt}
\newlength{\pointsSousTotal}
\setlength{\pointsSousTotal}{0pt}

\newlength{\souspointsExo}
\newcommand{\sousPoints}[1]{% Will only display the points, not make the assignement
    {\scriptsize{(#1~\ifdim#1pt<2pt point\else points\fi/\strippt\pointsExo)}}%
}

\newcounter{sousExercice}[numExercice]
\newcommand{\subexo}[2]{%
    \stepcounter{sousExercice}%
    \setlength{\souspointsExo}{#2pt}%makes the assignment outside of the group, no global required
    \setlength{\pointsSousTotal}{\pointsSousTotal + #2pt}%makes the assignment outside of the group, no global required
    \medskip        
    \textsf{%
        \textbf{\arabic{numExercice}.\arabic{sousExercice}} :~#1%
        \hfill\sousPoints{#2}% Points
    }
}


\newcommand{\exercice}[2]{%
    \stepcounter{numExercice}%
    \setlength{\pointsExo}{#2pt}%
    \setlength{\pointsSousTotal}{0pt}%
    \setlength{\pointsTotal}{\pointsTotal + #2pt}%
    \medskip

    \textbf{Exercice \arabic{numExercice}} :~#1\hfill%
    {\normalsize{(#2~\ifdim#2pt<2pt point\else points\fi)}}% Points

    \medskip
}

\newcommand{\subtotal}{\strippt\pointsSousTotal}

\newcommand{\Total}{Total des points : \strippt\pointsTotal}

\begin{document}
\exercice{A first one}{2.5}
\subexo{Anything}{2}

\subexo{Something}{0.5}

Sub-Total: \strippt\pointsSousTotal

\exercice{A title}{4}
\subexo{another thing}{2.5}

\subexo{and a thing}{1.5}

Sub-Total: \strippt\pointsSousTotal

\end{document} 

You must log in to answer this question.

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