# How to make a local variable in Plain TeX?

I want to simplify my code below by creating a local variable as a temporary container to save the value of \numexpr#1+#2+#3+#4+#5}.

\documentclass[dvips,dvipsnames,rgb,table]{book}
\usepackage[a4paper,hmargin=20mm,vmargin=20mm]{geometry}
\usepackage{longtable}
\usepackage{array}
\usepackage{calc}
\usepackage{lscape}

\usepackage{pstricks,pst-node}
\newpsstyle{gridstyle}{%
gridwidth=0.4pt,%default: 0.8pt
gridcolor=Red!20,%default: black
griddots=0,%default: 0
%
gridlabels=3pt,%default: 10pt
gridlabelcolor=Blue,%default: black
%
subgriddiv=5,%default: 5
subgridwidth=0.2pt,%default: 0.4pt
subgridcolor=Green!20,%default: gray
subgriddots=0%default: 0
}

\makeatletter
\newcommand\ratio[2]{\strip@pt\dimexpr#1pt/#2\relax}
\makeatother

\setlength{\tabcolsep}{8pt}
\setlength{\arrayrulewidth}{0.5pt}
\arrayrulecolor{Red}

\newcounter{No}
\renewcommand{\theNo}{\arabic{No}}

\newcolumntype{S}[1]%
{%
>{\begin{minipage}{#1\linewidth-2\tabcolsep-2\arrayrulewidth}\vspace{\tabcolsep}}%
c%
<{\vspace{\tabcolsep}\end{minipage}}%
}%
\newcolumntype{O}[1]%
{%
>{\begin{minipage}{#1\linewidth-2\tabcolsep-1.5\arrayrulewidth}\vspace{\tabcolsep}}%
c%
<{\vspace{\tabcolsep}\end{minipage}}%
}%
\newcolumntype{I}[1]%
{%
>{\begin{minipage}{#1\linewidth-2\tabcolsep-\arrayrulewidth}\vspace{\tabcolsep}}%
c%
<{\vspace{\tabcolsep}\end{minipage}}%
}%

\newenvironment{InlineTable}[5][0]%
{%
\setcounter{No}{0}%
\newcount\ITT
\ITT\numexpr#1+#2+#3+#4+#5\relax
\begin{longtable}%
{%
|>{\stepcounter{No}\centering\scriptsize\theNo}O{\ratio{#2}{\ITT}}<{}%
|>{\centering}I{\ratio{#3}{\ITT}}<{\input{\jobname.tmp}}%
|>{\centering\lstinputlisting{\jobname.tmp}}I{\ratio{#4}{\ITT}}<{}%
|>{\scriptsize}O{\ratio{#5}{\ITT}}<{}%
|%
}%
\hline\ignorespaces%
}%
{%
\end{longtable}%
}

\newcommand{\Comment}[1]{&&&#1\tabularnewline\hline}

\usepackage{listings}
\lstset{%
language={PSTricks},
alsolanguage={[LaTeX]TeX},
breaklines=true,
basicstyle=\ttfamily\scriptsize,%
keywordstyle=\color{blue},
backgroundcolor=\color{yellow!30}%
}
\usepackage{fancyvrb}

\def\MyRow{%
\VerbatimEnvironment%
\begin{VerbatimOut}{\jobname.tmp}%
}

\def\endMyRow{%
\end{VerbatimOut}%
}

\usepackage{lipsum}

\begin{document}
\clearpage
\pagestyle{empty}
%Landscape starts here.
\begin{landscape}

\begin{InlineTable}[10]{5}{25}{30}{40}%
%=============
\begin{MyRow}
\pspicture*[showgrid](3,3)
\pnode(1,1){A}
\pnode(3,3){B}
\ncline{A}{B}
\endpspicture
\end{MyRow}
\Comment{\lipsum[1]}
%=============
\begin{MyRow}
\begin{pspicture}[showgrid](3,3)
\psframe*[linecolor=red!30](3,2)
\end{pspicture}
\end{MyRow}
\Comment{\lipsum[2]}
%=============
\begin{MyRow}
\pspicture[showgrid](3,3)
\psframe*[linecolor=green!30](3,2)
\endpspicture
\end{MyRow}
\Comment{\lipsum[3]}
%=============
\begin{MyRow}
\pspicture[showgrid](3,3)
\psframe*[linecolor=Yellow](3,2)
\endpspicture
\end{MyRow}
\Comment{%
$$\int_a^b f(x)\, \textrm{d}x=F(b)-F(a)$$
is the fundamental theorem of calculus.
}
%=============
\begin{MyRow}
\pspicture[showgrid](3,3)
\psframe*[linecolor=Maroon!30](3,2)
\endpspicture
\end{MyRow}
\Comment{%
Today I ate burnt bread. It was so delicious.
$$\int_a^b f(x)\, \textrm{d}x=F(b)-F(a)$$
is the fundamental theorem of calculus.
}
%=============
\end{InlineTable}
\end{landscape}
%Landscape stops here.
\pagestyle{plain}
\end{document}

-
Quite apart from my answer to the question, I don't think this is going to work as \stepcounter is not expandable. Table header material needs to be expanded to set up the underlying \halign. –  Joseph Wright Dec 30 '10 at 16:54
Also, this has nothing to do with plain TeX. –  Joseph Wright Dec 30 '10 at 16:56
It works, see my update. Thanks. –  xport Dec 30 '10 at 17:00
Please try and post minimal examples that focus on the question you have. Your code here is far too long. –  Hendrik Vogt Dec 31 '10 at 8:31

LaTeX environments form groups, and so any variable you set within it will be local unless you use \global. Now, LaTeX counters are set globally, so you'll need a TeX count:

\newcount\mycount
...
\newenvironment{InlineTable}[5][0]%
{%
\mycount\numexpr#1+#2+#3+#4+#5\relax
...

-
Can I put \newcount\mycount as a local variable inside the environment definition above? –  xport Dec 30 '10 at 16:57
@xport. Ah, you are thinking of 'local to a function'. TeX does not work like that: things are local to TeX groups. You can of course put \newcount\mycount inside the definition, but the new count is allocated globally. This makes life a little complicated, and I would recommend not doing it. (There have been various discussions on locally-allocated variables recently. The problem is that as TeX doesn't have functions, but has macros, the 'localness' is not so easy to track in a general sense. Perhaps take a look at the etex package for local allocation of count variables.) –  Joseph Wright Dec 30 '10 at 17:01
I think I might write something for my blog (texdev.net) about local variables. –  Joseph Wright Dec 30 '10 at 17:02
macros are local, but registers (counts, lengths, boxes, etc.) are global. –  Leo Liu Dec 30 '10 at 17:12
@Leo. Not quite. By convention, registers are allocated globally, although they can be assigned locally. It's quite possible to do a local allocation of registers: see the etex package for one approach. The problem is that 'local' here is somewhat different to other languages, and this leads to a situation where local allocation does not necessarily translate into 'a good idea'. –  Joseph Wright Dec 30 '10 at 17:27