# What causes this runaway argument when attempting to parse \jobname?

I’m attempting to parse the jobname of my (Xe)LaTeX document to set a true/false flag for later use. I came across this solution which seemed promising and which I implemented (see the following MWE).

\documentclass{report}

\newif\ifFraktur
\makeatletter%
\newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}%
\def\filename@parse@#1_#2\@nil{%
\gdef\filenameflag{#2}%
}%
\makeatother
\filenameparse{\jobname}%

\if{f}\filenameflag{%
\Frakturtrue}%
\else{%
\Frakturfalse}%
\fi%

\begin{document}

\ifFraktur{We have an f document}%
\else{We have an a document.}%
\fi
\end{document}


The filename of this file is mwe-1-0_a.tex which corresponds to what I’m going to use for my actual file (version-m-n_f.tex, where m and n are placeholders for the version numbers and f is a placeholder for the flag which can bei either a or f).

Running this, I get the following error:

Runaway argument?
mwe-1-0_a\@nil
! Paragraph ended before \filename@parse@ was complete.
\par
l.11


Ignoring the error (hitting enter) allowed the document to compile with no further errors.

Trying to get to the bottom of the issue, I decided to copy the already linked answer, but I modified it slightly to be the following:

\documentclass{article}

\makeatletter
\newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}
\def\filename@parse@#1_#2_#3\@nil{%
\gdef\fileA{#1}% first part
\gdef\fileB{#2}% middle part
\gdef\fileC{#3}% final part
}
\makeatother

\filenameparse{\jobname}

\begin{document}

\fileA \par
\fileB \par
\fileC
\end{document}


Surprisingly, this not only also generates a runaway argument, but also none of the three macros \fileA, \fileB or \fileC are defined. Whereupon I examined the mwe-1-0_f.tex (as above) and realised that it compiled, but the final \ifFraktur clause was evaluated as false.

There are probably multiple issues at work here, but I would be most interested in the cause for the runaway argument for the time being.

the characters in \jobname have catcode 12 (like \meaning or \string) so you want a catcode 12 _

\documentclass{report}

\newif\ifFraktur
\makeatletter%
\catcode\_=12
\newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}%
\def\filename@parse@#1_#2\@nil{%
\gdef\filenameflag{#2}%
}%
\catcode\_=8
\makeatother
\filenameparse{\jobname}%

\edef\testf{\string f}
\ifx\testf\filenameflag
\Frakturtrue
\else
\Frakturfalse
\fi%

\begin{document}

\ifFraktur
We have an f document
\else
We have an a document.
\fi
\end{document}

• I guessed the intention of \if{f} although I may have guessed wrong. Nov 18, 2016 at 1:09
• You guessed correctly.
– Jan
Nov 18, 2016 at 1:17

Here's an implementation that also allows you to extract the version numbers, based on my code for Parsing file name into document

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\cs_generate_variant:Nn \regex_split:nnN { nV }
\seq_new:N \l_liz_jobname_seq

\NewDocumentCommand{\splitjobname}{m}
{
\regex_split:nVN { #1 } \c_sys_jobname_str \l_liz_jobname_seq
}

\DeclareExpandableDocumentCommand{\jobnamepart}{m}
{
\seq_item:Nn \l_liz_jobname_seq { #1 }
}

\DeclareExpandableDocumentCommand{\isfrakturTF}{mm}
{
\str_if_eq_x:nnTF { \jobnamepart{-1} } { f } { #1 } { #2 }
}
\ExplSyntaxOff

\splitjobname{ [ _ \- ] } % at _ or -

\begin{document}

This document's name \isfrakturTF{has}{has not} a trailing f'.

First part: \jobnamepart{1}\par
Second part: \jobnamepart{2}\par
Third part: \jobnamepart{3}

\end{document}


If the file name is mwe-1-0_a.tex, the output is

If the name is mwe-1-0_f.tex`, the output is