Creating ready-to-print photo books with Ruby and TeX
Ruby Beats Go
Why use Ruby for the glue code and not Go, which has become the de facto choice in this Programming Snapshot column, you ask? Well, a scripting language like Ruby simply can't be beaten for plain vanilla text manipulation and simple, concise, easy-to-extend code that almost looks like a config file. On top of that, Ruby's template system ERB is great for dumping text or picture file names into predefined snippets with a mess of TeX code. There is a good reason why configuration management tools like Puppet and Chef use Ruby as a reference language for dynamically adapting variegated configuration files catering to individual environments.
Listing 2 shows you the Ruby glue code to turn the book description scripts into TeX. It defines a class that user scripts need to include to generate coffee table books, just like Listing 1 does in line 2. Scripts call the built-in Ruby function require_relative bm
to find the library from Listing 2 in the same directory and can then immediately get started by calling Bm.new
. The returned bm
instance then lets you create sophisticated photo books with just a few commands.
Listing 2
bm.rb
01 #!/usr/bin/ruby 02 require 'erb' 03 04 class Bm 05 attr_accessor :name 06 07 def initialize 08 @tmpldir = "tmpl" 09 @photodir = "photos" 10 @tex = "" 11 end 12 13 def add(tmpl, text: "", photos: []) 14 tpath = "#{@tmpldir}/#{tmpl}.tex" 15 16 photos = photos.map { 17 |path| "#{@photodir}/#{path}"} 18 19 t = ERB.new(File.read(tpath)) 20 @tex += t.result_with_hash( 21 text: text, photos: photos) 22 end 23 24 def print 25 texf = "#{@name}.tex" 26 File.open(texf, "w") { 27 |f| f.write(@tex) } 28 system("xelatex", texf) 29 end 30 end
Short Paths
To keep things tidy, the predefined TeX templates are all located in a subdirectory named tmpl/
. To help the user call them by simple names, such as cover
, Listing 2 defines an @tmpldir
instance variable that points to the subdirectory containing the templates. When it's time to load a template, line 14 prepends the tmpl
path to the provided file name and adds a .tex
suffix thereafter. This means that the generated path points to a real file, which the ERB template processor can then read from disk in line 19.
The template processor uses ERB
's result_with_hash()
method in line 20 to insert the text supplied for the page caption, and the paths to the photo files, into the respective template. The placeholders in the templates are <%= text %>
for the page text and <%= photos[0] %>
for the first element of the photos
array passed in, containing a list of JPEG paths to the photos to be included. For the image paths, there is no need to laboriously type in the entire path each time. As long as the @photodir
instance variable is pointing to the directory where all the images are stored (photos
in our example), you only need to specify the file name without a path in each case in Listing 1.
Defining the Name
To define the name of the book file to be created, the calling script sets the name
attribute of a Bm
object as shown in line 5 of Listing 1. To make this work, Listing 2 uses attr_accessor
in line 5 to define :name
and with it a read-write attribute name
for all objects of the class.
This means that an instance of the Bm
class in bm
can simply call bm.name = "mybook"
, like it does in line 5 of Listing 1, to set the book name by assignment. Line 25 in Listing 2 uses @name
to obtain the name from the instance variable and interpolates it within a string with "#{@name}"
. This gives you the name of the TeX file with all the piled up TeX code and will send the file to the XeLaTeX LaTeX compiler in the next step.
This means that line 26 only needs to open the .tex
file for writing and drop the content of the @tex
instance variable there, after having assembled all the necessary TeX instructions in it. The system()
call in line 28 then runs XeLaTeX against this, which produces a PDF document of the same name with the finished photo book, if all goes well.
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
![Learn More](https://www.linux-magazine.com/var/linux_magazin/storage/images/media/linux-magazine-eng-us/images/misc/learn-more/834592-1-eng-US/Learn-More_medium.png)
News
-
Endless OS 6 has Arrived
After more than a year since the last update, the latest release of Endless OS is now available for general usage.
-
Fedora Asahi 40 Remix Available for Macs with Apple Silicon
If you've been anticipating KDE's Plasma 6 for your Apple Silicon-powered Mac, then you're in luck.
-
Red Hat Adds New Deployment Option for Enterprise Linux Platforms
Red Hat has re-imagined enterprise Linux for an AI future with Image Mode.
-
OSJH and LPI Release 2024 Open Source Pros Job Survey Results
See what open source professionals look for in a new role.
-
Proton 9.0-1 Released to Improve Gaming with Steam
The latest release of Proton 9 adds several improvements and fixes an issue that has been problematic for Linux users.
-
So Long Neofetch and Thanks for the Info
Today is a day that every Linux user who enjoys bragging about their system(s) will mourn, as Neofetch has come to an end.
-
Ubuntu 24.04 Comes with a “Flaw"
If you're thinking you might want to upgrade from your current Ubuntu release to the latest, there's something you might want to consider before doing so.
-
Canonical Releases Ubuntu 24.04
After a brief pause because of the XZ vulnerability, Ubuntu 24.04 is now available for install.
-
Linux Servers Targeted by Akira Ransomware
A group of bad actors who have already extorted $42 million have their sights set on the Linux platform.
-
TUXEDO Computers Unveils Linux Laptop Featuring AMD Ryzen CPU
This latest release is the first laptop to include the new CPU from Ryzen and Linux preinstalled.