解析分隔符内的键值对,并在列表列表中为每个标记添加不同的颜色

解析分隔符内的键值对,并在列表列表中为每个标记添加不同的颜色

这是我的代码:

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\lstset{
    basicstyle=\ttfamily,
    moredelim=*[s][\color{gray}]{[}{]},
    keywords=[0]{a,b,foo,baz},
    keywords=[1]{Apple,Ball,bar,qux},
    keywordstyle=[0]\color{blue},
    keywordstyle=[1]\color{red},
}
\begin{document}
\begin{lstlisting}
[ a = Apple ]
[ b = Ball ]
[ foo = bar ]
[ baz = qux ]
Other text is rendered in basic style.
\end{lstlisting}
\end{document}

输出如下:

在此处输入图片描述

上面的输出是所需的输出。但上面的 LaTeX 代码不是所需的代码。我希望 LaTeX 代码能够处理任意键名和值名。键名和值名不能在 LaTeX 代码中硬编码。

顺便说一句,如果这很重要的话,在我的语法中,关键名称是关键词并且值名称是字符串。如果解决方案可以将键名解析为关键字,将值名解析为字符串并相应地设置样式,那就太好了,但不是必需的。

答案1

使用版本listings

以下是利用该功能获得所需效果的解决方案。为此,分别定义了literate字符[=和的三个钩子。]

每当[文本中出现 a 时,方括号将设置为括号颜色,其余文本将切换到关键颜色。字符也会发生类似情况=,但后面的文本将设置为值部分的颜色。最后,每当]出现 a 时,我们将切换回其他颜色。

由于值部分可能会出现额外的平衡方括号,因此这里也使用了上一个解决方案中使用的括号计数(见下文)。为了检查我们当前是否处于值部分,\ifinvaluepart引入了一个新的条件开关。

新版本的示例代码:

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}

\definecolor{brackets}{named}{gray}
\definecolor{keys}{named}{blue}
\definecolor{values}{named}{red}
\definecolor{other}{named}{black}

\makeatletter
\lstset{
    basicstyle={\global\invaluepartfalse
                \global\@brack@level=0
                \ttfamily\color{other}},
    literate={[}{{\@open@bracket}}1 {=}{{\@equal@sign}}1 {]}{{\@close@bracket}}1
}

\newcount\@brack@level
\newif\ifinvaluepart

\def\@open@bracket{%
    \ifinvaluepart
        \global\advance\@brack@level 1
        [%
    \else
        \textcolor{brackets}{[}%
        \color{keys}%
    \fi
}
\def\@equal@sign{%
    \ifinvaluepart
        =%
    \else
        \global\invalueparttrue
        \textcolor{brackets}{=}%
        \color{values}%
    \fi
}
\def\@close@bracket{%
    \ifinvaluepart
        \ifnum\@brack@level>0
            \global\advance\@brack@level -1
            ]%
        \else
            \global\invaluepartfalse
            \textcolor{brackets}{]}%
            \color{other}%
        \fi
    \else
        ]%
    \fi
}
\makeatother

\begin{document}
\begin{lstlisting}
[ a = Apple ]
[ b = Ball ]
[ foo = bar ]
[ baz = qux ]
[ 'foobar' = "#" + val[x[i][j]] ]
[ \LaTeX = \textbf{cool} ]
Other text is rendered in basic style.
\end{lstlisting}
\end{document}

在此处输入图片描述


替代版本使用alltt

这并非您所要求的,但无论如何,它也许对您有用。listings我们使用该alltt包来排版代码。这使得解析键/值对变得更容易(或完全可能)。

首先,我们基于定义一个新环境kvcolor(实际上\kvcolor也是唯一一个) 。此外,将字符设为活动字符,并定义一个新命令,该命令使用 TeX 的分隔参数扫描第一个字符之后的所有内容,将中间的文本设置为关键字,然后将控制权移交给以解析值部分。\endkvcoloralltt[[=\@find@string@end

我们也可以使用分隔参数作为值,但您注意到值应该是字符串类型,因此最好它们也可以包含方括号。为此,\@find@string@end逐个字符进行扫描,从而计算平衡的[/]对,直到找到最后一个]。在两者之间找到的所有内容都被视为值字符串的一部分。

这种方法相对简单,但有几个缺点。最明显的是,包提供的所有花哨功能都不listings可用。此外,环境保留了、和字符alltt的通常含义。如果您在其他文本中需要它们,则必须明确转义它们。另一方面,当值字符串的扫描处于活动状态时,这些字符将变为可打印字符,否则如果在值字符串中使用带参数的宏,它将严重中断。如上所述,方括号也必须匹配。\{}

完整代码如下:

\documentclass{article}
\usepackage{xcolor}
\usepackage{alltt}

\definecolor{brackets}{named}{gray}
\definecolor{keys}{named}{blue}
\definecolor{values}{named}{red}
\definecolor{other}{named}{black}

\makeatletter
\newcount\@brack@level

\begingroup
\catcode`\[=\active
\gdef\kvcolor{%
    \alltt
    \color{other}
    \catcode`\[=\active
    \def[##1={%
        \global\@brack@level=0
        \begingroup
        \color{brackets}%
        \char`\[%
        \textcolor{keys}{##1}%
        \char`\=%
        \bgroup
        \catcode`\[=12 \catcode`\\=12
        \catcode`\{=12 \catcode`\}=12
        \color{values}
        \@find@string@end
    }
}
\endgroup

\def\@find@string@end#1{%
    \let\@next=\@find@string@end
    \if\noexpand#1[%
        \global\advance\@brack@level 1
        \char`\[%
    \else \if\noexpand#1]%
        \ifnum\@brack@level>0
            \global\advance\@brack@level -1
            \char`\]%
        \else
            \let\@next=\@string@finish
        \fi
    \else
        #1%
    \fi\fi
    \@next
}
\def\@string@finish{%
    \egroup % \color
    \char`\]%
    \endgroup
}

\let\endkvcolor=\endalltt
\makeatother

\begin{document}
\begin{kvcolor}
[ a = Apple ]
[ b = Ball ]
[ foo = bar ]
[ baz = qux ]
[ 'foobar' = "#" + val[x[i][j]] ]
[ \LaTeX = \textbf{cool} ]
Other text is rendered in basic style.
\end{kvcolor}
\end{document}

在此处输入图片描述

相关内容