Typesetting for a Verilog LstInput

Hack to make this work.

I initially wrote the stuff below about listings really bizarre behavior and then immediately discovered a hack that makes this work. The key is to use moredelim=*[s][\colorIndex]{[}{]} where \colorIndex is a new macro that examines the listings-internal token register \lst@token to decide what to typeset. It also makes : display in a literate style which combines with the * option to moredelim to make this work. Contrary to my assertion at the very bottom of this answer, \lst@token does contain the material to be typeset, but not when ** is given to moredelim which was how I tested.

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\definecolor{vgreen}{RGB}{104,180,104}
\definecolor{vblue}{RGB}{49,49,255}
\definecolor{vorange}{RGB}{255,143,102}

\lstdefinestyle{verilog-style}
{
    language=Verilog,
    basicstyle=\small\ttfamily,
    keywordstyle=\color{vblue},
    identifierstyle=\color{black},
    commentstyle=\color{vgreen},
    numbers=left,
    numberstyle=\tiny\color{black},
    numbersep=10pt,
    tabsize=8,
    moredelim=*[s][\colorIndex]{[}{]},
    literate=*{:}{:}1
}

\makeatletter
\newcommand*\@lbracket{[}
\newcommand*\@rbracket{]}
\newcommand*\@colon{:}
\newcommand*\colorIndex{%
    \edef\@temp{\the\lst@token}%
    \ifx\@temp\@lbracket \color{black}%
    \else\ifx\@temp\@rbracket \color{black}%
    \else\ifx\@temp\@colon \color{black}%
    \else \color{vorange}%
    \fi\fi\fi
}
\makeatother

\usepackage{trace}
\begin{document}

\begin{lstlisting}[style={verilog-style}]
module Mixing {
    ///////// ADC /////////
    inout              ADC_CS_N,
    output             ADC_DIN,
    input              ADC_DOUT,
    output             ADC_SCLK,

    ///////// ADC /////////
    input              AUD_ADCDAT,
    inout              AUD_ADCLRCK,
    inout              AUD_BCLK,
    output             AUD_DACDAT,
    inout              AUD_DACLRCK,
    output             AUD_XCK,

    ///////// clocks /////////
    input              clock2_50,
    input              clock3_50,
    input              clock4_50,
    input              clock_50,

    ///////// HEX /////////
    output      [6:0]  HEX0,
    output      [6:0]  HEX1,
    output      [6:0]  HEX2,
    output      [6:0]  HEX3,
    output      [6:0]  HEX4,
    output      [6:0]  HEX5,

    ///////// FOO /////////
    output      [2]    FOO,
}
\end{lstlisting}
\end{document}

enter image description here

Bizarre listings behavior.

This was initially a nonanswer that was too complicated for a comment. Almost immediately after posting it, I found the workaround above.

The two "obvious" ideas I have for this are the following.

  1. Make : be typeset as literate in black. Combining this with the * or ** option in moredelim typesets the colon in black.
  2. Use the answer you pointed out in the comments to create a new macro \colorIndex that takes one argument and typesets it in orange with brackets surrounding it. This is in conjunction with the is delimiter style.

Unfortunately, this doesn't solve the problem. The argument that get passed to \colorIndex is fairly complicated, it gets used multiple times to style various parts, including the space before the [6:0]!

Here's an example that demonstrates this bizarre behavior.

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\definecolor{vgreen}{RGB}{104,180,104}
\definecolor{vblue}{RGB}{49,49,255}
\definecolor{vorange}{RGB}{255,143,102}

\lstdefinestyle{verilog-style}
{
    language=Verilog,
    basicstyle=\small\ttfamily,
    keywordstyle=\color{vblue},
    identifierstyle=\color{black},
    commentstyle=\color{vgreen},
    numbers=left,
    numberstyle=\tiny\color{black},
    numbersep=10pt,
    tabsize=8,
    literate=*{:}{{\textcolor{black}{:}}}1
}

\newcommand\colorIndex[1]{[\textcolor{vorange}{#1}]}

\begin{document}

No delimiters.
\begin{lstlisting}[style={verilog-style}]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=[s][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[s][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[s][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[s][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[s][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[s][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=[s][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[s][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[s][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[s][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[s][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[s][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\newpage
\verb!moredelim=[is][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[is][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[is][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[is][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[is][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[is][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=[is][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[is][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[is][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[is][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[is][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[is][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}
\end{document}

You can see how the various settings for moredelim change the output. First, using the [s] style of delimiters.

enter image description here

And now using [is].

enter image description here

I really can't explain this behavior. I was hoping to use moredelim=*[s][\colorIndex]{[}{]} and have \colorIndex examine its arguments to decide how to style the various pieces.

I tried poking around at listings internals to see if \colorIndex could determine what it was about to typeset in order to set the appropriate color, but I didn't see anything useful. (There's a \lst@token which is a token register which looks like it's used to fill in the various parts of the line, but it was always empty when \colorIndex was called.)

I don't have time to investigate this further right now, but hopefully someone else will have an idea.