序列literate

序列literate

我正在用 Verilog 代码编写 LaTeX 文档,并且我想在以下场合使用彩色数字:

  • 简单数字(例如# 30
  • 公交车(例如[3:0]
  • 二进制或十六进制表示(例如4'hF

此外,我不希望在字符串(''"")、注释后(//)和字符后(例如i3test_3mod)出现彩色数字。

我已经阅读了其他主题,并且除了最后一个问题(单词中或字符后的数字)之外,我已经解决了这个问题。

如果有人能帮助我,我将非常感激。

这是我的代码:

\documentclass[a4paper, 12pt]{article}
\usepackage[english,greek]{babel} % 
\usepackage[utf8x]{inputenc}
\usepackage{courier} % font for code
\usepackage{kerkis}  % font for normal text
\usepackage{color}   
\usepackage{listings}
\usepackage[usenames,dvipsnames]{xcolor}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Here i define the digits that i want to be colored orange
\newcommand\digitstyle{\color{orange}}
\newcommand\noncoldig{\color{black}}   %********************************
\makeatletter
\newcommand{\ProcessDigit}[1]
{%
  \ifnum\lst@mode=\lst@Pmode\relax%
   {\digitstyle #1}%
  \else
    #1%
  \fi
}
\newcommand{\NotDigit}[1]          %************************
{%
 \ifnum\lst@mode=\lst@Pmode\relax%
  {\noncoldig #1}%
 \else
   #1%
 \fi
}
\makeatother
\lstset{literate=
    {0}{{{\ProcessDigit{0}}}}1
    {1}{{{\ProcessDigit{1}}}}1
    {2}{{{\ProcessDigit{2}}}}1
    {3}{{{\ProcessDigit{3}}}}1
    {4}{{{\ProcessDigit{4}}}}1
    {5}{{{\ProcessDigit{5}}}}1
    {6}{{{\ProcessDigit{6}}}}1
    {7}{{{\ProcessDigit{7}}}}1
    {8}{{{\ProcessDigit{8}}}}1
    {9}{{{\ProcessDigit{9}}}}1
    {.0}{{{\ProcessDigit{.0}}}}2
    {.1}{{{\ProcessDigit{.1}}}}2
    {.2}{{{\ProcessDigit{.2}}}}2
    {.3}{{{\ProcessDigit{.3}}}}2
    {.4}{{{\ProcessDigit{.4}}}}2
    {.5}{{{\ProcessDigit{.5}}}}2
    {.6}{{{\ProcessDigit{.6}}}}2
    {.7}{{{\ProcessDigit{.7}}}}2
    {.8}{{{\ProcessDigit{.8}}}}2
    {.9}{{{\ProcessDigit{.9}}}}2
    {'h}{{{\ProcessDigit{'h}}}}2
    {'b}{{{\ProcessDigit{'b}}}}2
    {A}{{{\ProcessDigit{A}}}}1
    {B}{{{\ProcessDigit{B}}}}1
    {C}{{{\ProcessDigit{C}}}}1
    {D}{{{\ProcessDigit{D}}}}1
    {E}{{{\ProcessDigit{E}}}}1
    {F}{{{\ProcessDigit{F}}}}1
    {\_4}{{{\NotDigit{\_4}}}}2,  %*********************** 
    morestring=[b]",
    morestring=[b]',
    morecomment=[l]//,
}

% Here i define the language
\definecolor{mygreen}{RGB}{28,172,0} 
\lstset{language=Verilog, 
    basicstyle=\small\selectlanguage{english}\ttfamily,   
    breaklines=true,
    morekeywords={},
    keywordstyle=\color{blue},
    morekeywords=[2]{1}, keywordstyle=[2]{\color{black}},
    identifierstyle=\color{black},
    commentstyle=\color{mygreen},
    showstringspaces=false,
    frame=single,
    numbers=left,
    numberstyle={\small \color{black}},
    numbersep=9pt, 
}

% Here i define the caption
\renewcommand{\lstlistingname}{Κώδικας \textlatin{Verilog}} % in english it means: Verilog Code

\begin{document}

\begin{lstlisting}[caption =\textlatin{\texttt{test\_4bit\_counter.v}}]
module test_4bit_counter (); // 4 must not be colored orange

  reg clk, s_s, ld, clr;
  wire [3:0] cnt;            // 3, 0 are correctly colored
  wire c0;                   // 0 must not be colored orange

  four_bit_counter inst0 (clk, s_s, ld, clr, dt, cnt, c0);
  // 0 must not be colored orange
  initial 
    begin
      # 5 clk <= 0; s_s <= 0; ld <= 0; clr <= 0; dt <= 4'hD;
    end  // all digits are correctly colored

  always # 10 clk <= !clk; // 10 is correctly colored
    initial 
      begin
        # 30 clr <= 1; // 30, 1 is correctly colored
      end

