我如何突出显示 JSON 字符串值但不突出显示属性?

我如何突出显示 JSON 字符串值但不突出显示属性?
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 的搜索中名列前茅,我认为将其包括在内很有用。

相关内容