2

My tags are follows:

\documentclass{book}
\usepackage{xcolor}
\usepackage{textcomp,listings}%

\lstnewenvironment{python}[1][]{%
\lstset{%
mathescape=false,%
language=python,%
basicstyle=\ttfamily\normalsize,%
otherkeywords={*,\{, \} },%
keywordstyle=\color{black},%
stringstyle=\color{black},%
showstringspaces=false,%
emph={class, pass, in, for, while, if, is, elif, else, not, and, or,%
def, print, exec, break, continue, return},%
emphstyle=\color{black}\bfseries,%
emph={[3]True, False, None, self},%
emphstyle=[2]\color{black!10},%
emph={[3]from, import, as},%
emphstyle=[3]\color{black},%
upquote=true,%
morecomment=[s]{"""}{"""},%
commentstyle=\color{gray}\slshape,%
aboveskip=12pt,belowskip=12pt,xleftmargin=-2pt,xrightmargin=3pt,framexleftmargin=20pt,framextopmargin=1pt,%
rulesepcolor=\color{gray},#1%
}}{}%

\begin{document}

\begin{python}
In [7]: np.searchsorted(X, 0.5)
Out[7]: 4998210 # This is 1 for test 1000
\end{python}

\begin{python}
In [7]: np.searchsorted(X, 0.5) # left edge 1234567890

 from scipy import stats
    dist stats.uniform (0, 2)  # left edge 0, width  2
\end{python}

\end{document}

It is working fine without issues. Please confirm that I need the arabic numerals (i.e., 0 to 9) should be in roman always, refer the screen shot:

enter image description here

Is this possible to fix? Please advise...

Henri Menke
  • 109,596
MadyYuvi
  • 13,693
  • 1
    Do you want the numbers to be in roman font only in comments or everywhere? – siracusa Aug 16 '19 at 05:06
  • @siracusa Thanks for your attention. Other places it comes correctly (in roman font), but in the commented text it comes in italic, but I need those to be in roman – MadyYuvi Aug 16 '19 at 05:39

1 Answers1

2

Here's a solution that makes use of the general number highlighting approach presented in Listings: color numbers only out of keywords.

We need to make some changes to the OutputOther hook from that solution, because in this case you want to override the default style no matter whether you are in a comment or not. The new hook looks like:

\lst@AddToHook{OutputOther}{%
    \lst@ifparsenumbers
        \expandafter\@hook@ifnumber\the\lst@token\@end {%
            \let\orig@thestyle=\lst@thestyle
            \def\lst@thestyle{\orig@thestyle\lst@numbersstyle}%
        }{}%
    \fi
}

Also to your \lstset command the following lines have to be added:

parsenumbers=true,
numbersstyle=\upshape

Wherever a number is then parsed by listings in the input, the numbersstyle is added to the currently active style.


Full example code:

\documentclass{book}
\usepackage{xcolor}
\usepackage{textcomp,listings}%


\makeatletter

%%% Copied from https://tex.stackexchange.com/a/500690/23765
% Some conditional tests
\def\@genericif#1{#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
\def\@ifdigit#1{\@genericif{\ifnum1<1\noexpand#1\relax}}
\def\@ifempty#1{\@genericif{\if\relax\detokenize{#1}\relax}}