endmodule
\end{lstlisting}

\end{document}

答案1

literate看来我们不能同时激活单字母和双字母序列(listings包裹。

因此,我在 Lua 中创建了一个小补丁。它以用 Verilog 语言编写的输入文件(假设它是以verilog-input.v开头\begin{lstlisting}并以 结尾的文件\end{lstlisting})为输入,找到关键点并进行更改。输出写入文件verilog-output.v,我们可以通过 将其加载到 TeX 中\input verilog-output.v。在下面的示例中,我将结果直接包含在 LaTeX 文件中,以便于与代码的原始版本进行比较。

如果我们还想运行 Verilog 代码(输入文件),我们需要删除\begin{lstlisting}[...]部分\end{lstlisting}内容,然后使用\lstinputlisting命令(例如,参见listings请使用“手册”来代替命令\input

我在 Lua 中使用了常见的正则表达式。在 TeX 级别,我将的颜色改为identifierstyle红色,这样我们就能发现它与普通文本的区别。(下划线 +)数字的样式与命令中设置的basicstyle+组合相同。如果我们在命令中更改颜色,我们就能识别出那些关键部分。identifierstyle\lstset\maldigitstyle

关键的改变是我激活了mathescape,然后我们就可以在该区域排版任何东西了。关键命令如下所示:\def\maldigitstyle#1{{\color{red}\textrm{\ttfamily\small#1}}}。修改后的一个点如下所示:module test$\maldigitstyle{\_4}$bit_counter ();。我们可以看到,Lua 代码片段还将下划线改为\_,原因是当我们进入常规 TeX 环境时,下划线再次成为活动字符。

我附上了这两个文件和结果预览。将 Verilog 代码提取到输入文件后,我们运行这两个命令(可以使用任何 LaTeX 引擎):

texlua verilog-convert.lua
lualatex mal-digits.tex

Lua代码是该verilog-convert.lua文件:

-- A Lua snippet which converts _azAZ + digit sequence to a command.
-- texlua verilog-convert.lua

input="verilog-input.v"
output="verilog-output.v"

f=io.open(input, "r")
malcontent=f:read("*a")
--print(malcontent) -- an original version
f:close()

malcontent=unicode.utf8.gsub(malcontent, "([^\\])([_a-zA-Z][0-9]+)", function(s,t)
   print("Wrapping "..s..t.." into a command...")
   if string.sub(t,1,1)~="_" then s=s..string.sub(t,1,1); t=string.sub(t, 2) end
   --print(s,t)
   t=string.gsub(t,"_","\\_")
   return s.."$\\maldigitstyle{"..t.."}$"
   end -- function(s)
   )
--print(malcontent) -- a modified version

newf=io.open(output, "w")
newf:write(malcontent)
newf:close()

TeX 代码是mal-digits.tex文件:

\documentclass[a4paper, 12pt]{article}
\usepackage[english,greek]{babel} % 
\usepackage[utf8x]{inputenc}
\usepackage{courier} % font for code
\usepackage{kerkis}  % font for normal text
\usepackage{color}   
\usepackage{listings}
\usepackage[usenames,dvipsnames]{xcolor}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Here i define the digits that i want to be colored orange
\newcommand\digitstyle{\color{orange}}
\newcommand\noncoldig{\color{black}}   %********************************
\makeatletter
\newcommand{\ProcessDigit}[1]
{%
  \ifnum\lst@mode=\lst@Pmode\relax%
   {\digitstyle #1}%
  \else
    #1%
  \fi
}
\newcommand{\NotDigit}[1]          %************************
{%
 \ifnum\lst@mode=\lst@Pmode\relax%
  {\noncoldig #1}%
 \else
   #1%
 \fi
}
\makeatother
\lstset{literate=
    {0}{{{\ProcessDigit{0}}}}1
    {1}{{{\ProcessDigit{1}}}}1
    {2}{{{\ProcessDigit{2}}}}1
    {3}{{{\ProcessDigit{3}}}}1
    {4}{{{\ProcessDigit{4}}}}1
    {5}{{{\ProcessDigit{5}}}}1
    {6}{{{\ProcessDigit{6}}}}1
    {7}{{{\ProcessDigit{7}}}}1
    {8}{{{\ProcessDigit{8}}}}1
    {9}{{{\ProcessDigit{9}}}}1
    {.0}{{{\ProcessDigit{.0}}}}2
    {.1}{{{\ProcessDigit{.1}}}}2
    {.2}{{{\ProcessDigit{.2}}}}2
    {.3}{{{\ProcessDigit{.3}}}}2
    {.4}{{{\ProcessDigit{.4}}}}2
    {.5}{{{\ProcessDigit{.5}}}}2
    {.6}{{{\ProcessDigit{.6}}}}2
    {.7}{{{\ProcessDigit{.7}}}}2
    {.8}{{{\ProcessDigit{.8}}}}2
    {.9}{{{\ProcessDigit{.9}}}}2
    {'h}{{{\ProcessDigit{'h}}}}2
    {'b}{{{\ProcessDigit{'b}}}}2
    {A}{{{\ProcessDigit{A}}}}1
    {B}{{{\ProcessDigit{B}}}}1
    {C}{{{\ProcessDigit{C}}}}1
    {D}{{{\ProcessDigit{D}}}}1
    {E}{{{\ProcessDigit{E}}}}1
    {F}{{{\ProcessDigit{F}}}}1
    {\_4}{{{\NotDigit{\_4}}}}2,  %*********************** 
    morestring=[b]",
    morestring=[b]',
    morecomment=[l]//,
}

