55

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?

4
  • 2
    the full json definition is on the page json.org Nov 17, 2012 at 15:04
  • 1
    @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, 2012 at 15:39
  • 1
    I updated my answer; I initially overlooked the numerals issue; now I've added it to my answer. Nov 17, 2012 at 16:55
  • 1
    both single- and double-quoted strings should probably have the [b] type as they are backslash-escaped in JSON (and Javascript).
    – mlc
    Apr 8, 2014 at 20:01

2 Answers 2

85

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}

enter image description here

3
  • 6
    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, 2014 at 6:47
  • 1
    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, 2015 at 10:24
  • 4
    @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. Jan 4, 2016 at 12:58
16

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}
}
2
  • 4
    Thanks, this version fixed some errors I get with the accepted answer. Dec 6, 2019 at 12:38
  • 1
    Thank you! I like the color pallete you defined.
    – Huyen
    Jun 10, 2023 at 0:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .