# Is there a simple way to create a local length

I want to redefine \textheight and \textwidth inside a \parbox. \textwidth works pretty well so far. But the textheight-part works only with the help of a \newlength. Unfortunately the \newlength will be created globally. \setlength assigns it only locally.

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}

\begin{document}

\parbox{0.5\textwidth}{
\def\textwidth{\linewidth}
\newlength{\mylocal}
\setlength{\mylocal}{0.99\textheight}
\edef\textheight{\mylocal}
\parbox[t][\textheight]{\textwidth}{
\framebox[\textwidth]{Text2}
\vfill
\framebox[\textwidth]{Text3} \the\mylocal
}%inner parbox
}%outer parbox

\the\mylocal

\framebox[\textwidth]{Text4}

\end{document}


As you can see, there is no undefined-error outside, the \parbox. If I use \newlength{\mylocal} outside the \parbox there will be such an error.

• Why would you want to redefine \textheight and \textwidth? Why do you create a length inside a parbox? This looks rather unsane. – Ulrike Fischer Apr 22 '16 at 8:18
• why do you want to redefine them? \def\textwidth{\linewidth} makes \textwidth into a macro not a length register which will break almost all existing uses. – David Carlisle Apr 22 '16 at 8:19
• You should not screw up the register system with \newlength in a local setup – user31729 Apr 22 '16 at 8:19
• I got it: Simply \setlength{\textheight}{0.98\textheight} and \setlength{\textwidth}{\linewidth}. How couldn't I see it? You may recommend not to do this, but in the package I'm making, this is locally (!) useful. – MaestroGlanz Apr 22 '16 at 8:42

Let's look at the basics. First of all, \textwidth, \textheight and \linewidth are <dimen> registers, internally defined with \newdimen.

If you do \def\textwidth{\linewidth} you are not setting \textwidth to the current line width, but just making \textwidth into a macro that will expand to \linewidth (the name of the internal register that stores the current line width, to be mostly used in lists).

When you do \edef\textheight{\mylocal}, you're doing the same: \textheight becomes a macro that expands to \mylocal.

Such (useless) redefinitions will disappear at the end of the parbox they're made in, because the parbox is surrounded by a group. The allocation of \mylocal won't disappear, but its value will by the same reason.

You can use <dimen> parameters locally, although I suggest using your own parameters (there's plenty of registers, now).

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}

\begin{document}

\parbox{0.5\textwidth}{
\setlength\textwidth{\linewidth}
\setlength\textheight{0.99\textheight}
\parbox[t][\textheight]{\textwidth}{
\framebox[\textwidth]{Text2}
\vfill
\framebox[\textwidth]{Text3}
}%inner parbox
}%outer parbox

\framebox[\textwidth]{Text4}

\end{document}


Note that you can assign a value to a parameter using its current value:

\setlength{\textheight}{0.99\textheight}


is perfectly legal and effective. However, it would be much better to assign your own parameters:

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}

\newlength\mgwidth \newlength\mgheight

\begin{document}

\parbox{0.5\textwidth}{
\setlength\mgwidth{\linewidth}
\setlength\mgheight{0.99\textheight}
\parbox[t][\mgheight]{\mgwidth}{
\framebox[\mgwidth]{Text2}
\vfill
\framebox[\mgwidth]{Text3}
}%inner parbox
}%outer parbox

\framebox[\textwidth]{Text4}

\end{document}