# Expl3' tl variable storing the result of a \seq_map_inline: OK in article's title but not in beamer's title

As pointed out by the following MCE, an expl3' token list variable storing the result of a \seq_map_inline: used in \title's argument:

• works like a charm with the article class,
• doesn't work with the beamer class:

      ! Undefined control sequence.
<argument> \LaTeX3 error:
A sequence was misused.


Do you know why and how to make it work with beamer's class as well?

% \documentclass{article}
\documentclass{beamer}
\usepackage{xparse}
\ExplSyntaxOn
\seq_gset_from_clist:Nn \g_tmpa_seq { foo, bar }
\tl_set:Nn \g_tmpa_tl
{
\seq_map_inline:Nn \g_tmpa_seq
{
#1,\c_space_tl
}
}
\title{\g_tmpa_tl}
\ExplSyntaxOff
\begin{document}
\maketitle
\end{document}


## Edit: aim that led me to the current question (and its simplified MCE)

For a course I'm giving, I prepare some presentations with the beamer class (BTW, what follows could apply to any class). The content of the whole course is splitted in several subjects (one file per subject) that are \input. The subjects (titles)/corresponding files that may be treated are (say):

• "Foo 1"/foo1.tex
• "Foo 2"/foo2.tex
• "Foo 3"/foo3.tex
• "Foo 4"/foo4.tex
• "Foo 5"/foo5.tex

The presentations' contents (chosen subjects) varies depending on the audience and/or on the course progress.

The point is, I want for a given presentation the chosen subjects' titles to appear in the presentation's \title.

Suppose the current presentation is about "Foo 2" and "Foo 4". I could do the following:

\documentclass{beamer}
...
\title{
% Foo 1,
Foo 2,
% Foo 3,
Foo 4
% Foo 5,
}
\begin{document}
\maketitle
% \input{foo1}
\input{foo2}
% \input{foo3}
\input{foo4}
% \input{foo5}
\end{document}


but this way of doing is painful and error prone: whenever the list of \inputed files changes, I have to (not forget to) change the \title's content.

