example
{
"name" : "alan",
"alias" : "nala"
}
如果我使用
morecomment=[s][\color{red}]{"}{"},
我如何突出显示 JSON 字符串值(在右侧)但不突出显示属性(在左侧)?
答案1
这里确实需要 MWE,因此接下来的内容有点像是盲目尝试……
编辑:现在您可以为数值 JSON 值指定独特的样式。
\documentclass{article}
%\usepackage[T1]{fontenc}
%\usepackage[scaled=0.85]{beramono}
\usepackage{xcolor}
\usepackage{listings}
\newcommand\JSONnumbervaluestyle{\color{blue}}
\newcommand\JSONstringvaluestyle{\color{red}}
% switch used as state variable
\newif\ifcolonfoundonthisline
\makeatletter
\lstdefinestyle{json}
{
showstringspaces = false,
keywords = {false,true},
alsoletter = 0123456789.,
morestring = [s]{"}{"},
stringstyle = \ifcolonfoundonthisline\JSONstringvaluestyle\fi,
MoreSelectCharTable =%
\lst@DefSaveDef{`:}\colon@json{\processColon@json},
basicstyle = \ttfamily,
keywordstyle = \ttfamily\bfseries,
}
% flip the switch if a colon is found in Pmode
\newcommand\processColon@json{%
\colon@json%
\ifnum\lst@mode=\lst@Pmode%
\global\colonfoundonthislinetrue%
\fi
}
\lst@AddToHook{Output}{%
\ifcolonfoundonthisline%
\ifnum\lst@mode=\lst@Pmode%
\def\lst@thestyle{\JSONnumbervaluestyle}%
\fi
\fi
%override by keyword style if a keyword is detected!
\lsthk@DetectKeywords%
}
% reset the switch at the end of line
\lst@AddToHook{EOL}%
{\global\colonfoundonthislinefalse}
\makeatother
\begin{document}
\section{A simple example}
\begin{lstlisting}[style=json]
example
{
"name" : "alan",
"alias" : "nala",
}
\end{lstlisting}
\section{A more complicated example}
\begin{lstlisting}[style=json]
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"height_cm": 167.6,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
]
}
\end{lstlisting}
\end{document}
答案2
构建于@jub0bs 的精彩回答,我能够设计出以下语言定义:
\documentclass{article}
%\usepackage[T1]{fontenc}
\usepackage{xcolor}
\usepackage{listings}
\newcommand\jsonkey{\color{purple}}
\newcommand\jsonvalue{\color{cyan}}
\newcommand\jsonnumber{\color{orange}}
% switch used as state variable
\makeatletter
\newif\ifisvalue@json
\lstdefinelanguage{json}{
tabsize = 4,
showstringspaces = false,
keywords = {false,true},
alsoletter = 0123456789.,
morestring = [s]{"}{"},
stringstyle = \jsonkey\ifisvalue@json\jsonvalue\fi,
MoreSelectCharTable = \lst@DefSaveDef{`:}\colon@json{\enterMode@json},
MoreSelectCharTable = \lst@DefSaveDef{`,}\comma@json{\exitMode@json{\comma@json}},
MoreSelectCharTable = \lst@DefSaveDef{`\{}\bracket@json{\exitMode@json{\bracket@json}},
basicstyle = \ttfamily
}
% enter "value" mode after encountering a colon
\newcommand\enterMode@json{%
\colon@json%
\ifnum\lst@mode=\lst@Pmode%
\global\isvalue@jsontrue%
\fi
}
% leave "value" mode: either we hit a comma, or the value is a nested object
\newcommand\exitMode@json[1]{#1\global\isvalue@jsonfalse}
\lst@AddToHook{Output}{%
\ifisvalue@json%
\ifnum\lst@mode=\lst@Pmode%
\def\lst@thestyle{\jsonnumber}%
\fi
\fi
%override by keyword style if a keyword is detected!
\lsthk@DetectKeywords%
}
\makeatother
\begin{document}
\section{A complex example}
\begin{lstlisting}[language=json]
{
"hello": "world",
"traits": {"rotated": false, "x": 100, "y": 200},
"name":
"test"
}
\end{lstlisting}
\end{document}
这里介绍的主要修复是忽略空格——多个键/值对可以存在于同一行并正确突出显示,而键和值之间也可以有多行,在这种情况下也会保留突出显示:
另一个有用的改进是,此版本还支持突出显示键,而不仅仅是值。虽然这对于初始问题来说不是必需的,但它是一个常见的用例,而且由于这个问题在关于如何以这种方式突出显示 JSON 的搜索中名列前茅,我认为将其包括在内很有用。