example
{
"name" : "alan",
"alias" : "nala"
}
If I use
morecomment=[s][\color{red}]{"}{"},
How can I highlight JSON string values (on the right side) but not the attributes (left side)?
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It only takes a minute to sign up.
Sign up to join this communityexample
{
"name" : "alan",
"alias" : "nala"
}
If I use
morecomment=[s][\color{red}]{"}{"},
How can I highlight JSON string values (on the right side) but not the attributes (left side)?
A MWE is really needed here, so what follows is a bit of a shot in the dark...
Edit: now you can specify a distinct style for numerical JSON values.
\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}
Building on @jub0bs's fantastic answer, I was able to devise the following language definition:
\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}
The main fix introduced here is that whitespace is ignored --- multiple key/value pairs can exist on the same line and get highlighted correctly, while there can also be multiple lines between the key and the value and highlighting is also retained in this case:
Another useful improvement is that this version also supports highlighting of the key, rather than just the value. While this was not required for the initial question, it is a common use case, and since this question is at the top of searches on how highlight JSON in this manner, I feel that it is useful to include.
\documentclass{...}
and ending with\end{document}
. – jub0bs Aug 8 '14 at 16:27