% Here i define the language
\definecolor{mygreen}{RGB}{28,172,0} 
\lstset{language=Verilog, 
    basicstyle=\small\selectlanguage{english}\ttfamily,   
    breaklines=true,
    morekeywords={},
    keywordstyle=\color{blue},
    morekeywords=[2]{1}, keywordstyle=[2]{\color{black}},
    identifierstyle=\color{red},
    commentstyle=\color{mygreen},
    showstringspaces=false,
    frame=single,
    numbers=left,
    numberstyle={\small \color{black}},
    numbersep=9pt, 
    mathescape=true,
}

% Here i define the caption
\renewcommand{\lstlistingname}{Κώδικας \textlatin{Verilog}} % in english it means: Verilog Code

% basicstyle+identifierstyle
\def\maldigitstyle#1{{\color{red}\textrm{\ttfamily\small#1}}}
\addtolength{\textheight}{3in}
\addtolength{\voffset}{-1in}

\begin{document}
% common loading of a file would be:
% \input verilog-output.v
\begin{lstlisting}[caption =\textlatin{\texttt{test\_4bit\_counter.v}}]
module test$\maldigitstyle{\_4}$bit_counter (); // 4 must not be colored orange

  reg clk, s_s, ld, clr;
  wire [3:0] cnt;            // 3, 0 are correctly colored
  wire c$\maldigitstyle{0}$;                   // 0 must not be colored orange

  four_bit_counter inst$\maldigitstyle{0}$ (clk, s_s, ld, clr, dt, cnt, c$\maldigitstyle{0}$);
  // 0 must not be colored orange
  initial 
    begin
      # 5 clk <= 0; s_s <= 0; ld <= 0; clr <= 0; dt <= 4'hD;
    end  // all digits are correctly colored

  always # 10 clk <= !clk; // 10 is correctly colored
    initial 
      begin
        # 30 clr <= 1; // 30, 1 is correctly colored
      end

endmodule
\end{lstlisting}

\ifx\relax % this is the original version
% common loading would be:
% \input verilog-input.v
\begin{lstlisting}[caption =\textlatin{\texttt{test\_4bit\_counter.v}}]
module test_4bit_counter (); // 4 must not be colored orange

  reg clk, s_s, ld, clr;
  wire [3:0] cnt;            // 3, 0 are correctly colored
  wire c0;                   // 0 must not be colored orange

  four_bit_counter inst0 (clk, s_s, ld, clr, dt, cnt, c0);
  // 0 must not be colored orange
  initial 
    begin
      # 5 clk <= 0; s_s <= 0; ld <= 0; clr <= 0; dt <= 4'hD;
    end  // all digits are correctly colored

  always # 10 clk <= !clk; // 10 is correctly colored
    initial 
      begin
        # 30 clr <= 1; // 30, 1 is correctly colored
      end

endmodule
\end{lstlisting} 
\fi % end of an original version

\end{document}

Lua 代码片段输出示例

序列literate

如果我们想试验一下代码,这个 Lua 代码片段会将 [下划线,字母] + 数字组合生成到文件中mal-corr.tex)。我根本没有使用它,但它可能会有所帮助。我们运行texlua mal-corrector.lua

-- chrleft={ {65,90}, {97,122} }
chrleft={ {95,95}, {65,90}, {97,122} }
f=io.open("mal-corr.tex","w")

f:write([[\lstset{literate=
]])
for counter, outerlr in pairs(chrleft) do
for outer=outerlr[1],outerlr[2] do
for inner=0,9 do
-- print(outer,string.char(outer))
together=string.char(outer)..inner
f:write([[    {]]..together..[[}{{{\NotDigit{]]..together..[[}}}}2
]])
end -- inner
end -- outer
end -- outerlr
f:write([[}
]])
f:close()

相关内容