我将简单解释一下背景,以便可以更简单地解决这个问题,但我仍然对实际问题的答案感兴趣。
我的章节标题很窄,而且使用大字体,所以可能会出现必须断开的情况。我想不惜一切代价防止单词连字符,所以我想我可以简单地将标题内的所有单个单词包装到\mbox
es 中。这将导致插入换行符之间单词,而不是单词内部的单词。
但当然,我不想改变我对 的使用\chapter
。也就是说,我不是想写\chapter{\mbox{Some} \mbox{chapter}}
。相反,我想通过重新定义\chapter
(好吧,[explicit]titlesec
实际上使用)来处理这个问题。
我的想法是创建一个列表解析器,使用etoolbox
空格分隔单词并将单词包装在 mbox 中。从概念上讲,这非常简单:
\newcommand*\mboxed[1]{%
\let\do\mbox
\DeclareListParser{\dospacelist}{ }
\dospacelist#1}
\titleformat{\chapter}
{\sffamily\Huge}
{\thechapter\ }
{0pt}
{\mboxed{#1}}
不出所料,这不起作用。我也尝试在mboxed
组内的命令中将空间的 catcode 更改为 11,但这也不起作用。
它甚至可能的用 (La)TeX编写mboxed
宏?它应该是什么样子?
难度增加(加分项):标题本身也可以包含宏,例如,我的其中一章定义为
\chapter{{\texorpdfstring{\cpp}{C++}}
... 因为该\cpp
命令(字符串“C++”的漂亮打印版本)在 PDF 标签中不起作用。
答案1
基于\zap@space
中的宏source2e
。它使用\fbox
而不是\hbox
来进行演示。
\documentclass{book}
\usepackage[explicit]{titlesec}
\usepackage{hyperref}
\def\cpp{C++}
\titleformat{\chapter}
{\sffamily\Huge}
{\thechapter\ }
{0pt}
{\mboxed{#1}}
\makeatletter
\def\mboxed#1{%
\@mboxed#1 \@empty
}
\def\@mboxed#1 #2{%
\fbox{#1}\space % fbox here to have a visual test
\ifx #2\@empty\else
\expandafter\@mboxed
\fi
#2%
}
%\let\orig@chapter\chapter
%\renewcommand*{\chapter}[2][]{%
% \orig@chapter[#1]{\mboxed{#2}}%
%}%
\makeatother
\begin{document}
\chapter{The Test of the code}
\mboxed{This should be tested}
\chapter{I like to thank you for this easy question}
\chapter{Also works with macros like \texorpdfstring{\cpp}{C++} very well}
\chapter{More difficult stuff should be wrapped in double braces {{A\empty{} B}} to hide the spaces!}
\end{document}
答案2
根据 Caramdir 的评论提到TeX 常见问题解答,以下解决了我的特定问题:
\titleformat{\chapter}
{\sffamily\Huge}
{\thechapter\ }
{0pt}
{\begingroup%
\parbox[b]{\textwidth}{%
\hyphenpenalty=10000%
\exhyphenpenalty=10000%
#1}%
\endgroup}
不过,我仍然对空格分隔列表解析的解决方案感兴趣。