2

I have a related question here whose solution is being blocked by the following error "Missing \endcsname inserted":

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}
%\usepackage{subcitations}

\usepackage{listofitems}
\usepackage{xifthen}
\usepackage{xstring}

\usepackage[backend=biber, style=numeric, subentry]{biblatex}

\begin{filecontents}{\jobname2.bib}
@set{two,
entryset = {twomain,twosub1},
}
@article{twomain,
author = {Yoon},
title = {A paper},
journaltitle = {Journal Title},
date         = 2020,
}
@article{twosub1,
url={http://sub1.com}
}

@article{one,
url={http://other2.example.com}
}

@article{three,
url={http://other3.example.com}
}
\end{filecontents}
\addbibresource{\jobname2.bib}


\begin{document}

\newcommand{\subcite}[2]{
    % Split the names of the references and the sub-citations on commas
    \readlist*\mains{#1}
    \readlist*\subs{#2}

    % Define string to hold citations
    \def\citations{\foreachitem\x\in\mains[]{\ifthenelse{\xcnt>1}{,}{}\x{\ifthenelse{\xcnt>\subslen}{}{\subs[\xcnt]}}}}
    
    Citations: \citations  % => Citations: one,twosub1,three
    
    %\cite{\citations} % This errors with "Missing \endcsname inserted."
}


\def\citations1{one,twosub1,three}

1. \cite{one,twosub1,three}        % works fine => 1. [1,2,3]
2. \cite{\citations1}        % works fine => 2. [1,2,3]
3. \subcite{one,two,three}{,sub1}  % errors => 3. Citations: one,twosub1,three

\printbibliography
\end{document}

Is there a way to avoid / resolve this error?

1
  • You should be aware that you should not define commands with \def and even less commands with numbers “in their name”.
    – egreg
    Dec 11, 2020 at 15:43

2 Answers 2

3

Your \citations are not expandable. Here is one of many ways to fix this. (BTW, \def\citations1{...} works a bit "by accident".)

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}
%\usepackage{subcitations}

\usepackage{listofitems}
\usepackage{xifthen}
\usepackage{xstring}

\usepackage[backend=biber, style=numeric, subentry]{biblatex}

\begin{filecontents}{\jobname2.bib}
@set{two,
entryset = {twomain,twosub1},
}
@article{twomain,
author = {Yoon},
title = {A paper},
journaltitle = {Journal Title},
date         = 2020,
}
@article{twosub1,
url={http://sub1.com}
}

@article{one,
url={http://other2.example.com}
}

@article{three,
url={http://other3.example.com}
}
\end{filecontents}
\addbibresource{\jobname2.bib}


\begin{document}

\newcommand{\subcite}[2]{%
    % Split the names of the references and the sub-citations on commas
    \readlist*\mains{#1}%
    \readlist*\subs{#2}%
    % Define string to hold citations
    \edef\citations{}%
    \foreachitem\x\in\mains[]{\ifnum\xcnt>1\relax
        \edef\citations{\citations,\x}%
        \else   
        \edef\citations{\citations\x}%
        \fi
    \ifnum\xcnt>\subslen
    \else
    \edef\citations{\citations\subs[\xcnt]}%
    \fi}%
    \expandafter\cite\expandafter{\citations}% This errors with "Missing \endcsname inserted."
}


\def\citations1{one,twosub1,three}

1. \cite{one,twosub1,three}        % works fine => 1. [1,2,3]
2. \cite{\citations1}        % works fine => 2. [1,2,3]
3. \subcite{one,two,three}{,sub1}  % works fine => 1. [1,2,3]

\printbibliography
\end{document}

enter image description here

1
  • 1
    I took the liberty to fix two spurious spaces.
    – egreg
    Dec 11, 2020 at 22:19
2

I propose an expl3 based answer. It's not really different than your approach, but has quite a few advantages:

  1. spaces around commas in the input are ignored
  2. there is no risk to overwrite existing commands
  3. no need to complicate things with different choices based on a counter
\begin{filecontents}{\jobname.bib}
  @set{two,
  entryset = {twomain,twosub1},
}
@article{twomain,
  author = {Yoon},
  title = {A paper},
  journaltitle = {Journal Title},
  date = 2020,
}
@article{twosub1,
  url = {http://sub1.com}
}

@article{one,
  url = {http://other2.example.com}
}

@article{three,
  url = {http://other3.example.com}
}
\end{filecontents}

\documentclass{article}
\usepackage{csquotes}
\usepackage[backend=biber, style=numeric, subentry]{biblatex}
%\usepackage{xparse} % uncomment if using LaTeX prior to release 2020-10-01

\addbibresource{\jobname.bib}

\ExplSyntaxOn

\NewDocumentCommand{\subcite}{mm}
 {
  \ajp_subcite:nn { #1 } { #2 }
 }

\seq_new:N \l_ajp_subcite_main_seq
\seq_new:N \l_ajp_subcite_sub_seq
\seq_new:N \l_ajp_subcite_final_seq

\cs_new_protected:Nn \ajp_subcite:nn
 {
  % split the first and second arguments at commas
  \seq_set_split:Nnn \l_ajp_subcite_main_seq { , } { #1 }
  \seq_set_split:Nnn \l_ajp_subcite_sub_seq { , } { #2 }
  % merge the items in a new sequence
  \seq_clear:N \l_ajp_subcite_final_seq
    % here ##1 is the index, ##2 the entry in the first sequence
    % \seq_item:Nn returns nothing if the sequence is shorter
  \seq_map_indexed_inline:Nn \l_ajp_subcite_main_seq
   {
    \seq_put_right:Nx \l_ajp_subcite_final_seq { ##2 \seq_item:Nn \l_ajp_subcite_sub_seq { ##1 } }
   }
  % make the citations: deliver all items separated by a comma
  \cite
   {
    \seq_use:Nn \l_ajp_subcite_final_seq { , }
   }
 }

\ExplSyntaxOff

\newcommand\citationtest{one,twosub1,three}

\begin{document}

1. \cite{one,twosub1,three}

2. \cite{\citationtest}

3. \subcite{one,two,three}{,sub1}

4. \subcite{one, two, three}{ , sub1}

\printbibliography

\end{document}

enter image description here

Beware: with \def\citations1{...} you are redefining \citations, which is a macro that's used in your \subcite command. You cannot define commands having numbers in their name with \def (unless you go with \csname, but then the same has to be used to call the macro, making it not really practical).

Try the code proposed in Lazy squirrel's answer with

1. \cite{one,twosub1,three}        % works fine => 1. [1,2,3]
2. \subcite{one,two,three}{,sub1}  % works fine => 1. [1,2,3]
3. \cite{\citations1}        % doesn't work!

and you'll have a surprise.

Note also that TeX is not free-form. Spaces are relevant and blank lines generate a \par token. Also an endline is converted into a space (unless you use a % to mask the endline). Even an experienced TeX programmers blunder at times (Lazy squirrel's answer, for instance, had two spurious spaces, before my edit.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .