5

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?

3 Answers 3

4

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:

enter image description here

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

1
  • 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
2

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:

enter image description here

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

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

enter image description here

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

\splitjobname{ [ _ \- ] }

one would get the same output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.