latex中minted代码高亮的有趣示例

latex中minted代码高亮的有趣示例

1. 引言

前一篇文章,介绍了minted的基本用法和选项,本文件介绍几个有趣的示例,主要通过逃逸代码、代码高亮,以及标签引用来实现对代码的某些代码行的重点解释和介绍。

2.pre 示例:代码环境的行距调整

minted的高亮代码环境可以调整内部行距,也可以调整minted代码环境前后的垂直间距。
后者使用两个钩子在环境前后添加垂直间距,这种方式对一般的环境都是通用的。

\BeforeBeginEnvironment{minted}{\vspace{1em}}
\AfterEndEnvironment{minted}{\vspace{1em}}

而前者可以通过选项baselinestretch调整行距。
下面的代码中,第一个代码环境使用默认的行距,第二和三个代码环境分布使用2倍和3倍的行距。
比如:

\documentclass{minimal}
\usepackage[b5paper]{geometry}
\usepackage{ctex}
\usepackage{xcolor}
\usepackage{minted}

\usemintedstyle{pastie}
\begin{document}

\begin{minted}[linenos=true]{c++}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{minted}

\begin{minted}[linenos=true,baselinestretch=2]{c++}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{minted}

\begin{minted}[linenos=true,baselinestretch=3]{c++}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{minted}

\end{document}

结果为:
在这里插入图片描述

2. 示例一:利用逃逸字符写数学公式注释以及正文的数学符号

minted中的逃逸代码除了在注释中使用(前提是启用texcl选项)外,也可以直接在设定的逃逸字符之间使用(设置escapeinside)。还要注意在逃逸代码中使用数学公式需要启用mathescape选项。

比如:

\documentclass{ctexart}
\usepackage{xcolor}
\usepackage{minted}

\begin{document}

\begin{minted}%
[linenos,
frame=single,
rulecolor=purple!50!black,
texcl=true,
escapeinside=||,
mathescape
]{python3}
def f(x,theta):
    y = x|\colorbox{green}{**}|2
    y = y|\textcolor{red}{+}$\theta$|
    return y

def func(lst):
    s=sum(lst) # $s=\sum x$
    y=[sin(x) for x in lst] # $y=\sin x$
    return None
\end{minted}

\end{document}

结果为:

在这里插入图片描述
其中第2和3行使用了逃逸字符来使用逃逸代码。给运算符加上了背景和颜色,参数theta使用了数学符号。
而第7和8行直接在代码的注释中使用逃逸代码,给出了代码解释的数学公式。

3. 示例二:完全利用minted实现代码行的引用和介绍

minted宏包提供了大量的选项,可以设置不同的格式。其中代码行号相关也有不少,包括间隔输出行号的方式。然而没有合适的显示指定行号的方式,因此我们通常显示所有的行号,然后把重点要解释的行,用其它方式突出出来,并且可以利用逃逸的latex代码来实现标签和引用。

如下就是一个例子:


\documentclass{article}
\usepackage{fontspec}
\setmainfont{CMU Serif}
\usepackage{ctex}
\usepackage{xcolor}
\usepackage{etoolbox}
\usepackage[colorlinks]{hyperref}
\usepackage{lipsum}
\usepackage[paperwidth=21cm,paperheight=29cm,top=2cm,bottom=2cm,left=3cm,right=3cm]{geometry}
\usepackage{xltxtra,mflogo,texnames}
\usepackage{minted}

\begin{document}

\renewcommand{\theFancyVerbLine}{\sffamily
\textcolor{blue!50!black}{\small\oldstylenums{\arabic{FancyVerbLine}}}}

\begin{minted}%
[encoding=utf8,
linenos,
frame=single,
rulecolor=purple!50!black,
texcl=true,
highlightcolor=green!40,
highlightlines={7,9},
]{python3}
#
#authoryear style
#
def formatlabelauthor(bibentry):

    if 'author' in bibentry:
        namelist=bibentry['author'] #\label{line:namelist:author}
    elif 'editor' in bibentry:
        namelist=bibentry['editor'] #\label{line:namelist:editor}
    elif 'translator' in bibentry:
        namelist=bibentry['translator']
    else:
        namelist='Anon'

    return [namelist,namelist]
