在 \lettrine 参数中操作字符串时,我遇到了一些奇怪的行为和错误:代码要么无法编译,要么产生意外结果。最重要的是,它与字体有关,例如,有些东西可以与常规字体一起使用,但无法与某些其他字体一起使用,例如这里的大多数字体:https://tug.org/FontCatalogue/otherfonts.html#initials
任何关于此问题的见解和如何解决这个问题的建议都将不胜感激!
以下是一个典型的例子:
\documentclass{article}
\usepackage{times,lettrine,Eileen,coolstr,stringstrings,xstring}
%\renewcommand*{\LettrineFontHook}{\Eileenfamily} %%% Eileen fancy drop letter WTF?
\newcommand*{\first}[1]{\substring{#1}{1}{1}} %%% stringstrings version
%\newcommand*{\first}[1]{\substr{#1}{1}{1}} %%% coolstr version DOES NOT WORK AT ALL
%\newcommand*{\first}[1]{\StrLeft{#1}{1}} %%% xstring version DOES NOT WORK AT ALL
\begin{document}
\lettrine{\first{Whaaat}}{hat} the duck? %%% DOES NOT WORK AS INTENDED WITH EILEEN
\vspace{3em}
\lettrine{\first{What}}{hat} the duck? %%% DOES NOT WORK AT ALL WITH EILEEN
\end{document}
答案1
在这种情况下,我建议使用原始 TeX 来执行此操作,而无需解析包。
\documentclass{article}
\usepackage{times,lettrine,Eileen}
\def\firstaux#1#2\relax{{#1}{#2}}
\newcommand\flettrine[1]{\expandafter\lettrine\firstaux#1\relax}
\begin{document}
\flettrine{What} the duck?\bigskip
\renewcommand*{\LettrineFontHook}{\Eileenfamily}
\flettrine{What} the duck?
\end{document}
stringstrings
如果你出于其他原因(例如更复杂的操作)想要使用,我会\substring
使用店铺将结果放入 中\thestring
,然后传递\thestring
给\lettrine
,方式如下:
\documentclass{article}
\usepackage{times,lettrine,Eileen,coolstr,stringstrings,xstring}
\newcommand*{\first}[1]{\substring[q]{#1}{1}{1}} %%% stringstrings version
\newcommand\flettrine[2]{\first{#1}\lettrine{\thestring}{#2}}
\begin{document}
\flettrine{Whaaat}{hat} the duck? %%% DOES NOT WORK AS INTENDED WITH EILEEN
\vspace{3em}
\renewcommand*{\LettrineFontHook}{\Eileenfamily} %%% Eileen fancy drop letter WTF?
\flettrine{What}{hat} the duck? %%% DOES NOT WORK AT ALL WITH EILEEN
\end{document}
答案2
它expl3
真的很容易:
\documentclass{article}
\usepackage{newtxtext,lettrine,Eileen,xparse}
\renewcommand*{\LettrineFontHook}{\Eileenfamily} %%% Eileen fancy drop letter WTF?
\ExplSyntaxOn
\NewDocumentCommand{\IiroLettrine}{O{}m}
{
\lettrine[#1]{\tl_range:nnn { #2 } { 1 } { 1 }}{\tl_range:nnn { #2 } { 2 } { -1 } }
}
\ExplSyntaxOff
\begin{document}
\IiroLettrine{What} the duck?
\end{document}
您的代码的问题在于它\StrLeft{#1}{1}
没有产生第一个字母,而是产生了打印它的指令集,但\lettrine
只需要一个字母(扩展后)。
该\tl_range:nnn
函数是完全可扩展的,因此 没有任何问题\lettrine
。\tl_range:nnn { #1 } { 1 } { 1 }
参数中的第一个项被传递;\tl_range:nnn { #1 } { 2 } { -1 }
其余项被生成(第二个负数表示“直到最后一项”)。
由于需要小型大写字母,最好使用newtxtext
提供真正小型大写字母的,而不是使用的伪小型大写字母times
。
您也可以使用 来实现这一点xstring
,利用其尾随可选参数功能:
\documentclass{article}
\usepackage{newtxtext,lettrine,Eileen,xstring}
\renewcommand*{\LettrineFontHook}{\Eileenfamily} %%% Eileen fancy drop letter WTF?
\newcommand{\IiroLettrine}[2][]{%
\StrLeft{#2}{1}[\firstletter]%
\StrGobbleLeft{#2}{1}[\otherletters]%
\lettrine[#1]{\firstletter}{\otherletters}%
}
\begin{document}
\IiroLettrine{What} the duck?
\end{document}
在这两种情况下,我都保留了可选参数\lettrine
可用\IiroLettrine
。