3

I'm defining the VHDL language with listing package. As it is not a popular language, the default settings didn't match my expectation so I write the following language definition to improve it:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{listings}
\usepackage{color}

\definecolor{shellGreen}{RGB}{19,193,106}
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
\definecolor{mateBlack}{RGB}{45,45,50}
\definecolor{comment}{rgb}{0.1,0.6,0.2}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}

\lstdefinestyle{vhdl}{
   language=vhdl,
   frame=single,
   basicstyle=\scriptsize,
   breaklines=true,
   captionpos=b,
   keepspaces=true,
   backgroundcolor=\color{backcolor},
   keywordstyle=[1]\color{blue}\bf,
   keywordstyle=[2]\color{red}\bf,
   keywordstyle=[3]\color{cyan!50}\bf,
   stringstyle=\color{orange},
   commentstyle=\color{comment},
   tabsize=2,
%   number=left,
%   numberstep=5pt,
   showspaces=false,
   showstringspaces=false,
   showtabs=false,
   moredelim=[s][\textcolor{green}]{component}{is},
   morekeywords=[1]{
      library, use ,all,entity,is,port,in,out,end,architecture,of, body,
      function, variable, begin,and,or,Not,downto,ALL, signal, process, if,
      else, elsif, case, when, then, range, to, component, type, with, select,
      others, constant, inout, buffer, map, true, false, array, subtype, wait,
      wait for, generic, =, <, >, <=, >=, =>,
   },
   alsoletter={=, <, >},
   morekeywords=[2]{
          STD_LOGIC_VECTOR,STD_LOGIC,IEEE,STD_LOGIC_1164, work, local, real,
          math_real, time, NUMERIC_STD,STD_LOGIC_ARITH,STD_LOGIC_UNSIGNED,
          std_logic_vector, std_logic, ieee, numeric_std, std_ulogic,
          std_logic_1164, natural, bit, bit_vector, signed, unsigned,
          boolean, integer
    },
    morekeywords=[3]{rising_edge, falling_edge, resize, to_signed, to_unsigned},
    morecomment=[l]{--},
    morecomment=[s][\color{orange}]{'}{'},
}

\lstset{style=vhdl}

\begin{document}
VHDL code:

\begin{lstlisting}[style=vhdl]
  component Input is
    port(
      startButton  : in  std_logic;     -- When 1, start game
      fire         : in  std_logic;     -- When 1, shoot a rocket
      clk          : in  std_logic;     -- 40MHz
      reset        : in  std_logic;     -- Active high
      left         : in  std_logic;     -- Left arrow button
      right        : in  std_logic;     -- Right arrow button
      newMissile   : out std_logic;     -- If 1, new missile launched
      gameStarted  : out std_logic;     -- When 0, show start screen
      alienX       : out std_logic_vector(9 downto 0);  -- first alien position from left screen
      alienY       : out std_logic_vector(8 downto 0);  -- first alien position from top screen
      shipPosition : out std_logic_vector(9 downto 0)   -- Ship x coordinate
      );
  end component;
\end{lstlisting}
\end{document}

This gave me the following output: Output

I have two problems. The first one is how to color in green everything between "component" and "is", but the delimiters should stay in blue (in my example, they are in green as well). I tried this: moredelim=[s][\textcolor{green}]{component}{is}, (Note that without this line, "component" and "is" are display in blue, as I want).

The second problem is, when they is not enough space to displayed a long line, listing start a new line. However, if the last word displayed before starting a new line was colored, the frame will be colored too (this happens three times in my code above, when the comment is split).

Thank in advance to everyone that can help me.

  • 1
    For your second problem, look at this answer. – Tiuri May 15 '17 at 8:37
  • For the first problem, I would only have a workaround that requires editing the VHDL code. I guess that's not what you are looking for? – Tiuri May 15 '17 at 8:40
  • Unfortunately i can't. It's a real project that must respect some syntax rules. – Nakrule May 15 '17 at 8:48
4

The second problem is easy to fix, you just need to give an explicit rulecolor parameter:

 rulecolor=\color{black}

The first one can be solved by defining a new command that does the styling for the component ... is block:

\def\component#1{%
    \textbf{\textcolor{blue}{component\ }}%
    \textcolor{green}{#1}%
    \textbf{\textcolor{blue}{\ is}}%
}

The parameter is the code between component and is (without the spaces). listings allows you to use a styling command taking one parameter in moredelim, while discarding the delimiers itself when the first optional parameter is [is]:

moredelim=[is][\component]{component\ }{\ is},

And here's the complete, updated sample:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{listings}
\usepackage{color}

\definecolor{shellGreen}{RGB}{19,193,106}
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
\definecolor{mateBlack}{RGB}{45,45,50}
\definecolor{comment}{rgb}{0.1,0.6,0.2}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}

\lstdefinestyle{vhdl}{
   language=vhdl,
   frame=single,
   basicstyle=\scriptsize,
   breaklines=true,
   captionpos=b,
   keepspaces=true,
   backgroundcolor=\color{backcolor},
   keywordstyle=[1]\color{blue}\bf,
   keywordstyle=[2]\color{red}\bf,
   keywordstyle=[3]\color{cyan!50}\bf,
   stringstyle=\color{orange},
   commentstyle=\color{comment},
   tabsize=2,
%   number=left,
%   numberstep=5pt,
   showspaces=false,
   showstringspaces=false,
   showtabs=false,
   moredelim=[is][\component]{component\ }{\ is},
   morekeywords=[1]{
      library, use ,all,entity,is,port,in,out,end,architecture,of, body,
      function, variable, begin,and,or,Not,downto,ALL, signal, process, if,
      else, elsif, case, when, then, range, to, component, type, with, select,
      others, constant, inout, buffer, map, true, false, array, subtype, wait,
      wait for, generic, =, <, >, <=, >=, =>,
   },
   alsoletter={=, <, >},
   morekeywords=[2]{
          STD_LOGIC_VECTOR,STD_LOGIC,IEEE,STD_LOGIC_1164, work, local, real,
          math_real, time, NUMERIC_STD,STD_LOGIC_ARITH,STD_LOGIC_UNSIGNED,
          std_logic_vector, std_logic, ieee, numeric_std, std_ulogic,
          std_logic_1164, natural, bit, bit_vector, signed, unsigned,
          boolean, integer
    },
    morekeywords=[3]{rising_edge, falling_edge, resize, to_signed, to_unsigned},
    morecomment=[l]{--},
    morecomment=[s][\color{orange}]{'}{'},
    rulecolor=\color{black},
}
\def\component#1{%
    \textbf{\textcolor{blue}{component\ }}%
    \textcolor{green}{#1}%
    \textbf{\textcolor{blue}{\ is}}%
}

\lstset{style=vhdl}

\begin{document}
VHDL code:

\begin{lstlisting}[style=vhdl]
  component Input is
    port(
      startButton  : in  std_logic;     -- When 1, start game
      fire         : in  std_logic;     -- When 1, shoot a rocket
      clk          : in  std_logic;     -- 40MHz
      reset        : in  std_logic;     -- Active high
      left         : in  std_logic;     -- Left arrow button
      right        : in  std_logic;     -- Right arrow button
      newMissile   : out std_logic;     -- If 1, new missile launched
      gameStarted  : out std_logic;     -- When 0, show start screen
      alienX       : out std_logic_vector(9 downto 0);  -- first alien position from left screen
      alienY       : out std_logic_vector(8 downto 0);  -- first alien position from top screen
      shipPosition : out std_logic_vector(9 downto 0)   -- Ship x coordinate
      );
  end component;
\end{lstlisting}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.