4

I use Michael Wichura's old Table macros (see http://www.pctex.com/addons.html) in several places, and I need to access them from within another macro. The problem (I think) is that some of the characters that are used in the Table macros are not passed on correctly. Let me illustrate with some codes.

\documentclass[11pt]{article}

\usepackage{etoolbox}

% These three lines read the macros
\input{nine}
\input{eight}
\input{Table}

\begin{document}

This is a table: % The following few lines use the Table macros
 $$
 \BeginTable
  \BeginFormat
  | lw8 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
 $$

\def\QuestionSolution{Q} % This identifies whether I want a question or solution

\expandafter\ifstrequal\expandafter{\QuestionSolution}{S}{%
This is the question}{%
This is the solution with the same table:
 $$
 \BeginTable
  \BeginFormat
  | lw20 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
$$}

\end{document}

The output I get from this code looks like this:

enter image description here

The first table is fine but, clearly, there is a problem when the table macros are invoked from within the \ifstrequal macro. In fact, the same problem occurs when I call the table from any macro.

Of course, I know that I could reconstruct all of these tables using more standard LaTeX codes. The problem is that I have about 200 such (full-page) tables to rewrite in a fairly short interval of time.

Is there an easier way to fix this problem?

Thank you in advance for your help.

  • See Why is \[\] preferable to $$? – Werner Sep 7 '13 at 0:44
  • Actually @Werner, in this case I think $$ is preferable because it is being used as a quick way to center the table (something that I have seen many plain tex users do) – Aditya Sep 7 '13 at 3:01
  • @Aditya Well, in that case, \centerline is the correct option. – yo' Sep 7 '13 at 7:50
4

You can use \scantokens and a command that makes the input less awkward and the processing more flexible.

\documentclass[11pt]{article}

\usepackage{etoolbox}

\newcommand{\QS}[2]{%
  \expandafter\ifstrequal\expandafter{\QuestionSolution}{S}{#1}{\scantokens{#2}}%
}

% These three lines read the macros
\input{nine}
\input{eight}
\input{Table}

\begin{document}

This is a table: % The following few lines use the Table macros
 $$
 \BeginTable
  \BeginFormat
  | lw8 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
 $$

\def\QuestionSolution{Q} % This identifies whether I want a question or solution

\QS{This is the question}{%
This is the solution with the same table:
 $$
 \BeginTable
  \BeginFormat
  | lw8 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
$$}

\end{document}

enter image description here

An alternative without \scantokens, but less flexible, is

\makeatletter
\newcommand{\QS}{%
  \expandafter\ifstrequal\expandafter{\QuestionSolution}{S}{\@firstoftwo}{\@gobble}%
}
\makeatother

The second argument is actually read as such only in the true case, when it's discarded. In the "false" case, the first argument is discarded by \@gobble and the table is processed (inside a group, but it should make no difference).

5

When you use a macro like \something{<x>}{<y>}{<z>}, LaTeX reads all of the arguments <x>, <y> and <z> before processing things inside \something. And you're right, there are category codes that are changed as part of PiCTeX's Table macros that cannot happen after the arguments have been read. As such, you need a different approach to handling this, avoiding the use of a macro conditional.

Below I've used the pdfTeX primitive \pdfstrcmp{<one>}{<two>} which returns a value of 0 if <one> is equal to <two>. You can then use a regular \ifnum<pdfstroutput>=0 <T>\else <F>\fi construct to condition on the equality:

enter image description here

\documentclass[11pt]{article}

% These three lines read the macros
\input{pictable/nine}
\input{pictable/eight}
\input{pictable/Table}

\begin{document}

This is a table: % The following few lines use the Table macros
\[
  \BeginTable
    \BeginFormat
      | lw8 | rw4 | rw4 |
    \EndFormat
    " Line 1  " 1.23 " 4.56 "\\
    " Line 2  " 7.89 " 0.12 "\\
  \EndTable
\]

\def\QuestionSolution{Q} % This identifies whether I want a question or solution

\ifnum\pdfstrcmp{\QuestionSolution}{S}=0%
  This is the question
\else%
  This is the solution with the same table:
 \[
   \BeginTable
    \BeginFormat
    | lw20 | rw4 | rw4 |
    \EndFormat
    " Line 1  " 1.23 " 4.56 "\\
    " Line 2  " 7.89 " 0.12 "\\
   \EndTable
 \]
\fi

\end{document}
  • Thank you, Werner. Your explanation and solution make complete sense. Also, you have just saved me about two weeks of (table-rewriting) work. – Simon Gervais Sep 7 '13 at 1:07
  • perhaps the percent character after 0 in the \ifnum test should be removed; it doesn't matter here but with 0% TeX is going to expand what comes next to finish finding a number. Or do \if\pdfstrcmp{\QuestionSolution}{S}0%: in case of \if-10% or \if10% TeX will take the false branch and the true branch for \if00%. In that case the %is necessary to avoid adding a spurious space. – user4686 Sep 7 '13 at 13:36
2

Here is another method which does not use \scantokens, and it does not have group braces to be (perhaps, in some cases) removed. It does not use \ifstrequal either, only plain \if.

(to tell the truth the code here is not "inside a macro" at all)

\documentclass[11pt]{article}

%  \usepackage{etoolbox}  % not needed in this approach


\newcommand*{\QS}{\if\QuestionSolution S\expandafter\zaptoS\fi }

\newcommand{\bS}{}      % checking if already defined
% \S is \textsection so I chose \bS (begin S)

\long\def\bS #1\eS{}

\newcommand{\zaptoS}{} %checking if already defined
\long\def\zaptoS #1\bS{}

\newcommand*{\eS}{}   % (end S)


% These three lines read the macros
\input{pictable/base/nine}
\input{pictable/base/eight}
\input{pictable/base/Table}

\begin{document}

This is a table: % The following few lines use the Table macros
 $$
 \BeginTable
  \BeginFormat
  | lw8 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
 $$

\def\QuestionSolution{Q} % I want a question

\QS
This is the question
\bS 
This is the solution with the same table:
 $$
 \BeginTable
  \BeginFormat
  | lw8 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
$$
\eS

\def\QuestionSolution{S} % I now want here a solution

\QS % question from here to \bS
This is the question
\bS  % solution from here to \eS
This is the solution with the same table:
 $$
 \BeginTable
  \BeginFormat
  | lw8 | rw4 | rw4 |
  \EndFormat
  " Line 1  " 1.23 " 4.56 "\\
  " Line 2  " 7.89 " 0.12 "\\
 \EndTable
$$
\eS

\end{document}

codes

  • I propose this answer because it allows inside the questions/solutions to use \if..\else..\fi constructs with no surprises, as there is no apparent conditional to TeX apart from the one processed in one go when \QS is executed. – user4686 Sep 7 '13 at 14:23
  • I guess the more common situation is when one wants to display or not display the solutions (the questions being always printed). Then the mark-up needed would be only the \bS...\eS. One would have a switch \ifsolutions and define \def\bS{\ifsolutions\else\expandafter\zaptoeS\fi}, with \long\def\zaptoeS #1\eS {} and \def\eS {}. This way inside the solution code, arbitrary TeX code can be used with no possible surprise from TeX scanning conditional branches, compared to doing \ifsolutions <solution code>\fi. – user4686 Sep 7 '13 at 14:37
  • Makes me think that the LaTeX mark-up \begin{solution}...\end{solution} does not make it easy to define the solution environment to annihilate conditionally its contents, seems this is exactly the job of package comment. – user4686 Sep 7 '13 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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