% Author: Nelson Lago
% This file is distributed under the MIT Licence

\ProvidesPackage{imeusp-headers}[2020/01/30 2.1 Running headers, IME/USP style]

% Há duas packages para a configuração dos cabeçalhos/rodapés:
% fancyhdr, a mais tradicional e mais usada, e titleps, que é
% um pouco mais moderna. Esta classe tem dois códigos completos
% para a implementação dos cabeçalhos que queremos, cada um
% utilizando uma das packages. Por padrão, usamos fancyhdr,
% mas o código com titleps está aqui caso haja alguma vantagem
% em migrar para ele. Observe que, nesse caso, o valor de
% headsep de geometry deve ser mudado de 11mm para 12.5mm.

\RequirePackage{etoolbox}

\newbool{UseFancyhdr}
\booltrue{UseFancyhdr}

\DeclareOption{titleps}{
    \boolfalse{UseFancyhdr}
}

\ProcessOptions

\ifUseFancyhdr % implementação com fancyhdr

\RequirePackage{fancyhdr}

% A formatação dos cabeçalhos/rodapés envolve duas coisas:
%
% 1. Definir qual texto deve ser impresso em cada página (nome
%    do capítulo ou seção, nome do autor, número da página etc.)
%
% 2. Imprimir esse texto no lugar correto (esquerda, direita ou
%    centro, cabeçalho ou rodapé)
%
% A definição do texto a imprimir é complexa, pois a preparação dos
% cabeçalhos/rodapés acontece de maneira independente da construção do
% restante da página. Textos fixos como, digamos, o nome do livro ou
% do seu autor, não trazem dificuldades. Já textos variáveis, como o
% nome do capítulo ou seção, o número da página etc. envolvem a
% passagem de informações sobre a página atual para o mecanismo de
% construção dos cabeçalhos.
%
% Isso é feito através de "variáveis" especiais chamadas "marks". O uso
% mais comum das marks é armazenar o nome do capítulo e da seção atuais:
% a cada novo capítulo ou seção, os comandos \chaptermark e \sectionmark
% são executados (isso é automático, você não precisa fazer nada); esses
% comandos definem uma "mark" com o nome do capítulo/seção a ser usado
% nos cabeçalhos/rodapés. Assim, modificando a definição dos comandos
% \chaptermark e \sectionmark, é possível modificar o texto a ser
% incluído nos cabeçalhos/rodapés.
%
% Definido o conteúdo das marks, o lugar em que cada texto é impresso
% é definido com os comandos \fancyhead e \fancyfoot. "RO" significa
% "Right side of Odd pages"; "LE" significa "Left side of Even pages" etc.
%
% LaTeX por padrão tem duas "marks": "\leftmark" e "\rightmark". Elas
% têm esses nomes porque originalmente eram usadas para armazenar o
% conteúdo a ser impresso nas páginas pares e ímpares. Isso, no entanto,
% não é obrigatório; a escolha desses nomes foi bastante infeliz. Para
% definir o conteúdo dessas marks, usam-se os comandos \markboth{A}{B}
% (define \leftmark como A e \rightmark como B) e \markright{C} (define
% \rightmark como C). Não há o comando \markleft.
%
% O procedimento de definição dos cabeçalhos e rodapés, portanto, envolve:
%
% 1. Redefinir \chaptermark e \sectionmark (ambas recebem um parâmetro,
%    que é o nome do capítulo/seção) para fazê-los executar \markboth e
%    \markright, inserindo o conteúdo desejado nas marks;
%
% 2. Usar \fancyhead e \fancyfoot para definir os cabeçalhos e rodapés
%    usando o conteúdo de \leftmark e \rightmark.
%
% Além das marks, é possível usar também as variáveis \thepage (número
% da página), \thechapter (número do capítulo) e \thesection (número da
% seção).
%
% Neste modelo, modificamos chaptermark e sectionmark para armazenar
% o número e nome do capítulo em leftmark e o número e nome da seção
% em rightmark. MAS imprimimos rightmark nas páginas pares (esquerda)
% e leftmark nas páginas ímpares (direita)!


%%%%%%%%%%

% Sem linha separando o cabeçalho
\renewcommand{\headrulewidth}{0pt}

% Queremos colocar o número da página mais próximo da borda do papel (na
% horizontal). Para isso, vamos aumentar \headwidth, somando "tamanho da
% margem direita -10mm" (o número vai ficar a 10mm da borda).
%
% Observe que a package geometry define \evensidemargin, mas seu valor não
% necessariamente corresponde ao que queremos aqui (não sei bem como nem
% por que geometry define esse valor). Ao invés de usá-lo, vamos calcular
% manualmente.
%
% A distância entre a borda esquerda/interna do papel e o início do texto
% é dada por (1in + \hoffset + \oddsidemargin); a margem direita, portanto,
% é dada por (\paperwidth - (1in + \hoffset + \oddsidemargin + \textwidth)).
\dimdef{\othermargin}{\paperwidth - 1in - \hoffset - \oddsidemargin - \textwidth}
\addtolength{\headwidth}{\othermargin}
\addtolength{\headwidth}{-10mm}

