Category Archives: geek

2019-05-20 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, /r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

Adding :target option for the TOC keyword in Org Mode

Now that A- can be counted on to happily play with a babysitter for several hours once a week, I’ve decided to alternate consulting and personal projects. Two weeks ago, I used my personal time to make a script that renewed my library books automatically. This week, I set aside time to look at Org Mode. DC had asked me to update the patch I made to allow people to specify a target for the table of contents, and I was curious about whether I could hack something together.

Patch for adding :target to TOC keyword

Here’s a sample file that shows what I mean:

#+OPTIONS: toc:nil
* Not this section
** Heading X
** Heading Y
* Target
  :PROPERTIES:
  :CUSTOM_ID: TargetSection
  :END:
** Heading A
** Heading B
* Another section
#+TOC: headlines 1 :target "Target"

Here’s the core of how to make it work for HTML exports:

(defun org-html-keyword (keyword _contents info)
  "Transcode a KEYWORD element from Org to HTML.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((key (org-element-property :key keyword))
  (value (org-element-property :value keyword)))
    (cond
     ((string= key "HTML") value)
     ((string= key "TOC")
      (let ((case-fold-search t))
  (cond
   ((string-match "\\<headlines\\>" value)
    (let ((depth (and (string-match "\\<[0-9]+\\>" value)
          (string-to-number (match-string 0 value))))
    (scope
     (cond
      ;; link
      ((string-match ":target +\"\\([^\"]+\\)\"" value)
       (let ((link (with-temp-buffer
         (save-excursion
           (insert (org-make-link-string (match-string 1 value))))
         (org-element-link-parser))))
         (pcase (org-element-property :type link)
           ((or "custom-id" "id") (org-export-resolve-id-link link info))
           ("fuzzy" (org-export-resolve-fuzzy-link link info))
           (_ nil))))
      ;; local
      ((string-match-p "\\<local\\>" value) keyword))))
      (org-html-toc depth info scope)))
   ((string= "listings" value) (org-html-list-of-listings info))
   ((string= "tables" value) (org-html-list-of-tables info))))))))

It was a lot of fun Doing the Right Thing(s): writing documentation, adding tests, and making it work for more than just HTML export. I found out where to make the changes by using grep to search for TOC in the Org Mode source code. All the heavy lifting was already done by org-export-collect-headlines, so it was just a matter of passing the right scope. It took me a while to figure out that I needed to pass an Org link element. An easy way of making that element work for both fuzzy and ID-specific links was to insert the target text into a temporary buffer (remembering to use org-make-link-string) and then calling org-element-link-parser.

I tried figuring out how to make it work with a link to another file, but I didn’t get very far, so I figured I’d just wrap things up nicely there.

I wasn’t sure if my original post made it through because I sent it through Gmane and Cc:d DC, who got it with an empty To:, so I ended up submitting it twice. I just realized I forgot to add test-ox-ascii.el. I don’t want to spam the list, so I’ll send that along with other changes if people have feedback.

But look! Open source contributions! I’m so excited. I wonder what I’ll get to do in two weeks from now. =)

2019-05-13 Emacs news

Update: Added link to Paris meetup on May 21.

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, /r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

2019-05-06 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, /r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

2019-04-29 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, /r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

Using some babysitting time for personal projects

After A- headed out the door with the babysitter, I resisted the urge to work on consulting projects and picked a few personal projects instead. I organized and published another Emacs News post, then settled in for some coding.

I made good progress on using Puppeteer to automate renewing my library books. I even packaged it up as a Docker image, pushed it to my Linode server, and successfully ran it there. Hooray! That means we’re one step closer to getting A- her own library card, since I’ll be able to renew items on both of our cards without the hassle of logging in and out of various accounts on my phone.

So far, so good. The ROI doesn’t make straightforward sense – I wouldn’t each up enough overdue fines to balance the opportunity cost from not consulting – but learning how to automate headless browsers will open up a lot more web automation possibilities, and extra practice wrapping it in a Docker container was a nice bonus. And yeah, turning three minutes of mild annoyance every few days or so into something more automated will probably be worthwhile. The next steps are for me to turn it into a cronjob so that my server can run it daily, and to test to make sure it works when a book can’t be renewed.

I also wanted to prepare for doing Emacs Hangouts again. It turns out that my Logitech H800 Bluetooth headset microphone doesn’t work properly on Ubuntu Bionic. Something about HFP and PulseAudio. At least audio output works, so that will reduce the feedback. I just finished apt-get dist-upgrade when A- returned with the babysitter, so I’ll work on this again next time.

Alternating consulting sessions with personal projects seems like a good plan. It feels a little indulgent, but so did my experiment with semi-retirement when I was just starting, and that worked out really well for us.

This babysitting setup seems to work well for us considering A-‘s late schedule and shifting interests. A 5-hour session gives me enough time to dig into a challenge or learn a new skill. A- seems to need more connection time after babysitting (probably letting off the tension from behaving so well with a new person all afternoon), but that’s perfectly okay.

I’ve liked spending all this time with A-, and I like the little stories I pick up from watching her learn every day. At the playground, she was so proud of being able to climb over the top of the climbing structure by herself. But these moments belong to her, not to me, so it’s okay for me to step back and have my own moments. Part of her journey as a child is separating herself from me, and part of my journey as a parent is separating myself from her.

Slowly, slowly, slowly making time for my own things again!

Update 12:39 AM: It looks like Bluetooth headset microphones are not really working on Linux these days, so I’ll just use the headset to listen in order to reduce feedback, and I’ll use my Yeti microphone if I set up for an Emacs Hangout or Emacs Chat session.