Command to italicize text with slanted numbers

As I understand, there's no maths involved since you are writing just text. This solution is not perfect but may give you a start.

This solution replaces all the numbers with the \textsl{…} version. If you want any number not to be replaced, you must enclose it in {…}.

\documentclass{scrartcl}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \italicize { m }
  { \nathdwek_italicize:n { #1 } }
\cs_new_protected:Npn \nathdwek_italicize:n #1
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  \tl_map_inline:nn { 0123456789 }
   { \tl_replace_all:Nnn \l_tmpa_tl { ##1 } { \textsl { ##1 } } }
  \textit { \tl_use:N \l_tmpa_tl }
 }
\ExplSyntaxOff

\begin{document}
I want this with upright numbers. Like 1, or 2 or 123.\par
\emph{I want this with italics numbers. Like 1, or 2 or 123.}\par
\italicize{I want this with slanted numbers. Like 1, or 2 or 123.}
\end{document}

enter image description here


Very similar to Manuel's, but with regular expressions instead of mappings:

\documentclass{scrartcl}

\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand \italicize { m }
  { \nathdwek_italicize:n { #1 } }

\tl_new:N \l_nathdwek_text_tl
\cs_new_protected:Npn \nathdwek_italicize:n #1
 {
  \tl_set:Nn \l_nathdwek_text_tl { #1 }
  \regex_replace_all:nnN { (\d+) } { \c{textsl}\cB\{\1\cE\} } \l_nathdwek_text_tl
  \textit { \tl_use:N \l_nathdwek_text_tl }
 }
\ExplSyntaxOff

\begin{document}
I want this with upright numbers. Like 1, or 2 or 123.\par
\emph{I want this with italics numbers. Like 1, or 2 or 123.}\par
\italicize{I want this with slanted numbers. Like 1, or 2 or 123.}
\end{document}

enter image description here

The search expression

(\d+)

means “find any cluster of one or more digits and remember it”; the replace expression

\c{textsl}\cB\{\1\cE\}

means “replace with \textsl{ followed by what you found (the \1 bit) followed by }.

An advantage is that 123 will be replaced by \textsl{123} instead of \textsl{1}\textsl{2}\textsl{3}.


The search and replace solutions provided by Manuel and egreg are quite tricky. The restriction of those solutions is that, you can only change the text font in the argument of the command, without any special macro expansion.

The straightforward solution to the problem, however, is to use a mixed font. A mixed font can be dynamically set up in a modern TeX engine like XeTeX and LuaTeX, but the virtual font mechanism is also available in old TeX engines.

I will provide a XeTeX solution as well as an old virtual font solution, leaving the LuaTeX solution for LuaTeX experts.

1. A XeTeX Solution

See also: Font selection in XeTeX for specific characters

% !TeX program = xelatex
\documentclass{article}

\XeTeXinterchartokenstate=1
\chardef\CharNormal=0
% Test for old and new versions of the latex kernel
\ifx\e@alloc@intercharclass@top\@undefined
    \chardef\CharBound=255
\else
    \chardef\CharBound=\e@alloc@intercharclass@top % 4095 for new version of XeTeX engine
\fi
\newXeTeXintercharclass\CharNumbers
\XeTeXcharclass`0=\CharNumbers
\XeTeXcharclass`1=\CharNumbers
\XeTeXcharclass`2=\CharNumbers
\XeTeXcharclass`3=\CharNumbers
\XeTeXcharclass`4=\CharNumbers
\XeTeXcharclass`5=\CharNumbers
\XeTeXcharclass`6=\CharNumbers
\XeTeXcharclass`7=\CharNumbers
\XeTeXcharclass`8=\CharNumbers
\XeTeXcharclass`9=\CharNumbers
\newtoks\TokSetfont
\makeatletter
\TokSetfont={\begingroup
  \ifnum\strcmp{\f@shape}{\itdefault}=0
    \slshape
  \fi}
\makeatother
\XeTeXinterchartoks\CharNormal\CharNumbers=\TokSetfont
\XeTeXinterchartoks\CharBound\CharNumbers=\TokSetfont
\XeTeXinterchartoks\CharNumbers\CharNormal={\endgroup}
\XeTeXinterchartoks\CharNumbers\CharBound={\endgroup}

\usepackage{listings,color}

\begin{document}

\textit{Italic text can be 01234567890 different.}

\begin{itshape}
Text mode 123 in math equation:
\[
  xyz1234 \ne \textit{xyz1234}
\]
Complex macro expansion:
\def\foo{[123\noexpand\bar456]}
\def\bar{hello 789 hello}
\foo
\end{itshape}

\begin{lstlisting}[basicstyle=\itshape\color{blue}]
There is not any restriction for the mixed 1234567890 font:
qwerty001 bar456
\end{lstlisting}

\end{document}

enter image description here

2. Using Virtual Fonts

It is also possible to create a virtual font to mix cmti* and cmsl* fonts. Although it is much more complicated, a virtual font can work in TeX without any restriction.

  1. Create cmti10.pl via

    tftopl cmti10.tfm cmti10.pl
    
  2. Edit cmti10.pl, add these font mappings at the beginning of the file:

    (MAPFONT D 0 (FONTNAME cmti10))
    (MAPFONT D 1 (FONTNAME cmsl10))
    (CHARACTER C 0 (MAP (SELECTFONT D 1) (SETCHAR C 0)))
    (CHARACTER C 1 (MAP (SELECTFONT D 1) (SETCHAR C 1)))
    (CHARACTER C 2 (MAP (SELECTFONT D 1) (SETCHAR C 2)))
    (CHARACTER C 3 (MAP (SELECTFONT D 1) (SETCHAR C 3)))
    (CHARACTER C 4 (MAP (SELECTFONT D 1) (SETCHAR C 4)))
    (CHARACTER C 5 (MAP (SELECTFONT D 1) (SETCHAR C 5)))
    (CHARACTER C 6 (MAP (SELECTFONT D 1) (SETCHAR C 6)))
    (CHARACTER C 7 (MAP (SELECTFONT D 1) (SETCHAR C 7)))
    (CHARACTER C 8 (MAP (SELECTFONT D 1) (SETCHAR C 8)))
    (CHARACTER C 9 (MAP (SELECTFONT D 1) (SETCHAR C 9)))
    

    and save the file as cmtisl10.vpl.

  3. Create cmtisl10.tfm and cmtisl10.vf via

    vptovf cmtisl10.vpl
    
  4. You can use the mixed font now:

    \documentclass{article}
    \font\1=cmtisl10
    \begin{document}
    \1 Italic text can be 01234567890 different.
    \end{document}
    
  5. You may want to define a new font shape for the mixed font in NFSS. And of course there are more different sizes to handle too (repeat step 1 to 3).

    \documentclass{article}
    
    \DeclareFontShape{OT1}{cmr}{m}{itsl}{
            <-8>    cmtisl7
            <8-9>   cmtisl8
            <9-10>  cmtisl9
            <10-12> cmtisl10
            <12->   cmtisl12
          }{}
    \newcommand\itslshape{\fontshape{itsl}\selectfont}
    \DeclareTextFontCommand\textitsl{\itslshape}
    
    \usepackage{listings,color}
    
    \begin{document}
    
    \textitsl{Italic text can be 01234567890 different.}
    
    \begin{lstlisting}[basicstyle=\itslshape\color{blue}]
    There is not any restriction for the mixed 1234567890 font:
    qwerty001 bar456
    \end{lstlisting}
    
    \end{document}
    

enter image description here

See also: How to create a virtual font?

Tags:

Fonts

Italic