Convert source code to syntax highlighted image - syntax-highlighting

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:
The resolution is lacking (using -resample and -density offer no improvement).
The syntax highlighting is unsuitable for a white page (can probably change enscript's colour theme).
Using Courier100 produces several .png files, which would need to be stitched together.
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.

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:
Load the source code into an editor that can add splashes of colour.
Export the source code as an HTML document (with embedded FONT tags).
Convert the HTML document to a PS file.
Convert the PS file to a PNG file.
Trim the white border of the PNG and the overzealous source code border.
Add a border around the image, using the same background colour as the HTML document.
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

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.

Related

Imagemagick error using overlapcrop on Window with Cygwin

I am using Imageimagick to crop arieal images in equal sizes.
Searching Google imagemagick tutorials led me to Fred Weinhaus scripts tutorial which I followed. When I am passing the command on bash or cmd based on syntax given in this website (bash /fullpathto/scriptname.sh with arguments /fullpathto/inputimage /fullpathto/outputimage)
I am getting error
$ overlapcrop -s 128 -o 50% -m matrix -M -L \
-R 'F:\bash\top_potsdam_2_10_RGB' 'F:\bash\o.jpg'
error Invalid Parameter - F:\bash\top_potsdam_2_10_RGB
FILE F:\bash\top_potsdam_2_10_RGB DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAS ZERO SIZE
Even if we set the directory in the path, we get the same error:
$ overlapcrop -s 128 -o 50% -m matrix -M -L -R top_potsdam_2_10_RGB.png o.png
--Screenshots of imagemagick --help and convert --help
error I am getting
Windows is useless when it comes to quoting, so maybe try escaping the % sign by adding a second one or a caret (^) in front of it.
Also, try removing the F: from the paths and try putting the files in the current directory in case the slashes are causing errors.
Finally, you may have your PATH set incorrectly so that when the script executes the convert command it finds the Windows utility that converts filesystems to NTFS rather than the ImageMagick utility that converts images.
Try running:
convert /?
and seeing if you get an error/help message from Windows CONVERT.EXE or something from ImageMagick. If you get the Windows one, your PATH is incorrect and you need to put the directory where you installed ImageMagick ahead (in front of) C:\WINDOWS\System32 or wherever Windows CONVERT.EXE lives and restart your Command Prompt window.

A terminal command (Mac) to change the extension of all the files in a folder

I'll try to make this as short as possible.
I have a folder that contains 9000 images (almost). But the extension of these images is png. I would like to change the extension of all these images in one command so they all become .jpg
If someone knows a way to do that can you please share it?
Thank you for your help.
If they are PNG images that you are trying to turn into jpgs, I'd recommend installing Imagemagick (via homebrew), and using the "mogrify" command to change them (see https://www.imagemagick.org/script/mogrify.php):
magick mogrify -format jpg *.png
If they are all actually jpegs, and you've ended up with the wrong file extension, you can do something like:
ls | grep \.png$ | sed 'p;s/\.png/\.jpg/' | xargs -n2 mv
See: Batch renaming files in command line and Xargs (even though it's linux, these tools are all available in the OSX default install)
I did it by using a virtual machine (Windows)
In the cmd I used this command : ren *.* *.jpg and it worked. Although I guess on Mac it's a bit harder.

Batch converting SVG to PNG in Inkscape doesn't work

I want to convert multiple SVG files in the folder C:\Users\Eric\Desktop\svg to 512x512 PNG files with the name [SVG File Name].svg.png.
I tried the following command:
for /f %f in ('dir /b "C:\Users\Eric\Desktop\svg"') do inkscape -z -e %f.png -w 512 -h 512 %f
The command line detects the SVG files correctly and goes through them but Inkscape says the following:
C:\Users\Eric\Desktop\inkscape>inkscape -z -e [SVG File Name].svg.png -w 512 -h 512 [SVG File Name].svg
** (inkscape.exe:8412): WARNING **: Can't open file: [SVG File Name].svg (doesn't exist)
** (inkscape.exe:8412): WARNING **: Can't open file: [SVG File Name].svg (doesn't exist)
** (inkscape.exe:8412): WARNING **: Specified document [SVG File Name].svg cannot be opened (does not exist or not a valid SVG file)
I opened one file in the normal Inkscape program, and it worked.
For SVG to PNG conversion I found cairosvg (https://cairosvg.org/) performs better than ImageMagick. Steps for install and running on all files in your directory.
pip3 install cairosvg
Open a python shell in the directory which contains your .svg files and run:
import os
import cairosvg
for file in os.listdir('.'):
if os.path.isfile(file) and file.endswith(".svg"):
name = file.split('.svg')[0]
cairosvg.svg2png(url=name+'.svg',write_to=name+'.png')
This will also ensure you don't overwrite your original .svg files, but will keep the same name. You can then move all your .png files to another directory with:
$ mv *.png [new directory]
Inkscape is a good program.
Sometimes we don't understand the possibilities it has.
For better performance, you should use shell mode.
This mode consists of 2 steps:
Create a file, with the commands to execute.
Run this file using type .\command.txt | inkscape --shell where command.txt your file name, in windows console or bash.
All commands located in action-list, after typing inkscape --shell.
For example, if you want to convert SVG to png, your txt file should contains:
file-open:1.svg; export-filename:1.png; export-do; file-close
file-open:2.svg; export-filename:2.png; export-do; file-close
Syntax is command:arg; command2:arg2; etc
You can create this file using your favorite language like C++, Java, C# or Python.
P.S.
It's faster than using inkscape command with every file in PowerShell, but don't use it for long time operations because it has a memory leak:
Link to Gitlab

Imagemagick fonts not found in OSX

When trying to add annotations to images in ImageMagick, It failed with the following message:
convert: unable to read font `(null)' # error/annotate.c/RenderFreetype...
How do I make Imagemagick find these fonts?
The solution that worked for me was given by Neville in this post:
Create an imagemagick configuration folder: mkdir ~/.magick
Save this Perl script as /tmp/script.pl
Make the script executable: chmod +x /tmp/script.pl
Run the script locally and redirect the output to the file type.xml in ~/.magick: /tmp/script.pl > ~/.magick/type.xml
This solved the fonts problem, while installing fondu, the imagemagick pkg file and some other tricks didn't.
Great! Now I can annotate some flickr cats with the image size and resolution (I want this for finding the optimal resolution for an app I'm working on).
Adopting Adam Matan's answer, here's how I got this to work with imagemagick 7+ on macOS 10.12+ installed with homebrew. (This also assumes you have perl installed.)
Download the perl script and save it to /usr/local/bin/imagick_type_gen
Make the script executable:
chmod +x /usr/local/bin/imagick_type_gen
Find the font path for imagemagick by running convert -list font | grep Path. This should return where imagemagick is looking for fonts. The Apple path for me was this:
/usr/local/Cellar/imagemagick/7.0.7-22/etc/ImageMagick-7/type-apple.xml
Run imagick_type_gen and direct the output to the path above:
imagick_type_gen > /usr/local/Cellar/imagemagick/7.0.7-22/etc/ImageMagick-7/type-apple.xml
Run convert -list font | less to see the font names imagemagick will use, e.g., some fonts will be labeled as GeorgiaB instead of Georgia Bold. (hit q to quit)
imagemagick should now see the fonts you have installed on the your system.
The easiest way to solve this issue is copying the font you need to a ~/ folder, or anywhere your script is, then give the direct path:
convert -font "~/MyFont.ttc"

convert ~1000 swf to jpg / png / gif

I've got around 1000 swf (I even got the fla's) files I'd need to convert to any image (jpg, gif, png ...) with the only solution to save the fla as image at the moment. Not helpful with that amount.
Is there any command line tool I'd be able to use? I'm on Windows 7 or Ubuntu.
Already searched for a bunch of tools but they only convert one file at a time or have to be purchased.
Sidenote: the swf's aren't animated, just static pictures
Found a solution and want to share it:
I used sfwtools, which I installed with:
sudo add-apt-repository ppa:guilhem-fr/swftools
sudo apt-get update
sudo apt-get install swftools
Created a bash script using gedit (let's say it's called convertswf)
#!/bin/bash
for file in *.swf;
do
swfrender "$file" -o "$file.png"
done
or use this extended version if you have swf files in subfolders:
#!/bin/bash
for file in $(find "path/to/directory" -name '*.swf');
do
swfrender "$file" -o "$file.png"
done
finally did:
chmod +x convertswf
./convertswf
hope it helps!

Resources