将源代码转换为语法高亮的图片

8

背景

OpenOffice Writer缺少将ASCII文本源文件链接、应用语法高亮并包装在框架中的功能,并且在源文件更改时更新框架内容。然而,OpenOffice Writer可以链接到图像,并在图像更改时自动更新。

问题

这些图像需要高分辨率(300 dpi或更高),并具有适合于白色背景(即打印页面)的语法着色。

问题是什么?

如何从源代码文件自动创建高质量的图像,例如:

  • SQL;
  • PostgreSQL函数;
  • Java;
  • bash脚本;以及
  • R和PL/R?

尝试过的方法

大多数尝试都是以下主题的变体:

$ enscript --color -f Courier12 -B -1 --highlight=sql -h -o - source.sql |\
  convert - -trim -border 10 source.png

这种方法存在一些问题:
  1. 分辨率不够高(使用 -resample-density 也无法改善)。
  2. 语法高亮对于白色页面不太适用(可以尝试更改 enscript 的颜色主题)。
  3. 使用 Courier100 会产生多个 .png 文件,需要将它们拼接在一起。
  4. -border 10 意外地将背景颜色从白色变为浅灰色。

手动解决方案

将源文件转换为 PostScript 格式,完全避免使用 ImageMagick,然后将其导入到 GIMP 中即可得到所需的结果。不幸的是,这种解决方案需要进行一些手动操作,而我对 GIMP 批处理编程的经验几乎为零。
2个回答

7

软件要求

以下软件包适用于Windows和Linux系统,是实现完整工作方案所必需的:

  • gvim - 用于将语法高亮源代码导出为HTML。
  • moria - 语法高亮的颜色方案。
  • wkhtmltopdf - 将HTML文档转换为PDF或PostScript(PS)文档。
  • Ghostscript - 用于将PS转换为PNG。
  • ImageMagick - 用于裁剪PNG并添加边框。

一般步骤

以下是解决方案的工作方式:

  1. 将源代码加载到可以添加颜色的编辑器中。
  2. 将源代码导出为带有嵌入式FONT标签的HTML文档。
  3. 将HTML文档转换为PS文件。
  4. 将PS文件转换为PNG文件。
  5. 裁剪PNG的白色边框和过度渲染的源代码边框。
  6. 使用与HTML文档相同的背景颜色为图像添加边框。
  7. 删除临时文件。

安装

将组件安装到以下位置:

  • gvim - C:\Program Files\Vim
  • moria - C:\Program Files\Vim\vim73\colors
  • wkhtmltopdf - C:\Program Files\wkhtml
  • Ghostscript - C:\Program Files\gs
  • ImageMagick - C:\Program Files\ImageMagick

注意:ImageMagick有一个名为convert.exe的程序,不能替代Windows的convert命令。因此,在批处理文件中必须硬编码convert.exe的完整路径(而不是将ImageMagick添加到PATH)。

环境变量

添加或更新以下环境变量

  • GS_LIB = C:\Program Files\gs\gs9.00\lib
  • GS_PROG = C:\Program Files\gs\gs9.00\bin\gswin32.exe
  • PATH = "C:\Program Files\Vim\vim73";"C:\Program Files\wkhtml";"C:\Program Files\gs\gs9.00\bin"

批处理文件

以下是批处理源代码:

@ECHO OFF

ECHO Converting %1 to %1.html ...

gvim -e %1 -c "set nobackup" -c ":colorscheme moria" -c :TOhtml -c wq -c :q

ECHO Converting %1.html to %1.ps ...

wkhtmltopdf --quiet --dpi 1200 %1.html %1.ps

ECHO Converting %1.pdf to %1.png ...
IF EXIST %1.png DEL /q %1.png

gswin32 -q -dBATCH -dNOPAUSE -dSAFER -dNOPROMPT ^
 -sDEVICE=png16m -dDEVICEXRESOLUTION=600 -dDEVICEYRESOLUTION=600 ^
 -dDEVICEWIDTH=4958 -dDEVICEHEIGHT=7017 -dNOPLATFONTS ^
 -dTextAlphaBits=4 -sOutputFile=%1.png %1.ps

ECHO Trimming %1.png ...

move %1.png %1.orig.png

"C:\Program Files\ImageMagick\convert.exe" -trim +repage -trim +repage ^
  -bordercolor "#f0f0f0" -border 25x25 %1.orig.png %1.png

ECHO Removing old files ...
IF EXIST %1.orig.png DEL /q %1.orig.png
IF EXIST %1.html DEL /q %1.html
IF EXIST %1.ps DEL /q %1.ps

1
我不知道它在Windows上如何工作,但在Linux上我有wkhtmltoimage和wkhtmltopdf。有了这个想法,您可以跳过在过程中使用PS。 - A.D.

0

另一个选择是利用catage, CodeSnap, PolaCodecarbon-now-cli

CodeSnap和PolaCode是Visual Studio Code扩展程序,从命令行使用它们可能有点困难,但使用起来很简单。安装它们到你的编辑器时,请遵循说明。该解决方案适用于所有由Visual Studio Code支持的操作系统。

如果您正在使用基于Debian的Linux发行版,并且已经安装了Docker,则可以使用以下shell脚本创建catage Docker镜像:

#!/bin/bash
sudo docker build -t catage:local - <<EOF
FROM buildkite/puppeteer
USER node
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin
RUN mkdir /home/node/.npm-global
WORKDIR /home/node/app
RUN npm install -g catage
EOF

同样地,可以使用以下脚本创建 carbon-now-cli Docker 镜像:

#!/bin/bash
sudo docker build -t carbon-now:local - <<EOF
FROM alekzonder/puppeteer
USER root
RUN apt-get update
RUN apt-get install git -yq
RUN yarn global add carbon-now-cli
USER pptruser
EOF

使用以下方式在shell脚本中使用这些Docker镜像,从您的代码片段生成PNG图像:

#!/bin/bash
alias catage="sudo -E docker run --rm -it -v $PWD:/home/node/app catage:local catage"
alias carbon-now="sudo -E docker run --rm -it --init --cap-add=SYS_ADMIN --shm-size=1gb --user pptruser -v $PWD:/home/pptruser/app --workdir /home/pptruser/app carbon-now:local carbon-now"
catage --language java --no-line-numbers --theme Material --frame-title "My Code Snippet" --format png "my_code_snippet.java" "my_code_snippet.png" 
carbon-now "my_code_snippet.java" --target "my_code_snippet" --headless

Docker方法适用于Docker支持的所有操作系统。您可能需要根据您的操作系统的功能修改上述shell脚本示例,但基本命令保持不变。


你有相应的说明吗?如何将它们链接在一起?这个程序可以在哪些操作系统上运行?从命令行运行它是什么样子的?如何控制输出分辨率?提供链接列表是一个很好的开始,但如果你已经知道如何做到这一点,分享你的发现对其他人会非常有帮助。 - Dave Jarvis
使用Docker来做这样的事情听起来绝对是杀鸡焉用牛刀。虽然我没有尝试过,但我猜下载和运行Puppeteer镜像可能需要一些时间。 - JP de la Torre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接