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 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 ?

share|improve this question
    
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.) –  David Carlisle Apr 15 at 23:16
    
@HarishKumar but if it's not grouped the OP had better use \normalfont or some such to restore things afterwards –  David Carlisle Apr 15 at 23:18
    
@DavidCarlisle You are right. :) –  Harish Kumar Apr 15 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 at 23:19
1  

2 Answers 2

up vote 7 down vote accepted

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} 
share|improve this answer
1  
% don't let egreg get points for missing % brilliant :) –  cmhughes Apr 15 at 23:27
    
@cmhughes let's hope he doesn't notice –  David Carlisle Apr 15 at 23:28
1  
I did. I'll upvote this nonetheless. –  egreg Apr 15 at 23:36

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

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.