不一样的 LaTeX 教程:使用 listings 宏包美化代码
简介
LaTeX 中插入代码常用到 listings 宏包。利用 listing 宏包的相关设置可以大幅美化代码。
获得更好的阅读体验,请关注微信公众号:极与客。
代码基础框架
- 引入 listings 宏包。
- 引入 xcolor 宏包,设置可选参数为 dvipsnames。
- 在正文区使用 lstlisting 环境。
\documentclass{ctexart}
\usepackage{listings}
\usepackage[dvipsnames]{xcolor}
% 正文区
\begin{document}
% lstlisting环境
\begin{lstlisting} % Python代码
import random
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
class FrenchDesk:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
desk = FrenchDesk()
\end{lstlisting}
\end{document}
编译结果
注意:以上结果中,代码超出该行时,直接被截断!
设置语言、基础字体族、自动换行
- 可选参数
language
进行语言设置。 - 可选参数
basicstyle = \ttfamliy
,设置为打字机字体族。 - 可选参数
breaklines
进行自动换行。
\documentclass{ctexart}
\usepackage{listings}
\usepackage[dvipsnames]{xcolor}
% 正文区
\begin{document}
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true % 自动换行
]
import random
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
class FrenchDesk:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
desk = FrenchDesk()
\end{lstlisting}
\end{document}
编译结果
设置语法高亮
1 设置关键字高亮
- 指定语言后,会有一些默认的关键字。
- 通过可选参数
keywordstyle
设置关键字样式。
- 通过可选参数
morekeywords
指定更多的关键字。
注意:这里的更多关键字指的是那些在语言中属于关键字,但是没有被 LaTeX 识别。
\documentclass{ctexart}
\usepackage{listings}
\usepackage[dvipsnames]{xcolor}
% 正文区
\begin{document}
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={} % 设置更多的关键字,用逗号分隔
]
import random
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
class FrenchDesk:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
desk = FrenchDesk()
\end{lstlisting}
\end{document}
编译结果
已经顺眼多了!
2 设置强调词高亮
- 可选参数
emph
指定强调词。 - 可选参数
emphstyle
设置强调词样式。
\documentclass{ctexart}
\usepackage{listings}
\usepackage[dvipsnames]{xcolor}
% 正文区
\begin{document}
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle={\bfseries\color{Rhodamine}} % 强调词样式设置
]
import random
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
# 一个叫做 FrenchDesk 的类。a class named FrenchDesk.
class FrenchDesk:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
desk = FrenchDesk()
\end{lstlisting}
\end{document}
编译结果
悄悄地在 Python 代码中加了一些注释,但是好像并不美妙。
3 设置注释、字符串样式
- 可选参数
commentstyle
设置注释样式。 - 可选参数
stringstyle
设置字符串样式。
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black} % 设置字符串样式
]
其他没有显示的代码不变。
编译结果
注释间距很奇怪,我们让它紧凑一些。
4 紧凑一些
- 设置
columns=flexible
。
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black}, % 设置字符串样式
columns=flexible
]
编译结果
注意:注释紧凑的同时,其他代码也紧凑了,但我觉得挺好。
显示行号
- 设置可选参数
numbers
可显示行号,常numbers=left
。 - 可选参数
numbersep
调整行号的具体位置。
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black}, % 设置字符串样式
columns=flexible,
numbers=left, % 显示行号在左边
numbersep=2em % 设置行号的具体位置
]
编译结果
太糟糕了!行号怎么这么大!
- 通过设置可选参数
numberstyle=\footnotesize
使行号变小。
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black}, % 设置字符串样式
columns=flexible,
numbers=left, % 显示行号在左边
numbersep=2em, % 设置行号的具体位置
numberstyle=\footnotesize % 缩小行号
]
编译结果
感觉很合适。
可以加个边框
- 设置可选参数
frame
可以加一个边框,single
表示单边框。
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black}, % 设置字符串样式
columns=flexible,
numbers=left, % 显示行号在左边
numbersep=2em, % 设置行号的具体位置
numberstyle=\footnotesize % 缩小行号
frame=single % 边框
]
编译结果
或许代码有点太靠边框了。
- 可选参数
framesep
改变代码和边框的距离
注意:设置framesep
移动是边框而非代码!
% lstlisting环境
\begin{lstlisting}[ % 进行参数设置
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black}, % 设置字符串样式
columns=flexible,
numbers=left, % 显示行号在左边
numbersep=2em, % 设置行号的具体位置
numberstyle=\footnotesize, % 缩小行号
frame=single, % 边框
framesep=1em % 设置边框与代码的距离
]
编译结果
把设置移到导言区
- LaTeX 结构与样式分离,需要避免在正文区进行大量的样式设置。
- 在导言区,
\setlst
命令也可以完成对 lstlisting 环境的设置。
\documentclass{ctexart}
\usepackage{listings}
\usepackage[dvipsnames]{xcolor}
% 在导言区进行样式设置
\lstset{
language=Python, % 设置语言
basicstyle=\ttfamily, % 设置字体族
breaklines=true, % 自动换行
keywordstyle=\bfseries\color{NavyBlue}, % 设置关键字为粗体,颜色为 NavyBlue
morekeywords={}, % 设置更多的关键字,用逗号分隔
emph={self}, % 指定强调词,如果有多个,用逗号隔开
emphstyle=\bfseries\color{Rhodamine}, % 强调词样式设置
commentstyle=\itshape\color{black!50!white}, % 设置注释样式,斜体,浅灰色
stringstyle=\bfseries\color{PineGreen!90!black}, % 设置字符串样式
columns=flexible,
numbers=left, % 显示行号在左边
numbersep=2em, % 设置行号的具体位置
numberstyle=\footnotesize, % 缩小行号
frame=single, % 边框
framesep=1em % 设置代码与边框的距离
}
% 正文区
\begin{document}
% lstlisting环境
\begin{lstlisting}
import random
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
# 一个叫做 FrenchDesk 的类。a class named FrenchDesk.
class FrenchDesk:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
desk = FrenchDesk()
\end{lstlisting}
\end{document}
这样也有另外一个好处,正文区的每一个 lstlisting 环境都会被设置上相应的样式。针对于特殊情况,我们也可以在特殊的 lstlisting 对相关属性进行重写。
结语
或许在运行本次例子时,你会感觉代码放在了中间并不宽敞的区域。那是因为默认的版心在中间很小的区域。你可以通过以下方法来设置版心为 A4 纸的 80%:
\usepackage{geometry}
\geometry{a4papter,scale=0.8}
本文的所有代码都悄悄地加了此设置。嘻嘻。
- END -
发布于 2022-02-05 17:05