\end{minted}

作者姓名赋值见第\ref{line:namelist:author}行,编者姓名赋值见\ref{line:namelist:editor}行。

\end{document} 

其中通过highlightlines选项设置,高亮了这两个重点行,并且利用texcl选项,在注释中使用逃逸的latex标签代码,然后在正文中引用。结果如图所示:

利用高亮和行号引用来介绍代码

4. 示例三:利用逃逸代码来进行自定义代码行的引用和介绍

由于minted支持在高亮的代码中实现逃逸的latex代码,因此我们不仅仅可以在注释中使用latex代码,也可以直接在代码中使用。
另外,为了直接对指定行进行引用和重点介绍,我们可以利用这种方式实现复杂的效果,下面的代码中我们使用了zref来实现一套新的引用:

\documentclass{article}
    \usepackage{ctex}
    \usepackage{etoolbox}
    \usepackage{xcolor}
    \usepackage{hyperref}
    \usepackage[paperheight=29cm,paperwidth=21cm,top=2cm,bottom=2cm,left=3cm,right=3cm]{geometry}
    \usepackage{minted}
    \usepackage[user]{zref}
    \usepackage{tcolorbox}

\newtcbox{\codelinenobox}[1][red]{on line,colback=#1!10!white,colframe=#1!50!black,
arc=4.5pt, %圆弧的半径
before upper={\rule[0pt]{0pt}{6pt}},
%调整字符在宽中的位置,[]中负的越多,字符越向上偏离底线
boxrule=0.5pt, %边框线宽
boxsep=0pt,%字符与边框的间距
left=2.5pt,right=2.5pt,top=1.5pt,bottom=1.5pt
}

\newcounter{codelineno}
\setcounter{codelineno}{0}
\renewcommand*{\thecodelineno}{\codelinenobox[blue]{\arabic{codelineno}}}

\makeatletter

\zref@newprop{lineno}{\thecodelineno}

\zref@addprops{main}{lineno}

