5

I have written a simple function to calculate the width of a line of text and display it using tikz:

\documentclass{article}
%\usepackage{mathpazo}
\usepackage{domitian}
\usepackage[T1]{fontenc}
%\let\oldstylenums\oldstyle
\usepackage{tikz}
\usepackage{tkz-euclide}
\usetikzlibrary{math}
\usetikzlibrary{calc}
\usetikzlibrary{fpu}
\usetikzlibrary{fit}
\ExplSyntaxOn
\box_new:N \l_my_otherbox
\dim_new:N \l_my_dim
\dim_new:N \l_my_htdim
\dim_new:N \l_my_dpdim
\NewDocumentCommand{\boxlen}{m}
{
    \hbox_set:Nn \l_my_otherbox {#1}
    \dim_set:Nn \l_my_dim  {\box_wd:N \l_my_otherbox}
    \dim_set:Nn \l_my_htdim  {\box_ht:N \l_my_otherbox}
    \dim_set:Nn \l_my_dpdim  {\box_dp:N \l_my_otherbox}
    \begin{tikzpicture}        
        \node[draw,text~width=9cm,align=left,fill=white,draw=black,inner~sep=0pt] (box) at (0,0)
        {#1};  
         \draw[line~width=2pt]~($(box.south~west)+(0,-.5cm)$)~--~+(9cm,0) node[below,pos=0.5] {9 cm};
         \draw[red,line~width=2pt]~let~\p1=(box.west),\p2=(box.base)~in~($(box.base)+(\x1-\x2,-\dim_use:N \l_my_dpdim)$)~--~+(\dim_use:N \l_my_dim,0) node[below,pos=0.5] 
         {\fp_eval:n {round(\dim_to_decimal_in_cm:n {\dim_use:N \l_my_dim},2)}cm};
    \end{tikzpicture}
}
\ExplSyntaxOff
\begin{document}
This part of the document uses the \verb+domitian+ font family:\par
\boxlen{Long word.}
\vskip 2ex
\boxlen{\textbf{Even longer} word.}
\vskip 2ex
\boxlen{\textbf{Emphasize a word} or do not emphasize a word.}
\vskip 2ex
\boxlen{Emphasize a word or do not emphasize a word.}

{  % use computer modern roman
\fontfamily{cmr}\selectfont 
This part of the document uses the \verb+Computer Modern Roman+ font family:\par
\boxlen{Long word.}
\vskip 2ex
\boxlen{\textbf{Even longer} word.}
\vskip 2ex
\boxlen{\textbf{Emphasize a word} or do not emphasize a word.}
\vskip 2ex
\boxlen{Emphasize a word or do not emphasize a word.}
}
\end{document}

The function works fine when I use Computer Modern Roman (by the way it is really difficult to get the codes for the \fontfamily command). But if I use domitian, as the sentence gets longer the width calculated by \box_wd seems to be smaller than the actual length of the text. enter image description here

It seems that \box_wd is written for specific font families so I wonder if there is a way to calculate an adjustment for non-standard font families.

7
  • 1
    you typeset the text in a specific font, and then box_wd (\wd) is the size of the text in that font. the box commands themselves do not select any font. Nov 30, 2023 at 11:32
  • \dim_set_eq:NN is wrong and errors. Nov 30, 2023 at 11:40
  • 1
    @DavidCarlisle the problem is that tikz for some unknown reason changes \spaceskip and \xspaceskip in a node. With the option text badly ragged one gets the expected result tex.stackexchange.com/a/132748/2388 Nov 30, 2023 at 11:47
  • @UlrikeFischer yes i was just posting a spaceskip answer:-) Nov 30, 2023 at 11:51
  • @UlrikeFischer perhaps you can point out some of the errors, thanks.
    – Ted Black
    Nov 30, 2023 at 11:57

1 Answer 1

5

You can simplify to

\documentclass{article}
%\usepackage{mathpazo}
\usepackage{domitian}
\usepackage[T1]{fontenc}
%\let\oldstylenums\oldstyle
\usepackage{tikz}
\usepackage{tkz-euclide}
\usetikzlibrary{math}
\usetikzlibrary{calc}
\usetikzlibrary{fpu}
\usetikzlibrary{fit}
\ExplSyntaxOn
\box_new:N \l_my_otherbox
\dim_new:N \l_my_dim
\dim_new:N \l_my_htdim
\dim_new:N \l_my_dpdim
\NewDocumentCommand{\boxlen}{m}
{
    \hbox_set:Nn \l_my_otherbox {#1}
    \dim_set_eq:NN \l_my_dim  {\box_wd:N \l_my_otherbox}
    \dim_set_eq:NN \l_my_htdim  {\box_ht:N \l_my_otherbox}
    \dim_set_eq:NN \l_my_dpdim  {\box_dp:N \l_my_otherbox}
    \begin{tikzpicture}        
        \node[draw,text~width=9cm,align=left,fill=white,draw=black,inner~sep=0pt] (box) at (0,0)
        {#1};  
        \node[draw,green,text~width=9cm,align=left,fill=white,draw=black,inner~sep=0pt] (boxx) at (0,.5)
        {\box_use:N\l_my_otherbox};  
         \draw[line~width=2pt]~($(box.south~west)+(0,-.5cm)$)~--~+(9cm,0) node[below,pos=0.5] {9 cm};
         \draw[red,line~width=2pt]~let~\p1=(box.west),\p2=(box.base)~in~($(box.base)+(\x1-\x2,-\dim_use:N \l_my_dpdim)$)~--~+(\dim_use:N \l_my_dim,0) node[below,pos=0.5] 
         {\fp_eval:n {round(\dim_to_decimal_in_cm:n {\dim_use:N \l_my_dim},2)}cm};
    \end{tikzpicture}
}
\ExplSyntaxOff

\showoutput
\begin{document}

\boxlen{\textbf{Emphasize a word} or do not emphasize a word.}

\end{document}


enter image description here

where you can see the red line is showing the width of the green original box.

In the black text you are re-setting the text in a 9cm minipage, raggedright, which adjusts \spaceskip so the inter-word space is different

................\glue(\spaceskip) 3.33298
................\T1/Domitian-TLF/bold/n/10 a
................\glue(\spaceskip) 3.33298

as opposed to

.................\glue 2.5 plus 1.25 minus 0.833
.................\T1/Domitian-TLF/bold/n/10 a
.................\glue 2.5 plus 1.25 minus 0.833

The problem here is that by default tikz is using the plain tex definition of \raggedright which is

\def\raggedright{\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax}

so here the inter word space is unconditionally set to 1/3 em ignoring the (in this case tighter) space set by the font metrics.

If you use the text badly ragged option you use the standard latex definition which does not set spaceskip at all.

An alternative would be a version of the plain definition updated to use the \fontdimen parameters from the current font rather than assuming .3333em as a target width for a space.

The plain tex \raggedright version gets closer if it is changed to force the font-specified width rather than 1/3 em

enter image description here

If you add, after loading tikz

\makeatletter
\tikzoption{text ragged}[]%
{\def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip\fontdimen2\font \xspaceskip\fontdimen7\font}}%
\makeatother

but even then as this version of ragged right forces inter-word space to be even, you do not get a different space in the bold section as you would normally.

Depending on the real use case it may be better to not use a fixed with node and simply use a natural width node (which is an mbox) or as I do in the green text, re-use the box rather than re-setting the text with different settings.

9
  • is the solution to put the text badly ragged option in \node? (apologies but I cannot link your user id)
    – Ted Black
    Nov 30, 2023 at 12:13
  • @TedBlack you can't link to me as comments under an answer automatically go to the poster, yes that or put in a bug report to tikz to fix the ragged right code Nov 30, 2023 at 12:16
  • Thanks for your help, your answer has improved my understanding.
    – Ted Black
    Nov 30, 2023 at 12:31
  • @TedBlack I added a final possible tikz update Nov 30, 2023 at 12:33
  • 1
    Why is \dim_set_eq:NN rather than \dim_set_eq:Nn used here?
    – cfr
    Nov 30, 2023 at 22:14

You must log in to answer this question.

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