是否可能解释使用 minted 进行着色的控制台代码?
我目前的做法是:
使用以下命令创建包含控制台代码的文件
$ printf "normal text\n\033[0;36mcyan text\033[0;0m\nnormal text" > output.log
考虑以下最小的例子,
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{minted}
\begin{document}
\inputminted{bc}{output.log}
\end{document}
并使用以下命令进行编译:
$ pdflatex --shell-escape example.tex
我收到的错误:
...
(/usr/share/texmf-dist/tex/latex/graphics-def/pdftex.def))/usr/bin/pygmentize
(/usr/share/texmf-dist/tex/latex/l3backend/l3backend-pdfmode.def)
No file example.aux.
(/usr/share/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
) (./_minted-example/default-pyg-prefix.pygstyle)
(./_minted-example/default.pygstyle)
(./_minted-example/D4C350DCEFCF48E3B9E6D0F4E55D3D0403FA95147BD0676DCEE8C50F74C9
315E.pygtex
! Package inputenc Error: Unicode character ^^[ (U+001B)
(inputenc) not set up for use with LaTeX.
See the inputenc package documentation for explanation.
Type H <return> for immediate help.
...
l.3 ...text^^[[\PYG{l+m}{0}\PYG{p}{;}\PYG{l+m}{0}m
?
output.log
目前无法读取文件,因为inputenc
软件包不知道如何处理控制台代码开头的控制字符。如何解决这个问题?完成此操作后,是否可以解释minted
控制台代码以进行着色(即,将上例中的青色文本实际打印为青色)?
答案1
该方法https://tex.stackexchange.com/a/511945/可以扩展为与外部文件一起使用(如那里的评论中所述,但未包含在答案中)。外部文件的问题是该文件中的颜色命令使用单个控制字符\033
(001B
十六进制)而不是文字\e
(即,\
后跟e
)存储,如内联代码示例中所示。但是,您可以使用将此字符映射到 LaTeX 命令\DeclareUnicodeCharacter
。
梅威瑟:
\documentclass{article}
\usepackage[utf8]{inputenc}
\DeclareUnicodeCharacter{001B}{\ansi}
\usepackage{fancyvrb}
\usepackage{color}
\def\defaultcode{[0;0}
\def\bluecode{[0;34}
\def\redcode{[0;31}
\def\cyancode{[0;36}
\def\ansi#1m{%
\def\colcode{#1}%
\ifx\colcode\defaultcode\color{black}%
\else\ifx\colcode\bluecode\color{blue}%
\else\ifx\colcode\redcode\color{red}%
\else\ifx\colcode\cyancode\color{cyan}%
\fi\fi\fi\fi}
\begin{document}
\VerbatimInput[commandchars=\\\{\}]{clroutput.log}
\end{document}
结果:
另一种方法是使用minted
自定义词法分析器和 ANSI 颜色样式文件。另一个问题中的评论提到了词法分析器https://github.com/chriskuehl/pygments-ansi-color。此词法分析器在开发时就考虑了 HTML 输出,因此使用时minted
需要一些额外的代码。
词法分析器本身(pygments_ansi_color.py
)无需修改即可使用,并可将其放在与文档相同的目录中。此外,还必须将样式文件放在系统pygments/styles
目录中。样式文件的文件名很重要,因为它需要与文件内的样式类相对应。对于下面的 MWE,文件应称为ansicolor.py
,内容如下:
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
Number, Operator, Literal, Text, Generic, Whitespace, Token
import itertools
C = Token.C
Color = Token.Color
def _token_from_lexer_state(bold, faint, fg_color, bg_color):
"""Construct a token given the current lexer state.
We can only emit one token even though we have a multiple-tuple state.
To do work around this, we construct tokens like "Bold.Red".
"""
components = ()
if bold:
components += ('Bold',)
if faint:
components += ('Faint',)
if fg_color:
components += (fg_color,)
if bg_color:
components += ('BG' + bg_color,)
if len(components) == 0:
return Text
else:
token = Color
for component in components:
token = getattr(token, component)
return token
def color_tokens(fg_colors, bg_colors, enable_256color=False):
styles = {}
if enable_256color:
styles[Token.C.Bold] = 'bold'
styles[Token.C.Faint] = ''
for i, color in _256_colors.items():
styles[getattr(Token.C, 'C{}'.format(i))] = color
styles[getattr(Token.C, 'BGC{}'.format(i))] = 'bg:{}'.format(color)
for color, value in fg_colors.items():
styles[getattr(C, color)] = value
for color, value in bg_colors.items():
styles[getattr(C, 'BG{}'.format(color))] = 'bg:{}'.format(value)
else:
for bold, faint, fg_color, bg_color in itertools.product(
(False, True),
(False, True),
{None} | set(fg_colors),
{None} | set(bg_colors),
):
token = _token_from_lexer_state(bold, faint, fg_color, bg_color)
if token is not Text:
value = []
if bold:
value.append('bold')
if fg_color:
value.append(fg_colors[fg_color])
if bg_color:
value.append('bg:' + bg_colors[bg_color])
styles[token] = ' '.join(value)
return styles
# Note: You can use different background colors for improved readability.
fg_colors = bg_colors = {
'Black': '#000000',
'Red': '#EF2929',
'Green': '#8AE234',
'Yellow': '#FCE94F',
'Blue': '#3465A4',
'Magenta': '#c509c5',
'Cyan': '#34E2E2',
'White': '#ffffff',
}
class AnsicolorStyle(Style):
styles = default_style = ''
styles = {
Comment: '#177500',
Comment.Preproc: '#633820',
String: '#C41A16',
String.Char: '#2300CE',
Operator: '#000000',
Keyword: '#A90D91',
Name: '#000000',
Name.Attribute: '#836C28',
Name.Class: '#3F6E75',
Name.Function: '#000000',
Name.Builtin: '#A90D91',
Name.Builtin.Pseudo: '#5B269A',
Name.Variable: '#000000',
Name.Tag: '#000000',
Name.Decorator: '#000000',
Name.Label: '#000000',
Literal: '#1C01CE',
Number: '#1C01CE',
Error: '#000000',
}
styles.update(color_tokens(fg_colors, bg_colors))
然后,以下 MWE 将为转义代码产生彩色输出:
\documentclass{article}
\usepackage{minted}
\usemintedstyle{ansicolor} % set the style file
\begin{document}
% call minted with the ANSI lexer
\inputminted{pygments_ansi_color.py:AnsiColorLexer -x}{clroutput.log}
\end{document}
与上述方法相比的结果(针对带有青色和蓝线的文件):
请注意,minted
输出的颜色略有不同。您可以通过更改上述样式文件中的值来自定义颜色。请注意,每次更改样式文件时,您都需要删除缓存的结果minted
才能看到结果。
还请注意,样式文件包含许多实际上未使用的类别。样式是从 复制而来xcode.py
,遵循 的文档pygments-ansi-color
。