% The main parsing macros
\def\parse@num#1{%
    \@ifempty{#1}%
        {\parse@num@false}%
        {\@genericif{\parsesign}%
            {\parse@num@sign#1{}\@end}%
            {\parse@num@dig#1{}\@end}%
        }%
}
% Parse sign
\def\parse@num@sign#1#2\@end{%
    \@genericif{\ifx\parse@num@minus#1}%
        {\@ifempty{#2}{\parse@num@false}{\parse@num@dig#2\@end}}%
        {\@genericif{\ifx\parse@num@plus#1}%
            {\@ifempty{#2}{\parse@num@false}{\parse@num@dig#2\@end}}%
            {\parse@num@dig#1#2\@end}%
        }%
}
% Parse first digit
\def\parse@num@dig#1#2\@end{%
    \@ifdigit{#1}%
        {\@ifempty{#2}{\parse@num@true}{\parse@num@digs#2\@end}}%
        {\parse@num@false}%
}
% Parse optional following digits
\def\parse@num@digs#1#2\@end{%
    \@ifdigit{#1}{%
        \@ifempty{#2}%
            {\parse@num@true}%
            {\parse@num@digs#2\@end}%
    }{%
        \@genericif{\parsefloat}{%
            \@genericif{\ifx\parse@num@point#1}%
                {\@ifempty{#2}{\parse@num@false}{\parse@num@decs#2\@end}}%
                {\parse@num@false}%
        }{\parse@num@false}%
    }%
}
% Parse decimal places
\def\parse@num@decs#1#2\@end{%
    \@ifdigit{#1}{%
        \@ifempty{#2}%
            {\parse@num@true}%
            {\parse@num@decs#2\@end}%
    }{\parse@num@false}%
}

% User interface
\newcommand\ifnumber[4][]{%
    \begingroup
    \let\parsesign=\iftrue
    \let\parsefloat=\iftrue
    \let\parse@num@minus=-%
    \let\parse@num@plus=+%
    \let\parse@num@point=.%
    #1%
    \def\parse@num@true{\endgroup#3}%
    \def\parse@num@false{\endgroup#4}%
    \parse@num{#2}%
}   


%%% Additions to the listings package
\lst@Key{numbersstyle}{}{\def\lst@numbersstyle{#1}}
\lst@Key{parsenumbers}{false}[t]{\lstKV@SetIf{#1}\lst@ifparsenumbers}

\lst@AddToHook{OutputOther}{%
    \lst@ifparsenumbers
        \expandafter\@hook@ifnumber\the\lst@token\@end {%
            \let\orig@thestyle=\lst@thestyle
            \def\lst@thestyle{\orig@thestyle\lst@numbersstyle}%
        }{}%
    \fi
}
\def\@hook@ifnumber#1#2\@end{%
    \@genericif{\ifx\lst@nolig#1}%
        {\@hook@ifnumber@{#2}}%
        {\@hook@ifnumber@{#1#2}}%
}
\def\@hook@ifnumber@{%
    \ifnumber[\expandafter\let\expandafter\parse@num@minus\csname lst@um-\endcsname]%
}

\makeatother


\lstnewenvironment{python}[1][]{%
\lstset{%
mathescape=false,%
language=python,%
basicstyle=\ttfamily\normalsize,%
otherkeywords={*,\{, \} },%
keywordstyle=\color{black},%
stringstyle=\color{black},%
showstringspaces=false,%
emph={class, pass, in, for, while, if, is, elif, else, not, and, or,%
def, print, exec, break, continue, return},%
emphstyle=\color{black}\bfseries,%
emph={[3]True, False, None, self},%
emphstyle=[2]\color{black!10},%
emph={[3]from, import, as},%
emphstyle=[3]\color{black},%
upquote=true,%
morecomment=[s]{"""}{"""},%
commentstyle=\color{gray}\slshape,%
aboveskip=12pt,belowskip=12pt,xleftmargin=-2pt,xrightmargin=3pt,framexleftmargin=20pt,framextopmargin=1pt,%
rulesepcolor=\color{gray},#1,
parsenumbers=true,
numbersstyle=\upshape
}}{}%

\begin{document}

\begin{python}
In [7]: np.searchsorted(X, 0.5)
Out[7]: 4998210 # This is 1 for test 1000
"""
Some text 1234
"""
\end{python}

\end{document}

enter image description here


EDIT: The problem of the 0 not showing up in upright font is due to the fact that listings parses 0 and , as one unit (as both have codes digit or other). The OutputOther hook then tries to parse 0, as a number which fails and thus doesn't give the expected font.

As a workaround you can add the following line to the \lstset command:

literate={,}{{\char`\,}}{1}

which outputs

enter image description here

This makes the parser break before it reads the comma. In this special case there should be no side-effects, because commas shouldn't be part of keywords or other special syntax elements. Unfortunately, listings makes it hard to add the processing of new syntax elements, so working around one problem here often raises another one there.

siracusa
  • 13,411
  • Wow, such a great reply...much thankful to you.... – MadyYuvi Aug 16 '19 at 09:02
  • If I try second python text, `\begin{python} In [7]: np.searchsorted(X, 0.5) # left edge 1234567890

    from scipy import stats dist stats.uniform (0, 2) # left edge 0, width 2 \end{python}` 0 and 2 comes in italic which comes at the last line, any thing mistake I did? Please advise...

    – MadyYuvi Aug 16 '19 at 10:11
  • I've updated my question too... – MadyYuvi Aug 16 '19 at 10:14
  • Just now realised that comma between characters affected this error, is this possible to fix? advise please... – MadyYuvi Aug 16 '19 at 10:17
  • @MadyYuvi Please see the update – siracusa Aug 16 '19 at 10:36
  • Sorry to disturb again and again; now the problem with numbers comes in square brackets, i.e., if a line In [14]: x = np.arange(1, 4) # [1, 2, 3] then the digits comes in italic, how to fix it? please advise.... – MadyYuvi Aug 16 '19 at 11:16
  • @MadyYuvi You can add more entries to the literate option, in this case for [ and ], i.e. literate={,}{{\char`\,}}{1} {[}{{\char`\[}}{1} {]}{{\char`\]}}{1}. – siracusa Aug 16 '19 at 11:37
  • Yes, it helps to fix it, sorry, after sent the message only I realised that, anyhow, thanks a lot.... – MadyYuvi Aug 16 '19 at 12:01