\newcommand*{\codelineno}[2][]{%
\edef\ref@temp{#1}%
\ifx\ref@temp\@empty\relax%
\stepcounter{codelineno}%
\else%
\setcounter{codelineno}{#1}%
\fi%
\makebox[0pt][c]{\hss\thecodelineno\hspace{10pt}}%
\zlabel{#2}%
}

\makeatother

    \begin{document}

\begin{minted}[escapeinside=||,
frame=single,
rulecolor=purple!50!black,
highlightcolor=yellow!50,
highlightlines={7,9},
]{python3}
#
#authoryear style
#
def formatlabelauthor(bibentry):

    if 'author' in bibentry:
|\codelineno{line:tex:d}|        namelist=bibentry['author'] 
    elif 'editor' in bibentry:
|\codelineno{line:tex:e}|         namelist=bibentry['editor'] 
    elif 'translator' in bibentry:
        namelist=bibentry['translator']
    else:
        namelist='Anon'

    return [namelist,namelist]
\end{minted}

作者姓名赋值见第\zref[lineno]{line:tex:d}行,编者姓名赋值见\zref[lineno]{line:tex:e}行。

    \end{document} 

其中,我们在代码第7和9行,利用逃逸代码增加了新的行号标签,然后再正文中引用。标签和引用利用zref宏包实现。行号标签的用tcolorbox画了一个圈。定义的\codelineno命令,根据输入信息完成了行号的更新,行号标签的输出,以及标签生成。
注意python代码中的|\codelineno{line:tex:d}|
结果如图所示:

自定义行号标签

5 给代码块加上标题

评论有人文,怎么给代码块加上标题。这里增加一下整个内容,增加标题类似于增加图表标题,所以我们可以在listing浮动体换中添加,这个在前一个文章:latex中代码高亮显示宏包minted用法里面有所介绍,不过这再完整的说一下不同的方法。

要给代码块加上标题,有多种方式:

(1) 是利用minted提供的listing环境,自然可以利用caption来加上标题。

\begin{listing}[H]
\mint{cl}/(car (cons 1 '(2)))/

\caption{Example of a listing.}\label{lst:example}
\end{listing}

\begin{listing}[H]
\begin{minted}
import numpy as np
\end{minted}

\caption{Example of a listing.}\label{lst:example1}
\end{listing}


Listing \ref{lst:example} contains an example of a listing.

注意这是一个浮动体,默认要修改浮动体的位置,使用如下方式:

\makeatletter
\renewcommand{\fps@listing}{htp}
\makeatother

(2) 利用其它图表环境,将其minted代码包起来,然后加入标题。

\begin{figure}[!htbp]
\begin{minted}
import numpy as np
\end{minted}
\caption{Example of a listing.}\label{fig:example1}
\end{figure}

(3) 可以自己定义一个环境,将minted代码包起来,然后加入标题。

使用newfloat等宏包可以定义新的浮动体。

\usepackage{newfloat}
\usepackage{caption} 
\DeclareFloatingEnvironment{codeblock}
\captionsetup[codeblock]{labelfont={},name={代码},labelsep=space}

然后利用它:

\begin{codeblock}
\begin{minted}
import numpy as np
\end{minted}
\caption{Example of a codeblock.}\label{cb:example1}
\end{codeblock}

或者实现一个非浮动的:

\begin{center}
\begin{minted}
import numpy as np
\end{minted}
\captionof{codeblock}{Example of a codeblock.}\label{cb:example2}
\end{center}

这里没有用一个新定义的环境,只用一个center来做示例。目的是做一个非浮动的环境。标题则使用caption宏包提供captionof来输出。

示例代码:

\documentclass{article}
\usepackage{ctex}
\usepackage{minted}
\usepackage{newfloat}
\usepackage{caption}
\DeclareFloatingEnvironment{codeblock}
\SetupFloatingEnvironment{codeblock}{placement=htp}
\captionsetup[codeblock]{labelfont={},name={代码},labelsep=space}
\makeatletter
\renewcommand{\fps@listing}{htp}
\makeatother




\begin{document}

给代码块加上标题

要给代码块加上标题,有多种方式:

(1) 是利用minted提供的listing环境,自然可以利用caption来加上标题。

\begin{listing}[H]
\mint{cl}/(car (cons 1 '(2)))/

\caption{Example of a listing.}\label{lst:example}
\end{listing}

\begin{listing}[H]
\begin{minted}{python}
import numpy as np
\end{minted}

\caption{Example of a listing.}\label{lst:example1}
\end{listing}


Listing \ref{lst:example} contains an example of a listing.

注意这是一个浮动体,修改浮动体的位置,使用如下方式:


(2) 利用其它图表环境,将其minted代码包起来,然后加入标题。

\begin{figure}[!htbp]
\begin{minted}{python}
import numpy as np
\end{minted}
\caption{Example of a listing.}\label{lst:example1}
\end{figure}


(3) 可以自己定义一个环境,将minted代码包起来,然后加入标题。

使用newfloat等宏包可以定义新的浮动体。



\begin{codeblock}
\begin{minted}{python}
import numpy as np
\end{minted}
\caption{Example of a codeblock.}\label{cb:example1}
\end{codeblock}



\begin{center}
\captionof{codeblock}{Example of a codeblock.}\label{cb:example2}
\begin{minted}{python}
import numpy as np
\end{minted}
\end{center}

这里没有用一个新定义的环境,只用一个center来做示例。

\end{document}

结果为:
给代码块加上标题示例

6. 小结

虽然这里仅给出两个示例,但其实可以利用minted宏包,配合其它宏包,实现更多效果。总的来说,只要有需求,总是能够实现的。

enjoy!

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值