Parsing file name into document

I have a group of tex files named according to the following convention:

xxx_yyy_zzz.tex

I would like to use the components (xxx, yyy, zzz) of the file name as inputs in the document, n particular when creating the title / header. For example, I would like to be able to set the title of the document to be Learning about yyy'' and the author to bezzz'' with a footer that says xxx.

I have so far found some code that lets me remove the end of a file name: https://tex.stackexchange.com/a/21808

I have also tried using \StrBetween from the xstring package to process \currfilename from the currfile package, but this doesn't work.

\documentclass{article}
\usepackage{currfile}
\usepackage{xstring}

\begin{document}

\makeatletter
\filename@parse{\currfilename}
\StrBetween{\filename@base}{_}{_}
\makeatother

\end{document}


Actually I think I'm using \StrBetween wrong, but even if I do something like

\StrBetween{\filename@base}{xxx}{zzz}


it doesn't print out yyy, but if I do

\StrBetween{a \filename@base b}{a}{b}


then it will print xxx_yyy_zzz.

Are there any suggestions as to how I can take a file named xxx_yyy_zzz.tex and include the text components xxx, yyy, and zzz to be used later in the file, e.g., in the header or title?

Since you have a very specific filename-pattern, you can use TeX's \def to define a specific parameter text, from which you can extract the elements of the filename within the argument text:

\documentclass{article}

\makeatletter
\catcode\_=12
\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
}
\catcode\_=8
\makeatother

\begin{document}

\filenameparse{\jobname}

\verb|\fileA:| \fileA \par
\verb|\fileB:| \fileB \par
\verb|\fileC:| \fileC
\end{document}


\jobname carries the name of the file (without extension), which is then processed as #1_#2_#3, each component of which is extracted as \fileA, \fileB and \fileC, respectively.

• I tried something similar. The catcode of _ must be 12 for this to work. I have submitted an edit, in case you want to add the two required lines.
– Jan
Nov 18, 2016 at 1:15

Werner's solution is the better way to parse the separate componets in this case, but here is a method that uses the xstring' macros \StrBefore, and \StrBetween to extract the relevant components.

With the file below named "theory-relaivity-Einstein.tex", this outputs:

Code:

% This file is called "theory-relaivity-Einstein.tex"
\documentclass{article}
\usepackage{currfile}
\usepackage{xstring}

% Ensure that we are no overriding any existing macros:
\newcommand*{\XXX}{}%
\newcommand*{\YYY}{}%
\newcommand*{\ZZZ}{}%

\newcommand*{\FileNameParse}{%
\StrBefore{\currfilename}{-}[\XXX]%
\StrBetween[1,2]{\currfilename}{-}{-}[\YYY]%
\StrBetween[2,1]{\currfilename}{-}{.}[\ZZZ]%
}%

\begin{document}
\FileNameParse
XXX=\XXX,

Learning about \YYY"
Author=\ZZZ".

\end{document}


This implements a fairly general splitting method:

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

\splitjobname{ _ }

\begin{document}

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

\end{document}


If the job name is xxx_yyy_zzz.tex, then the output will be

If the job name is xxx-yyy_zzz.tex, then with

\splitjobname{ [ _ \- ] }


one would get the same output.