使用自定义章节命令时章节标题出现换行问题

使用自定义章节命令时章节标题出现换行问题

如果您必须强制在章节标题中换行,可以这样做:

\chapter[][A Long title that has to be broken,\\ how sad is this!]

但在我的文档中我必须定义自己的章节命令,以便有章节作者和副标题:

\newcommand\Chapter[3][]{%
  % Last char of the title 
  \StrRight{#2}{1}[\lastchar]%
  % Put to \
  \chapter[#2%
    % We want a point in the ToC between title and subtitle
    \if\relax\detokenize{#3}\relax%
    \else%
      % But not if there is a ?
      \if\lastchar? %
      \else%
        % Or a !
        \if\lastchar! %
        % If not set a point        
        \else%
        . %
        \fi%
      \fi%
    \fi%
  #3]{#2\\[2ex]\Large\Large#3}
  \chaptermark]{\markboth{%
  \if\relax\detokenize{#1}\relax  #2%
  \else  #1\fi }{}%  
}}

这按预期工作,但没有换行符:

\Chapter[A Long title]{A Long title that has to be broken,\\ how sad is this!}{Some boring subtitles} 

随着换行我收到一个错误:

! Paragraph ended before \@firstoftwo was complete.
<to be read again>
\par
l.2 ...how sad is this!}{}
I suspect you've forgotten a `}', causing me to apply this

但是,换行符可以正常工作,但在之前的页面上,换行符后的部分出现在额外的页面上。我做错了什么?

这是一个完整的工作示例:

\documentclass[10pt,twoside]{memoir}
\usepackage{xstring}

\usepackage{fontspec}
\usepackage{xltxtra}

\newcommand{\chapterauthor}

\renewcommand*{\cftchapterdotsep}{\cftdotsep}
\settocdepth{chapter}
\renewcommand{\cftchapterfont}{\normalfont}
\renewcommand{\cftchapterpagefont}{\normalfont}

\makeatletter
\DeclareRobustCommand\authortoctext[1]{%
{\addvspace{10pt}\nopagebreak\setlength{\parindent}{0em}\relax
\rightskip \@tocrmarg\relax
\itshape#1\par\addvspace{-7pt}}}
\makeatother
\newcommand\authortoc[1]{\needspace{3\baselineskip}%
  \gdef\chapterauthor{#1}%
  \addtocontents{toc}{\authortoctext{%
    \needspace{2\baselineskip}%   Vgl. http://tex.stackexchange.com/questions/134016
#1}}}


\renewcommand{\afterchaptertitle}{%

\vskip\onelineskip\begin{large}\normalfont\textit{\Large\chapterauthor}\end{large}
\vspace{4ex}
\vskip\onelineskip}

\newcommand\testchain[1]{%
  \StrRight{#1}{1}[\lastchar]%
  \IfStrEq{\lastchar}{?}{false}{true}%
}


\newcommand\Chapter[3][]{%
  % Last char of the title 
  \StrRight{#2}{1}[\lastchar]%
  % Put to \
  \chapter[#2%
    % We want a point in the ToC between title and subtitle
    \if\relax\detokenize{#3}\relax%
    \else%
      % But not if there is a ?
      \if\lastchar? %
      \else%
        % Or a !
        \if\lastchar! %
        % If not set a point        
        \else%
        . %
        \fi%
      \fi%
    \fi%
  #3]{#2\\[2ex]\Large\Large#3}
  \chaptermark]{\markboth{%
  \if\relax\detokenize{#1}\relax  #2%
  \else  #1\fi }{}%  
}}


\begin{document}
\tableofcontents*


   \Chapter[A Long title]{A Long title that has to be broken,\\ how sad is this!}{Some boring subtitles}
    \end{document}

答案1

一种可能性:使用

% settings to redefine \newline and then recover its original meaning
\let\oldnewline\newline
% redefinition: \newline is \relax
\newcommand\AnnCL{%
  \def\newline{\relax}}
% recovering the original meaning of \newline
\newcommand\RecCL{%
  \def\newline{\oldnewline}}

我定义了两个命令\AnnCL和,\RecCL将 重新定义\newline\relax,然后恢复其原始含义。在 的定义中的适当位置使用这些命令,您现在可以在 的第一个强制参数中\Chapter使用。文档正文中将出现换行符,但目录中不会出现任何效果。\newline\Chapter

\documentclass[10pt,twoside]{memoir}
\usepackage{xstring}

\newcommand{\chapterauthor}

\renewcommand*{\cftchapterdotsep}{\cftdotsep}
\settocdepth{chapter}
\renewcommand{\cftchapterfont}{\normalfont}
\renewcommand{\cftchapterpagefont}{\normalfont}

\makeatletter
\DeclareRobustCommand\authortoctext[1]{%
{\addvspace{10pt}\nopagebreak\setlength{\parindent}{0em}\relax
\rightskip \@tocrmarg\relax
\itshape#1\par\addvspace{-7pt}}}
\makeatother
\newcommand\authortoc[1]{\needspace{3\baselineskip}%
  \gdef\chapterauthor{#1}%
  \addtocontents{toc}{\authortoctext{%
    \needspace{2\baselineskip}%   Vgl. http://tex.stackexchange.com/questions/134016
#1}}}


\renewcommand{\afterchaptertitle}{%

\vskip\onelineskip\begin{large}\normalfont\textit{\Large\chapterauthor}\end{large}
\vspace{4ex}
\vskip\onelineskip}

\newcommand\testchain[1]{%
  \StrRight{#1}{1}[\lastchar]%
  \IfStrEq{\lastchar}{?}{false}{true}%
}

% settings to redefine \newline and then recover its original meaning
\let\oldnewline\newline
% redefinition: \newline is \relax
\newcommand\AnnCL{%
  \def\newline{\relax}}
% recovering the original meaning of \newline
\newcommand\RecCL{%
  \def\newline{\oldnewline}}

\newcommand\Chapter[3][]{\AnnCL%
  % Last char of the title 
  \StrRight{#2}{1}[\lastchar]%
  % Put to \
  %
  \chapter[#2%
    % We want a point in the ToC between title and subtitle
    \if\relax\detokenize{#3}\relax%
    \else%
      % But not if there is a ?
      \if\lastchar? %
      \else%
        % Or a !
        \if\lastchar! %
        % If not set a point        
        \else%
        .%
        \fi%
      \fi%
    \fi%
  #3]{\RecCL#2\\[2ex]\Large\Large#3}
  \chaptermark]{\markboth{%
  \if\relax\detokenize{#1}\relax  #2%
  \else  #1\fi }{}%  
}\RecCL}

\begin{document}
\tableofcontents*

\Chapter[A Long title]{A Long title that has to be\newline broken,  how sad is this!}{Some boring subtitles}

\end{document}

目录图片:

在此处输入图片描述

包含章节标题的页面图像:

在此处输入图片描述

答案2

您的问题是\StrRight尝试充分扩展论点但\\未能成功。

如果你还想在目录中换行,那么说

\newcommand\Chapter[3][]{%
  % Last char of the title
  \saveexpandmode\noexpandarg
  \StrRight{#2}{1}[\lastchar]%
  \restoreexpandmode
  % Put to \
  \chapter[#2%
  <...the rest is the same...>

解决了您的问题。否则,只需将其定义\?为文本中的换行符,并在目录中将其本地定义为无操作:

\protected\def\?{\\}

并说

\begingroup\let\?\relax
\tableofcontents*
\endgroup

\Chapter[A Long title]
  {A Long title that has to be broken,\? how sad is this!}
  {Some boring subtitles}

无论如何我都会坚持\noexpandarg这样做\StrRight

相关内容