0
\documentclass[a4paper]{article}
\usepackage{geometry}
\geometry{showframe}
\geometry{left=1cm,right=1cm,top=1cm,bottom=1cm}
\begin{document}
(1)

    \newlength{\ccc}{\dimexpr\textwidth-100pt}

% This cause error message: You can't use `\dimexpr' in vertical mode.Why is \dimexpr used here a wrong way?

(2)

    \newdimen\ddd{\dimexpr\textwidth-100pt}

% This also causes error.

(3)

        \def\aaa{\dimexpr\textwidth-100pt}
    
    \rule{\aaa}{10pt}

% This does work.
\end{document}

I'm confused. Does that mean length calculation can not be done by \dimexpr in \newlength?

4
  • 1
    newlength only has one argument so the dimexpr is just in the preamble not in any command, hence the error May 2, 2022 at 6:41
  • 1
    Newlength defines a new length, it cannot set a value, use setlength to set a value
    – daleif
    May 2, 2022 at 6:42
  • 1
    You want \usepackage{calc}\newlength{\ccc}\setlength{\ccc}{\textwidth-100pt} May 2, 2022 at 8:40
  • @HenriMenke I would use \dimexpr rather than calc, but either work. May 2, 2022 at 9:33

2 Answers 2

2

Your example (2): \newdimen has only one parameters, it declares a new "dimen" variable and sets it to 0pt. It has only one parameter (\ddd in your example). The following {\dimexpr ...} opens a group { and sees \dimexpr in vertical mode. TeX does not allow to use \dimexpr in this context. You can use \the\dimexpr... to print the value, but not \dimexpr alone. TeX reports the error.

Your example (3): you define macro (no variable) \aaa and it expands to \dimexpr.... You use this macro in the context \hrule height\aaa wich expands to \hrule height\dimexpr.... Now the \dimexpr is used in allowed context.

2

If you try

\documentclass{article}
\begin{document}

\newlength{\ccc}{10pt}

\the\ccc

\end{document}

you get

enter image description here

Can you see why? Because \newlength takes one argument, not two, so {10pt} is typeset. Next, the value of \ccc is shown, which is still 0pt.

If you do

\newlength{\ccc}{\dimexpr\textwidht-100pt}

then TeX tries to typeset {\dimexpr\textwidth-100pt} which raises an error about \dimexpr, which is not legal in that context.

There is a rationale. As a general rule, registers should be allocated in the preamble and their value can be set anywhere needed.

You first allocate the register, then set it. Allocation for a new length register is done with \newlength; setting a length register is done with \setlength.

\documentclass{article}
\newlength{\ccc}

\begin{document}

\setlength{\ccc}{\dimexpr\textwidth-100pt}

\rule{\ccc}{10pt}

\end{document}

By the way, if you want to fill the rest of the line with a 4pt thick rule, there is a different method that doesn't require measuring.

\documentclass{article}

\newcommand{\filltoend}{%
  \unskip\nobreak\leaders\hrule height4pt\hfill\mbox{}\par
}

\begin{document}

Some words\filltoend

Some words and some other words
Some words and some other words
Some words and some other words
Some words and some other words
Some words and some other words\filltoend

Some words and some other words
Some words and some other words
Some words and some other words
Some words and some other words
Some words\filltoend

\end{document}

enter image description here

3
  • Many thanks for yor suggestions especially for the idea of\filltoend!! And, if messureing is needed, for exmple, use a \parbox to occupy the rest of the line, any trick for it?
    – lyl
    May 2, 2022 at 10:11
  • @lyl Didn’t you ask for that elsewhere?
    – egreg
    May 2, 2022 at 10:48
  • I wonder if there is way to deal with this problem without using any package.
    – lyl
    May 2, 2022 at 12:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .