Pygments 和 ImageFormatter:将输出设置为 80 列

Posted

技术标签:

【中文标题】Pygments 和 ImageFormatter:将输出设置为 80 列【英文标题】:Pygments and ImageFormatter: set output to 80 columns 【发布时间】:2021-07-20 14:29:02 【问题描述】:

ImageFormatter 始终会创建一个 PNG 输出,其宽度取决于行长。

例如,这个 PNG 是 192 像素宽:

这是 384:

Pygments 中是否有模拟 80 列输出的设置,因此所有图像的宽度都相同?

这是我用来生成示例的代码:

#!/usr/bin/python3

from pygments import highlight
from pygments import lexers
from pygments.formatters.img import ImageFormatter
from pygments.styles import get_style_by_name, get_all_styles

lexer = lexers.get_lexer_by_name('C')

source_short = 'printf("%d\\n", i);'
source_long = 'printf("variable i is equal to %d.\\n", i);'

formatter = ImageFormatter(full = True, style = get_style_by_name('vim'))
open('short.png', 'wb').write(highlight(source_short, lexer, formatter))
formatter = ImageFormatter(full = True, style = get_style_by_name('vim'))
open('long.png', 'wb').write(highlight(source_long, lexer, formatter))

【问题讨论】:

【参考方案1】:

不确定这是否是最好的方法,但对我有用。

这是 MyFormatter,来自 ImageFormatter,其中行中的字符数始终为 80。format 方法的改动很小。

from pygments.formatter import Formatter
from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \
    get_choice_opt, xrange
from PIL import Image, ImageDraw, ImageFont
import subprocess

class MyFormatter(ImageFormatter):
    def __init__(self, **options):
        super().__init__(**options)

    def format(self, tokensource, outfile):
        self._create_drawables(tokensource)
        self._draw_line_numbers()
        im = Image.new(
            'RGB',
            self._get_image_size(80, self.maxlineno), # always 80
            self.background_color
        )
        self._paint_line_number_bg(im)
        draw = ImageDraw.Draw(im)
        # Highlight
        if self.hl_lines:
            x = self.image_pad + self.line_number_width - self.line_number_pad + 1
            recth = self._get_line_height()
            rectw = im.size[0] - x
            for linenumber in self.hl_lines:
            y = self._get_line_y(linenumber - 1)
            draw.rectangle([(x, y), (x + rectw, y + recth)],
                       fill=self.hl_color)
        for pos, value, font, kw in self.drawables:
            draw.text(pos, value, font=font, **kw)
        im.save(outfile, self.image_format.upper())

【讨论】:

以上是关于Pygments 和 ImageFormatter:将输出设置为 80 列的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 docutils 和 pygments 控制短/长标签名称?

用于 HTML、PHP 和 JavaScript 的 Pygments 样式

未定义的方法`highlight' Python+Pygments

使用 Pygments 过滤空格和换行符

在 Jekyll/Liquid 和 pygments 的 html 问题中突出显示

Python 中带有 Pygments 的分词器