1

Inside a table, I want to draw rules. Their length equals the cell length times a predefined ratio (i.e. \rule{\ratio\linewidth}{1ex}). I use the \DIVIDE{A}{B}{\ratio} function of the calculator-package that defines \ratio equal to the numeric value of A/B.

This works well if the ratio is defined outside the table. Yet, it bugs (with ! Undefined control sequence. as error message) if I define the ratio within the table.

Here is an example with a locally defined ratio in the last line only (see MWE).
enter image description here

Question: Is there a way to locally define and use a calculated value using calculator within a table? (I've tried to fiddle with \expandafter but with no success since I've reach there the limit of my TeX-skills)


MWE which compilation bugs if you uncomment the two last lines of the table.

\documentclass{scrartcl}
    \usepackage{calculator}
    \usepackage{tabularx}

\begin{document}
    \COPY{1}{\numberA}
    \COPY{2}{\numberB}
        \DIVIDE{\numberA}{\numberB}{\ratioOne}

    \begin{tabularx}{.5\linewidth}{|l|l|l|X|}
        \textbf{A} & \textbf{B} & \textbf{A/B} & \textbf{Relative rule}
        \\
        1 & 1 & 1 & \rule{\linewidth}{1ex}
        \\
        \numberA & \numberB & \ratioOne & \rule{\ratioOne\linewidth}{1ex}
        \\
        %\numberA & \numberB & \DIVIDE{\numberA}{\numberB}{\ratioTwo} \ratioTwo& \rule{\ratioTwo\linewidth}{1ex}
        %\\
    \end{tabularx}
\end{document}

Edit

Based on Christian's comment, I've found that if you define the ratio within the cell you use it, it compiles without error. (I.e. following line causes no error.)

\numberA & \numberB & \DIVIDE{\numberA}{\numberB}{\ratioTwo} \ratioTwo& \DIVIDE{\numberA}{\numberB}{\ratioThree}\rule{\ratioThree\linewidth}{1ex}\\
  • 1
    I think you struggle here with the cell grouping -- the value in one cell does not make it to other cell – user31729 Apr 14 '16 at 15:14
  • Indeed, since the cell \DIVIDE{\numberA}{\numberB}{\ratioTwo} \ratioTwo prints 0.5 as expected, and without causing an error during the compilation. – ebosi Apr 14 '16 at 15:16
2

Almost all commands defined by calculator have local behavior (his scope is restricted into groups). This is the reason because \ratioTwo is undefined when you change to another column in your tabularx environment.

Use the \GLOBALCOPY command to globalize your number:

\GLOBALCOPY{\ratioTwo}{\ratioTwo}

(note than you can assign the same name to the new global number).

Try this version of your code:

 \documentclass{scrartcl}
     \usepackage{calculator}
     \usepackage{tabularx}

 \begin{document}
 \COPY{1}{\numberA}
 \COPY{2}{\numberB}
    \DIVIDE{\numberA}{\numberB}{\ratioOne}

 \begin{tabularx}{.5\linewidth}{|l|l|l|X|}
    \textbf{A} & \textbf{B} & \textbf{A/B} & \textbf{Relative rule}
    \\
    1 & 1 & 1 & \rule{\linewidth}{1ex}
    \\
    \numberA & \numberB & \ratioOne & \rule{\ratioOne\linewidth}{1ex}
    \\
    \numberA & \numberB & \DIVIDE{\numberA}{\numberB}{\ratioTwo}
    \GLOBALCOPY{\ratioTwo}{\ratioTwo} \ratioTwo& \rule{\ratioTwo\linewidth}{1ex}
    \\
 \end{tabularx}
 \end{document}

But, why not define a new command to calculate ratio and print the tabular line? You can then write something like this:

 \documentclass{scrartcl}
     \usepackage{calculator}
     \usepackage{tabularx}

 \begin{document}

 \newcommand{\maketableline}[2]{%
      \GLOBALCOPY{#1}{\numberA}
      \GLOBALCOPY{#2}{\numberB}
        \DIVIDE{\numberA}{\numberB}{\ABratio}
        \GLOBALCOPY{\ABratio}{\ABratio}
          \numberA & \numberB & \ABratio & \rule{\ABratio\linewidth}{1ex}\\
         }

 \begin{tabularx}{.5\linewidth}{|l|l|l|X|}
    \textbf{A} & \textbf{B} & \textbf{A/B} & \textbf{Relative rule}
    \\
    \maketableline{1}{1}
    \maketableline{1}{2}
    \maketableline{2}{3}
    \maketableline{3}{4}
 \end{tabularx}
 \end{document}
1

Here's a solution with a wrapper for the \DIVIDE command, defining a \ratio#3 command, where #3 is the 3rd argument, say Two etc. It's a global command then, however, but survives the tabular cell.

Using a toks register could be an alternative.

\documentclass{scrartcl}
\usepackage{calculator}
\usepackage{tabularx}

\newcommand{\newratio}[3]{%
  \DIVIDE{#1}{#2}{\radioInt}%
  \expandafter\xdef\csname ratio#3\endcsname{\radioInt}%
}

\begin{document}
    \COPY{1}{\numberA}
    \COPY{2}{\numberB}
    \DIVIDE{\numberA}{\numberB}{\ratioOne}
    \begin{tabularx}{.5\linewidth}{|l|l|l|X|}
        \textbf{A} & \textbf{B} & \textbf{A/B} & \textbf{Relative rule}
        \\
        1 & 1 & 1 & \rule{\linewidth}{1ex}
        \\
        \numberA & \numberB & \ratioOne & \rule{\ratioOne\linewidth}{1ex}
        \\
        \numberA & \numberB & \newratio{\numberA}{\numberB}{Two}\ratioTwo & \rule{\ratioTwo\linewidth}{1ex}
        \\
    \end{tabularx}
\end{document}
  • I'll try to, little by little, understand your answer. Thank you! (Maybe I should have been more explicit in my long-term goal: I want to define a function that takes A as argument, and that computes a whole table row using a globally defined B value. It thus assesses the ratio for each line. So I'll figure out how to implement your answer in my real-case problem!) – ebosi Apr 14 '16 at 15:34
  • 1
    @ebo: This possible with \noalign{...} etc or using expl3, but my answer just makes \ratio.... available for all following table cells, using an \xdef.. (you need \xdef to store the value of \ratioInt (the internal value)) An ordinary \gdef would not be sufficient here – user31729 Apr 14 '16 at 15:35

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.