# How to improve listings display of JSON files?

I was wondering if there is a good way for JSON files to be listed with the listings package.

The only language definition I could come up with, is this:

\lstdefinelanguage{json}
{
morestring=[b]",
morestring=[d]'
}


Now, this highlights the strings used in JSON files, but the important syntactical things in JSON are the curly braces, the square brackets, commas, and colons. I have sadly no Idea how I could make them be highlighted in a different manner. I tried adding { and } as identifier or as keywords, but it didn't work.

I'd really like to make listed JSON files appear nicer, since on a project I need to document I'd really need it. Also, I couldn't find a JSON definition for that on the internet, anywhere else.

On a more general thought: can I highlight all numerals with listings?

• the full json definition is on the page json.org – David Carlisle Nov 17 '12 at 15:04
• @DavidCarlisle yes, I know that, but I still don't know how to construct a language definition for listings. Symbols such as { are not accepted as keywords. Or I'm doing something wrong. – polemon Nov 17 '12 at 15:39
• I updated my answer; I initially overlooked the numerals issue; now I've added it to my answer. – Gonzalo Medina Nov 17 '12 at 16:55
• both single- and double-quoted strings should probably have the [b] type as they are backslash-escaped in JSON (and Javascript). – mlc Apr 8 '14 at 20:01

## 2 Answers

Here's one possibility for the colon, comma, braces, square brackets, and numbers, using the literate key:

\documentclass{article}
\usepackage{bera}% optional: just to have a nice mono-spaced font
\usepackage{listings}
\usepackage{xcolor}

\colorlet{punct}{red!60!black}
\definecolor{background}{HTML}{EEEEEE}
\definecolor{delim}{RGB}{20,105,176}
\colorlet{numb}{magenta!60!black}

\lstdefinelanguage{json}{
basicstyle=\normalfont\ttfamily,
numbers=left,
numberstyle=\scriptsize,
stepnumber=1,
numbersep=8pt,
showstringspaces=false,
breaklines=true,
frame=lines,
backgroundcolor=\color{background},
literate=
*{0}{{{\color{numb}0}}}{1}
{1}{{{\color{numb}1}}}{1}
{2}{{{\color{numb}2}}}{1}
{3}{{{\color{numb}3}}}{1}
{4}{{{\color{numb}4}}}{1}
{5}{{{\color{numb}5}}}{1}
{6}{{{\color{numb}6}}}{1}
{7}{{{\color{numb}7}}}{1}
{8}{{{\color{numb}8}}}{1}
{9}{{{\color{numb}9}}}{1}
{:}{{{\color{punct}{:}}}}{1}
{,}{{{\color{punct}{,}}}}{1}
{\{}{{{\color{delim}{\{}}}}{1}
{\}}{{{\color{delim}{\}}}}}{1}
{[}{{{\color{delim}{[}}}}{1}
{]}{{{\color{delim}{]}}}}{1},
}

\begin{document}

\begin{lstlisting}[language=json,firstnumber=1]
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
0123456789
\end{lstlisting}

\end{document}


• One issue is that in a number-alphabet combination (such as a web address), the numbers also get highlighted in the same manner as standalone numbers, while alphabets don't get highlighted, which makes it a little bit weird. – xji Dec 14 '14 at 6:47
• Another issue is that string literals don't behave as such; for instance, if I have a { inside a string literal, it's also marked up. My example is { "fmt": "CREATE %{persistence}s TABLE %{identity}D %{if_not_exists}s (%{table_elements:, }s) %{inherits}s %{on_commit}s %{tablespace}s" } – alvherre Jul 17 '15 at 10:24
• @XiangJi morestring=[b]" after the last literate, i.e. after {]}{{{\color{delim}{]}}}}{1}, treats everything within double quotes as a String, overwriting the literate-behaviour for numbers. You might have to also define a stringstyle in order to get a consistent layout for your listing. – PattaFeuFeu Jan 4 '16 at 12:58

Here is an alternate solution which isn't always accurate but if your JSON is formatted "the usual way" it gives quite nice results and colors attributes different from values.

\usepackage{bera}% optional: just to have a nice mono-spaced font
\usepackage{listings}
\usepackage{xcolor}

\definecolor{eclipseStrings}{RGB}{42,0.0,255}
\definecolor{eclipseKeywords}{RGB}{127,0,85}
\colorlet{numb}{magenta!60!black}

\lstdefinelanguage{json}{
basicstyle=\normalfont\ttfamily,
commentstyle=\color{eclipseStrings}, % style of comment
stringstyle=\color{eclipseKeywords}, % style of strings
numbers=left,
numberstyle=\scriptsize,
stepnumber=1,
numbersep=8pt,
showstringspaces=false,
breaklines=true,
frame=lines,
backgroundcolor=\color{gray}, %only if you like
string=[s]{"}{"},
comment=[l]{:\ "},
morecomment=[l]{:"},
literate=
*{0}{{{\color{numb}0}}}{1}
{1}{{{\color{numb}1}}}{1}
{2}{{{\color{numb}2}}}{1}
{3}{{{\color{numb}3}}}{1}
{4}{{{\color{numb}4}}}{1}
{5}{{{\color{numb}5}}}{1}
{6}{{{\color{numb}6}}}{1}
{7}{{{\color{numb}7}}}{1}
{8}{{{\color{numb}8}}}{1}
{9}{{{\color{numb}9}}}{1}
}