O código parece não ter efeito quando dentro do `iftoggle`

O código parece não ter efeito quando dentro do `iftoggle`

Emesseresposta Foi-me sugerido corrigir hyperrefo mecanismo automático de manipulação de metadados do pdfauthor da seguinte maneira. O objetivo é fazer com que os metadados do PDF funcionem com authblkvários autores.

\documentclass{article}
\usepackage[pdfusetitle]{hyperref}
\usepackage{authblk}
\usepackage{xpatch}

\newtoggle{patchhref}
\toggletrue{patchhref}
%\iftoggle{patchhref}{
    \xpretocmd{\author}{\addhrauthor{#2}}{}{}
    \newif\iffirstauthor
    \firstauthortrue
    \newcommand{\addhrauthor}[1]{%
        \iffirstauthor%
            \newcommand{\hrauthor}{#1}\firstauthorfalse%
        \else%
            \xapptocmd{\hrauthor}{, #1}{}{}%
        \fi
    }
    \AtEndDocument{
        \hypersetup{pdfauthor={\hrauthor}}
    }
%}{
%}

\begin{document}
\title{The title}
\author{Firstname 1 Lastname 1}
\author{Second author}
\affil{First affiliation\\
   \href{mailto:firstname.fastname@affiliation}{firstname.fastname@affiliation}
}
\author{Name3}
\affil{Second affiliation}

\maketitle
Content.

\end{document}

Eu adicionei a iftogglecoisa, não estava na resposta original. Quando não estiver usando iftoggle, funciona. Mas, ao usar iftoggle(descomente as três linhas relacionadas para experimentar), falha ao chegar ao final do documento com Undefined control sequence. <argument> \hrauthor. Como se os comandos que definem hrauthornão tivessem sido executados. Mas a parte sobre \AtEndDocumenté executada. De acordo comessecomentário, substituindo iftogglepor obras de construção legadas if.

Como posso fazer esse patch funcionar condicionalmente, usando iftoggle, opreferidomecanismo para alternância condicional?

Responder1

Isso não tem nada a ver em \iftogglesi, mas com códigos de categoria (catcodes). Quando o TeX escaneia um token pela primeira vez, seu código de categoria é "congelado", ou seja, o TeX lembra o que era quando foi lido pela primeira vez. No seu caso, o #é o culpado.

\iftoggle{patchhref}expande para algo equivalente a \@firstoftwoou \@secondoftwo:

\newcommand\@firstoftwo[2]{#1}
\newcommand\@secondoftwo[2]{#2}

Isso verifica os próximos dois grupos e remove o segundo. Todos os catcodes do primeiro grupo são congelados no processo. #geralmente tem código de categoria 6e é necessário algum cuidado ao corrigir comandos com #. \xpretocmdtenta cuidar disso, mas se #já tiver sido verificado, isso falhará.

Você pode contornar esse problema definindo

{\catcode`#=11\relax
    \gdef\fixauthor{\xpretocmd{\author}{\addhrauthor{#2}}{}{}}%
}

antes do seu \iftogglee substituindo a \xpatchcmdlinha por \fixauthor.

Responder2

Você não precisa definir \addrauthorna parte de alternância: você precisa escrever o código de qualquer maneira.

O problema de fazer o patch no argumento de um comando pode ser resolvido de várias maneiras, a mais simples é usar condicionais padrão.

Aqui sugiro uma versão mais fácil da \addhrauthormacro com expl3.

\documentclass{article}

\usepackage{xpatch,xparse}
\usepackage[pdfusetitle]{hyperref}
\usepackage{authblk}

\ExplSyntaxOn
\seq_new:N \g_oc_hrauthor_seq
\NewDocumentCommand{\addhrauthor}{m}
 {
  \seq_gput_right:Nn \g_oc_hrauthor_seq { #1 }
 }
\NewExpandableDocumentCommand{\hrauthor}{}
 {
  \seq_use:Nn \g_oc_hrauthor_seq {,~}
 }
\ExplSyntaxOff

\newif\ifpatchhref
%\patchhreftrue

\ifpatchhref
  \xpretocmd{\author}{\addhrauthor{#2}}{}{}
  \AtEndDocument{\hypersetup{pdfauthor={\hrauthor}}}
\fi


\begin{document}
\title{The title}
\author{Firstname 1 Lastname 1}
\author{Second author}
\affil{First affiliation\\
   \href{mailto:firstname.fastname@affiliation}{firstname.fastname@affiliation}
}
\author{Name3}
\affil{Second affiliation}

\maketitle
Content.

\end{document}

informação relacionada