Letra inicial do título do capítulo como fundo do título com KOMA-Script

Oct 14 2020

Estou tentando recriar o seguinte estilo para títulos de capítulo para scrbook.

Tentei implementar isso redefinindo \chapterlinesformate usando o pacote xstringpara extrair o primeiro caractere do título do capítulo. Consegui remendar o código abaixo, mas dá o seguinte erro:

mwe.tex|22 error| Missing number, treated as zero. 

Se substituirmos #3em \firstchar{#3}por um texto explícito, em seguida, o código funciona e dá o resultado desejado. Suspeito que o comando \firstcharnão funcione porque o argumento #3de \chapterlinesformatjá está formatado. Mas não sei como contornar esse problema, ou como abordar a tarefa de forma diferente.

\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}

A saída se substituída \firstchar{#3}por \firstchar{Digital Services of the University}:

Respostas

2 frougon Oct 14 2020 at 06:57

Se você inserir \showtokens{#3}no início do seu redefinido \chapterlinesformat, verá isso no terminal e no arquivo de log:

> \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}

Portanto, você #3não começa com a primeira letra do título porque o KOMA-Script inseriu um valor muito alto \interlinepenalty(10000) para garantir que o título não possa ser quebrado entre duas páginas sem o seu consentimento explícito.

Método robusto

Configuração mais simples sem hyperrefnem 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}

Se você usar hyperrefou nameref, não é estritamente necessário, mas pode ser melhor, para alguns aplicativos, dizer explicitamente gettitlestringque o \MyFirstCharcomando nos títulos não importa:

\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}

O lado esquerdo mostra o favorito do PDF:

Solução mais automática, mas menos robusta

Outra forma, porém menos robusta de resolver o problema, consiste em usar uma expressão regular simples para encontrar a primeira letra \chapterlinesformatdo terceiro argumento de. O comando \myExtractFirstLetter, definido abaixo, atribui seu segundo argumento localmente, mas isso pode ser facilmente tornado global se você preferir.

\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}

SimonDispa Oct 14 2020 at 21:35

Eu ofereço uma alternativa usando o xcoffinpacote que achei muito mais versátil para ajustes finos de páginas de título, estilos de capítulo e similares. Para simplificar (para mim), redefini o comando \ scr @@ makeschapterhead em vez de \ Chapterlinesformat.

1 Allocate the coffins. (\New ..). Coffins are boxes with handles!

2 Fill the coffins with the material. (\Set ...)

3 Assemble the coffins by joining them by the handles. (\Join...)

4 Write the result.(\Typeset ...)

O caixão chamado \ Framex de dimensões zero serve como uma `` estrutura de suporte '' para coletar todo o resto.

A escrita final é feita no ponto de inserção atual.

Explicações de alguma forma expandidas podem ser encontradas nas perguntas e respostas anteriores

Criar uma caixa usando o pacote tcolorbox ou qualquer outro? (imagem)

Posicione a imagem ao lado de um texto dentro de uma caixa de ajuste criada em um novo ambiente

\documentclass{scrbook}

\usepackage{xcolor}
\usepackage{xstring}
\usepackage{xcoffins}

\newcommand{\formatLetter}{\fontsize{60}{6}\selectfont\color{black!15!white}}

\NewCoffin\Framex
\NewCoffin\FirstLetter
\NewCoffin\ChapterName

%% debug guides
\NewCoffin\Hguidegreen
\SetHorizontalCoffin\Hguidegreen{\color{green}\rule{400pt}{0.2pt}}
\NewCoffin\Vguidered
\SetHorizontalCoffin\Vguidered{\color{red}\rule{0,2pt}{200pt}}

