Код, похоже, не имеет никакого эффекта внутри `iftoggle`

Код, похоже, не имеет никакого эффекта внутри `iftoggle`

Вэтотответ Мне предложили пропатчить hyperrefмеханизм автоматической обработки метаданных pdfauthor следующим образом. Цель состоит в том, чтобы метаданные PDF работали с authblkнесколькими авторами.

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

Я добавил эту iftoggleвещь, ее не было в исходном ответе. Когда не используется iftoggle, это работает. Но при использовании iftoggle(раскомментируйте три связанные строки, чтобы попробовать), это дает сбой при достижении конца документа с Undefined control sequence. <argument> \hrauthor. Как будто команды, которые определяют, hrauthorне были выполнены. Но часть about \AtEndDocumentвыполняется. Согласноэтоткомментарий, замена iftoggleустаревшими ifконструкциями.

Как мне заставить этот патч работать условно, используя iftoggle,предпочитаемыймеханизм условного переключения?

решение1

Это не имеет ничего общего с \iftoggleper se, а с кодами категорий (catcodes). Когда TeX сканирует токен в первый раз, его код категории "замораживается", т. е. TeX помнит, каким он был, когда был прочитан впервые. В вашем случае виновником #является .

\iftoggle{patchhref}расширяется до чего-то эквивалентного \@firstoftwoили \@secondoftwo:

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

Это сканирует следующие две группы и удаляет вторую. Все catcodes в первой группе замораживаются в процессе. #обычно имеет код категории 6и требуется некоторая осторожность при исправлении команд с помощью #. \xpretocmdпытается позаботиться об этом, но если #уже был просканирован, это не удается.

Эту проблему можно обойти, определив

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

перед вашим \iftoggleи заменив \xpatchcmdстроку на \fixauthor.

решение2

Вам не нужно определять \addrauthorв части переключения: вам в любом случае придется написать код.

Проблему с внесением исправлений в аргумент команды можно решить разными способами, самый простой из которых — использование стандартных условных операторов.

Здесь я предлагаю более простую версию макроса \addhrauthorс 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}

Связанный контент