我正在尝试为 重新创建以下章节标题样式scrbook
。
我尝试通过重新定义\chapterlinesformat
并使用包来xstring
提取章节标题的第一个字符来实现这一点。我设法拼凑了下面的代码,但它给出了以下错误:
mwe.tex|22 error| Missing number, treated as zero.
如果用明确的文本替换#3
,\firstchar{#3}
则代码可以工作并给出所需的结果。我怀疑命令\firstchar
不起作用是因为#3
的参数\chapterlinesformat
已经格式化。但我不知道如何规避这个问题,或者如何以不同的方式完成任务。
\documentclass{scrbook}
\usepackage{xcolor}
\usepackage{xstring}
% getting the first character of a string using xparse
\newcommand{\firstchar}[1]{\StrChar{#1}{1}}
\renewcommand{\chapterlinesformat}[3]{%
\makebox(0,20)[l]{%
\hspace{-20pt}%
\fontsize{60}{6}%
\selectfont%
\color{black!15!white}%
\firstchar{#3}%
}%
#3
}
\begin{document}
\chapter*{Digital Services of the University}
Here is some text.
\end{document}
\firstchar{#3}
如果替换为,则输出为\firstchar{Digital Services of the University}
:
答案1
\showtokens{#3}
如果在重新定义的开头插入\chapterlinesformat
,您将在终端和日志文件中看到以下内容:
> \interlinepenalty \@M Digital Services of the University\@@par .
\chapterlinesformat #1#2#3->\showtokens {#3}
\myExtractFirstLetter {#3}\makeb...l.32 \chapter*{Digital Services of the University}
因此,您的#3
标题不以首字母开头,因为 KOMA-Script 插入了一个非常高的字母\interlinepenalty
(10000),以确保标题不会在未经您明确同意的情况下在两页之间断开。
稳健方法
最简单的设置,无需hyperref
nor nameref
:
\documentclass{scrbook}
\usepackage[T1]{fontenc} % for the non-ASCII demo title
\usepackage{lmodern} % can be arbitrarily scaled
\usepackage{xcolor}
\makeatletter
\long\def\@my@extract@first@char#1\MyFirstChar#2#3\my@endTitle{#2}
\newcommand{\myExtractFirstChar}[2]{%
\edef#2{\unexpanded\expandafter{\@my@extract@first@char #1\my@endTitle}}%
}
\let\MyFirstChar\@firstofone
\makeatother
\renewcommand{\chapterlinesformat}[3]{%
\myExtractFirstChar{#3}{\MyExtractedFirstChar}%
\makebox(0,20)[l]{%
\hspace{-20pt}%
\fontsize{60}{6}\selectfont
\color{black!15!white}%
\MyExtractedFirstChar
}%
#3% <--------- don't forget!
}
\begin{document}
\chapter{\MyFirstChar{Œ}uvres complètes}
Here is some text.
\end{document}
如果您使用hyperref
或nameref
,则不是绝对必要的,但对于某些应用程序来说,明确地告诉标题中的命令并不重要可能会gettitlestring
更好\MyFirstChar
:
\documentclass{scrbook}
\usepackage[T1]{fontenc} % for the non-ASCII demo title
\usepackage{lmodern} % can be arbitrarily scaled
\usepackage{xcolor}
\usepackage[expand]{gettitlestring}
\usepackage{nameref}
\usepackage{hyperref}
\makeatletter
\long\def\@my@extract@first@char#1\MyFirstChar#2#3\my@endTitle{#2}
\newcommand{\myExtractFirstChar}[2]{%
\edef#2{\unexpanded\expandafter{\@my@extract@first@char #1\my@endTitle}}%
}
\let\MyFirstChar\@firstofone
\GetTitleStringDisableCommands{\let\MyFirstChar\@firstofone}
\makeatother
\renewcommand{\chapterlinesformat}[3]{%
\myExtractFirstChar{#3}{\MyExtractedFirstChar}%
\makebox(0,20)[l]{%
\hspace{-20pt}%
\fontsize{60}{6}\selectfont
\color{black!15!white}%
\MyExtractedFirstChar
}%
#3% <--------- don't forget!
}
\begin{document}
\chapter{\MyFirstChar{Œ}uvres complètes\label{chap}}
Here is some text. The chapter title is ``\nameref{chap}.''
% You need \usepackage{refcount} in order to test this.
%
% \edef\zzz{\unexpanded\expandafter\expandafter\expandafter{%
% \getrefbykeydefault{chap}{name}{dflt}}}%
% \show\zzz % > \zzz=macro:->Œuvres complètes.
\end{document}
左侧显示PDF书签:
更自动化但稳定性较差的解决方案
另一种解决问题的方法(但不太可靠)是使用简单的正则表达式来查找 的\chapterlinesformat
第三个参数中的第一个字母。下面定义的命令\myExtractFirstLetter
将其第二个参数本地赋值,但如果您愿意,可以轻松地将其设为全局赋值。
\documentclass{scrbook}
\usepackage{lmodern} % can be arbitrarily scaled
\usepackage{xcolor}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l__jendrik_match_seq
% The second argument must be a macro or expl3 token list variable
\NewDocumentCommand \myExtractFirstLetter { m m }
{
% The (?i) makes the [a-z] class case-insensitive
\regex_extract_once:nnNTF { (?i)[a-z] } {#1} \l__jendrik_match_seq
{ \seq_get_left:NN \l__jendrik_match_seq #2 }
{ \tl_clear:N #2 } % no match -> clear the #2 macro / tl var
}
\ExplSyntaxOff
\renewcommand{\chapterlinesformat}[3]{%
\myExtractFirstLetter{#3}{\myFirstLetter}%
\makebox(0,20)[l]{%
\hspace{-20pt}%
\fontsize{60}{6}\selectfont
\color{black!15!white}%
\myFirstLetter
}%
#3% <--------- don't forget!
}
\begin{document}
\chapter*{Digital Services of the University}
Here is some text.
\end{document}