\makeatletter
\renewcommand*{\scr@@makeschapterhead}[2]{%
    \SetHorizontalCoffin\FirstLetter{\usekomafont{disposition}\formatLetter\StrChar{#2}{1}}%
    \JoinCoffins*\Framex[hc,vc]\FirstLetter[hc,vc]%
    % debug lines ************
    \JoinCoffins*\Framex[\FirstLetter-l,\FirstLetter-vc]\Hguidegreen[l,vc]% mid H guide debug
    \JoinCoffins*\Framex[\FirstLetter-hc,\FirstLetter-vc]\Vguidered[l,vc] % mid V guide debug
    % ************
    \SetHorizontalCoffin\ChapterName{\usekomafont{disposition}\usekomafont{#1}#2}%  
    \JoinCoffins*\Framex[\FirstLetter-hc,\FirstLetter-vc]\ChapterName[l,vc](0pt,-\CoffinDepth\ChapterName)% lower off center    
    \@tempskipa=\glueexpr \csname scr@#1@beforeskip\endcsname\relax\relax
    \csname scr@#1@afterindent\endcsname
    {\@afterindenttrue}{\@afterindentfalse}{%
        \ifdim\@tempskipa<\z@\@tempskipa-\@tempskipa\else
        \expandafter\ifnum\scr@v@is@ge{3.22}\@afterindenttrue\fi
        \fi
    }%
    \chapterheadstartvskip
    {%
        \let\IfUseNumber\@secondoftwo
        \ExecuteDoHook{heading/begingroup/#1}%
        \if@chapterprefix
        \let\IfUsePrefixLine\@firstoftwo
        \else
        \let\IfUsePrefixLine\@secondoftwo
        \fi
        \setlength{\parindent}{\z@}\setlength{\parfillskip}{\z@ plus 1fil}%
        \normalfont\usekomafont{disposition}{%
            \usekomafont{#1}{%
                \raggedchapter
                \IfUsePrefixLine{%
                    \chapterlineswithprefixformat{#1}%
                    {}%
                    {\interlinepenalty \@M\TypesetCoffin\Frame\@@par}%
                }{%
                    \chapterlinesformat{#1}%
                    {}%
%                   {\interlinepenalty \@M#2\@@par}%
                    {\interlinepenalty\@M\TypesetCoffin\Framex\@@par}%
                }%
            }%
        }%
        \ExecuteDoHook{heading/endgroup/#1}%
    }%
    \nobreak\par\nobreak
    \@tempskipa=\glueexpr \csname scr@#1@afterskip\endcsname\relax\relax
    \chapterheadendvskip
}
\makeatother

\begin{document}

\chapter*{Digital Services of the University}


Here is some text.

\end{document}

Para a versão final, é claro, os guias \ Join das linhas devem ser comentados.

Achei a xcoffinsolução muito segura e compatível com hyperrefoutros pacotes. É minha maneira preferida de lidar com estilos de capítulo porque torna muito fácil testar um protótipo e mostrar o resultado a outras pessoas. Apenas quatro etapas não intrusivas.

ATUALIZAÇÃO Este código obtém o mesmo resultado usando o comando\chapterlinesformat

\documentclass{scrbook} 
\usepackage{xcolor}
\usepackage{xstring}
\usepackage{xcoffins}

\newcommand{\formatLetter}{\fontsize{60}{6}\selectfont\color{black!15!white}}

\NewCoffin\Framex
\NewCoffin\FirstLetter
\NewCoffin\ChapterName

%% debug guides
\NewCoffin\Hguidegreen
\SetHorizontalCoffin\Hguidegreen{\color{green}\rule{400pt}{0.2pt}}
\NewCoffin\Vguidered
\SetHorizontalCoffin\Vguidered{\color{red}\rule{0,2pt}{200pt}}

\makeatletter
\renewcommand{\chapterlinesformat}[3]{%
\noexpandarg%
\StrBehind{#3}{\@M}[\mycpartbehind]%
\StrBefore{\mycpartbehind}{\@@par}[\mybefore]%
\expandarg% 
\StrLeft{\mycpartbehind}{1}[\firstcharx]%   
\SetHorizontalCoffin\FirstLetter{\usekomafont{disposition}\formatLetter\firstcharx}%
\JoinCoffins*\Framex[hc,vc]\FirstLetter[hc,vc]%
% debug lines ************
\JoinCoffins*\Framex[\FirstLetter-l,\FirstLetter-vc]\Hguidegreen[l,vc]% mid H guide debug
\JoinCoffins*\Framex[\FirstLetter-hc,\FirstLetter-vc]\Vguidered[l,vc] % mid V guide debug
% ************
\SetHorizontalCoffin\ChapterName{\usekomafont{disposition}\usekomafont{#1}#3}%  
\JoinCoffins*\Framex[\FirstLetter-hc,\FirstLetter-vc]\ChapterName[l,t](0pt,\CoffinDepth\ChapterName)% lower off center
\@hangfrom{#2}\noindent\TypesetCoffin\Framex(0pt,\CoffinDepth\ChapterName)
}
\makeatother    

\begin{document}

\chapter*{Digital Services of the University}

Here is some text.

\end{document}