A parte da versão A no exemplo a seguir é definida header/footer
por macros do pacote fancyhdr
.
Embora esta versão seja viável, é uma conquista estranha porque a mesma parte do código( \ifnum...
) é escrita duas vezes.
Exceto o argumento opcional nº 2, todos os outros códigos são exatamente iguais. Para melhorar, tentei a versão B abaixo, mas não funciona de jeito nenhum.
Será horrível, especialmente quando a mesma parte do código for grande.
Então, para resumir, existe uma maneira melhor de lidar com argumentos opcionais (estar lá ou não) para evitar código duplicado pesado.
\documentclass{article}
\usepackage{geometry,fancyhdr,xparse}
\geometry{showframe}
\begin{document}
first page\par\vspace{80em} second page
\pagestyle{fancy}
\fancyhf{}
%Version A: workable %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentCommand{\firstpage}{momm}{%
\IfNoValueTF{#2}
{#1{%
\ifnum\value{page}=1
#3% content of header/footer only at the first page
\else
#4% content of header/footer at the rest pages
\fi
}
}
{#1[#2]% the only diferrence between the two branches of \IfNoValueTF is, whether introducing the optional argument #2
{%
\ifnum\value{page}=1
#3% content of header/footer only at the first page
\else
#4% content of header/footer at the rest pages
\fi
}
}
}%\firstpage
% Test
\firstpage{\fancyhead}[c]{only at the first page}{at rest pages}
\firstpage{\rhead}{r first}{r rest}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Version B: not workable %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentCommand{\firstpageA}{momm}{%
#1 \IfNoValueTF{#2}{}{[#2]}
\ifnum\value{page}=1
#3% content of header/footer only at the first page
\else
#4% content of header/footer at the rest pages
\fi
}%\firstpageA
% Test
\firstpageA{\fancyhead}[c]{only at the first page}{at rest pages}
\firstpageA{\rhead}{r first}{r rest}
\end{document}
Responder1
Acredito que não seja útil tentar encaixar uma sintaxe estranha em um comando como esse.
É mais gratificante gastar um pouco mais de tempo desenvolvendo uma sintaxe mais amigável. Aqui eu proponho
\sethf{
head = <contents of all headers, except possibly the first>,
foot = <contents of all footers, except possibly the first>,
pos = <l|c|r>,
first = <possible exception for first header/footer>,
}
Apenas um entre head
ou foot
deve ser usado em uma chamada de \sethf
.
\documentclass{article}
\usepackage{fancyhdr,xparse}
\usepackage[paper=a6paper]{geometry} % smaller pictures
\usepackage{lipsum} % mock text
\pagestyle{fancy}
\fancyhf{}
\ExplSyntaxOn
\NewDocumentCommand{\sethf}{m}
{
\tl_clear:N \l__lyl_hf_pos_tl
\tl_clear:N \l__lyl_hf_first_tl
\tl_clear:N \l__lyl_hf_headfoot_tl
\keys_set:nn { lyl/hf } { #1 }
\lyl_hf_set:
}
\keys_define:nn { lyl/hf }
{
head .code:n = \__lyl_hf_aux:Nn \fancyhead { #1 },
foot .code:n = \__lyl_hf_aux:Nn \fancyfoot { #1 },
pos .tl_set:N = \l__lyl_hf_pos_tl,
first .tl_set:N = \l__lyl_hf_first_tl,
}
\tl_new:N \l__lyl_hf_headfoot_tl
\cs_new_protected:Nn \__lyl_hf_aux:Nn
{
\cs_set_eq:NN \__lyl_hf_temp:w #1
\tl_set:Nn \l__lyl_hf_headfoot_tl { #2 }
}
\cs_new_protected:Nn \lyl_hf_set:
{
\tl_if_empty:NT \l__lyl_hf_first_tl
{
\tl_set_eq:NN \l__lyl_hf_first_tl \l__lyl_hf_headfoot_tl
}
\__lyl_hf_set:NVVV
\__lyl_hf_temp:w % \fancyhead or \fancyfoot
\l__lyl_hf_pos_tl % position
\l__lyl_hf_first_tl % first page
\l__lyl_hf_headfoot_tl % other pages
}
\cs_new_protected:Nn \__lyl_hf_set:Nnnn
{
#1 [ #2 ] { \int_compare:nTF { \value{page} = 1 } { #3 } { #4 } }
}
\cs_generate_variant:Nn \__lyl_hf_set:Nnnn { NVVV }
\ExplSyntaxOff
\sethf{
head = other pages,
first = first page,
pos = c,
}
\sethf{pos = r, foot=\thepage}
\begin{document}
\lipsum[1-2]
\end{document}
Para responder sua pergunta: use uma macro para o código duplicado.
\documentclass{article}
\usepackage{fancyhdr,xparse}
\usepackage[paper=a6paper]{geometry} % smaller pictures
\usepackage{lipsum} % mock text
\pagestyle{fancy}
\fancyhf{}
\NewDocumentCommand{\firstpage}{momm}{%
\IfNoValueTF{#2}
{\setfirstpage{#1}{#3}{#4}}
{\setfirstpage{#1[#2]}{#3}{#4}}%
}
\NewDocumentCommand{\setfirstpage}{mmm}
{
#1{\ifnum\value{page}=1 #2\else #3\fi}
}
\firstpage{\fancyhead}[c]{first page}{other pages}
% can also be \firstpage{\chead}{first page}{other pages}
\begin{document}
\lipsum[1-2]
\end{document}
Vocêpodersubstitua a definição aqui por
\ExplSyntaxOn
\NewDocumentCommand{\firstpage}{momm}
{
\exp_last_unbraced:Nf #1 \IfNoValueTF{#2}{}{[#2]}
{
\int_compare:nTF { \value{page}=1 } { #3 } { #4 }
}
}
\ExplSyntaxOff
mas não é algo que eu faria sozinho. O código \IfNoValueTF{#2}{}{[#2]}
pode ser substituído de forma mais simples por \IfValueT{#2}{[#2]}
.
Responder2
Para o exemplo específico, simplesmente usar \thispagestyle
na primeira página provavelmente seria melhor, mas para a questão geral, você pode evitar a pré-digitalização dos argumentos até depois dos testes para argumentos opcionais, e uma macro auxiliar pode evitar a duplicação de código:
\documentclass{article}
\usepackage{geometry,fancyhdr,xparse}
\geometry{showframe}
\begin{document}
first page\par\vspace{80em} second page
\pagestyle{fancy}
\fancyhf{}
\def\fpageTF#1#2#3{#1{\ifnum\value{page}=1 #2\else #3\fi}}
\NewDocumentCommand{\firstpage}{mo}{%
\IfNoValueTF{#2}{\fpageTF{#1}}{\fpageTF{#1[#2]}}}
% Test
\firstpage{\fancyhead}[c]{only at the first page}{at rest pages}
\firstpage{\rhead}{r first}{r rest}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}