9

I have a tex file with name Chap-Name_of_Section.tex and I running pdflatex on it. I want to set the title of my document automatically according to the file name. This could be done using \jobname.

Here is my MWE. Save this file as Chap-Name_of_Section.tex,

\documentclass[12pt,a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{a4wide}

\title{\textbf{\jobname}}
\author{}
\date{}

\begin{document}
\maketitle
The name of the tex file is {\tt{Chap-Name\_of\_Section.tex}}. I am running {\verb|pdflatex|} on the tex file. After using {\verb|\jobname|} I get the title.

I want to print the title as ``Chap: Name of Section''. Note that `-' sign is to be replaced by `:' followed by a single space and underscores (`\_') are to be replaced by spaces.
\end{document}

But This is not what I want. I want to print the title as Chap: Name of Section. Note that - sign is to be replaced by : followed by a single space and underscores _ are to be replaced by spaces.

I have found \StrSubstitute from the xstring package. But this can change only one character. For example, if I replace \jobname with \StrSubstitute[0]{\jobname}{-}{: } in my code, the title would be, Chap: Name_of_Section.

How to replace both - and _ accordingly ?

5
  • 1
    The package a4wide has been deprecated for several years. Don't use it, as it's incompatible with much more useful packages.
    – egreg
    Commented Oct 4, 2017 at 8:26
  • 1
    unrelated comment: you shouldn't be using {\tt{..}} (\tt doesn't even take an argument so {\tt ..} if anything) but rather \texttt{..}.
    – cgnieder
    Commented Oct 4, 2017 at 8:26
  • also the braces around the \verb|..| are not necessary (but don't do harm I guess)
    – cgnieder
    Commented Oct 4, 2017 at 8:29
  • @egreg is there something similar to a4wide?
    – ddas
    Commented Oct 4, 2017 at 8:32
  • @ddas Use geometry
    – egreg
    Commented Oct 4, 2017 at 10:38

6 Answers 6

5

Apart from expl3, you can also use StrSubstitute with the option to save the result in a macro. Note that you need to convert _ to the right catcode, for example using \string.

MWE:

\documentclass{article}
\usepackage{xstring}

\title{\textbf{\subfinal}}
\author{}
\date{}

\begin{document}
\StrSubstitute{\jobname}{-}{: }[\subsemi]
\StrSubstitute{\subsemi}{\string_}{ }[\subfinal]
\maketitle
The name of the tex file is {\tt{Chap-Name\_of\_Section.tex}}. I am running {\verb|pdflatex|} on the tex file. After using {\verb|\jobname|} I get the title.

I want to print the title as ``Chap: Name of Section''. Note that `-' sign is to be replaced by `:' followed by a single space and underscores (`\_') are to be replaced by spaces.
\end{document}

Result:

enter image description here

1
  • 2
    you should replace {\tt{...}} by \texttt{...}
    – cgnieder
    Commented Oct 4, 2017 at 8:27
4

Same idea as in @jakun's answer, but implemented (without packages, also) in a way which is easier (more convenient, rather, as it takes less space) to extend to more special characters. Expandable, too.

\documentclass{article}

\long\def\DoThis #1#2\OrThat #3{\fi #1}
\makeatletter
\let\OrThat\@firstofone
\makeatother

\begingroup
  \makeatletter
  \catcode`_=12 % other
% if using Babel with a language that makes : a shorthand (French, e.g.)
% then you need  \catcode`: \active here and \DoThis{\noexpand: }
  \def\myParser#1{%
     \ifx\relax#1\DoThis{\@gobble}\fi
     \ifx -#1\DoThis{: }\fi
     \ifx _#1\DoThis{ }\fi
     \OrThat{#1}\myParser
  }%
  \xdef\parsedJobname{\expandafter\myParser\jobname\relax}
\endgroup

\title{\parsedJobname}

\begin{document}
    \maketitle
    The parsed jobname is ``\parsedJobname''.
\end{document}

If the above is file Test_Titre-Un.tex then the result is

enter image description here

Code for French as per code comment.

\begingroup
  \makeatletter
  \catcode`_=12 % other
  \catcode`\: \active 
  \def\myParser#1{%
     \ifx\relax#1\DoThis{\@gobble}\fi
     \ifx -#1\DoThis{\noexpand: }\fi
     \ifx _#1\DoThis{ }\fi
     \OrThat{#1}\myParser
  }%
  \xdef\parsedJobname{\expandafter\myParser\jobname\relax}
\endgroup

Produces (using babel+french):

enter image description here

