Category Archives: org

Labeling toy storage bins with photos and text using ImageMagick and org-babel

I wanted to make labels for A-‘s new toy storage: three low Trofast drawer frames all along the wall.

I liked how early childhood drop-in centres labeled their shelves with both pictures and text. That way, kids can find things before she can read, while still being exposed to print. I took pictures of the bin contents and renamed the files to the labels I wanted to put on them, such as 2x2 blocks.jpg. (We have a lot of Duplo.)

This time, I experimented with creating the labels entirely in Imagemagick instead of using LaTeX. First, I used a table in Org Mode to let me easily play with the dimensions and recalculate pixel sizes.

DPI   300
Columns 3  
Rows 5  
Paper width 14 4200
Paper height 8.5 2550
Minimum margins 0.5 150
Label width 4.3333333 1300
Label length 1.5 450

I passed the width and the height to the following code block by using header arguments. I liked using 400 pixels as the height instead of 450, so that’s what I used. My source image size was 4032×3024 pixels. If I resize them to a height of 400, that gives me a width of 533. Allowing 20 pixels for the text left and right borders gives me (- 1300 533 20 20) = 727 as the text width.

#+begin_src sh :dir ~/code/labels :var width=1300 :var textwidth=727 :var height=400 :var pointsize=72 :results silent
for x in source/*; do
  file=$(basename "$x")
  /usr/local/bin/convert \( \( "source/$file" -resize x${height} \) \
     \( -background white -fill black -font Alegreya-Regular -bordercolor White \
         -gravity West -border 20 -pointsize $pointsize -size ${textwidth}x caption:"${file%.*}" \) \
     +append \) \
     -extent ${width}x${height} \
     \( -fill none -stroke gray -draw "rectangle 0 0 $(echo $width - 1 | bc) $(echo $height - 1 | bc)" \) \
     "out/$file.png"
done
#+end_src

Sample resized label:

I moved the ones I wanted from the out directory to a ready directory and combined the ones I wanted to print into a PDF:

#+begin_src sh :dir ~/code/labels :results silent
montage ready/*.png -tile 3x5 -background none -geometry +0+0 print.png
convert print*.png -density 300 -quality 100 print.pdf
#+end_src

Then I printed the labels in colour on an 8.5×14″ sheet of paper (single-sided, landscape), cut them out, and taped them onto the bins with packing tape.

W- suggested taking macro shots that more clearly show the characteristics of things in the bins instead of just aiming down and taking pictures of the contents. Might be a good excuse to show A- basic product photography when we get back.

W- also recommended making the label text bigger. The first time I did it, I just picked a pointsize based on whatever fit the ones I wanted to print. I decided against letting Imagemagick maximize the font size because I didn’t want labels to have very different text sizes. After a little poking around, I figured out how to use caption: instead of label: to give me text that can neatly wrap within a given space, and that will probably let me use 90-point font instead of 72-point font. That will make the next iteration of labels even easier to read.

It’s nice having all these bins. A- is getting pretty good at heading straight for the bin she wants something from, and she even talks about them: “Horse is in animals bin.” I’m glad we labeled the most frequently used bins. I’ll tweak the labels when we get back from our trip. We’ll probably change some of the bin contents anyway.

Hooray for ImageMagick, and hooray for variables in org-babel blocks!

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:

out.jpg

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).

Story

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
      '(add-to-list 'org-latex-classes
                    `("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 the header.tex

    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}
    \beamertemplatenavigationsymbolsempty
    \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.

Using Org Mode, LaTeX, Beamer, and Medibang Paint to make a children’s book

Story

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

Thumbnails

spread0.png spread1.png spread2.png spread3.png spread4.png spread5.png

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
      '(add-to-list 'org-latex-classes
                    `("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
  • Tweak the header.tex

    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
    #+LATEX_HEADER: \input{header.tex}
    #+PROPERTY: header-args :var pages=12
    
    * Story
    
    ** 
    ** 
    ** 
    ** It's time to make a smoothie!
    ** I pour blueberries into the blender.
    ** Mama adds hemp seeds.
    ** I add spinach.
    ** Mama blends it all with some water.
    ** I peel and add a banana.
    ** I add some yogurt. 
    ** 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
    • painted and shaded 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")
           spread gravity page page))))
    
    (cl-loop for i from 0 to (1- pages) do
             (my/combine-spread-drawing-and-text i pages))
    

  • Create print spreads for saddle-stitching

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

  • Create thumbnails of spreads

    (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 "
               "thumbnails/spread%d.png")
       i i width shadow shadow i)))
    

  • Ideas for next steps

    • Better thumbnails for easy previews
    • PDF for online reading
    • More layout possibilities (photos, verses, etc.)
    • Smaller books:

      • crop marks on a full-page print, or
      • the right imposition rules to print more pages on a sheet

Org Mode: Inserting a function definition

While nudging jcs to add a definition of jcs-insert-url to the blog post about Making Things Easier, I realized it might be handy to have a quick function for inserting a function definition without thinking about where it’s defined. This tries to use the definition from the source, and it can fall back to using the stored function definition if necessary. There’s probably a better way to do this, but this was small and fun to write. =)

Naturally, I used it to insert itself:

(defun my/org-insert-defun (function)
  "Inserts an Org source block with the definition for FUNCTION."
  (interactive (find-function-read))
  (let* ((buffer-point (condition-case nil (find-definition-noselect function nil) (error nil)))
         (new-buf (car buffer-point))
         (new-point (cdr buffer-point))
         definition)
    (if buffer-point        
      (with-current-buffer new-buf ;; Try to get original definition
        (save-excursion
          (goto-char new-point)
          (setq definition (buffer-substring-no-properties (point) (save-excursion (end-of-defun) (point))))))
      ;; Fallback: Print function definition
      (setq definition (concat (prin1-to-string (symbol-function function)) "\n")))
    (insert "#+begin_src emacs-lisp\n" definition "#+end_src\n")))

Sorting Org Mode lists using a sequence of regular expressions

I manually categorize Emacs News links into an Org unordered list, and then I reorganize the list by using M-S-up (org-shiftmetaup) and M-S-down (org-shiftmetadown). I decide to combine or split categories depending on the number of links. I have a pretty consistent order. John Wiegley suggested promoting Emacs Lisp and Emacs development links at the top of the list. I like to sort the rest of the list roughly by interest: general links first, then Org, then coding, then other links at the bottom.

Here’s some code that sorts Org lists in a custom sequence, with unknown items at the bottom for easy re-ordering. It will take a list like:

- Other:
  - Link A
  - Link B
- Emacs development:
  - Link A
  - Link B
- Emacs Lisp:
  - Link A
  - Link B

and turn it into:

- Emacs Lisp:
  - Link A
  - Link B
- Emacs development:
  - Link A
  - Link B
- Other:
  - Link A
  - Link B
(defun my/org-sort-list-in-custom-order (order)
  "Sort the current Org list so that items are in the specified order.
ORDER is a list of regexps."
  (org-sort-list
   nil ?f
   (lambda ()
     (let ((case-fold-search t)
           (item
            (when (looking-at "[ \t]*[-+*0-9.)]+\\([ \t]+\\[[- X]\\]\\)?[ \t]+")
              (org-sort-remove-invisible (buffer-substring (match-end 0) (point-at-eol))))))
       (or (cl-position item order :test (lambda (a b) (string-match b a))) (1+ (length order)))))
   '<))

(defun my/emacs-news-sort-list ()
  (interactive)
  (my/org-sort-list-in-custom-order
   '("Emacs Lisp"
     "Emacs development"
     "Appearance"
     "Navigation"
     "Dired"
     "Org Mode"
     "Coding"
     "Calc"
     "Email and news"
     "Other"
     "Discussion"
     "Outside Emacs"
     "New packages?")))

One more little thing automated… The next thing would probably be to write some code that autocategorizes links based on an alist of (item . regexp) pairs, which would also reduce the need to re-sort the items afterwards. Still, this is good for dealing with manual categorization. =)

External brains – current state

Being the primary caregiver for a toddler means I’m distracted, often interrupted, and somewhat sleep-deprived, so using external brains (paper, phone, laptop) helps a lot. Here are a few things I rely on them to keep so that I can declutter my mind, worry less, and be more present:

  • Daily journal: This lets me tell W- stories about A-, appreciate A-‘s progress, and feel good about where the time went. I use Memento Database on my Android phone to add datestamped, categorized text notes to a Google Sheets spreadsheet.
  • Weekly/monthly review: This lets me appreciate progress over a longer period and plan for the next one. I edit the daily journal entries in Memento to set their importance (1: weekly highlight, 2: monthly), then filter, sort, group, and export the entries. I copy the text into Tasks Free (which synchronizes via Google Tasks) and then edit the text on my phone while A- nurses and sleeps. If I manage to have computer time, I might use Emacs to fill in more of my weekly or monthly review.
  • Tasks (next actions, inbox, waiting, thoughts, and assorted other lists): Tasks Free on my phone, since I can check it or add to it any time. I jot ideas/thoughts down here too, since I can write while nursing A- in bed. If I run out of battery, I charge my phone and move to W-‘s old phone, so I can keep writing. After I draft a thought that might be a good blog post, I copy it into the WordPress app and post it so that I can find it again later. (And so that other people might chime in with insights!) If I have time, I might copy a thought into Emacs, flesh it out further, and post it with org2blog.
  • Calendar: Google calendars – one for appointments, one for activity options. This way, I can hide all the optional stuff quickly.
  • Longer-term reminders, notes, work in progress: Org files. It’s so nice to be able to schedule tasks and have detailed notes on how to complete those tasks. I also really like being able to break things down with outlines and think out loud with code snippets. The weekly agenda review helps me catch reminders.
  • Photos and videos: I sync a Wi-Fi-enabled camera with my phone, then erase everything off the camera. Google Photos automatically uploads everything and shares them with W-. I post selected things to a Facebook closed group for kiddo updates.
  • Time and activity log: I track my time for curiosity. I made my own tracker (quantifiedawesone.com), and I made another button-based interface for easier tracking on my phone. That interface also lets me quickly log data to baby-connect.com, where I track A-‘s sleep, nursing, and potty use. I made my own visualizations, too.
  • Reference info: Org. Document scans in Dropbox or Owncloud, some GPG-encrypted.
  • Book notes: I’ve been reading mostly e-books from the library, so I take screenshots on my phone and they go through my photo workflow. I use Tasks Free to capture quick notes about paper books. I’d like to get back to sketchnotes when I have more focused time.
  • New words: I’m tracking this out of curiosity. She has said 350+ different words, and she’s not even 2 years old yet. :) Many of the words come from songs and books, so it helps to think of concrete experiences she can associate them with.
  • Scenarios, just-in-case notes: Org. Good for managing risks and worrying less.
  • Processes: Org. Good for step-by-step instructions when I’m sleep-deprived or doing something infrequently.
  • Finances: Ledger-cli. Text-based accounting, yay! I have some reports in ledger-mode and some in an Org file. I update this monthly or so.
  • Cooking: We manage our grocery list in OurGroceries because of the multiuser real-time sync. Recipes tend to be looked up on the Internet and then copied into a paper notebook or onto an index card when we like them. Meal plan is written on scrap paper and stuck to the front of the fridge.

I want to get better at structuring my observations of A-‘s progress, planning follow-up activities, and keeping the overall picture in mind. Since I’m roughly categorizing the daily journal entries in Memento / Google Sheets, I can probably create a table that will make it easy to see if there are neglected areas, and then extend that to plan ideas. Or, well, as much planning as one can do with a toddler, really – more like keeping an eye out for opportunities to build on A-‘s interests. So far it’s been okay, though. I’ve been learning about basic principles and skill components from textbooks on early childhood education, and that makes it a bit easier for me to improvise. I have a rough outline of areas to think about on a regular basis, and a few ideas to explore over the next few months.

I also want to get better at managing my book notes and other ideas I want to revisit at the appropriate time. I’m a little lacking on the review side, since most of my writing time is taken up by capturing observations and the occasional reflection. So far, this has also been okay. I just have to trust that whatever I’m writing down will still make sense to me in a few months or years, and the most important stuff will turn up on my radar at the appropriate time. Schedule-based reminders are easy, but things wait for all sorts of other factors. For example, there are lots of practical life skill exercises I picked up from the Montessori education books that will be a better fit when A-‘s fine motor skills improve.

I’d like to get back to drawing someday, although it may have to wait until I have more dedicated time. Whenever I start sketching out a thought, A- likes drawing on my paper or asking me to draw stuff for her. It’s all good, though, since it encourages us to scribble. It just means that I can’t take a picture and reuse the drawing – I have to type it up anyway, so I may as well explore the thought on my phone unless I want to think nonlinearly.

I’ll experiment with using timestamped notes in Memento to help me with offline logging when we go on our trip. I might also just spring for Internet access once we’re off the plane, since that’s useful for other things as well.

I’ve got a fair bit of clutter in my Org files, but I trust that the outlining tools will help me reorganize as needed. I tend to do just-in-time organizing: instead of starting with an outline and drilling down, I might capture a bunch of thoughts, refile them as the structure becomes clearer, and then work up and down from there.

I don’t spend nearly as much time on the computer as I might want to for optimal external-brain management, but the current system is surprisingly workable. Shifting more of my writing to my phone (including the weekly/monthly summaries) made a difference, since I don’t have to keep as much in my head or get constrained by computer time. I look forward to tweaking how things work as A- becomes more independent and as I learn more.