# Transcript [[!template new="1" text="""Hi, I'm Sacha Chua. This presentation is a quick tour""" start="00:00:00.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""of some of the things we do to run EmacsConf.""" start="00:00:04.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Since 2019, we've run it as an entirely online conference,""" start="00:00:07.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and we do as much of the organization as possible""" start="00:00:12.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""within Emacs itself.""" start="00:00:14.700" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""I have three reasons for making this presentation.""" start="00:00:16.580" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The first is entirely selfish: I need to figure out""" start="00:00:19.760" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""all the stuff I built for last year's EmacsConf,""" start="00:00:22.760" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""since it was a bit of a crazy scramble.""" start="00:00:25.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The second is that I want to show people""" start="00:00:28.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""the process of thinking about a complex project,""" start="00:00:30.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""looking for little things to automate in Emacs,""" start="00:00:33.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and building things up from small pieces.""" start="00:00:35.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Maybe you'll get some ideas""" start="00:00:38.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and start building tools for yourself, too.""" start="00:00:39.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The third is that you find any of these little tools interesting,""" start="00:00:42.760" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I want to point you to blog posts and source code""" start="00:00:47.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""where you can find out more.""" start="00:00:49.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That way, you don't need to try""" start="00:00:51.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to read and understand everything quickly.""" start="00:00:52.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""You can find this presentation and other links""" start="00:00:55.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""on the talk page at emacsconf.org/2023/talks/emacsconf.""" start="00:00:57.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""There are a lot of different parts,""" start="00:01:04.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so I'll try to use this map to help make sense of it all.""" start="00:01:06.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""There's so much information to work with,""" start="00:01:09.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so it probably doesn't surprise you that we use Org Mode a lot.""" start="00:01:11.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Most of the conference coordination happens over e-mail,""" start="00:01:14.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""which I can quickly search with notmuch.""" start="00:01:18.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Some of the information is private,""" start="00:01:20.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like emergency contact numbers.""" start="00:01:22.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We store the talk information in a private Org file.""" start="00:01:24.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I try to put as much as possible""" start="00:01:28.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""into our public organizers' notebook""" start="00:01:30.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that processes and decisions are documented.""" start="00:01:32.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We need a public website.""" start="00:01:35.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We use Ikiwiki to make the webpages""" start="00:01:36.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""because we can work with plain text files""" start="00:01:39.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""in a Git repository.""" start="00:01:41.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We also make a few static HTML pages""" start="00:01:42.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""for things where Ikiwiki is a little awkward.""" start="00:01:45.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We post announcements to mailing lists.""" start="00:01:48.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We also receive submissions in a private mailing list""" start="00:01:50.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that a number of people can review them.""" start="00:01:53.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We have a backstage area""" start="00:01:55.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""for sharing files with volunteers and speakers.""" start="00:01:56.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We share those files publicly when the talk goes live.""" start="00:01:59.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""And there's all the other stuff that goes into running EmacsConf,""" start="00:02:03.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like shell scripts and configuration files.""" start="00:02:06.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""First, speakers propose a talk by sending an e-mail.""" start="00:02:09.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We take the info from that e-mail and store it in Org properties""" start="00:02:12.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that we can work with it later.""" start="00:02:15.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Every talk is identified with an ID,""" start="00:02:18.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""but since `:ID:` and `:CUSTOM_ID:` have special meanings for Org,""" start="00:02:20.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I use `:SLUG:` as the keyword.""" start="00:02:24.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Speakers' names go into the `:NAME:` property,""" start="00:02:25.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and a short version goes into `:NAME_SHORT:`""" start="00:02:27.760" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that we can include that in a greeting.""" start="00:02:29.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""If people follow the template closely...""" start="00:02:32.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""...we can even automatically fill in the Org subtree for their talk.""" start="00:02:34.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We can use regular expressions to recognize the text""" start="00:02:38.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and extract the properties.""" start="00:02:40.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Other properties need to be set by hand.""" start="00:02:42.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I often mess things up when I retype them.""" start="00:02:45.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""To avoid typos, I have a function that sets a property""" start="00:02:47.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""based on the current region. I bind that to `C-c C-x p`.""" start="00:02:51.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That makes it much easier to set properties""" start="00:02:56.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that couldn't automatically be recognized.""" start="00:02:58.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Sometimes it makes sense to dynamically generate a property""" start="00:03:01.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and then edit it, like with filenames.""" start="00:03:04.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We like to name all the talk files the same way,""" start="00:03:07.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""but sometimes special characters in talk titles or speaker names""" start="00:03:10.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""need a little tweaking. I'll put that in a `:FILE_PREFIX:` property""" start="00:03:14.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so I can edit it.""" start="00:03:17.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""An Org property match can map over all the talk entries""" start="00:03:19.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that don't have `:FILE_PREFIX:` defined.""" start="00:03:22.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We can use that `:FILE_PREFIX:` to rename files from Emacs.""" start="00:03:25.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""With that property, we can then rename files using that prefix,""" start="00:03:29.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""some extra text, and the file extension.""" start="00:03:32.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Sometimes it's easier to work with the data outside Emacs,""" start="00:03:35.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like when I want to rename files with a shell script.""" start="00:03:38.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""If I export a subset of the data as JSON""" start="00:03:42.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""or JavaScript Object Notation, using `json-encode`...""" start="00:03:45.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""... then I can extract the data with `jq`""" start="00:03:48.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and use it in shell scripts.""" start="00:03:51.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Another example of semi-structured information""" start="00:03:53.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""is speaker availability.""" start="00:03:55.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We have speakers from all over the world,""" start="00:03:57.300" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so we try to schedule live Q&A sessions when they're around.""" start="00:03:59.620" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That means working with timezones.""" start="00:04:03.020" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Completion makes it much easier to set the timezone property""" start="00:04:05.020" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""without worrying about typos.""" start="00:04:08.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We can take advantage of the timezone list from the tzc package,""" start="00:04:10.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""which works with Unix timezone definitions.""" start="00:04:14.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Then we can convert times using Emacs.""" start="00:04:17.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Using a standard format to encode the availability""" start="00:04:19.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""makes it easier to parse.""" start="00:04:22.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I can use those availability constraints to report errors""" start="00:04:24.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""when I'm experimenting with the schedule.""" start="00:04:27.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Now that I have the availability information,""" start="00:04:29.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I can think about scheduling.""" start="00:04:31.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""When we were planning EmacsConf 2022, the schedule was so full,""" start="00:04:33.941" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I wanted to see if we could make it more manageable""" start="00:04:38.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""by splitting it up into two tracks.""" start="00:04:40.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It was hard to think about times with just a table.""" start="00:04:43.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I was able to turn the schedule information""" start="00:04:45.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""into an SVG to convince the other organizers""" start="00:04:48.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to get on board with this crazy plan.""" start="00:04:51.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""And the nice thing about SVGs is that""" start="00:04:53.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""they can even be clickable on the wiki.""" start="00:04:54.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Being able to quickly make SVGs of different schedules""" start="00:04:57.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""also helped me test scheduling ideas and think out loud.""" start="00:05:00.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I could change the time between talks, the order of the talks,""" start="00:05:04.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and even what tracks the talks were in.""" start="00:05:06.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This was helpful when I needed to include""" start="00:05:08.940" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""some late submissions or availability changes""" start="00:05:10.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and I wanted to ask speakers what they thought.""" start="00:05:13.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""They could see the different schedule options themselves.""" start="00:05:15.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's really nice to have Emacs Lisp support for working with SVGs.""" start="00:05:18.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I also love how I can have an Emacs Lisp block""" start="00:05:22.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""in an Org Mode document that updates an SVG""" start="00:05:25.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that I can view right there in my text editor.""" start="00:05:28.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Setting the timezone lets me automatically translate times""" start="00:05:32.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to the speaker's local timezone when I e-mail them.""" start="00:05:34.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That's mostly a matter of using `format-time-string` with a timezone.""" start="00:05:37.820" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""There's a lot of text to work with,""" start="00:05:41.780" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""which means templates are super handy.""" start="00:05:43.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""There are a number of templating functions for Emacs Lisp,""" start="00:05:45.700" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like the built-in `tempo.el` or `s-lex-format` from `s.el`.""" start="00:05:48.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I ended up writing something""" start="00:05:52.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that works with property lists (plists) instead,""" start="00:05:54.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""since we use plists all over the emacsconf-el library.""" start="00:05:58.020" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""All it does is replace `${variable}`""" start="00:06:02.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""with the value from a property list.""" start="00:06:04.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I use this mostly because I have a hard time""" start="00:06:05.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""keeping track of which `%s` is which when I use `format`,""" start="00:06:07.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and it's hard to get an overall view if I just use `concat`.""" start="00:06:11.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The code looks for the properties and replaces them with the values.""" start="00:06:14.300" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I just find it a little easier to think about sometimes.""" start="00:06:17.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Getting all the information is just a matter of going over""" start="00:06:21.300" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""all the talk entries using `org-map-entries`.""" start="00:06:24.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This builds the talk info by running a bunch of functions.""" start="00:06:27.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Some functions get the information from the Org file.""" start="00:06:30.700" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Other functions use the info already collected.""" start="00:06:33.820" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This can take a while to do again and again.""" start="00:06:36.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's useful to `memoize` this function""" start="00:06:39.260" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""when I know I'll be using it a lot,""" start="00:06:41.740" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like when I export the organizers notebook.""" start="00:06:43.500" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Memoize caches recent values.""" start="00:06:45.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""We combine this templating function""" start="00:06:48.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""with the talk information""" start="00:06:50.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to fill in the conference wiki,""" start="00:06:51.480" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""since that's a matter of writing templated strings to files.""" start="00:06:53.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The talk pages are generated once""" start="00:06:56.480" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and then left alone for manual editing,""" start="00:06:58.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""while the navigation is regenerated""" start="00:07:00.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""every time we change the details.""" start="00:07:02.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Here are some examples""" start="00:07:04.660" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""of how we fill in the conference wiki.""" start="00:07:05.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We put in the format of the talk, how Q&A works,""" start="00:07:07.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and what the status is.""" start="00:07:10.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Once the talk is live, we include the video""" start="00:07:12.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and the links to the files, too.""" start="00:07:14.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The code is a little bit long,""" start="00:07:17.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""but the important part is that""" start="00:07:18.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""we fill in a plist with the values we calculate,""" start="00:07:20.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and then we can use `emacsconf-replace-plist-in-string`""" start="00:07:22.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to put that all together.""" start="00:07:26.380" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The schedule is a little more complicated.""" start="00:07:28.020" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I wrote an Ikiwiki directive""" start="00:07:30.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that the markup is more manageable,""" start="00:07:32.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and the Emacs Lisp function uses that.""" start="00:07:34.020" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The Ikiwiki directive takes all the data and turns it into HTML...""" start="00:07:36.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""...so we can use Emacs Lisp to iterate over""" start="00:07:40.620" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""a slightly smaller property list""" start="00:07:42.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and put them into the format Ikiwiki expects.""" start="00:07:44.820" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's nice to be able to navigate between talks""" start="00:07:47.780" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""without going back to the schedule page each time.""" start="00:07:50.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This is handled by keeping two extra copies of the list:""" start="00:07:52.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""one with the first talk popped off,""" start="00:07:55.580" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and one with an extra element added to the beginning.""" start="00:07:57.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Then we can use the heads of those lists""" start="00:08:00.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""for next/previous links.""" start="00:08:02.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Links to the next talks are also handy""" start="00:08:04.380" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""on the collaborative Etherpad documents""" start="00:08:06.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that we use for collecting questions, answers, and notes""" start="00:08:08.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""during each talk.""" start="00:08:12.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Etherpad has an API...""" start="00:08:12.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""...so I can start the pads off with a template""" start="00:08:15.300" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""before the conference.""" start="00:08:17.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I don't want to accidentally overwrite a pad""" start="00:08:18.940" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that has been manually edited.""" start="00:08:21.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We can save the timestamp of the last modification""" start="00:08:22.940" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and then compare it before overwriting.""" start="00:08:25.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Templates are also very handy when it comes to e-mail.""" start="00:08:28.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Sometimes we send e-mails one at a time,""" start="00:08:31.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like when we let a speaker know""" start="00:08:33.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that we've received their proposal.""" start="00:08:35.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That's mostly a matter of plugging the talk's properties""" start="00:08:36.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""into the right places in the template.""" start="00:08:39.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Sometimes we send e-mails to lots of speakers at the same time,""" start="00:08:41.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like when we send them instructions for uploading their files.""" start="00:08:45.020" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Instead of sending one e-mail and Bcc-ing everyone,""" start="00:08:48.300" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""or sending people multiple e-mails""" start="00:08:51.620" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""because they have multiple talks,""" start="00:08:53.480" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I like to draft these as individual e-mails""" start="00:08:55.140" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to each speaker (or group of speakers,""" start="00:08:57.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""if more than one person is associated with a talk).""" start="00:08:59.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That gives me an opportunity to personalize it further.""" start="00:09:02.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Many speakers answer questions live""" start="00:09:05.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""in BigBlueButton web conference rooms.""" start="00:09:08.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Setting up one room per group of speakers""" start="00:09:10.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""makes it easy to give the speakers the details""" start="00:09:12.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and associate the recorded video with the talk afterwards.""" start="00:09:15.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""For EmacsConf 2023,""" start="00:09:18.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I used Spookfox to control Mozilla Firefox from Emacs""" start="00:09:20.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that I could automate creating the rooms""" start="00:09:25.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and adding the URLs to the talk properties in my Org file.""" start="00:09:27.480" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Then I can use mail merge to send each speaker""" start="00:09:30.957" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""the check-in instructions for their specific room.""" start="00:09:33.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Some speakers will take questions by e-mail""" start="00:09:36.900" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""after the conference instead of attending live,""" start="00:09:39.140" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so we send them shorter instructions""" start="00:09:41.620" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""just in case they want to drop by.""" start="00:09:43.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""[Live Q&A sessions]: After the first rush of questions,""" start="00:09:45.540" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""we can open it up for other people to join.""" start="00:09:47.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This is handled by changing the public page""" start="00:09:50.580" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""from one that just refreshes in a loop""" start="00:09:53.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to one that redirects to the actual web conference room.""" start="00:09:55.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Just in case, we also""" start="00:09:58.821" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""generate static copies of those redirects""" start="00:10:00.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that we can copy them if needed.""" start="00:10:02.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That way, I don't have to count on Emacs being able to""" start="00:10:04.300" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""publish them over TRAMP.""" start="00:10:06.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""During the conference, I'm often jumping from talk to talk.""" start="00:10:08.121" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Instead of going to the Org file""" start="00:10:11.660" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and then searching for the talk,""" start="00:10:13.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I've made a little Hydra with keyboard shortcuts.""" start="00:10:14.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""One of these shortcuts lets me""" start="00:10:17.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""jump to a talk with completion""" start="00:10:19.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that I can just type in part of the talk ID,""" start="00:10:20.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""title, or speaker name.""" start="00:10:24.260" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I've also defined some Embark actions""" start="00:10:26.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that I can act on a talk right from the completion menu.""" start="00:10:28.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""For example, I might want to jump to the wiki page""" start="00:10:32.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""or e-mail the speaker.""" start="00:10:35.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""I can also add notes to a talk while looking at an email,""" start="00:10:36.700" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like when a speaker lets me know""" start="00:10:40.100" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that their video will be late.""" start="00:10:41.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Making it easy to add a note turns Emacs into""" start="00:10:43.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""a very basic contact relationship management system, or CRM.""" start="00:10:45.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The way this works is that we have a function""" start="00:10:49.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""that lists all the email addresses associated with a talk.""" start="00:10:52.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We can then map that over the list of talks,""" start="00:10:55.460" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""look up the author of the current email,""" start="00:10:57.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""prompt the user for the talk to add the note to, and add the note.""" start="00:10:59.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""On to captions.""" start="00:11:03.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We've been doing captions for the last couple of years,""" start="00:11:04.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and now we have a small army of volunteer captioners.""" start="00:11:07.240" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""They get early access to the recorded talks""" start="00:11:10.420" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and fix up misrecognized words, format keyboard shortcuts""" start="00:11:12.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to follow Emacs conventions, spell names correctly,""" start="00:11:16.160" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and do all sorts of other wonderful things.""" start="00:11:19.580" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""One of our evil plans with EmacsConf""" start="00:11:21.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""is to get cool stuff out of people's heads into videos""" start="00:11:24.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and also make captions so that those videos can be searched.""" start="00:11:28.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""To make that possible, we first need a backstage area""" start="00:11:32.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""where volunteers can get the files.""" start="00:11:35.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This is just a simple password-protected directory""" start="00:11:36.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""with a static HTML page that lists the talks by status""" start="00:11:39.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and shows the files related to each talk.""" start="00:11:43.740" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""As a talk moves through the process, I update its TODO state""" start="00:11:46.380" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and republish this index.""" start="00:11:49.900" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Talks that are ready to be captioned show up in that section,""" start="00:11:51.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and volunteers can call dibs on the talk they're interested in.""" start="00:11:54.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""That's all done with a function that formats the information""" start="00:11:58.180" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and uses TRAMP to save the file directly to the server.""" start="00:12:00.980" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""You can find more details on our captioning process""" start="00:12:04.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""at emacsconf.org/captioning.""" start="00:12:06.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I like using subed to edit subtitles within Emacs.""" start="00:12:09.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Let's talk about actually playing the talks.""" start="00:12:13.220" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""For EmacsConf 2022, we tried using Emacs timers""" start="00:12:16.060" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to run the talks.""" start="00:12:19.560" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It turns out that you can't call TRAMP from a timer""" start="00:12:20.940" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""when you're already using TRAMP from another timer""" start="00:12:24.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""at the same time.""" start="00:12:26.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I thought about just tweaking the schedule""" start="00:12:27.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so that we always start things at different times,""" start="00:12:29.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""but I figured there's probably a more elegant way to do this.""" start="00:12:31.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This year, I'm planning to experiment with using cron""" start="00:12:35.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to start talks on autopilot.""" start="00:12:37.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The shell scripts will take care of playing the videos...""" start="00:12:39.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""... figuring out the appropriate Q&A...""" start="00:12:42.480" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""... and joining the web conference if needed.""" start="00:12:44.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We just need to format the information...""" start="00:12:47.580" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""...and install it as the track's crontab.""" start="00:12:49.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's useful to be able to switch tracks""" start="00:12:52.220" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to manual mode independently,""" start="00:12:54.080" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""just in case things go haywire.""" start="00:12:55.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Then we can start everything manually.""" start="00:12:57.900" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""I can also manually update a talk's status,""" start="00:13:00.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""like when the host tells me that it's okay to open up the Q&A.""" start="00:13:02.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The shell scripts we run from the crontab""" start="00:13:06.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""can also update the talk status themselves.""" start="00:13:08.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""Then a bunch of things automatically happen based on""" start="00:13:11.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""the talk status changes.""" start="00:13:14.320" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This uses `org-after-todo-state-change-hook`.""" start="00:13:15.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We get the talk information""" start="00:13:18.960" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and pass it to a list of functions.""" start="00:13:20.360" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Internet Relay Chat or IRC is an easy way for people""" start="00:13:22.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to join the conversation around EmacsConf.""" start="00:13:26.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""We announce a talk whenever it changes state.""" start="00:13:29.140" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""For example, when a talk starts,""" start="00:13:31.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""we post the URLs to the talk webpage""" start="00:13:33.600" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and the Etherpad for questions. We change the topic as well,""" start="00:13:36.040" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""so anyone can see the current talk's information""" start="00:13:39.440" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""even if they're a little late.""" start="00:13:41.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""This is easy to do with a little bit of Emacs Lisp""" start="00:13:43.180" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""because (of course!) Emacs has an IRC client.""" start="00:13:45.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""In fact, it has several.""" start="00:13:48.520" video="mainVideo-emacsconf" id="subtitle"]] [[!template new="1" text="""It seems like a lot of automation and Emacs Lisp,""" start="00:13:49.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""but really, all of this was just built up little by little.""" start="00:13:53.140" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""And tinkering with this is *fun*, you know?""" start="00:13:56.900" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's like always being able to ask,""" start="00:13:59.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text=""""Hey, wouldn't it be cool if..."""" start="00:14:01.260" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and then actually being able to go and do it.""" start="00:14:03.301" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Sometimes it feels like EmacsConf is an excuse""" start="00:14:05.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""for me to play with Emacs.""" start="00:14:08.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's pretty amazing what you can do""" start="00:14:10.200" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""by combining a bunch of pieces.""" start="00:14:12.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""A way to store slightly-structured information.""" start="00:14:13.800" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""A way to get it out again. Templates.""" start="00:14:16.720" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""TRAMP, for working with remote files""" start="00:14:18.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and running remote commands.""" start="00:14:20.680" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""A way to talk to a web browser.""" start="00:14:21.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""A way to work with SVGs.""" start="00:14:23.840" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""An email client. A chat client.""" start="00:14:25.400" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""You can smoosh them all together""" start="00:14:27.760" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""in a way that you couldn't if they were all separate things.""" start="00:14:29.640" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The code is in the emacsconf-el repository.""" start="00:14:32.700" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""It's a bit of a tangle because it's accumulating organically""" start="00:14:36.280" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""and I haven't really had the brainspace""" start="00:14:39.120" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""to step back and clean it up.""" start="00:14:40.880" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""But if you spotted anything interesting in this presentation,""" start="00:14:42.580" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""you can go check it out and see what you can scavenge.""" start="00:14:45.920" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""The link and this presentation are available""" start="00:14:48.620" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""from this talk's webpage at emacsconf.org/2023/talks/emacsconf .""" start="00:14:51.000" video="mainVideo-emacsconf" id="subtitle"]] [[!template text="""Let's figure out how to make Emacsconf even awesomer next year!""" start="00:14:59.120" video="mainVideo-emacsconf" id="subtitle"]] Captioner: sachac Questions or comments? Please e-mail [sacha@sachachua.com](mailto:sacha@sachachua.com?subject=Comment%20for%20EmacsConf%202022%20emacsconf%3A%20EmacsConf.org%3A%20How%20we%20use%20Org%20Mode%20and%20TRAMP%20to%20organize%20and%20run%20a%20multi-track%20conference)