\newcommand{\formataNumPaginas}{
  \fancyhead[RO]{\raisebox{8mm}{\footnotesize\bfseries\thepage}}
  \fancyhead[LE]{\raisebox{8mm}{\footnotesize\bfseries\thepage}}
}

\newcommand{\formataCabecalhosDinamicos}{
  \fancyhead[LO]{\scriptsize\MakeTextUppercase{\rightmark}}
  \fancyhead[RE]{\scriptsize\MakeTextUppercase{\leftmark}}
}

\fancypagestyle{mainmatter}{
  % Número e nome do capítulo no cabeçalho das páginas pares
  % (e nas ímpares quando não há seções)
  \renewcommand{\chaptermark}[1]{
    \markboth
      {\thechapter\hskip 0.3em |\hskip 0.3em ##1}
      {\thechapter\hskip 0.3em |\hskip 0.3em ##1}
  }

  % Número e nome da seção no cabeçalho das páginas ímpares
  \renewcommand{\sectionmark}[1]{
    \markright{\thesection\hskip 0.3em |\hskip 0.3em ##1}
  }

  \fancyhf{}
  \formataNumPaginas{}
  \formataCabecalhosDinamicos{}
}

% Formato para capítulos não-numerados mas que devem
% aparecer no sumário (tipicamente, a introdução):
\fancypagestyle{onlynames}{
  % Só o nome do capítulo/seção, sem numeração
  \renewcommand{\chaptermark}[1]{\markboth{##1}{##1}}
  \renewcommand{\sectionmark}[1]{\markright{##1}}

  \fancyhf{}
  \formataNumPaginas{}
  \formataCabecalhosDinamicos{}
}

\fancypagestyle{appendix}{
  \renewcommand{\chaptermark}[1]{%
    \markboth{%
      % Páginas ímpares: "Apêndice/Anexo X"
      \@chapapp\ \thechapter%
    }{%
      % Páginas pares: "X | nome do apêndice/anexo"
      \thechapter\hskip 0.3em |\hskip 0.3em ##1%
    }
  }

  \fancyhf{}
  \formataNumPaginas{}
  \formataCabecalhosDinamicos{}
}

% Na frontmatter e backmatter, não há números de capítulos e (em geral)
% não há subdivisões (capítulos/seções/subseções), apenas um nível.
% O correto, então, é usar o mesmo texto (nome do capítulo ou seção,
% sem número) nas páginas pares ou ímpares.
%
% Normalmente, a bibliografia e o índice remissivo não definem os
% cabeçalhos (não executam "chaptermark/sectionmark"), mas "forçamos"
% isso manualmente (em bibconfig.tex e index.tex).
\fancypagestyle{backmatter}{
  \renewcommand{\chaptermark}[1]{\markboth{##1}{##1}}
  \renewcommand{\sectionmark}[1]{\markboth{##1}{##1}}

  \fancyhf{}
  \formataNumPaginas{}
  \formataCabecalhosDinamicos{}
}

% A página inicial de cada capítulo é automaticamente configurada para o estilo
% "plain", então vamos definir esse estilo (colocando o número de página no
% mesmo lugar das demais). As páginas iniciais também usam esse estilo.
\fancypagestyle{plain}{
  \fancyhf{}
  \formataNumPaginas{}
}

\else % implementação desabilitada com titleps

% Se você está usando a package titlesec, ela deve ser carregada
% *antes* desta package e deve incluir a opção pagestyles.
\@ifpackageloaded{titlesec}
  {
      \@ifpackagewith{titlesec}{pagestyles}
	  {} % all set!
          { % pagestyles option missing

            \PackageError{imeusp-headers}
              {
                \MessageBreak
                \MessageBreak
                \MessageBreak
                Para usar esta package com a opcao\MessageBreak
                titleps em conjunto com a package\MessageBreak
                titlesec, titlesec deve ser carregada\MessageBreak
                *antes* desta e deve incluir a opcao\MessageBreak
                pagestyles\MessageBreak
                \MessageBreak
              }
              {
                \MessageBreak
                Nao ha como continuar sem remover\MessageBreak
                a opcao titleps desta package ou\MessageBreak
                acrescentar a opcao pagestyles\MessageBreak
                para titlesec\MessageBreak
                \MessageBreak
              }
              \stop
          }
  }
  {\RequirePackage{titleps}} % no titlesec loaded, use titleps


% Queremos colocar o número da página mais próximo da borda do papel (na
% horizontal). Para isso, vamos aumentar a largura do cabeçalho, somando
% "tamanho da margem direita -10mm" (o número vai ficar a 10mm da borda).
%
% Observe que a package geometry define \evensidemargin, mas seu valor não
% necessariamente corresponde ao que queremos aqui (não sei bem como nem
% por que geometry define esse valor). Ao invés de usá-lo, vamos calcular
% manualmente.
%
% A distância entre a borda esquerda/interna do papel e o início do texto
% é dada por (1in + \hoffset + \oddsidemargin); a margem direita, portanto,
% é dada por (\paperwidth - (1in + \hoffset + \oddsidemargin + \textwidth)).
\dimdef{\IHstretch}{\paperwidth - 1in - \hoffset - \oddsidemargin - \textwidth -10mm}

% WTF 9pt? Não sei, mas precisei acrescentar para acertar o alinhamento...
\widenhead[\IHstretch + 9pt][0pt]{9pt}{\IHstretch}


%%%%% Conteúdo dos cabeçalhos %%%%%

% Números de páginas
\newrobustcmd\IHpgnum{\raisebox{8mm}{\footnotesize\bfseries\thepage}}

% Formata "X | título do capítulo" e "X.X | título da seção"
\newrobustcmd\IHformat[2]{\MakeTextUppercase{#1\hskip 0.3em |\hskip 0.3em #2}}

% Número e nome do capítulo
\newrobustcmd\IHchap{\IHformat{\thechapter}{\chaptertitle}}

% Número e nome da seção (ou do capítulo se não houver seção)
\newrobustcmd\IHsec{%
    \ifdefvoid{\thesection}
      {\IHchap}
      {\IHformat{\thesection}{\sectiontitle}}%
}

% "Apêndice X" / "Anexo X"
\newrobustcmd\IHapp{\MakeTextUppercase{\@chapapp\ \thechapter}}

% "Bibliografia", "Índice Remissivo" e
% capítulos não-numerados (Introdução)
\newrobustcmd\IHbarechap{\MakeTextUppercase{\chaptertitle}}
\newrobustcmd\IHbaresect{\MakeTextUppercase{\sectiontitle}}

%%%%% Formato dos cabeçalhos %%%%%

% Formato padrão:
%
% Números de página na borda externa,
% número e nome do capítulo nas páginas pares,
% número e nome da seção nas páginas ímpares
\newpagestyle{mainmatter}[\scriptsize]{
  \sethead
      % even-left even-center even-right
      [\IHpgnum][][\IHchap]
      % odd-left odd-center odd-right
      {\IHsec}{}{\IHpgnum}
}

% A página inicial de cada capítulo é automaticamente configurada para o estilo
% "plain", então vamos definir esse estilo (colocando o número de página no
% mesmo lugar das demais). As páginas iniciais também usam esse estilo.
\renewpagestyle{plain}[\scriptsize]{
  \sethead
      % even-left even-center even-right
      [\IHpgnum][][]
      % odd-left odd-center odd-right
      {}{}{\IHpgnum}
}

% Formato para capítulos não-numerados mas que devem
% aparecer no sumário (tipicamente, a introdução):
% Só o nome do capítulo/seção, sem numeração.
\newpagestyle{onlynames}[\scriptsize]{
  \sethead
      % even-left even-center even-right
      [\IHpgnum][][\IHbarechap]
      % odd-left odd-center odd-right
      {\IHbaresect}{}{\IHpgnum}
}

% Formato dos apêndices/anexos:
%
% "Apêndice X" / "Anexo X" nas páginas pares,
% letra e nome do apêndice/anexo nas páginas ímpares
\newpagestyle{appendix}[\scriptsize]{
  \sethead
      % even-left even-center even-right
      [\IHpgnum][][\IHapp]
      % odd-left odd-center odd-right
      {\IHchap}{}{\IHpgnum}
}

% Formato da bibliografia e índice remissivo:
%
% Na frontmatter e backmatter, não há números de capítulos e (em geral)
% não há subdivisões (capítulos/seções/subseções), apenas um nível.
% O correto, então, é usar o mesmo texto (nome do capítulo ou seção,
% sem número) nas páginas pares ou ímpares.
%
% Normalmente, a bibliografia e o índice remissivo não definem os
% cabeçalhos (não executam "chaptermark/sectionmark"), mas "forçamos"
% isso manualmente (em bibconfig.tex e index.tex).
\newpagestyle{backmatter}[\scriptsize]{
  \sethead
      % even-left even-center even-right
      [\IHpgnum][][\IHbarechap]
      % odd-left odd-center odd-right
      {\IHbarechap}{}{\IHpgnum}
}

\fi

\endinput
