我正在用 Verilog 代码编写 LaTeX 文档,并且我想在以下场合使用彩色数字:
- 简单数字(例如
# 30
) - 公交车(例如
[3:0]
) - 二进制或十六进制表示(例如
4'hF
)
此外,我不希望在字符串(''
,""
)、注释后(//
)和字符后(例如i3
或test_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}
序列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()