2

I'm trying to vertically offset some underscores in a filename representation: some_file_name.ext so that the underscore is moved above the baseline. Here is what I tried def'ing:

\def\raiseunderscore#1-#2{\dimexpr\height#1#2\relax}

but I'm getting error: ! You can't use `\dimexpr' in restricted horizontal mode.

So in my notoriously fragmented competence on TeX primitives, I tried:

\def\raiseunderscore#1-#2{\leavevmode\dimexpr\height#1#2\relax}

to no avail.

How can I vertically offset the underscore character when used in normal text as _? Also, is there a way I can have this occur in all instances (globally) instead of making a macro for it?

Update: Here is what I am trying to achieve (I've changed the macro name for brevity) :

raised by some

raised by a lot

lowered by a lot

Here is a short MVE of what I've tried so far:

\documentclass{article}

\def\offsetchr#1#2{\dimexpr\height#1#2\relax}
\begin{document}

This sentence has a raised\quad\offsetchr{15pt}{\_} \quad character in the middle.

This sentence also has a raised\quad\offsetchr{2.5em}{\_} \quad character in the middle.

This sentence has a lowered\quad\offsetchr{-2.5em}{\_} \quad character in the middle.

\end{document}
2
  • 1
    \dimexpr just computes an (dimension) expression, it doesn't move things around. Can you please show a compilable example of what you're trying? Feb 12, 2021 at 13:21
  • Added what you requested.
    – Ole Aldric
    Feb 12, 2021 at 14:20

2 Answers 2

2

Your example with \dimexpr is not understandable for me, so for TeX too. Of course, you cannot use \dimexpr in the typesetting material without any context.

But you can use \raise\hbox primitive construction and set the _ as an active character when the parameter of the \filename is read:

{\catcode`_13 
   \gdef_{\raise.35ex\hbox{\string_}}
}
\def\filename{\bgroup\catcode`_=13 \filenameA}
\def\filenameA#1{\tt#1\egroup}

% test:
\filename{some_file_name.ext}
 
1
  • Just to relieve the intense suspense as to why I posted a question with \dimexpr is simply because I found this as an answer somewhere online, but as it didn't work (and my questionable understanding of primitives) I posted it here since it is what i've tried and searched for. \raise0.2ex\hbox{\_} did it for me in the particular place i needed it, but no answer has provided a global solution (for all paragraph text).
    – Ole Aldric
    Feb 15, 2021 at 20:25
1

If you don't need backslashes in the file names, you can do with the following:

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\filename}{m}
 {
  \aldric_filename:n { #1 }
 }

\str_new:N \l_aldric_filename_str
\tl_new:N \l_aldric_filename_tl
\cs_generate_variant:Nn \tl_replace_all:Nnn { NV }

\cs_new_protected:Nn \aldric_filename:n
 {
  % stringify the file name
  \str_set:Nn \l_aldric_filename_str { #1 }
  % define a token list with it
  \tl_set:Nx \l_aldric_filename_tl { \str_use:N \l_aldric_filename_str }
  % replace all _ with a macro for a raised underscore
  \tl_replace_all:NVn \l_aldric_filename_tl \c_underscore_str { \aldric_filename_raised_us: }
  % deliver the result
  \texttt{ \tl_use:N \l_aldric_filename_tl }
 }

\cs_new_protected:Nn \aldric_filename_raised_us:
 {
  \raisebox { 0.2ex } { \c_underscore_str } % fix the parameter to suit
 }

\ExplSyntaxOff

\begin{document}

\filename{some_file_name.ext}

\filename{some_$tr@ng&_file_name.txt}

{\footnotesize\filename{some_file_name.ext}}

\end{document}

enter image description here

2
  • It works, flawlessly. But I don't have the slightest clue how. I'm not in any way versed in ExplSyntax. I assume that you somehow capture the underscore with \c_underscore_str and raise it with a \raisebox?
    – Ole Aldric
    Feb 12, 2021 at 14:33
  • @OleAldric Yes, \c_underscore_str is a constant string containing the standard “printable” underscore. The indirection is needed because _ has a special use under \ExplSyntaxOn.
    – egreg
    Feb 12, 2021 at 15:00

You must log in to answer this question.

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