3

In Parse filename and extract revision from name, the OP wanted to parse a file name of the format cv3.01 to extract the revision number 3.01.

@egreg posted the following solution for a file name with a general prefix:

\documentclass{article}

\makeatletter
\edef\revision@prefix{\detokenize{%
  % customize based on the file name structure
  cv% <---- change the characters before %
}}
\expandafter\def\expandafter\revision@get\revision@prefix#1\@nil{#1}
\edef\revision{\expandafter\revision@get\jobname\@nil}
\makeatother

\begin{document}

This document is Rev~\revision.

\end{document}

What if I had a file name structure like cv3.01temp? How could this approach be generalized to parse the file name as given by \jobname with an arbitrary (potentially empty) prefix and postfix?

3 Answers 3

2

Save the file as cv3.01temp.tex and enjoy. ;-)

\documentclass{article}

\makeatletter
\edef\revision@prefix{\detokenize{%
  % customize based on the file name structure
  cv% <---- change the characters before %
}}
\edef\revision@postfix{\detokenize{%
  % customize based on the file name structure
  temp% <---- change the characters before %
}}
\begingroup\edef\x{\endgroup
  \def\noexpand\revision@get\revision@prefix##1\revision@postfix\noexpand\@nil{##1}}%
\x
\edef\revision{\expandafter\revision@get\jobname\@nil}
\makeatother

\begin{document}

This document is Rev~\revision.

\end{document}

The \@nil has been kept in case the postfix is empty.


The trick is, besides detokenizing the prefix and postfix for the already explained reason, to define \revision@get so that it has a single argument delimited by the (detokenized) prefix and the (detokenized) postfix followed by \@nil. This is achieved by expanding the strings inside an \edef and then executing the obtained macro.

Actually an argument delimiter is only what follows the parameter in the <parameter text>, so the leading tokens are just required after the macro name.


Just for fun, here's a way to extract the first run of digits and periods from the job name; if no such run is found, \revision is set to ???.

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

\ExplSyntaxOn
\cs_generate_variant:Nn \regex_extract_once:nnNTF { nV }
\regex_extract_once:nVNTF { [\d\.]+ } \c_sys_jobname_str \l_tmpa_seq
 { \tl_set:Nx \revision { \seq_item:Nn \l_tmpa_seq { 1 } } }
 { \tl_set:Nn \revision { ??? } }
\ExplSyntaxOff

\begin{document}

This document is Rev~\revision.

\end{document}
4
  • Is the \begingroup and \endgroup pair required? I've pulled it out and its seems to work fine.
    – Guho
    Oct 10, 2015 at 21:12
  • @Guho They're for removing the definition of \x when it's executed.
    – egreg
    Oct 10, 2015 at 21:13
  • Interesting. I suppose you would only want to be able to execute it once. Stellar answer!
    – Guho
    Oct 10, 2015 at 21:15
  • @Guho Yes, \x is executed once and then undefined; or it reverts to the previous definition if there was one. Covering one's tracks. ;-)
    – egreg
    Oct 10, 2015 at 21:17
2

enter image description here

\documentclass{article}

\def\zzz{\expandafter\zzzz\filename\relax}
\def\zzzz#1{%
\ifcat1#1#1\fi
\ifx\relax#1\else\expandafter\zzzz\fi}

\begin{document}

\def\filename{cv3.01temp} Revision: \zzz

\def\filename{3.02temp} Revision: \zzz

\def\filename{cv3.03} Revision: \zzz

\expandafter\scantokens\expandafter{\expandafter
\edef\expandafter\filename\expandafter{\jobname}}
Revision: \zzz


\end{document}
7
  • My intention was for the file name to be defined automatically from \jobname. I have clarified the question.
    – Guho
    Oct 10, 2015 at 20:54
  • @Guho ah now that's unfortunate as \jobname is a rather special beast, any "letters" are not letters (catcode 11) but all catcode 12, so the above test won't distinguish letters from numbers in \jobname, i'll add a wrapper to so \jobname works in a minute... Oct 10, 2015 at 20:57
  • @Guho updated answer showing you get 5 if \jobname is foo5zzz Oct 10, 2015 at 21:03
  • What if the file name is cv3.01-temp?
    – egreg
    Oct 10, 2015 at 21:07
  • 1
    @egeg if needed you could locally make - catcode 11, it covers more cases than just looking for a fixed string temp% <---- change the characters before % ;-) Oct 10, 2015 at 22:23
1

Using a listofitems approach.

\documentclass{article}
\usepackage{listofitems}
\newcommand\revision[1]{
  \setsepchar{cv||temp}%
  \ignoreemptyitems
  \readlist\mylist{#1}%
  \mylist[1]%
}
\begin{document}
\revision{cv3.01temp}

\revision{3.02temp}

\revision{cv3.03}

\def\filename{cv3.04atemp2017-10-27}
\revision{\filename}
\end{document}

enter image description here

You must log in to answer this question.

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