Note having the subjects' titles in the corresponding files is useless: they would be too late read to be in the presentation's \title (okay, another way of doing would be to write them in the .aux file and read them at the next compilation when the \title has to be filled, but that's another story).

So, what I am aiming, is to have :

• a fixed property list (say \g_subjects_prop) containing the whole list of the subjects with, for each of them:
• as key: the name of the corresponding file,
• as value: its title. This list could be populated in a config file thanks to a document command (say SubjectFileTitle{⟨filename⟩}{⟨title⟩}),
• a sequence (say \g_chosen_subjects_seq) containing the keys of the chosen subjects. This sequence could be populated in the preamble thanks to a document command (say ChosenSubjects{⟨comma separated list of keys (files)⟩}),
• a token list (say \g_title_tl, instead of \l_tmpa_tl(?)) containing the values corresponding to the chosen keys above to be passed as \title's argument,
• a document command (say \InputChosenSubjects) which, where used, inserts the sequence of the \inputed chosen files.

Thanks to egreg's answer, I managed with the following code:

\begin{filecontents*}{foo2}
\begin{frame}
\frametitle{Foo 2 subject: quite interesting!}
...
\end{frame}
\end{filecontents*}

\documentclass{beamer}
\usepackage{xparse}

\ExplSyntaxOn

\prop_new:N \g_subjects_prop
\seq_new:N \g_chosen_subjects_seq
\tl_new:N \g_title_tl

\NewDocumentCommand{\SubjectFileTitle}{mm}
{
\prop_gput:Nnn \g_subjects_prop {#1} {#2}
}

\cs_new_protected:Npn \__chosen_subjects:n #1
{
\seq_gset_from_clist:Nn \g_chosen_subjects_seq {
#1
}
\seq_map_inline:Nn \g_chosen_subjects_seq
{
\prop_get:NnN \g_subjects_prop {##1} \l_tmpa_tl
\tl_if_empty:NF \l_tmpa_tl {
\seq_put_right:Nn \g_tmpa_seq {\prop_item:Nn \g_subjects_prop {##1}}
}
}
\tl_gset:Nx \g_title_tl
{
\seq_use:Nn \g_tmpa_seq {,~}
}
\title{\g_title_tl}
}

\NewDocumentCommand{\ChosenSubjects}{m}
{
\__chosen_subjects:n {#1}
}

\cs_new_protected:Npn \__input_chosen_subjects_files:
{
\seq_map_inline:Nn \g_chosen_subjects_seq
{
\par
\file_if_exist_input:nF {##1}{%
\begin{frame}
\end{frame}
}
}
}

\NewDocumentCommand{\InputChosenSubjects}{}{
\__input_chosen_subjects_files:
}

\ExplSyntaxOff

\SubjectFileTitle{foo1}{Foo 1}
\SubjectFileTitle{foo2}{Foo 2}
\SubjectFileTitle{foo3}{Foo 3}
\SubjectFileTitle{foo4}{Foo 4}
\SubjectFileTitle{foo5}{Foo 5}

\ChosenSubjects{
% foo1,
foo2,
% foo3,
foo4,
% foo5,
}

\begin{document}
\maketitle{}
\InputChosenSubjects
\end{document}

• In beamer the title argument is being stored in \inserttitle, but that value is also being fed to \hypersetup{pdftitle={...} could that be the culprit? Emulating storing in a macro and using it, does not seem to cause problems, but I haven't tested hypersetup May 7, 2019 at 8:04
• It IS a hyperref error, in a article variant add hyperref and \newcommand\test[1]{\def\inserttest{#1}}\test{\g_tmpa_tl} and try \hypersetup{pdftitle=\inserttest}, this gies the same error May 7, 2019 at 8:17

You are asking TeX do perform \seq_map_inline:Nn while processing \maketitle. More likely, you want \maketitle to print the list of words separated by “comma and space”. In order to do this, use \tl_gset:Nx and \seq_use:Nn.

\documentclass{beamer}
\usepackage{xparse}

\ExplSyntaxOn
\seq_gset_from_clist:Nn \g_tmpa_seq { foo, bar }
\tl_gset:Nx \g_tmpa_tl
{
\seq_use:Nn \g_tmpa_seq {,~}
}
\exp_args:NV \title \g_tmpa_tl
\ExplSyntaxOff

\begin{document}
\maketitle
\end{document}


I'd note that \g_tmpa_tl is not the proper variable to use, but I believe it is just for the sake of the example.

Here's an edited version of your code. I renamed functions and variables giving a common prefix. Most importantly, I fixed a glitch: if a property doesn't exist in a prop variable, then

\prop_get:NnN <prop variable> {<property>} <tl variable>


sets the token list variable to \q_no_value, rather than to “empty”. So the test to use is \quark_if_no_value:NF.

Also, instead of calling \title{\g_pres_title_tl}, I'd prefer

\exp_args:NV \title \g_pres_title_tl


so the contents of the variable is passed to \title, rather than the container.

\begin{filecontents*}{foo2}
\begin{frame}
\frametitle{Foo 2 subject: quite interesting!}
...
\end{frame}
\end{filecontents*}

\documentclass{beamer}
\usepackage{xparse}

\ExplSyntaxOn

%% variables
\prop_new:N \g_pres_subjects_prop
\seq_new:N \g_pres_subjects_chosen_seq
\tl_new:N \g_pres_title_tl

%% User level commands
\NewDocumentCommand{\SubjectFileTitle}{mm}
{
\prop_gput:Nnn \g_pres_subjects_prop {#1} {#2}
}

\NewDocumentCommand{\ChosenSubjects}{m}
{
\pres_subjects_choose:n {#1}
}

\NewDocumentCommand{\InputChosenSubjects}{}
{
\pres_input_chosen_subjects_files:
}

%% functions
\cs_new_protected:Npn \pres_subjects_choose:n #1
{
\seq_gset_from_clist:Nn \g_pres_subjects_chosen_seq { #1 }
\seq_map_inline:Nn \g_pres_subjects_chosen_seq
{
\prop_get:NnN \g_pres_subjects_prop {##1} \l_tmpa_tl
\quark_if_no_value:NF \l_tmpa_tl
{
\seq_put_right:NV \l_tmpa_seq \l_tmpa_tl
}
}
\tl_gset:Nx \g_pres_title_tl
{
\seq_use:Nn \l_tmpa_seq {,~}
}
\exp_args:NV \title \g_pres_title_tl
}

\cs_new_protected:Npn \pres_input_chosen_subjects_files:
{
\seq_map_inline:Nn \g_pres_subjects_chosen_seq
{
\par
\file_if_exist_input:nF {##1}
{
\begin{frame}
\end{frame}
}
}
}
\ExplSyntaxOff

\SubjectFileTitle{foo1}{Foo 1}
\SubjectFileTitle{foo2}{Foo 2}
\SubjectFileTitle{foo3}{Foo 3}
\SubjectFileTitle{foo4}{Foo 4}
\SubjectFileTitle{foo5}{Foo 5}

\ChosenSubjects{
% foo1,
foo2,
% foo3,
foo4,
% foo5,
blurb % this doesn't exist among the defined files
}

\begin{document}
\maketitle{}
\InputChosenSubjects
\end{document}

• Indeed, I wanted "TeX to perform \seq_map_inline:Nn while processing \maketitle": I'm a bit lost about what is possible and what is not in expl3 :) About \g_tmpa_tl: what would you advise instead? May 7, 2019 at 11:23
• @DenisBitouzé I can't understand from the example code what your aim is. May 7, 2019 at 11:25
• I detailed my aim in the question. May 8, 2019 at 20:22
• @DenisBitouzé I added an edited version. May 8, 2019 at 20:47
• @DenisBitouzé Try with blurb as in my code. May 8, 2019 at 20:59

Too long for comment, this gives the same error without beamer

\documentclass{article}
\usepackage{hyperref}
\usepackage{xparse}
\ExplSyntaxOn
\seq_gset_from_clist:Nn \g_tmpa_seq { foo, bar }
\tl_set:Nn \g_tmpa_tl
{
\seq_map_inline:Nn \g_tmpa_seq
{
#1,\c_space_tl
}
}

\newcommand\test[1]{
\def\inserttest{#1}
}
\test{\g_tmpa_tl}
\ExplSyntaxOff
\begin{document}
%\maketitle

\hypersetup{pdftitle=\inserttest}

test

\end{document}

• Good catch! Now, isn't it "normal" since, following egreg's advise, that works with \seq_use:Nn instead of \seq_map_inline:Nn. May 7, 2019 at 11:28
• @DenisBitouzé isn't the issue that egregs solution is fully expandable where as yours is not (I can never understand the various ltx3 macros). Though, not at all sure why we get that particular error? We know that hyperref does a lot of parsing of the PDF data it uses. May 7, 2019 at 11:33

beamer issues (in beamerbasetitle.sty)

\hypersetup{pdftitle={\inserttitle\ifx\insertsubtitle\@empty\else\ - \insertsubtitle\fi}}


This means that \inserttitle should be something that hyperref can handle in a bookmark -- when expl3 commands are involved: Stick to commands with a star in the documentation.

You can avoid that beamer uses the title as pdftitle by using

\documentclass[usepdftitle=false,hyperref={pdftitle=somethingsafe}]{beamer}


This will also affect author pdf-fields, so they would need to be set manually too.