September 2025
school, playdates, newsletter, EmacsConf infrastructure
2025-09-30-11
Science Centre adventure zone
First day: Grade 4
play group
farmers market
First week of Gr. 4! Celebration ice cream
Biidaasige Park, 9x
Trying the loom at Riverdale; also, Happy Kingdom
Bubbles at the park
KidSpark with friends
composted bitter melon, moved strawberries
A+ donated some clothes to the kids clothing swap; Little Miss Light Rye
reusable wipes dispenser
Turns out I needed a nap.
Sortbot
swimming
catch-up day
a good talk; popsicles at the park
newsletter HTML
magic show
taking a break from fretting
had fun coding
Etherpad 2.x
line art
taxes
towel slide
C-'s hat was stuck
Nature Club: poison ivy (okay so far)
A+ caught up with her homework
emergency kit
drawing icons
School: A+ started virtual grade 4.
After we figured out that we needed to check Google Classroom instead of Brightspace for assignments, she was able to catch up with her homework.
She often complains of boredom, but that's expected. Sometimes she tries the extra math topics I introduce. In general, though, she'd rather have the slack time to explore her own interests instead of doing more of the same. Totally understandable. I'll read through the CEMC math problems anyway so that I can keep some of them in my back pocket.
Play: Most days, we made it out to the playground after school. A+ had lots of fun playing with her closest friends, and she was also fine hanging out with me whenever they were playing a game she wasn't keen on. Sometimes we'd do math while waiting: algebra, binary conversion, geometry.
Independence: For my part, I think I've managed to mostly wrangle my school-related anxiety back to the occasional weekend check-in.
It helps to remind myself that it's a good way for her to practise making her own decisions in a low-stakes environment: what to do when, what kinds of breaks to take in between. Better to try things and possibly run into things she needs to figure out or get help with now than wait until university. The more I step back, the more I can appreciate how she's growing: getting stuff done during class time, stepping outside to self-regulate when a party's getting too noisy for her. Compared to last year, it's much easier for me to say, "All right, you're in charge. I haven't even checked what's due when. What do you want to work on first, and do you want any help from me?" Usually all the help she wants is hugs, although sometimes I still type what she dictates when the assignment is really boring. It's nice that she can tell me what she wants. I also like seeing that carry over into her social life at the playground. She can think ahead about potential reasons for conflict and stick up for herself when her predictions come true. She enjoyed expanding her emergency kit to cover more scenarios, and it was great to see her satisfaction when the pencil and paper she'd packed came in handy.
My own time: An easy way to tone down my fretting is to redirect some of that nervous energy into my own projects. It's good for me and it's good for A+, who likes it better when I treat her as a 9-("and a half!")-year-old instead of a 5-year-old. I went from spending practically all day with A+ in summer to having more focus time. I'm settling into my own rhythms. There's usually one big chunk I can dedicate to something that might take a long time. Monday is Emacs News, Tuesday is for consulting, Wednesday is my own stuff, Thursday is Bike Brigade, and Friday is Bike Brigade feedback or other things as needed. The other chunk of time might be for miscellaneous tasks: writing, tidying, errands, and so on. The long focus time chunk helps me feel like I'm making tangible progress on things that require coherent thought, and having another chunk for odds and ends lets me putter around with things that might not flow as smoothly.
Thanks to this rhythm, I managed to resist the temptation to focus on just the consulting requests. I finally got to implement a few of the Emacs tweaks that have been collecting dust in my inbox. I upgraded the Etherpad we use for EmacsConf. I felt a little more solid about it because I did it via an Ansible playbook I tested in Vagrant instead of doing it ad-hoc.
I also changed my Bike Brigade newsletter workflow to convert the Google Doc draft into a big mass of HTML that I can just dump into one block. I've been using it for the past few weeks. This is difficult for people to squeeze last-minute edits in, but getting rid of all those mouse clicks makes me a lot happier, and nothing has been truly urgent. It's a trade-off, but I'm okay with choosing to increase my happiness (or at least reduce annoyance).
Fun: In addition to these small technical improvements, I've been practising drawing, too: mostly simple little black-and-white icons, sometimes drawn with references. It's a reasonable way to use the time I'd otherwise spend waiting at playdates. I like it, although I'll probably mix more thoughts and colours back in. The icons are like babbling with words. Sometimes I still want to unwind tangled thoughts into sentences and paragraphs. Sometimes I can't think of anything in particular, and working on visual vocabulary at least keeps me moving forward.
I haven't been doing piano as much, so I decided to just stick with the Simply Piano subscription instead of adding Piano Marvel.
I want to get through more of the songs I've marked as favourites. There's still much for me to learn, and it's fun practising with music that we recognize.
I also haven't been playing as much Stardew Valley lately, probably because I'd rather spend that time tweaking Emacs instead. Sometimes A+ likes to interleave homework sessions and Stardew Valley days, so we're still making a little progress on our Stardew Valley Expanded farm. I enjoy playing co-op with her.
The weather's getting colder. I'll be wrapping up our real-life garden soon. Eventually I'll need to shift my playdate time-filler to things I can do outside even with gloves on. Maybe less drawing and more dictation as a way of fleshing out thoughts, or maybe some reading too. Last year, her playmates shifted indoors as the weather cooled down. We might see if this year we'll have more outdoor playdates with new friends, or if the two extracurriculars A+ is in (along with some more bike adventures with us, now that W- is retired) will be enough for us. There's a definite seasonality to my life at the moment, which feels nice.
Next: In October, I probably should record EmacsConf introductions so that I have more space for handling captions once the videos come in. I've scheduled some TODOs for the different e-mails I need to send speakers, too. On the personal side, I want to keep giving A+ space to take ownership of her learning. A+ wants to experiment with gymnastics classes, so we'll try that out.
Building on Visual vocabulary practice - ABCs, I
decided to make a regular grid that I could then
automatically split up into individual images. I
used Emacs's svg.el to generate the grid. I
started with 4 rows of 7 boxes to match the
alphabet example, but I realized that using 5 rows
of 7 boxes each would let me reuse the grid for a
monthly calendar. I numbered the boxes to make it
easier to double-check if the lists line up, but I
can write over the numbers for things like dates
since the background won't be exported.
I used convert icon-grid.svg icon-grid.png to
make it from the SVG produced by the following
code.
Code for producing the template
(require'svg)
(defvarmy-dot-grid-boxes-params'(:num-rows 5
:num-cols 7
:dot-size 3
:line-width 3
:dot-spacing 60
:grid-color"#a6d2ff":row-size 6
:col-size 6
:text-size 50
:margin-top 2))
(cl-defunmy-dot-grid-boxes-template (&key (num-rows 5)
(num-cols 7)
(dot-size 3)
(line-width 3)
(dot-spacing 60)
(grid-color "#a6d2ff")
(row-size 6)
(col-size 6)
(text-size 50)
(margin-top 2))
"Prepare an SVG with a dot grid within a table with solid gridlines.Each dot is a solid circle of DOT-SIZE filled with GRID-COLOR spaced DOT-SPACING apart.The gridlines are also GRID-COLOR. They should divide the image into ROWS and COLUMNS, which are ROW-SIZE * DOT-SPACING and COL-SIZE * DOT-SPACING apart.The table has a top margin with the dot grid, and this is MARGIN-TOP * DOT-SPACING tall.All dots are centered on their x, y coordinates.The rest of the image's background is white."
(let* ((width (* num-cols col-size dot-spacing))
(height (* dot-spacing (+ margin-top (* num-rows row-size))))
(margin-top-height (* margin-top dot-spacing))
(svg (svg-create width height)))
(dotimes (row (+ (* num-rows row-size) margin-top))
(dotimes (col (1+ (* num-cols col-size)))
(let ((x (* col dot-spacing))
(y (* row dot-spacing)))
(svg-circle svg x y dot-size
:fill-color grid-color
:stroke-width 0))))
(when (> text-size 0)
(dotimes (i (* num-rows num-cols))
(let ((x (* (% i num-cols) col-size dot-spacing))
(y (+ margin-top-height (* (/ i num-cols) row-size dot-spacing))))
(svg-text svg
(number-to-string (1+ i))
:x x :y (+ y text-size)
:fill-color grid-color
:font-size text-size
:stroke-width 0))))
(dotimes (col (1+ num-cols))
(let ((x (* col col-size dot-spacing)))
(svg-line svg x margin-top-height x height
:stroke-color grid-color
:stroke-width line-width)))
(dotimes (row (1+ num-rows))
(let ((y (+ margin-top-height (* row row-size dot-spacing))))
(svg-line svg 0 y width y
:stroke-color grid-color
:stroke-width line-width)))
svg))
With that function defined, I can make a template with:
I used that template to draw a bunch of little doodles. The Noteful app I use on my iPad makes it easy to import a template and then export my drawings without including the template.
(If this blog post is out of date, you can check the Dot-grid box templates section in my config for my current code.)
Once I imported the template into Noteful, it was
easy to draw using fragments of time. 35 boxes are
a lot, but each icon was just a few minutes of
drawing, and I enjoyed seeing the progress.
me
A+
pizza
mom and kid
flower
witch hat
pencil
chopsticks
rice bowl
peach
pillow
desk fan
folding fan
pumpkin
jack o' lantern
ghost
taxes
broomstick
bubbles
candy
bow
bao
bowl
strawberry
tomato
cherries
cake slice
cake
mug
teacup
tempest in a teapot
skull
poison
cauldron
tree
baseball cap
propeller beanie
top hat
magic
magic wand
cape
playing card
hanging towel
folded towels
soap dispenser
bar soap
picnic table
picnic basket
bread
croissant
donut
donut
sandwich
soup bowl
rice and eggs
oatmeal
From "How to Draw Cute Doodles and Illustrations" - Kamo
2025-09-29-05
enjoyment
crying
happy or asleep
making a mistake
sleepy
yum or cheeky
cheerful or excited
smiling
confusion
anger
unsettled
discomfort
front view
rear view
side view
sitting on a chair
teacher
baby
kids (1-3)
kids (4-5)
walking
running
jumping
raising a hand
sitting on the floor
swinging
singing
drawing
sunny
rain
cloudy
windy
stormy
snow
moon and stars
Splitting up the drawings into individual components
Because I kept all my doodles within the
template's boxes, it was easy to split up the
images into individual files. First, I needed the
text for all the labels. Sometimes I typed this in
manually, and sometimes I used Google Cloud Vision
to extract the text (editing it a little bit to
put it in the right order and fix misrecognized
text). Then I used Emacs Lisp to read the labels
from the text file, calculate the coordinates, and
use ImageMagick to extract that portion of the
image into a file. I used filenames based on the
label of the individual icon and the ID of the
image it came from.
I really liked being able to write code to extract
and name images all in one go. If you don't want
to dive into Emacs Lisp, though, you can slice up
a large image into small ones using ImageMagick.
I had worked on a similar visual vocabulary
project in 2013, but I had made it as a shared
notebook in Evernote. That's gone now, and I can't
remember if I backed it up or where I would've
saved a backup to. Ah well, no harm in starting
again, with files under my control.
Looking up images
Now that I'd broken down the images into labelled
components, I wanted to be able to quickly look up
icons from a web browser; my own version of The
Noun Project. First, I exported the label information
into a JSON.
Code for processing a sketch and updating the index
My curves are shaky. I'm mostly learning to ignore
that and draw anyway. Good thing redoing them is
a matter of a two-finger tap with my left
hand, and then I can redraw until it feels mostly
right. I try up to three times before I say, fine,
let's just go with that.
I often draw with my iPad balanced on my lap,
so there's an inherent wobbliness to it. I think
this is a reasonable trade-off. Then I can keep
drawing cross-legged in the shade at the
playground instead of sitting at the table in the
sun. The shakiness is still there when I draw on a
solid table, though. I have a Paperlike screen
protector, which I like more than the slippery
feel of the bare iPad screen. That helps a little.
It's possible to cover it up and pretend to
confidence that I can't draw with. I could smooth
out the shakiness of my curves by switching to
Procreate, which has more stylus sensitivity
settings than Noteful does. A+ loves the way
Procreate converts her curves to arcs. She moves
the endpoints around to where she wanted to put
them. I'm tempted to do the same, but I see her
sometimes get frustrated when she tries to draw
without that feature, and I want to show her the
possibilities that come with embracing
imperfection. It's okay for these sketches to be a
little shaky. These are small and quick.
They don't have to be polished.
The Internet says to draw faster and with a looser
grip, and that lots of practice will build fine
motor skills. I'm not sure I'll get that much
smoother. I think of my mom and her Parkinson's
tremors, and I know that time doesn't necessarily
bring improvement. But it's better to keep trying
than to shy away from it. Maybe as I relax more
into having my own time, working on my own things
and moving past getting things done, I'll give
myself more time for drawing exercise, like
filling pages with just lines and circles.
Reflections on sources
I had fun coming up with words and drawing them. I
could start with whatever was in front of me and
go from there. I used my phone to look up the
occasional reference image, like the heart.
Sometimes A+ suggested things to draw. Sometimes
she even took over.
The books were handy when I didn't feel like
thinking much. I could just reproduce the
already-simplified drawings. I often felt like I
still wanted to tweak things a bit more to make
them feel like my own, though, which was a useful
way to figure out more about what I like.
Instead of mimicking other people's sketches, I
can mine my sketchnotes and pull out the concepts
I tend to think about a lot. If I've drawn them in
Noteful, I can even copy them from their original
sketches, resize them, and make the lines a
consistent thickness. If I've drawn them
elsewhere, it's easy enough to redraw.
Building a visual library is a great way to learn how to actually draw things.
I'm curious about using this 30-minute drawing exercise to start paying attention to a few things, and maybe using the shrimp method if there's something I really want to nail down.
Visual mnemonic links might be a way to explore the connections between things as I wander around ideas (even though this video is way more advanced than I am).
Next steps
I think I'll keep drawing these visual vocabulary
practice sketches, focusing more on my own ways of
drawing. It's fun. I have 324 icons at the moment.
I wonder what the collection will be like when I
have a thousand terms in it.
On the Emacs side, it might be
interesting to quickly add a related doodle to the
margin of a blog post, or to look up or copy a
personal reference image as I untangle my thoughts
in a sketch. I'm tempted to write some Emacs Lisp
that searches for these terms in my draft blog
posts and adds a little hint whenever it finds a
match. Another small piece of code might identify
recurring nouns and verbs in recent posts and
suggest those if I haven't drawn them yet. Could be fun.
While collecting posts for Emacs News, I came
across this question about adding up Org Mode
table data by tag hierarchy, which might be
interesting if you want to add things up in
different combinations. I haven't needed to do
something like that myself, but I got curious
about it. It turns out that you can define a tag
hierarchy like this:
The first two lines remove any other tags you've
defined in your config aside from those in
org-tag-persistent-alist, but can be omitted if
you want to also include other tags you've defined
in org-tag-alist. Note that it doesn't have to
be a strict tree. Tags can belong to more than one
tag group.
EduMerco wanted to know how to use those tag
groups to sum up rows in a table. I added a
#+NAME header to the table so that I could refer
to it with :var source=source later on.
(defunmy-sum-tag-groups (source &optional groups)
"Sum up the rows in SOURCE by GROUPS.If GROUPS is nil, use `org-tag-groups-alist'."
(setq groups (or groups org-tag-groups-alist))
(cons
(car source)
(mapcar
(lambda (tag-group)
(let ((tags (org--tags-expand-group (list (car tag-group))
groups nil)))
(cons (car tag-group)
(seq-map-indexed
(lambda (colname i)
(apply '+
(mapcar (lambda (tag)
(let ((val (or (elt (assoc-default tag source) i) "0")))
(if (stringp val)
(string-to-number val)
(or val 0))))
tags)))
(cdr (car source))))))
groups)))
Then that can be used with the following code:
#+begin_src emacs-lisp :var source=source :colnames no :results table(my-sum-tag-groups source)#+end_src
to result in:
tag
Q1
Q2
GT1
10
9
GT2
4
8
GT3
5
11
Because org--tags-expand-group takes the groups
as a parameter, you could use it to sum things by
different groups. The #+TAGS: directives above set
org-tag-groups-alist to:
I haven't specifically needed to add tag groups in tables myself, but I suspect the recursive expansion in org--tags-expand-group might come in handy even in a non-Org context. Hmm…
I messed up on one of my tax forms, so I needed to
send the tax agency a single document that
included the amended tax return and the supporting
slips, with my name, social insurance number, and
reference number on every page. It turned out to
be rather complicated trying to get calculated
\pageref to work with \includepdf, so I just
used \hyperlink with hard-coded page numbers. I
also needed to use qpdf --decrypt input.pdf
output.pdf to decrypt a PDF I downloaded from one
of my banks before I could include it with
\includepdf.
Here's what I wanted to do with this Org Mode / LaTeX example:
Coloured header on all pages with info and page
numbers
Including PDFs
Hyperlinks to specific pages
* Letter#+DATE:2025-09-24#+LATEX_CLASS: letter#+OPTIONS: toc:nil ^:nil title:nil#+LATEX_HEADER: \usepackage[margin=1in]{geometry}#+LATEX_HEADER: \hypersetup{hidelinks}#+LATEX_HEADER: \usepackage{pdfpages}#+LATEX_HEADER: \usepackage{fancyhdr}#+LATEX_HEADER: \usepackage{lastpage}#+LATEX_HEADER: \usepackage{xcolor}#+LATEX_HEADER: \signature{FULL NAME GOES HERE}#+LATEX_HEADER: \fancypagestyle{plain}{#+LATEX_HEADER: \fancyhf{}#+LATEX_HEADER: \fancyhead[L]{\color{teal}\hyperlink{page.1}{HEADER INFO}}#+LATEX_HEADER: \fancyhead[R]{\color{teal}\thepage\ of \pageref{LastPage}}#+LATEX_HEADER: }#+LATEX_HEADER: \pagestyle{plain}#+LATEX_HEADER: \makeatletter#+LATEX_HEADER: \let\ps@empty\ps@plain#+LATEX_HEADER: \let\ps@firstpage\ps@plain#+LATEX_HEADER: \makeatother#+LATEX_HEADER: \renewcommand{\headrulewidth}{0pt}#+LATEX_HEADER: \newcommand{\pdf}[1]{\includepdf[link,pages=-, scale=.8]{#1}}#+LATEX_HEADER: \newcommand{\pages}[2]{\hyperlink{page.#1}{#1}-\hyperlink{page.#2}{#2}}#+LATEX: \begin{letter}{}#+LATEX: \opening{Dear person I am writing to:}
Text of the letter goes here.
Please find attached:
| Pages | || @@latex:\pages{2}{10}@@ | Description of filename1.pdf || @@latex:\hyperlink{page.5}{5}@@ | Can link to a specific page || @@latex:\pages{11}{15}@@ | Description of filename2.pdf |#+LATEX:\closing{Best regards,}#+LATEX: \end{letter}#+LATEX: \pdf{filename1.pdf}#+LATEX: \pdf{filename2.pdf}
After filling it in, I exported it with C-c C-e
(org-export) C-s (to limit it to the subtree)
l p (to export a PDF via LaTeX).
Not the end of the world. At least I learned a
little more LaTeX and Org Mode along the way!
When A+ saw what I was doing, she asked me to swap
out my meeting icon from "people around a table"
to her online meetings at virtual school. She even
added details: "This is the kid with the Minecraft
background, this is the kid with big
headphones…" I enjoyed watching her in this
state of playful focus. I wonder what else I can
draw that she might have fun taking over.
"Meeting" is my favourite one in this set, but
since that's mostly A+'s, my next favourite is
"freeze." Canada gets even colder than -20C, but
for me, -20C is definitely stay inside weather.
I've also been enjoying Kamo's books, like How to
Draw Cute Doodles and Illustrations. Her style
reminds me of the Illustration School series by Sachiko
Umoto, which I also liked. I think I tend towards
simple and approachable rather than realistic or
technically impressive. Learning how to draw
concrete things might help me get better at
drawing abstract things. It's fun to slow down and
pay attention to more details, too. Turns out I'd
been drawing guitar holes in the wrong place all
this time. Now I know!
With the EmacsConf call for proposals now closed,
I have a little time before EmacsConf speakers
send in their pre-recorded videos come in for
captioning. I decided to dust off the
infrastructure to see what makes sense to upgrade.
We use Etherpad for collaborative note-taking
during EmacsConf. It's straightforward to use and
pretty reliable. Conference participants can use
it to share notes, questions, and links. They can
also use IRC to ask questions, and volunteers copy
those questions into the pad for the talk. Hosts
and speakers can keep an eye on the pad for
questions. We send speakers a copy of their talk's
pad after the conference, and we post that along
with other follow-up questions on the conference
wiki. Here's an example: Writing academic papers
in Org-Roam.
A native Emacs solution for collaborative notes
would be even better. CRDT was great for
experimenting with real-time collaboration within
Emacs, but I'm not sure it can handle a ton of
simultaneous connections and I don't want to find
out in the middle of the conference. Also, requiring
Emacs would leave out the people who only have a
web browser handy. It would be super cool if we
had something with Emacs, web, and IRC interfaces,
but for now, Etherpad will do.
We started by using Wikimedia's instance, and then
we moved to hosting our own. For the past two
years, we've used Etherpad 1.9.7.
Etherpad is currently at version 2.5.0. There are
some performance improvements, bugfixes, and
security fixes, so I think it'll be worth
upgrading to that. I don't know of any specific
issues or upgrades, but it's a good idea to stay
closer to the latest release than to get too far
out of date.
I switched our
roles/pad/tasks/main.yml to use
systemli.etherpad from ansible-galaxy. I also
figured out how to set up a Vagrant virtual
machine that I could destroy and reconfigure with
vagrant destroy; vagrant up --provision. Here's
my Vagrant file for that:
- name: Pre-flight checks and package installation
hosts: pad
become: truegather_facts: falsepre_tasks:
- name: Ensure ntpdate is installed for time sync
ansible.builtin.apt:
name: ntpdate
state: present
update_cache: yes
- name: Synchronize system clock
ansible.builtin.command: ntpdate pool.ntp.org
changed_when: true
- name: Ensure ACL package is installed
ansible.builtin.apt:
name: acl
state: present
- name: Load vars
hosts: pad
tags: always
tasks:
- include_vars:
file: vagrant-vars.yml
- name: Set up pad proxy
hosts: pad
tags: proxy
roles:
- pad-proxy
- name: Set up pad
hosts: pad
tags: pad
roles:
- pad
I had used Vagrant in 2013, and it felt good to
have the time to set up more testing
infrastructure. I liked being able to test my
pad and pad-proxy roles against a local
virtual machine. I could figure out whatever
tweaks I needed without messing up the production
instance that we use for some meetups in
between conferences.
Our production instance is on Debian 10 (Buster).
That has reached its end of life for security
updates, so apt-cache update doesn't work on it
any more, and those steps in my Ansible playbook
fail. I'm waiting for Amin Bandali to work on
upgrading that server, since he has other stuff
running on it. By setting update_cache variable
that I override in my inventory.yml and referring
to it with update_cache: "" in
my task, I can conditionally disable the apt-cache
update steps. That let me run the playbook against
the production server, and now we're on Etherpad 2.x.
I recently updated our BigBlueButton instance to version 3.0.12. We've decided to stay with Icecast 2.4.4-1 for doing the livestreaming. We'll probably also keep OBS 29.1.2 and ffmpeg 6.0.1 instead of upgrading. With no must-have new features and other organizers' limited availability, it's better to keep those parts stable. This year, we'll continue using whisperx to help with the first draft of captions, but we'll probably try large-v3 instead of large-v2 by default. Some people find that large-v3's performance is better, some people find it's worse, so we'll see. Now that I know about whisperx's --initial_prompt option, I might be able to nudge it to the vocabulary and punctuation style we like.
Since the bones seem pretty solid, I'm looking
forward to refamiliarizing myself with the Emacs
Lisp code I wrote to help run the conference. I
saved a bunch of improvement ideas from last year,
and I can't wait to turn them into code. That's
probably going to be lots of fun!