2

My question is closely related to this one. The solution there works fine for text, but here is my scenario.

I want to typeset the names of all packages specially, so it is clear what I refer to. For this, I defined the command:

\newcommand*{\pkg}[1]{\textsf{\detokenize{#1}}}

I use \detokenize because I have to use _ often in the name of a package, so it I don't want the extra \. Also, sometimes I copy-paste the name from somewhere, so it already has the form package_name.


I am using lmodern fonts, mostly out of inertia. Surely, if you can suggest a better font which has a decent underscore and looks nice, that's great. I tried palatino and times, as suggested in the related question. I don't like palatino. times could work, but the \textsf seems too big in relation to normal text.


\documentclass[12pt]{report}
\usepackage{lmodern}        % use modern latin fonts
\usepackage[T1]{fontenc}    % use 8 bit output font encoding with more glyphs
\usepackage[utf8]{inputenc} % so you can type ă

\usepackage{relsize}        % allows you to resize individual characters e.g. underscore
\renewcommand{\_}{\textscale{.5}{\textunderscore}}

\newcommand*{\pkg}[1]{\textsf{\detokenize{#1}}} % typeset the name of a package: \pkg{tum_ardrone}
\newcommand*{\ds}[1]{\textsl{\textsf{\detokenize{#1}}}} % and of a dataset \ds{RIMES}
% these complicated definitions ensure that you always get correct spacing after the command
% and that you cannot forget the correct form (e.g. \FRCNN{}) because this would give you
% bad spacing; and that the name is not hyphenated
\makeatletter
    \@ifdefinable{\FRCNN}{\def\FRCNN#{\mbox{\pkg{Faster R-CNN}}}}
    \@ifdefinable{\CTPN}{\def\CTPN#{\mbox{\pkg{CTPN}}}}
    \@ifdefinable{\RESNET}{\def\RESNET#{\mbox{\pkg{ResNet-101}}}}
    \@ifdefinable{\CRNN}{\def\CRNN#{\mbox{\pkg{CRNN}}}}
\makeatother


\begin{document}

Template\_bin % works

\pkg{Template_bin} % nope

\end{document}

Edit: Forgot to say that I use things like \section{The \pkg{Template_bin}}, \caption[\pkg{Pkg_name}]{...} etc . Ideally, it would work there too, but if it's too difficult I guess I can find a workaround or not use \pkg{} there.

enter image description here

  • Neither palatino nor times affects the sans-serif font. Why do you have special characters in filenames? This is just asking for trouble, surely? – cfr Mar 06 '18 at 01:07
  • Interesting about the effect of font on sans-serif. I didn't know. They are not filenames, but how I chose to name my datasets :(. This was before writing the report, so all the figures bear these names. Also, I thought _ is a way of avoid trouble with spaces in filenames ? – Ciprian Tomoiagă Mar 06 '18 at 10:16
  • 1
    Well, spaces are bad, for sure, and underscores are good in filenames. But underscores are trouble when processing because they are special characters. – cfr Mar 06 '18 at 21:55

2 Answers2

3

Here I use listofitems to read the \detokenized output of \pkg and replace the instances of catcode12 _ with \_.

\documentclass[12pt]{report}
\usepackage{lmodern}        % use modern latin fonts
\usepackage[T1]{fontenc}    % use 8 bit output font encoding with more glyphs
\usepackage[utf8]{inputenc} % so you can type ă

\usepackage{relsize}        % allows you to resize individual characters e.g. underscore
\usepackage{listofitems}
\renewcommand{\_}{\textscale{.5}{\textunderscore}}
% THIS IS WHAT I AM SEARCHING THE DETOKENIZED STRING FOR
\expandafter\setsepchar\expandafter{\detokenize{_}}%
%
\newcommand*{\pkg}[1]{%
  \edef\tmp{\detokenize{#1}}%
  \readlist\xyz{\tmp}% FIND ALL INSTANCES OF _
  {\sffamily%
  \foreachitem\x\in\xyz{\ifnum\xcnt=1\else\_\fi\x}}% REPLACE _ WITH \_
} % typeset the name of a package: \pkg{tum_ardrone}
\newcommand*{\ds}[1]{\textsl{\textsf{\detokenize{#1}}}} % and of a dataset \ds{RIMES}
% these complicated definitions ensure that you always get correct spacing after the command
% and that you cannot forget the correct form (e.g. \FRCNN{}) because this would give you
% bad spacing; and that the name is not hyphenated
\makeatletter
    \@ifdefinable{\FRCNN}{\def\FRCNN#{\mbox{\pkg{Faster R-CNN}}}}
    \@ifdefinable{\CTPN}{\def\CTPN#{\mbox{\pkg{CTPN}}}}
    \@ifdefinable{\RESNET}{\def\RESNET#{\mbox{\pkg{ResNet-101}}}}
    \@ifdefinable{\CRNN}{\def\CRNN#{\mbox{\pkg{CRNN}}}}
\makeatother


\begin{document}

\textsf{Template\_bin} % works

\pkg{Template_bin} % nope

\pkg{Template_double_bin} % nope

\end{document}

enter image description here


As a follow up for the OP, who expanded the question to include having \pkg in section titles, the best I could do is have a quiet mode of \pkg that did not print out its result, instead saving it in \pkgname. In this way, one could define the \pkgname before the section heading with \pkg[q]{My_bad} and then use the result in the section heading: \section{The package is \pkgname}.

\documentclass[12pt]{report}
\usepackage{lmodern}        % use modern latin fonts
\usepackage[T1]{fontenc}    % use 8 bit output font encoding with more glyphs
\usepackage[utf8]{inputenc} % so you can type ă

\usepackage{relsize}        % allows you to resize individual characters e.g. underscore
\usepackage{listofitems}
\renewcommand{\_}{\textscale{.5}{\textunderscore}}
% THIS IS WHAT I AM SEARCHING THE DETOKENIZED STRING FOR
\expandafter\setsepchar\expandafter{\detokenize{_}}%
%
\makeatletter
\newcommand*{\pkg}[2][\relax]{%
  \edef\tmp{\detokenize{#2}}%
  \readlist\xyz{\tmp}% FIND ALL INSTANCES OF _
  \def\pkgname{}%
  \foreachitem\x\in\xyz{\ifnum\xcnt=1\else\g@addto@macro\pkgname{\_}\fi%
    \expandafter\g@addto@macro\expandafter\pkgname\expandafter{\x}}%
  \expandafter\def\expandafter\pkgname\expandafter{%
    \expandafter\textsf\expandafter{\pkgname}}%
  \ifx\relax#1\relax\pkgname\fi% REPLACE _ WITH \_
} % typeset the name of a package: \pkg{tum_ardrone}
\makeatother
\newcommand*{\ds}[1]{\textsl{\textsf{\detokenize{#1}}}} % and of a dataset \ds{RIMES}
% these complicated definitions ensure that you always get correct spacing after the command
% and that you cannot forget the correct form (e.g. \FRCNN{}) because this would give you
% bad spacing; and that the name is not hyphenated
\makeatletter
    \@ifdefinable{\FRCNN}{\def\FRCNN#{\mbox{\pkg{Faster R-CNN}}}}
    \@ifdefinable{\CTPN}{\def\CTPN#{\mbox{\pkg{CTPN}}}}
    \@ifdefinable{\RESNET}{\def\RESNET#{\mbox{\pkg{ResNet-101}}}}
    \@ifdefinable{\CRNN}{\def\CRNN#{\mbox{\pkg{CRNN}}}}
\makeatother


\begin{document}
\tableofcontents

\pkg[q]{My_bad}
\section{The package is \pkgname}

\textsf{Template\_bin} % works

\pkg{Template_bin} % nope

\pkg{Template_double_bin} % nope

\pkg[q]{My_other_bad}
\let\nextbad\pkgname
\pkg[q]{My_third_bad}
\section{The package names are \nextbad{} and \pkgname}
\end{document}

enter image description here

  • Beautiful ! I was thinking it must be something along the lines foreach token in \detokenize; if ..., but I need to learn latex programming. Small question: does the \setsepchar mean that the items in \xyz will be {Template, _, bin}, as opposed to {T, e, m, ..., _, b, i, n} ? – Ciprian Tomoiagă Mar 06 '18 at 10:30
  • Hmm, I now realise that it works on the MWE, but I failed to say that I use \pkg inside section titles and other places like that (captions, etc). And it fails there with ! Incomplete \iffalse; all text was ignored after line 44 , where line 44 is \section{\pkg{Template_bin}} – Ciprian Tomoiagă Mar 06 '18 at 10:53
  • @CiprianTomoiagă The listofitems package (https://ctan.org/pkg/listofitems) can do multi-level parsing of an input, based on parsing separators you provide. Here is an answer that shows some of its capability, https://tex.stackexchange.com/questions/338634/how-to-split-parameter-and-assign-result-into-separate-variables-or-an-array/338637#338637, though you should look at the documentation. – Steven B. Segletes Mar 06 '18 at 10:53
  • @CiprianTomoiagă I cannot make it seamless, but instead provide a quiet mode of \pkg that doesn't output the result immediately, but saves it in \pkgname, to be used later (like in a section heading). – Steven B. Segletes Mar 06 '18 at 11:20
  • Wow! Thank you ! I really appreciate you put the time into this complication. Could you please comment a couple of words as to why it is more difficult when we want to use it in e.g. \section ? Which part of TeX does not allow commands like this in section arguments ? Thank you very much ! – Ciprian Tomoiagă Mar 06 '18 at 11:36
  • 1
    @CiprianTomoiagă The \readlist is not expandable; however the result of the \readlist if fully expandable. This is, again, part of the listofitems package. – Steven B. Segletes Mar 06 '18 at 11:46
1

Ask TeX to do the required replacement without touching the other tokens.

I'd prefer \scalebox to \textscale; I also add some simplification for your complicated definitions.

\documentclass[12pt]{report}
\usepackage{lmodern}        % use modern latin fonts
\usepackage[T1]{fontenc}    % use 8 bit output font encoding with more glyphs
\usepackage[utf8]{inputenc} % so you can type ă
\usepackage{graphicx}
\usepackage{xparse}

\RenewDocumentCommand{\_}{}{\scalebox{0.5}[1]{\textunderscore}}

\ExplSyntaxOn
\NewDocumentCommand{\changeunderscore}{m}
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  \regex_replace_all:nnN { _ } { \c{_} } \l_tmpa_tl
  \tl_use:N \l_tmpa_tl
 }
\ExplSyntaxOff

% typeset the name of a package: \pkg{tum_ardrone}
\newcommand*{\pkg}[1]{\textsf{\changeunderscore{#1}}}
% and of a dataset \ds{RIMES}
\newcommand*{\ds}[1]{\textsl{\textsf{\changeunderscore{#1}}}}
% syntactic sugar
\makeatletter
\newcommand{\newcommandb}[2]{\@ifdefinable{#1}{\def#1##{#2}}}
\makeatother

\newcommandb{\FRCNN}{\mbox{\pkg{Faster R-CNN}}}
\newcommandb{\CTPN}{\mbox{\pkg{CTPN}}}
\newcommandb{\RESNET}{\mbox{\pkg{ResNet-101}}}
\newcommandb{\CRNN}{\mbox{\pkg{CRNN}}}

\newcommandb{\TB}{\pkg{Template_bin}}

\begin{document}

Template\_bin

\pkg{Template_bin}

\TB{}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Wow ! Super nice ! Thank you, @egreg ! I need to learn LaTeX3 syntax to understand how all this works, but it works ! Thank you for the nice syntactic sugar, too !

    p.s. Should I downvote because it doesn't answer the question, haha ? I can't figure out a better title, without \detokenize :(

    – Ciprian Tomoiagă Mar 06 '18 at 18:20
  • 1
    @CiprianTomoiagă It doesn't use \detokenize, yes; what if your package has an accent in the name? ;-) – egreg Mar 06 '18 at 18:26