Categories: sharing

RSS - Atom - Subscribe via email

Making a menu of activities

| sketchnotes, drawing, parenting, play

A- wants to be with me almost all the time. This can be challenging.

A multiple-choice question is easier than a fill-in-the-blank one, especially when it comes to "What do we do now?" A- seems less grumpy throughout the day when she can go from one activity to another of her choosing. I like letting her take the lead. I also like not having to come up with stuff. During bedtime, I sketched this menu:

View or add comments

Kindergarten means I get to learn how to write, too

| drawing

A- wants to learn cursive, probably because it's extra-fancy and the sort of thing Elizabeth Bennet would have done. There's some support for teaching cursive in kindergarten, so it's not totally crazy. It's a good opportunity for me to improve my lettering skills, too. She usually likes it when we do the same thing at the same time, so working on letters together is a good way to nudge her to practise fine motor skills. We did a brush lettering worksheet for "Aa" from Amy Latta Creations. This one is my worksheet.

I've got lots to learn about controlling a brush pen. Doing lots of drills will probably help me get my up-strokes to be as thin as the samples.

A- often asks me to connect my letters. I think I'll make our own worksheets so that she can connect letters too.

At bedtime, I drew in my sketchbook while she read independently. When she noticed what I was doing, she said she liked the 3D letters and encouraged me to do more. She pointed to blank spaces on the page and suggested things to add.

Not that different compared to my lettering experiments from 2013:

But hey, I'm learning stuff!

View or add comments

This is a test post from Org Mode to 11ty

| blogging, org, emacs

At the moment, my Org file needs to be in the proper content directory. I'm planning to copy the way ox-hugo allows me to export to a different directory and export filename. In the meantime, this is a start.

;;; ox-11ty.el --- Eleventy export for Emacs Org Mode  -*- lexical-binding: t -*-

;; Copyright (C) 2021 Sacha Chua

;; Author: Sacha Chua <sacha@sachachua.com>
;; Version: 2.17.0
;; Package-Requires: ((emacs "27"))
;; Keywords: org, eleventy, 11ty
;; Homepage: https://github.com/sachac/ox-11ty

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; A very rough starting point for exporting to 11ty from Org Mode.
;;

;;; Code:

(require 'ox-html)

(defun org-11ty-template (contents info)
  (let* ((date (org-export-data (plist-get info :date) info))
         (title (org-export-data (plist-get info :title) info))
         (permalink (org-export-data (plist-get info :permalink) info))
         (categories (org-export-data (plist-get info :categories) info))
         (collections (org-export-data (plist-get info :collections) info))
         (front-matter (json-encode
                        (list :permalink permalink
                              :date date
                              :title title
                              :categories (split-string categories)
                              :tags (split-string collections)))))
    (format
     "module.exports = class {
  data() {
    return %s;
  }
  render() {
    return %s;
  }
}"
     front-matter
     (json-encode-string contents))))

