## Making an 8-page 7″x4.25″ captioned photo book with Org Mode and LaTeX

Here’s another technique that makes a simple photo book. I wanted to
make an 8-page book that could be printed 4 pages to a 8.5″x14″ sheet
(duplex, flip along the short edge), with a final page size of
7″x4.25″.

Sample with my own photos:

## Prerequisites

• ImageMagick
• Texlive (probably)
• latex-beamer
• Org Mode and Emacs

## Process

We can define the labels and their captions in a named table like this:

 Let’s Go for a Walk Caption for photo 1 placeholder.png Caption for photo 2 placeholder.png Caption for photo 3 placeholder.png Caption for photo 4 placeholder.png Caption for photo 5 placeholder.png

Note that the first page is row #1 this time, instead of starting with
the last page.

Then we generate the LaTeX code with some Emacs Lisp, like so:

#+begin_src emacs-lisp :var pages=story :results value latex :exports results
(mapconcat (lambda (row) (format "\\graphicframe{%s}{%s}" (cadr row) (org-export-string-as (car row) 'latex t))) pages "\n")
#+end_src


I put that in a subtree for easier exporting with C-c C-e C-s l b (org-export-dispatch, subtree, LaTeX, Beamer).

## Process

• Set up Org Mode export to Beamer
(eval-after-load "ox-latex"
;; update the list of LaTeX classes and associated header (encoding, etc.)
;; and structure
("beamer"
,(concat "\\documentclass[presentation]{beamer}\n"
"[DEFAULT-PACKAGES]"
"[PACKAGES]"
"[EXTRA]\n")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))


This file gets included in the LaTeX file for the children’s book.
Tweak it to change the appearance. In this example, I use black serif
text text on the left side of a picture, both occupying roughly half
of the page. I also experimented with using a different font this time, which you might need to install (for me, I did apt-get install texlive-fonts-extra).

\geometry{paperwidth=7in,paperheight=4.25in,left=0.5in,right=0.5in}
\usepackage{etoolbox}
\usepackage[T1]{fontenc}
\usepackage{Alegreya}
\usefonttheme{serif}
\setbeamercolor{normal text}{fg=black,bg=white}
\setbeamercolor{structure}{fg=black,bg=white}
%% \setbeamertemplate{frametitle}
%% {
%%   \begin{center}
%%   \noindent
%%   \insertframetitle
%%   \end{center}
%% }
\newcommand{\graphicframe}[2] {
{
%% \if #1\empty
%% \usebackgroundtemplate{}
%% \fi
\ifstrempty{#1}{
\begin{frame}[plain]
\begin{center}
\noindent
\textbf{\huge{#2}}
\end{center}
\end{frame}
}{
\begin{frame}[plain]
\begin{columns}
\begin{column}{0.48\textwidth}
\huge{#2}
\end{column}
\begin{column}{0.48\textwidth}
\includegraphics[height=\textheight,width=\textwidth,keepaspectratio=true]{#1}
\end{column}
\end{columns}
\end{frame}
}
}
}
\usepackage[noframe]{showframe}
\renewcommand{\maketitle}{}

• Create the PDF
pdflatex index.tex

• Create one PNG per page
mkdir pages
convert -density 300 index.pdf -quality 100 pages/page%d.png

• Create the 4-up imposition

The diagram at https://pressnostress.com/iw/howto/booklets/1.html was helpful.

montage $$page4.png -rotate 180$$ $$page3.png -rotate 180$$ page7.png page0.png -tile 2x2 -mode Concatenate front.png
montage $$page2.png -rotate 180$$ $$page5.png -rotate 180$$ page1.png page6.png -tile 2x2 -mode Concatenate back.png
convert front.png back.png -density 300 ../print.pdf


## Other notes

Placeholder image from https://en.wikipedia.org/wiki/File:Portrait_placeholder.png – public domain.

## Week ending 2018-03-10

A- got a new conformer last week. Progress: she didn’t cry in the waiting room, although she still burst into tears as soon as she saw the ocularist. We’re continuing with the conformer approach instead of switching to a painted shell because A- still rubs the conformer out of her eye from time to time, and it’s easier to replace a conformer. Maybe we’ll switch when she’s closer to school age.

I asked her where she wanted to go for Field Trip Friday. She said, “Riverdale Farm. I miss that. I have fun. Big sheep make big noises.” So we went, and we enjoyed looking at the baby goats. We passed by the Children’s Book Bank, and I was delighted to find that you can take double the number of books on Fridays. I picked up a few more Seuss books.

We’ve been making more of an effort to explore and catalogue places so that we can make the most of Toronto’s resources. We checked out Baird Park, which has a playset with a short tunnel that A- actually worked up the courage to go through. She liked going down the twisty slide on my lap, and then graduated to going down the twisty slide at Lithuania Park with a little push. I posted a few park reviews in Google just in case other people find those notes handy, and I should find some way of organizing my own copy of the notes too.

A- has been having fun with both fine and gross motor skills. She practised using a ladle to pour and a butter knife to spread. She goose-stepped and danced.

A- can talk about more abstract things. She scribbled and said she was drawing “nervous.” One time, W- was carrying her up the stairs to change her diaper, and she was getting a little wriggly and distracted. He said, “Focus.” She said with enthusiasm, “Diaper!”

She likes being involved. When she was at the sink, she said with delight: “Yes! I’m busy!”

One time, she insisted that I carry her up bridal-style in my arms (which she accomplished by flopping in a certain way and protesting if I tried changing things). I was mystified, but it all became clearer once we got upstairs and she wanted me to read Emma to her. The Cozy Classics version has just twelve words, and “carry” is one of them. “Frank Churchill carry. Emma,” she said. Aha!

She often sings nursery rhymes and other songs. She sang part of “Mamma Mia” while dancing, and then obligingly repeated while I suppressed my laughter long enough to record her on video.

Little improvements:

• W- set up a Synology DS718 network-attached storage server. Wheee! I feel more grown-up with proper backups. I set up borg backups for my server and my laptop. Next: Docker containers for testing the backups…
• I set up lots of voice shortcuts to help me with groceries and with tracking. For example, I can say, “Okay Google, baby awake” and it will log that in my system. I explored Tasker’s Memento support, too.
• I figured out how to use Org Mode and LaTeX to typeset drawing templates for children’s books, and I used that to make a book about smoothies. Next: photos, more layouts
• Lots of tidying up in the basement, too. Whee!
• I switched to writing in Markor on Android. I briefly enabled Markdown support in WordPress, but it was messing up some of my other posts, so I turned it off again.
• I set up god-mode in Emacs, which does make phone use a bit easier.

## Using exiftool to put date, rating, and title in photo filenames

Now that we have a Synology backup server, I want to get better at keeping and organizing photos. I’ve got lots of pictures and videos of A- in Google Photos, but I don’t want to rely only on that. When Google eventually decommissions the service (no signs of this now, but you can never tell), I’d like to already have copies of my favourite photos and videos all prioritized and backed up instead of spending days wading through accumulated cruft.

I had previously added significant moments to a “Weekly highlights” album in the Google Photos app. I had also tried to select a number of those for “Level 2 highlights” and “Level 3 highlights” roughly approximating monthly and yearly filters. This was awkward, though, since Google Photos didn’t let me see which photos were already in an album or which timespans weren’t well represented. I wanted a five-star rating system so that I could gradually winnow images I liked, and I wanted tags for more flexibility.

The F-Stop Gallery app on Android seemed to be a quick way to sort through images, rate them, and tag them. I liked how it stored the metadata in the file instead of in a separate database. The bulk management tools were decent, although of course it would be even better to do things with fewer taps.

I downloaded ZIPs of my highlight albums and extracted them to a Samba share so that I could access them from my phone. I rated the level 3 highlights as 5 stars, level 2 as 3 stars, and weekly highlights as 2 stars, leaving the 4-star level for finer distinctions if I need to fiddle with things. Then I used cp -n (no clobber; don’t overwrite existing files) to copy the 5-star photos, then the 3-star photos, and lastly the 2-star photos. That way, even if a photo was in multiple albums, the file would have just the highest rating I assigned.

I can’t always rely on apps to index and search by the metadata in a file, so I like putting that information in the filename. A good filename might look like this:

2016-08-01-20-14-44 ### Relaxing on the deck #family.jpg

It starts with a date and time, since timelines make sense. I add one to the number of stars and convert that to # so that I can easily search for, say, ### to show me all entries that have at least two stars. This also creates a neat ASCII bar chart effect when looking at lists of filenames. I want to include the title if available, and any tags for easy searching as well.

Here’s the Bash script that takes an image file and renames it accordingly:

#!/bin/bash
exiftool -m \
-"Filename<\${DateTimeOriginal;s/[ :]/-/g} \${Rating;s/([1-5])/'#' x (\$1 + 1)/e} \${Title} \${Subject;s/^/#/;s/, / #/g}.%e" \ "[email protected]" This probably has bugs, but it seems to be a decent start. It was great to find out that I can pass Perl expressions to exiftool to modify the field value. I figured out that I could combine that with the /e flag for executable replacements so that I could generate a string of N+1 characters. While tinkering with the code, I accidentally used \1 instead of \$1 in my Org Mode block. That made a number such as 5 turn up as a scalar with a six-digit value, so I ended up with a really long line of #####... in my Org file. Emacs was definitely not happy. I ended up opening my Org file in vi so that I could delete the offending line. Anyway, I managed to recover from that and figure out what I needed to put in. Yay!

It would be pretty neat to have some kind of inotify thing watching my NAS inbox and processing files accordingly. In the meantime, I don’t mind running another script. We’ll see how this goes!

## February 2018

In addition to our usual field trips to the Science Centre and the ROM, we went to Riverdale Farm. A- named the animals and enjoyed talking about them, although she found the sheep a little loud. We also started visiting family more often, for both big things like Chinese New Year and A-‘s birthday as well as small things like an afternoon of hanging out.

A- wanted to build a Duplo tower so tall that she had to stand on a chair to add blocks to it. She got pretty good at inserting shapes into her sorter and screwing together the nuts and bolts in her toolkit.

She walked astride her balance bike all the way to the kitchen by herself. She carried empty containers on a tray. She danced a lot and imitated other aspects of music class. She enjoyed bouldering. She wanted to try out a life jacket while swimming, and she kicked her legs too. She picked up diving rings with her foot.

She sang Humpty Dumpty, Baa Baa Black Sheep, and Hey Diddle Diddle practically in full. I could prompt her to show me a sleepy face, a sad face, and so on. She talked about recent events and how she felt, often revisiting moments that were particularly significant to her. She echoed many of the things we often say, such as “Give it a try.” She asked for specific things using “I need…” and often thanked us.

She played more independently, often amusing herself for a number of minutes or toddling off to a different room while telling us to stop. She confidently touched different textures in books. She asked to be pushed faster while in the playground swing, and she wanted to go down the twisty slide.

Her eye exam went well. The pediatrician is working on referrals to Sick Kids for dentistry and endocrinology.

We replaced our printer with an HP M277dw, and I learned how to use it to make short books for A-. I figured out an Emacs News workflow that I can do entirely from my phone, and I set up Syncthing for my files too. We organized A-‘s toys and clothes into IKEA Trofast drawers. I uploaded old photos to Google Photos. Progress!

March: A new conformer, a consultation with the anesthesia dentist, more children’s books, and lots of time with A-. We’ll figure this out!

## Story

• It’s time to make a smoothie!
• I pour blueberries into the blender.
• Mama blends it all with some water.
• I peel and add a banana.
• Mama blends it again.
• Yum yum!

## Process

• Prerequisites

• ImageMagick
• Texlive (probably)
• latex-beamer
• Org Mode and Emacs
• Set up Org Mode export to Beamer

(eval-after-load "ox-latex"
;; update the list of LaTeX classes and associated header (encoding, etc.)
;; and structure
("beamer"
,(concat "\\documentclass[presentation]{beamer}\n"
"[DEFAULT-PACKAGES]"
"[PACKAGES]"
"[EXTRA]\n")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))


• Set up image directories

mkdir text-pages blank-spreads drawn drawn-pages


 text-pages Will contain one image per page of just the plain text. blank-spreads Will contain text spreads ready for drawing drawn Export one image per spread (without the text layers) from your drawing program drawn-pages Will contain one image per page combining text and drawing

This file gets included in the LaTeX file for the children’s book. Tweak it to change the appearance. In this example, I use black serif text at the bottom of the page.

\geometry{paperwidth=7in,paperheight=8.5in,left=0.5in,top=0.5in,right=0.5in,bottom=0.5in}
\setbeamercolor{normal text}{fg=black,bg=white}
\setbeamercolor{structure}{fg=black,bg=white}
\usefonttheme{serif}
\setbeamertemplate{frametitle}
{
\begin{center}
\vspace{0.7\textheight}
\noindent
\insertframetitle
\end{center}
}
\usepackage[noframe]{showframe}
\renewcommand{\maketitle}{}


• Write the story

I used Org Mode to make it easy to write the story.

Some considerations:

• Because we’re printing this as a saddle-stitched booklet, the number of lines should be a multiple of four. Sixteen is probably a good maximum.
• The first heading is actually for the last page.
• The second heading is for the cover page.
• The third heading is for the first inner page, the fourth heading is for the second inner page, and so on.
#+OPTIONS:   TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc author:nil date:nil
#+OPTIONS: H:1
#+startup: beamer
#+LaTeX_CLASS: beamer
#+LaTeX_CLASS_OPTIONS: [20pt]
#+BEAMER_FRAME_LEVEL: 1

* Story

**
**
**
** It's time to make a smoothie!
** I pour blueberries into the blender.
** Mama blends it all with some water.
** I peel and add a banana.
** Mama blends it again.
** Yum yum!


• Make the tex, PDF, page PNGs, and spread PNGs

1. Go to the subtree for the story and use M-x org-export-dispatch (C-c C-e) with the subtree option (C-s) to export it as a Beamer file (option l b).
2. Use pdflatex to convert the .tex to PDF.

pdflatex index.tex


3. Create one PNG per text page with:

convert -density 300 index.pdf -quality 100 text-pages/page%02d.png


4. Create spreads to draw on with:

montage text-pages/page*.png -tile 2x1 -mode Concatenate blank-spreads/spread%d.png


5. Optionally, create a layered PSD with:

convert blank-spreads/spread*.png $$-clone 1,0 -background white -flatten -alpha off$$ -reverse spreads-for-drawing.psd


• Draw

I imported the PNG layers into MediBang Paint on a Samsung Note 8 Android phone, and then:

• imported photos
• traced them
• hid the text layers
• exported one PNG per spread to QuickPic, renamed them, and uploaded them to Dropbox, because I couldn’t figure out how to export to Dropbox directly

Layer folders were handy for organizing spread-related images. I couldn’t seem to move all of the layers in a layer folder together on Android, but the iPad was able to do so. If I didn’t have the iPad handy, I combined the layers by exporting a PNG and then importeing it back into MediBang Paint.

This was a decent setup that allowed me to draw and paint even when I was in bed nursing A- and waiting for her to fall asleep. I held the phone with one hand and rotated the canvas as needed so that it was easier for me to draw lines with my right. Because of the awkward position and the small screen size, the lines are not as smooth as I might like, but the important thing is that they’re there. Whee! =)

It turns out to be possible to use the free MediBang Pro drawing program under Wine on Linux to import the PSD and save it to the cloud. I was also sometimes able to switch to drawing with iPad Pro with Pencil, but it was harder to find time to do that because that usually made A- want to draw too.

Anyway, after I drew and exported the PNGs, the next step was to…

• Convert the drawn spreads back to pages and combine them with the text

Here’s some code that combines the drawing and the text. Keeping the drawing and the text separate until this stage (instead of exporting the PNGs with the text) makes it easier to change the text later by recreating the text PNGs and running this step.

(defun my/combine-spread-drawing-and-text (page num-pages)
(let ((gravity (if (= (% page 2) 1) "West" "East"))
(spread (/ (% page num-pages) 2)))
(shell-command
(format
(concat "convert \$$" "drawn/spread%d.png -gravity %s " "-chop 50%%x0 +repage \$$ "
"text-pages/page%02d.png -compose darken "
"-composite drawn-pages/page%02d.png")

(cl-loop for i from 0 to (1- pages) do


This code pairs up the drawn pages into a PDF that can be printed duplex. Make sure to choose the option to flip along the short edge. I hard-coded the page orders for 4-, 8-, 12-, and 16-page booklets.

(let* ((page-order
'((0 1 2 3)   ; hard-coded page sequences
(0 1 2 7 6 3 4 5)
(0 1 2 11 10 3 4 9 8 5 6 7)
(0 1 2 15 14 3 4 13 12 5 6 11 10 7 8 9)))
(sequence
(mapconcat (lambda (d) (format "drawn-pages/page%02d.png" d))
(elt page-order (1- (/ pages 4))) " ")))
(shell-command
(format
"montage %s -tile 2x1 -mode Concatenate print-duplex-short-edge-flip.pdf"
sequence)))


• Print and bind

After printing and folding the book, I used tape to make the book hold together. Tada!

• Create on-screen PDF for reading

A little bit of manipulation so that the last page is in the right place:

(shell-command
(format "convert %s onscreen.pdf"
(mapconcat 'identity (cl-loop for i from 1 to pages
collect (format "drawn-pages/page%02d.png" (% i pages))) " ")))


(cl-loop
for i from 0 to (1- (/ pages 2)) do
(shell-command
(format
(concat "convert "
"\$$blank-spreads/spread%d.png " "drawn/spread%d.png " "-compose darken " "-resize %dx -flatten \$$ "
"\$$+clone -background black -shadow 50x1+%d+%d \$$ "
"+swap -compose src-over -composite "