Convert source code to syntax highlighted image
Asked Answered
L

2

9

Background

OpenOffice Writer lacks the ability to link to an ASCII text source file, apply syntax highlighting, wrap it in a frame, and update the frame contents whenever the source file changes. However, OpenOffice Writer can link to images, and will update the images automatically when they change.

Problem

The images need to be high-resolution (300 dpi or greater) with syntax colouring appropriate for a white background (i.e., a printed page).

Question

How can high-quality images be created automatically from source code files, such as:

  • SQL;
  • PostgreSQL functions;
  • Java;
  • bash scripts; and
  • R and PL/R?

Attempts

Most attempts have been a variation on the following theme:

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

There are a few problems with this approach:

  1. The resolution is lacking (using -resample and -density offer no improvement).
  2. The syntax highlighting is unsuitable for a white page (can probably change enscript's colour theme).
  3. Using Courier100 produces several .png files, which would need to be stitched together.
  4. The -border 10 unexpectedly changes the background colour from white to lightgray.

Manual Solution

Converting the source files to PostScript -- avoiding ImageMagick altogether -- and then importing them into The GIMP will produce the desired results. Unfortunately, that solution involves a bit of manual work, and my GIMP batch programming experience is next to nil.

Ladoga answered 15/10, 2010 at 2:1 Comment(0)
L
7

Software Requirements

The following software packages are available for both Windows and Linux systems, and are required for a complete, working solution:

  • gvim - Used to export syntax highlighted source code to HTML.
  • moria - Colour scheme for syntax highlighting.
  • wkhtmltopdf - Converts HTML documents to PDF or PostScript (PS) documents.
  • Ghostscript - Used to convert PS to PNG.
  • ImageMagick - Used to trim the PNG and add a border.

General Steps

Here is how the solution works:

  1. Load the source code into an editor that can add splashes of colour.
  2. Export the source code as an HTML document (with embedded FONT tags).
  3. Convert the HTML document to a PS file.
  4. Convert the PS file to a PNG file.
  5. Trim the white border of the PNG and the overzealous source code border.
  6. Add a border around the image, using the same background colour as the HTML document.
  7. Delete temporary files.

Installation

Install the components into the following locations:

  • 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

Note: ImageMagick has a program called convert.exe, which cannot supersede the Windows convert command. Because of this, the full path to convert.exe must be hard-coded in the batch file (as opposed to adding ImageMagick to the PATH).

Environment Variables

Add or update the following environment variables:

  • 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"

Batch File

Here is the batch source text:

@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
Ladoga answered 23/11, 2010 at 3:29 Comment(1)
I don't know how it works on Windows but on Linux I have wkhtmltoimage along with wkhtmltopdf. With that in mind, you can skip the use of PS in the process.Paigepaik
M
1

Another option is to make use of catage, CodeSnap, PolaCode or carbon-now-cli.

CodeSnap and PolaCode are Visual Studio Code extensions, and it may be difficult to use them from the command line, but they are simple to use. Follow the instructions when installing them into your editor. This solution works for all operating systems supported by Visual Studio Code.

If you are using a Debian-based Linux distribution, and you have Docker installed, then you can create a catage Docker image using the following shell script:

#!/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

Similarly, a carbon-now-cli Docker image can be created with the following script:

#!/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

Use these Docker images in a shell script as follows, to generate PNG images from your code snippets:

#!/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

The Docker approach works for all operating systems supported by Docker. You may have to modify the above shell script examples according to the capabilities of your operating system, but the basic commands remain the same.

Marcellmarcella answered 6/4, 2020 at 13:55 Comment(2)
Do you have instructions to go along with those? How do you link them together? What operating systems will this work on? What does running it from the command-line look like? How do you control the output resolution? Providing a list of links is a great start, but if you've already figured out how to do it, sharing your findings would be quite helpful to other people.Ladoga
Using Docker for something like this sounds like an absolute overkill. I haven't tried it, but I guess it would take some time time for the Puppeteer image to download and run.Leger

© 2022 - 2024 — McMap. All rights reserved.