4
  • 1
    this will not work with filenames containing spaces, but I never use such filenames to start with, and particularly with TeX. Off the top of my head I don't even recall if such filenames are authorized with TeX.
    – user4686
    Commented Oct 4, 2017 at 9:33
  • 1
    pdflatex "I like spaces .tex" will work with web2c based texs using " to quote any spaces. Commented Oct 4, 2017 at 12:34
  • @DavidCarlisle ok, I never tested that; will it work flawlessly in integrated environments? I guess they take care that quotes do not get lost when calling executables on auxiliary files.
    – user4686
    Commented Oct 4, 2017 at 14:06
  • @ddas do you want a solution allowing spaces in filenames? I have the impression the motivation is rather to avoid them, but in case you do want, then the answer can be amended... (it would get more complicated, though...)
    – user4686
    Commented Oct 4, 2017 at 14:20
4

Here is more simple, format independent, expandable solution:

\def\cnvjobname{\expandafter\cnvjobnameA\jobname\relax}
\def\cnvjobnameA#1{\ifx\relax#1\else
   \ifx-#1: \else \expandafter\ifx\string_#1 \else #1\fi\fi
   \expandafter\cnvjobnameA\fi
}

%test:
\message{... "\cnvjobname"}

\bye
3

Without any packages:

\documentclass{article}

\catcode`_=12 % other
\newcommand{\myParser}[1]{%
    \let\do=\myParser
    \ifx \relax #1%
        \let\do=\relax
    \else\ifx -#1%
        : %
    \else\ifx _#1%
        \ %
    \else
        #1%
    \fi\fi\fi
    \do
}
\catcode`_=8 % subscript

\title{\expandafter\myParser\jobname\relax}

\begin{document}
    \maketitle
\end{document}

Please note that this is not expandable (you can not use it in an \edef).

This is an expandable version:

\documentclass{article}

\begingroup
    \makeatletter
    \catcode`_=12 % other

    \gdef\myParser#1{%
        \ifx -#1%
            \expandafter \@firstoftwo
        \else
            \expandafter \@secondoftwo
        \fi
            {: \myParser}
            {%
                \ifx _#1%
                    \expandafter \@firstoftwo
                \else
                    \expandafter \@secondoftwo
                \fi
                    { \myParser}
                    {%
                        \ifx \relax #1%
                            \expandafter \@firstoftwo
                        \else
                            \expandafter \@secondoftwo
                        \fi
                            {}
                            {#1\myParser}%
                    }%
            }%
    }
\endgroup

\edef\parsedJobname{\expandafter\myParser\jobname\relax}
\title{\parsedJobname}

\begin{document}
    \maketitle
    The parsed jobname is ``\parsedJobname''.
\end{document}
2

You could use expl3's excellent regex module:

\documentclass[12pt,a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{a4wide}
\usepackage{expl3}

\ExplSyntaxOn
\tl_set:NV \l_tmpa_tl \c_sys_jobname_str
\regex_replace_once:nnN { - } { \cO:\  } \l_tmpa_tl
\regex_replace_all:nnN { _ } { \  } \l_tmpa_tl
\exp_args:NV \title \l_tmpa_tl
\ExplSyntaxOff

\begin{document}
\maketitle
\end{document}
1
  • 2
    \jobname is available as \c_sys_jobname_str; the first instruction should be \tl_set:NV \l_tmpa_tl \c_sys_jobname_str and the last one \exp_args:NV \title \l_tmpa_tl; to be picky, the replacement string for the hyphen should be \cO:\ , because : is a letter under \ExplSyntaxOn.
    – egreg
    Commented Oct 4, 2017 at 8:31
2

An expandable version:

\documentclass{article}

\makeatletter
\newcommand{\massagedjobname}{%
  \expandafter\massage@jobname\jobname\@nil
}
\newcommand{\massage@jobname}[1]{%
  \ifx#1\@nil
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {\massage@token#1}%
}
\def\massage@token#1{%
  \ifx#1-%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {: \massage@jobname}%
  {\massage@token@i#1}%
}
\begingroup\lccode`?=`_
\lowercase{%
  \endgroup
  \gdef\massage@token@i#1{%
    \ifx#1?%
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    { }{#1}%
    \massage@jobname
  }%
}
\makeatother

\begin{document}

\title{\massagedjobname}
\author{Me}

\maketitle

\edef\test{\massagedjobname}
\texttt{\meaning\test}

\texttt{macro:->Chap: Name of Section}% check!
\end{document}

enter image description here

Of course there's an expl3 version:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\massagedjobname}{}
 {
  \str_map_function:NN \c_sys_jobname_str \ddas_jobname:n
 }
\cs_new:Nn \ddas_jobname:n
 {
  \str_case:nnF { #1 }
   {
    { - }{ :~ }
    { _ }{ ~ }
   }
   { #1 }
 }
\ExplSyntaxOff

\begin{document}

\title{\massagedjobname}
\author{Me}

\maketitle

\edef\test{\massagedjobname}
\texttt{\meaning\test}

\texttt{macro:->Chap: Name of Section}% check!
\end{document}

You must log in to answer this question.

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