使用 minted 解释控制台代码设置的颜色

使用 minted 解释控制台代码设置的颜色

是否可能解释使用 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/可以扩展为与外部文件一起使用(如那里的评论中所述,但未包含在答案中)。外部文件的问题是该文件中的颜色命令使用单个控制字符\033001B十六进制)而不是文字\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

相关内容