3

Question

I came to a question that : How to calc the width of a environment or a paragraph by LaTeX3?

What I have done

\documentclass{article}

\begin{document}
\ExplSyntaxOn
\box_new:N \l_calc_width_box
\dim_new:N \l_calc_width_dim
\cs_new:Npn \calcwidth:n #1
    {
        \the\linewidth
        \vbox_set:Nw \l_calc_width_box { #1 } \vbox_set_end:
        \dim_set:Nn \l_calc_width_dim { \box_wd:N \l_calc_width_box } \par
        \dim_use:N \l_calc_width_dim
        #1
    }
\calcwidth:n {test}

\calcwidth:n 
    {
        \begin{enumerate}
            \item 
            \item 
            \item 
        \end{enumerate}
    }
\ExplSyntaxOff
\end{document}

My idea is that

  1. store what I want to measure in a box
  2. calc the width of the box
  3. store the width in a dim variable

Problems I met

  1. If I store the content in a vbox, then the width of it is the current linewidth;
  2. If I store the content in a hbox, then
  • I couldn't use some environments like enumerate as the content which will get issues
  • hbox is always horizontal: If use \box_wd:N to get the width of it, it'll goes up without limitation as the content become more and more

What I want

  1. I want to know if I can do it by using box module.
  2. If there are any other better ways in LaTeX3 to get the width or height of the content, which may include environment, easily.
  3. To make my desire more clear, I use a picture: enter image description here

I want to calculate the width of the red part but not the blue part

8
  • Take a look at the varwidth package for reference on how to do such things.
    – Skillmon
    Dec 20, 2021 at 9:24
  • It's written by TeX, which I didn't know too much, it's hard for me to understand..
    – xdyy
    Dec 20, 2021 at 9:27
  • 1
    the width of a box with vertical material is always what you set \hsize to be (eg \linewidth once you have a list). hboxes have a natural width but vertical material is line broken to a specified width, even witha short text like test the width of the box is not at the red line, white space is added to each line to make it full width. compare tables have lcr natural width 1-line columns and p{..} fixed width columns. to do what you want you need something like varwidth or tabular that makes multiple trial settings at different widths and finds a width that makes a suitable setting. Dec 20, 2021 at 9:32
  • 1
    The LaTeX3 programming layer is written in TeX as well. And if you want to do this with LaTeX2e constructs you'll have to alter said LaTeX2e constructs to make it work. Or you do \hbox_set:Nn \l_xdyy_calc_width_box { \begin{varwidth}{\hsize} #1 \end{varwidth} } and measure the width of that.
    – Skillmon
    Dec 20, 2021 at 9:33
  • Thank you so much, by using varwidth environment in the box setting, I get what I want exactly !
    – xdyy
    Dec 20, 2021 at 9:45

1 Answer 1

6

You could use the varwidth package inside your LaTeX3 code. While not perfect style this is fine as long as there is no LaTeX3 interface for what you want. The varwidth package allows to specify a maximum width for a box, but yields a box less wide if possible.

You can interface it from within your code by nesting it inside a \hbox_set:Nn.

\documentclass[]{article}

\usepackage{varwidth}

\ExplSyntaxOn
\dim_new:N \l_xdyy_width_dim
\box_new:N \l__xdyy_calc_width_box
\NewDocumentCommand \calcwidth { m }
  {
    \xdyy_calc_width:Nn \l_xdyy_width_dim {#1}
    \dim_use:N \l_xdyy_width_dim
    \par
    \fbox { \box_use:N \l__xdyy_calc_width_box }
  }
\cs_new_protected:Npn \xdyy_calc_width:Nn #1#2
  {
    \hbox_set:Nn \l__xdyy_calc_width_box
      { \begin{varwidth} { \hsize } #2 \end{varwidth} }
    \dim_set:Nn #1 { \box_wd:N \l__xdyy_calc_width_box }
  }
\ExplSyntaxOff

\begin{document}
\calcwidth{test}

\calcwidth
  {%
    \begin{enumerate}
      \item abc
      \item def
    \end{enumerate}
  }
\end{document}
1
  • Thanks so much for making a full answer, I'll use it in my code.
    – xdyy
    Dec 20, 2021 at 13:04

You must log in to answer this question.

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