# Biggest depth of a character in a string

I need to find depth of a string, for this end i would like to loop over the string and ask for depth of every character.

I ask for depth like this:

\dimen=\fontchardp\expandafter\font\a


And loop like this:

\def\mystring{abcdefgh}
\StrLen{\mystring}[\len]
\newcount\X \X=\len

\loop
\StrMid{\mystring}{\X}{\X}\par
\unless\ifnum \X<1
\repeat


But this doesn't work, even though i tried with different combinations of \expandafter:

\dimen=\fontchardp\font\StrMid{\mystring}{\X}{\X}


If there are easier ways to get depth of a string i would appreciate it, but also i would like to know how to make previous line of code work. Thanks.

• Using \StrChar is simpler, isn't it? – egreg Apr 25 '17 at 9:50
• @egreg probably i need start with reading docs not programming:) – Yola Apr 25 '17 at 11:28
• If ligatures are involved, then the depth of the ligature can be different than the maximum depth of the characters that are used to build the ligature. – Heiko Oberdiek Aug 6 '17 at 14:23

The answer by marsupilam covers how one would normally achieve the task: typeset the content and get the box depth.

There are two issues with the code you've got. First, the TeX primitive \dimen has to be followed by a register number, not by an =. Using the fact that \dimen0 is a scratch register in LaTeX, you therefore can use \dimen0=<some valid dimension>. The second is that \StrMid doesn't generate a letter per se (it's not 'expandable'), it is instructions to do that in a typesetting context. However, there is an optional argument that will 'return' what you want

\StrMid{\mystring}{\X}{\X}[\tmp] % \tmp now expands to the substring


We can use that with \expandafter to get what \fontchardp requires: the character number you are interested in

\documentclass{article}
\usepackage{xstring}

\begin{document}

\def\mystring{abcdefgh}
\StrLen{\mystring}[\len]
\newcount\X
\X=\len

\loop
\StrMid{\mystring}{\X}{\X}[\tmp]
\dimen0=\fontchardp\expandafter\font\expandafter\tmp
\edef\x{\tmp\space\the\dimen0 }%
\show\x
\unless\ifnum \X<1 %
\repeat

\end{document}


(I've show rather than typeset the result)

• Really appreciate this! – Yola Apr 25 '17 at 8:53

I don't know about your approach using a loop, but to get the depth, just use \settodepth

You can also use the calc package \depthof

\documentclass{article}

\begin{document}
\def\mystring{abcdefgh}
\newlength\myLength

\settodepth{\myLength}{\mystring}

\the\myLength
\end{document}


Cheers,

• +1, could you please also provide a solution for the line of code which doesn't work in the post? I think there is an important concept behind it. – Yola Apr 25 '17 at 8:19

Similar to Joseph’s, but using less code

\documentclass{article}
\usepackage{xstring}

\newcount\X
\newdimen\stringdepth

\begin{document}

\def\mystring{abcdefgh}
\StrLen{\mystring}[\len]

\X=0
\stringdepth=0pt

\loop
\ifnum\len>\X
\StrChar{\mystring}{\X}[\tmp]%
\begingroup\edef\x{\endgroup
\dimen0=\fontchardp\font\tmp\relax
}\x
\ifdim\dimen0>\stringdepth \stringdepth=\dimen0 \fi
% just for showing the work
\typeout{\tmp\space has depth \the\dimen0 }%
\repeat

\typeout{Max depth: \the\stringdepth}

\end{document}


Of course

\settodepth{\stringdepth}{\mystring}


is much more efficient.

A different loop, quite flexible, as shown by the examples: the current item is referred to as #1 in the final argument to \stringloop:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\stringloop}{smm}
{
\IfBooleanTF{#1}
{ % we have a macro as argument
\tl_map_inline:Nn #2 { #3 }
}
{ % an explicit token list
\tl_map_inline:nn { #2 } { #3 }
}
}
\ExplSyntaxOff

\newdimen\stringdepth

\begin{document}

\def\mystring{abcdefgh}

\stringloop{abcdefgh}{\typeout{#1 has depth \the\fontchardp\font#1}}

\stringdepth=0pt
\stringloop*{\mystring}{%
\ifdim\fontchardp\font#1>\stringdepth
\stringdepth=\fontchardp\font#1\relax
\fi
}
\typeout{Max depth in \mystring: \the\stringdepth}

\end{document}


Here is the output on the terminal (and log file):

a has depth 0.0pt
b has depth 0.0pt
c has depth 0.0pt
d has depth 0.0pt
e has depth 0.0pt
f has depth 0.0pt
g has depth 1.94444pt
h has depth 0.0pt
Max depth in abcdefgh: 1.94444pt
`
• As you might guess, for my answer I was sticking close to the OP's code to make it illustrative. – Joseph Wright Apr 25 '17 at 10:37
• @JosephWright That's why I upvoted your answer! – egreg Apr 25 '17 at 10:41