Preciso encontrar a profundidade de uma string, para isso gostaria de fazer um loop na string e pedir a profundidade de cada caractere.
Peço profundidade assim:
\dimen=\fontchardp\expandafter\font`\a
E faça um loop assim:
\def\mystring{abcdefgh}
\StrLen{\mystring}[\len]
\newcount\X \X=\len
\loop
\StrMid{\mystring}{\X}{\X}\par
\advance \X by -1
\unless\ifnum \X<1
\repeat
Mas isso não funciona, embora eu tenha tentado com diferentes combinações de \expandafter
:
\dimen=\fontchardp\font`\StrMid{\mystring}{\X}{\X}
Se houver maneiras mais fáceis de obterprofundidade de uma cordaeu agradeceria, mas também gostaria de saber como fazer a linha de código anterior funcionar. Obrigado.
Responder1
Oresposta de marsupilamcobre como alguém normalmente realizaria a tarefa: compor o conteúdo e obter a profundidade da caixa.
Existem dois problemas com o código que você possui. Primeiro, a primitiva TeX \dimen
deve ser seguida por um número de registro, não por um =
. Usando o fato de que \dimen0
é um registro de rascunho no LaTeX, você pode usar \dimen0=<some valid dimension>
. A segunda é que \StrMid
não gera uma cartapor si só(não é 'expansível'), são instruções para fazer isso em um contexto de composição tipográfica. Porém, existe um argumento opcional que 'retornará' o que você deseja
\StrMid{\mystring}{\X}{\X}[\tmp] % \tmp now expands to the substring
Podemos usar isso para \expandafter
obter o que \fontchardp
é necessário: o personagemnúmeroVocê está interessado em
\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
\advance \X by -1 %
\unless\ifnum \X<1 %
\repeat
\end{document}
(Eu mostrei em vez de digitar o resultado)
Responder2
Não sei sobre sua abordagem usando um loop, mas para obter profundidade, basta usar\settodepth
Ver :https://tex.stackexchange.com/a/37294/116936
Você também pode usar o calc
pacote\depthof
\documentclass{article}
\begin{document}
\def\mystring{abcdefgh}
\newlength\myLength
\settodepth{\myLength}{\mystring}
\the\myLength
\end{document}
Saúde,
Responder3
Semelhante ao de Joseph, mas usando menos código
\documentclass{article}
\usepackage{xstring}
\newcount\X
\newdimen\stringdepth
\begin{document}
\def\mystring{abcdefgh}
\StrLen{\mystring}[\len]
\X=0
\stringdepth=0pt
\loop
\ifnum\len>\X
\advance\X by 1
\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}
Claro
\settodepth{\stringdepth}{\mystring}
é muito mais eficiente.
Um loop diferente, bastante flexível, como mostram os exemplos: o item atual é referido #1
no argumento final para \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}
Aqui está a saída no terminal (e arquivo de log):
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