(defun org-11ty-export-as-11ty (&optional async subtreep visible-only body-only ext-plist)
  "Export current buffer as 11ty file."
  (interactive)
  (org-export-to-buffer '11ty "*org 11ty export*" async subtreep visible-only body-only ext-plist))

(defun org-11ty-export-to-11ty (&optional async subtreep visible-only body-only ext-plist)
  (interactive)
  (let* ((info
          (org-combine-plists
           (org-export--get-export-attributes '11ty subtreep visible-only)
           (org-export--get-buffer-attributes)
           (org-export-get-environment '11ty subtreep)))
         (base-file-name (concat (or
                                  (and (plist-get info :file-name)
                                       (if (string= (file-name-base (plist-get info :file-name)) "")
                                           (concat (plist-get info :file-name) "index")
                                         (plist-get info :file-name)))
                                  (org-export-output-file-name "" subtreep))
                                 ".11ty.js"))
         (file
          (if (plist-get info :base-dir)
              (expand-file-name base-file-name (plist-get info :base-dir))
            base-file-name)))
    (when (file-name-directory file)
      (make-directory (file-name-directory file) :parents))
    (org-export-to-file '11ty file
      async subtreep visible-only body-only ext-plist)))

(org-export-define-derived-backend '11ty 'html
  :menu-entry
  '(?1 "Export to 11ty JS"
       ((?b "As buffer" org-11ty-export-as-11ty) 
        (?1 "To file" org-11ty-export-to-11ty)))
  :translate-alist
  '((template . org-11ty-template))
  :options-alist
  '((:permalink "PERMALINK" nil nil)
    (:categories "CATEGORIES" nil 'split)
    (:base-dir "ELEVENTY_BASE_DIR" nil nil)
    (:file-name "FILE_NAME" nil nil)
    (:collections "ELEVENTY_COLLECTIONS" nil 'split)))

;;; ox-11ty.el ends here

https://github.com/sachac/ox-11ty/

View or add comments

Statically generating my blog with Eleventy

| blogging

Things will probably be a little strange on my blog for the next few days, as I've decided to experiment with statically generating my blog with Eleventy. It's a little complicated because I wanted to keep as many of my posts and category/tag feeds as possible.

To speed things up, I usually work with a subset of my posts. Generating a partial copy of my site results in 557 files and takes 3.73 seconds. When I generate the full copy of my site, it writes 13358 files in 96.73 seconds.

With any luck, I'll be able to get most of the things working before the next Emacs News post. Let's see!

View or add comments

Sharing more of my discretionary time

Posted: - Modified: | writing

Depending on what time A- finally goes to bed, I might have around 1-2 hours of discretionary time that I can use to focus on a small task and complete it. If I pick something that’s too big, I get tempted to stay up late, which often makes me grumpy the next day. So a good approach might be to have a number of reasonably small tasks that give me as quick a payoff as possible, especially if those tasks can result in compounding improvements.

Now that I can post Org Mode headings to my journal from Emacs, it’s easier to log finished tasks as journal entries that will get picked up during my weekly and monthly review. The next step might be to figure out how to flesh out those lines into more useful posts. That way, I can find things again by searching my blog. Also, if other people can pick up ideas from my posts, I might be able to benefit from their improvements.

There’s a lot of room for growth in terms of my workflow for doing stuff, learning stuff, and sharing stuff. Here’s what a possible learning path might be like:

sharing-path.png

  • Planning: I’ve just started excavating the Org files that I’ve been tossing ideas into over the last 5+ years of limited discretionary time. Now things are mostly refiled, and I’ve got quite a few projects on my priority list. I might spend a bit of non-computer time mulling over 1-3 possibilities throughout the day, and then work on the most interesting one after processing my inbox. I find that in the course of a week, I tend to focus on one or two projects in order to take advantage of momentum. It’s also good to set aside planning/improvement/review time instead of getting tempted to prioritize coding all the time, as fun as it is to write stuff.

    I don’t have to optimize this. Most tasks are good to work on and move me forward, so I don’t have to spend a lot of time trying to analyze the best effort/reward ratio. I can usually just go with whatever I feel like working on.

  • Coding: I usually work with Emacs Lisp or Javascript, with a little bit of Python. I have some technical debt in Ruby that I don’t have the brainspace to dig into at the moment. It may have to wait until A- goes to in-person school. For Emacs Lisp, my next workflow improvement might be to get the hang of Lispy. For my personal projects, infrastructure is the main thing tripping me up. I need to spend some time setting up a proper development environment and learning more about workflows so that I can reduce risk when I’m working on stop-and-go things.
  • Writing: Dictation is out for now, since I don’t feel much like talking at night. It’s nice to be quiet after a whole day of talking with a kiddo. When I get the Georgi keyboard I ordered, stenography might be an interesting long-term skill investment. The bottleneck is probably still my thinking speed, though. That means I could probably:
    • embrace lists and outlines as a way of getting fragmented thoughts down (possibly over several sessions) and then shuffling them around into some form of coherence (yay Org Mode)
    • lower my threshold for posting; it’s better to think out loud
  • Screenshots: I recently tweaked my shortcuts for inserting screenshots. Now I just need to make them part of muscle memory.
  • Drawings: I can sketch things out on my Lenovo X220 tablet PC, although flipping the screen is a little annoying. One option might be to leave my screen rotated and then use a Bluetooth keyboard to type and use shortcuts. The keyboard isn’t as comfortable to type on as my laptop is, though. Hmm… org-krita doesn’t quite fit my workflow, so I need to write my own. I want to be able to quickly sketch something. If I like it, I want to convert it, rename it with a caption, and add it to my sketches.

(defun my/org-insert-drawing-as-link ()
  (interactive)
  (let ((file (make-temp-file "/tmp/image" nil ".psd")))
    (copy-file my/index-card-template-file file t)
    (insert (org-link-make-string (format "file:%s" file)))
    (my/open-images-in-krita (list file))))

(defun my/preview-in-other-buffer (file)
  (with-current-buffer (find-file-noselect file)
    (display-buffer (current-buffer))))

(defun my/org-convert-sketch-at-point (&optional two-col)
  (interactive "p")
  (let* ((link (org-element-context))
         (file (org-element-property :path link))
         date
         (intermediate (concat (file-name-sans-extension file) ".png"))
         new-file new-link)
    (unless (eq (org-element-type link) 'link)
      (error "Not at a link"))
    ;; (call-process "krita" nil nil nil file "--export" "--export-filename" intermediate)
    (call-process "convert" nil nil nil (concat file "[0]") intermediate)
    (my/preview-in-other-buffer intermediate)
    (setq
     date (org-read-date)
     caption (read-string "Caption: ")
     new-file (expand-file-name (format "%s %s.png" date caption) my/sketches-directory)
     new-link (concat "#+CAPTION: " date " " caption "\n"
                      (org-link-make-string (concat "sketch:" (file-name-base new-file)))))
    (rename-file intermediate new-file t)
    (delete-region (org-element-property :begin link)
                   (org-element-property :end link))
    (if two-col
        (progn (insert
                (format  "#+begin_columns
#+begin_column50
%s
#+end_column50
#+begin_column50
"
                         new-link))
               (save-excursion (insert "
#+end_column50
#+end_columns
")))
      (insert new-link "\n"))))

(defun my/reload-sketches ()
  (interactive)
  (url-retrieve "https://sketches.sachachua.com/reload" (lambda (&rest args) (message "Updated sketches."))))

What are drawings useful for? Nonlinear thinking, sharing, flipping through, building up, visual shorthand, fun. Text is nicer for searching, linking, and dealing with stop-and-go thoughts.

W-‘s offered to let me use his iPad. Concepts and Procreate are both pretty cool, and I have a reasonable workflow for sending files back to my computer and getting them into my Org file. My X220 is still the fastest for quickly switching between text and drawing. I guess either will do.

Also, graphviz is pretty handy for quick diagrams, and it will probably be even more useful as I dig into it and other text-based diagram tools. The diagram at the beginning of this post was generated with:

#+begin_src dot :file "sharing-path.png" :cmdline -Kdot -Tpng -Nfontname=sachacHand -Nfontsize=30
digraph {
  rankdir=LR;
  node [shape=box];
  "Planning" -> "Coding" -> "Writing" -> "Screenshots" -> "Drawings" -> "GIFs?" -> "Video" -> "Streaming";
  "Planning" -> "Reading" -> "Writing";
  "Planning" -> "Writing";
}
#+end_src

Animated GIFs, videos, and streaming may have to wait until I have more brainspace. Plenty to tweak even now!

View or add comments

Python, Org Mode, and writing Org tables to CSVs so that I can read them back

| emacs, org, writing

I’ve been getting deeper into Python so that I can model our personal finances. I really like using the pandas library to manipulate data. All those years I spent trying to juggle increasing complex spreadsheets… Working with Python code in Org Babel blocks is just so much more fun. I like being able to keep my assumptions in tables without having to fuss around with naming cells for easy-to-read formulas, slice and summarize parts of my data frames, organize my notes in outlines and add commentary, and define more complicated functions that I don’t have to squeeze into a single line.

I haven’t quite been able to tempt W- into the world of Org Babel Python blocks. Still, I don’t want to give up the awesomeness of having pretty tables that I can easily edit and use. So I have a bunch of named tables (using #+NAME:), and some code that exports my tables to CSVs:

#+NAME: tables
| Table         | Key                 |
|---------------+---------------------|
| assets_w      | Description         |
| assets_s      | Description         |
| tax_rates     |                     |
| disposition   | Asset               |
| probate_rates | Asset               |
| basic         | Client information  |
| base_expenses | Category            |
| general       | General assumptions |

#+begin_src emacs-lisp :results silent :var tables=tables :tangle no
  (defun my-tbl-export (row)
    "Search for table named `NAME` and export."
    (interactive "s")
    (save-excursion
      (goto-char (point-min))
      (let ((case-fold-search t))
        (when (search-forward-regexp (concat "#\\+NAME: +" (car row)) nil t)
          (next-line)
          (org-table-export (format "%s.csv" (car row)) "orgtbl-to-csv")))))
  (mapc 'my-tbl-export tables)
#+end_src

and some code that imports them back in, and formats tables nicely if I’m displaying them in Org. The in_org block doesn’t get tangled into index.py, so I don’t clutter command-line use with Org table markup.

#+begin_src python :results silent :tangle no
  in_org=1
#+end_src

#+begin_src python :results silent :exports code
  import pandas as pd
  import numpy as np
  import orgbabelhelper as ob
  def out(df, **kwargs):
    if 'in_org' in globals():
      print(ob.dataframe_to_orgtable(df, **kwargs))
    else:
      print(df)
    return df
#+end_src

#+begin_src python :results silent :var tables=tables :colnames yes
  for row in tables:
    table = row[0]
    index = row[1] 
    if row[1] == '':
      index = None
    globals()[table] = pd.read_csv(table + '.csv', index_col=index).apply(pd.to_numeric, errors='ignore')
    # print(globals()[table])
#+end_src

Then I can use C-c C-v C-b (org-babel-execute-buffer) to update everything if I change the table in my Org file, and I can use C-c C-v C-t (org-babel-tangle) to create an index.py that W- can read through or run without needing Org.

View or add comments

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

| emacs, org, publishing

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.

View or add comments