测试数字是否在逗号分隔的范围/数字列表中

测试数字是否在逗号分隔的范围/数字列表中

Martin Scharrer 针对这个问题发表了一个非常优雅的答案“利用列表创建斑马效果”。我想扩展该代码以仅突出显示逗号分隔列表中给出的行。动机是我想突出显示从文件输入的某些功能齐全的 C 代码行,而不使用任何转义字符

这意味着我需要一个命令

\ifinrange{<num>}{<range>}{<TRUE>}{<FALSE>}% num>=0

范围{-2,4,8-10, 15-}{0,1,2,4,8,9,10,15,16,...}

\ifinrange{ 0}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE
\ifinrange{ 3}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> FALSE
\ifinrange{ 4}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE
\ifinrange{ 9}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE    %% EDIT: changed 7 to 9
\ifinrange{11}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> FALSE
\ifinrange{20}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE

下面的代码

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{beramono}
\usepackage{listings}
\usepackage{xcolor}
\makeatletter
\newcommand\realnumberstyle[1]{}
\newcommand{\HighLight}[3]{%
    {\realnumberstyle{#3}}%
    \begingroup
    \lst@basicstyle
    \ifinrange{\value{lstnumber}}{#2}{%
        \color{#1}%
        \rlap{\hspace*{\lst@numbersep}%
        \color@block{\linewidth}{\ht\strutbox}{\dp\strutbox}}}{}%
    \endgroup}
\newcommand{\ifinrange}[4]{}%%<<<<<<<<<<<<<<<<<
\makeatother
\begin{document}
\begin{lstlisting}[language=C,
                   basicstyle=\ttfamily,
                   numberstyle=\HighLight{green!35}{-3,6},
                   numbers=left]
/**
* Prints Hello World.
**/
#include <stdio.h>

int main(void) {
   printf("Hello World!");
   return 0;
}
\end{lstlisting}
\end{document}

必须生产

在此处输入图片描述

答案1

这是一个适用于您输入的基本解决方案。它可能会在错误位置的空格处中断,因此请避免使用它们。

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{beramono}
\usepackage{listings}
\usepackage{xcolor}
\makeatletter
\newcommand\realnumberstyle[1]{}
\newcommand{\HighLight}[3]{%
    {\realnumberstyle{#3}}%
    \begingroup
    \lst@basicstyle
    \ifinrange{\value{lstnumber}}{#2}{%
        \color{#1}%
        \rlap{\hspace*{\lst@numbersep}%
        \color@block{\linewidth}{\ht\strutbox}{\dp\strutbox}}}{}%
    \endgroup}

\usepackage{pgf}
\usepackage{pgffor}

\newcount\rangea
\newcount\rangeb

\newcommand\ifinrange[2]{%
    \global\let\inrange\@secondoftwo
    \foreach \range in {#2} {%
        \afterassignment\getrangeb
        \rangea=0\range\relax
        \pgfmathtruncatemacro\result{ ( #1 >= \rangea) && (#1 <= \rangeb) }%
        \ifnum\result=1\relax
            \breakforeach
            \global\let\inrange\@firstoftwo
        \fi
    }%
    \inrange
}
\newcommand\getrangeb{%
    \@ifnextchar\relax
        {\rangeb=\rangea}%
        {\@getrangeb}%
}
\def\@getrangeb-#1\relax{%
    \ifx\relax#1\relax
        \rangeb=100000%   \maxdimen is too large for pgfmath
    \else
        \rangeb=#1\relax
    \fi
}

\makeatother
\begin{document}
\begin{lstlisting}[language=C,
                   basicstyle=\ttfamily,
                   numberstyle=\HighLight{green!35}{-3,6},
                   numbers=left]
/**
* Prints Hello World.
**/
#include <stdio.h>

int main(void) {
   printf("Hello World!");
   return 0;
}
\end{lstlisting}
\end{document}

结果

相关内容