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 6 '18 at 1: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 6 '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 6 '18 at 21:55
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

| improve this answer | |
  • 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 6 '18 at 18:20
  • 1
    @CiprianTomoiagă It doesn't use \detokenize, yes; what if your package has an accent in the name? ;-) – egreg Mar 6 '18 at 18:26
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

| improve this answer | |
  • 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 6 '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 6 '18 at 10:53
  • @CiprianTomoiagă The listofitems package (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, tex.stackexchange.com/questions/338634/…, though you should look at the documentation. – Steven B. Segletes Mar 6 '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 6 '18 at 11:20
  • 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 6 '18 at 11:46

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.