EmacsConf 2025 notes

| emacs, emacsconf

Intended audience: This is a long post (~ 8,400 words). It's mostly for me, but I hope it might also be interesting if you like to use Emacs to do complicated things or if you also happen to organize online conferences.

: Added a note about streaming from virtual desktops.

The videos have been uploaded and thank-you notes have been sent, so now I get to write quick notes on EmacsConf 2025 and reuse some of my code from last year's post.

Stats

While organizing EmacsConf 2025, I thought it was going to be a smaller conference compared to last year because of lots of last-minute cancellations. Now that I can finally add things up, I see how it all worked out:

2024 2025 Type
31 25 Presentations
10.7 11.3 Presentation duration (hours)
21 11 Q&A web conferences
7.8 5.2 Q&A duration (hours)
18.5 16.5 Total

EmacsConf 2025 was actually a little longer than 2024 in total presentation time, although that's probably because we had more live talks which included answering questions. It was almost as long overall including live Q&A in BigBlueButton rooms, but we did end an hour or so earlier each day.

Looking at the livestreaming data, I see that we had fewer participants compared to the previous year. Here are the stats from Icecast, the program we use for streaming:

  • Saturday:
    • gen: 107 peak + 7 lowres (compared to 191 in 2024)
    • dev: 97 peak + 7 lowres (compared to 305 in 2024)
  • Sunday: I forgot to copy Sunday stats, whoops! I think there were about 70 people on the general stream. Idea: Automate this next time.

The YouTube livestream also had fewer participants at the time of the stream, but that's okay. Here are the stats from YouTube:

2024 peak 2025 peak YouTube livestream
46 23 Gen Sat AM
24 7 Gen Sat PM
15 8 Dev Sat AM
20 14 Dev Sat PM
28 14 Gen Sun AM
26 11 Gen Sun PM

Fewer people attended compared to last year, but it's still an amazing get-together from the perspective of being able to get a bunch of Emacs geeks in a (virtual) room. People asked a lot of questions over IRC and the Etherpads, and the speakers shared lots of extra details that we captured in the Q&A sessions. I'm so glad people were able to connect with each other.

Based on the e-mails I got from speakers about their presentations and the regrets from people who couldn't make it to EmacsConf, it seemed that people were a lot busier in 2025 compared to 2024. There were also a lot more stressors in people's lives. But it was still a good get-together, and it'll continue to be useful going forward.

At the moment, the EmacsConf 2025 videos have about 20k views total on YouTube. (media.emacsconf.org doesn't do any tracking.) Here are the most popular ones so far:

While I was looking at the viewing stats on YouTube, I noticed that people are still looking at videos all the way back to 2013 (like Emacs Live - Sam Aaron and Emacs Lisp Development - John Wiegley), and many videos have thousands of views. Here are some of the most popular ones from past conferences:

Views aren't everything, of course, but maybe they let us imagine a little about how many people these speakers might have been able to reach. How wonderful it is that people can spend a few days putting together their insights and then have that resonate with other people through time. Speakers are giving us long-term gifts.

Timeline

Of course, the process of preparing all of that started long before the days of the conference. We posted the call for proposals towards the end of June, like we usually do, because we wanted to give people plenty of time to start thinking about their presentations. We did early acceptances again this year, and we basically accepted everything, so people could start working on their videos almost right away. Here's the general timeline:

CFP 2025-06-27 Fri
CFP deadline 2025-09-19 Fri
Speaker notifications 2025-09-26 Fri
Publish schedule 2025-10-24 Fri (oops, forgot to do this elsewhere)
Video submission target date 2025-10-31 Fri
EmacsConf 2025-12-06 Sat - 2025-12-07 Sun
Live talks, Q&A videos posted 2025-12-17
Q&A notes posted 2025-12-28
These notes 2026-01-01
submissions_plot.png
Figure 1: EmacsConf 2025: cumulative proposals and video uploads

This graph shows that we got more proposals earlier this year (solid blue line: 2025) compared to last year (gray: 2024), although there were fewer last-minute ones and more cancellations this year. Some people were very organized. (Video submissions in August!) Some people sent theirs in later because they first had to figure out all the details of what they proposed, which is totally relatable for anyone who's found themselves shaving Emacs yaks before.

I really appreciated the code that I wrote to create SVG previews of the schedule. That made it much easier to see how the schedule changed as I added or removed talks. I started stressing out about the gap between the proposals and the uploaded videos (orange) in November. Compared to last year, the submissions slowly trickled in. The size of the gap between the blue line (cumulative proposals) and the orange line (cumulative videos uploaded) was much like my stress level, because I was wondering how I'd rearrange things if most of the talks had to cancel at the last minute or if we were dealing with a mostly-live schedule. Balancing EmacsConf anxiety with family challenges resulted in all sorts of oopses in my personal life. (I even accidentally shrank my daughter's favourite T-shirt.) It helped to remind myself that we started off as a single-track single-day conference with mostly live sessions, that it's totally all right to go back to that, and that we have a wonderful (and very patient) community. I think speakers were getting pretty stressed too. I reassured speakers that Oct 31 was a soft target date, not a hard deadline. I didn't want to cancel talks just because life got busy for people.

It worked out reasonably well. We had enough capacity to process and caption the videos as they came in, even the last-minute uploads. Many speakers did their own captions. We ended up having five live talks. Live talks are generally a bit more stressful for me because I worry about technical issues or other things getting in the way, but all those talks went well, thank goodness.

For some reason, Linode doesn't seem to show me detailed accrued charges any more. I think it used to show them before, which is why I managed to write last year's notes in December. If I skip the budget section of these notes, maybe I can post them earlier, and then just follow up once the invoices are out.

I think the timeline worked out mostly all right this year. I don't think moving the target date for videos earlier would have made much of a difference, since speakers would probably still be influenced by the actual date of the conference. It's hard to stave off that feeling of pre-conference panic: Do we have enough speakers? Do we have enough videos? But these graphs might help me remember that it's been like that before and it has still worked out, so it might just be part of my job as an organizer to embrace the uncertainty. Most conferences do live talks, anyway.

Emacs Lisp code for making the table

(append '(("slug" "submitted" "uploaded" "cancelled") hline)
        (sort (delq nil
                    (org-map-entries
                     (lambda ()
                       (list
                        (org-entry-get (point) "SLUG")
                        (org-entry-get (point) "DATE_SUBMITTED")
                        (org-entry-get (point) "DATE_UPLOADED")
                        (org-entry-get (point) "DATE_CANCELLED")))
                     "DATE_SUBMITTED={.}"))
              :key (lambda (o) (format "%s - %s" (elt o 3) (elt o 2)))
              :lessp #'string<) nil)

Python code for plotting the graph
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import io

all_dates = pd.date_range(start='2025-06-01', end='2025-12-09', freq='D')
def convert(rows):
    df = pd.DataFrame(rows, columns=['slug', 'proposal_date', 'upload_date', 'cancelled_date'])
    df = df.map(lambda x: pd.NA if (x == [] or x == "nil") else x)
    df['proposal_date'] = pd.to_datetime(df['proposal_date']).apply(lambda d: d.replace(year=2025))
    df['upload_date'] = pd.to_datetime(df['upload_date']).apply(lambda d: d.replace(year=2025))
    df['cancelled_date'] = pd.to_datetime(df['cancelled_date']).apply(lambda d: d.replace(year=2025))
    prop_counts = df.groupby('proposal_date').size().reindex(all_dates, fill_value=0).cumsum()
    additions = df[df['proposal_date'].notna()].groupby('proposal_date').size().reindex(all_dates, fill_value=0)
    subtractions = df[df['cancelled_date'].notna()].groupby('cancelled_date').size().reindex(all_dates, fill_value=0)
    upload_counts = df[df['upload_date'].notna()].groupby('upload_date').size().reindex(all_dates, fill_value=0).cumsum()
    prop_counts = (additions - subtractions).cumsum()
    return prop_counts, upload_counts

prop_counts, upload_counts = convert(current_data)
prop_counts_2024, upload_counts_2024 = convert(previous_data)

plot_df = pd.DataFrame({
    'Date': all_dates,
    '2025 Proposals': prop_counts.values,
    '2025 Videos': upload_counts.values,
})
plot_df_melted = plot_df.melt(id_vars='Date', var_name='Type', value_name='Count')
sns.set_theme(style="whitegrid")
plt.figure(figsize=(12, 6))
plt.plot(all_dates, prop_counts_2024, color='gray', label='2024 cumulative proposals')
plt.plot(all_dates, upload_counts_2024, color='gray', alpha=0.5, label='2024 cumulative uploads')
ax = sns.lineplot(data=plot_df_melted, x='Date', y='Count', hue='Type', linewidth=2.5)
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
plt.title('EmacsConf 2025: cumulative proposals and video uploads', fontsize=16)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Cumulative Count', fontsize=12)
plt.tight_layout()
plt.savefig('submissions_plot.png')

Managing conference information in Org Mode and Emacs

Organizing the conference meant keeping track of lots of e-mails and lots of tasks over a long period of time. To handle all of the moving parts, I relied on Org Mode in Emacs to manage all the conference-related information. This year, I switched to mainly using the general organizers notebook, with the year-specific one mostly just used for the draft schedule. I added some shortcuts to jump to headings in the main notebook or in the annual notebook (emacsconf-main-org-notebook-heading and emacsconf-current-org-notebook-heading emacsconf.el).

As usual, we used lots of structured entry properties to store all the talk information. Most of my functions from last year worked out fine, aside from the occasional odd bug when I forgot what property I was supposed to use. (:ROOM:, not :BBB:…)

The validation functions I thought about last year would have been nice to have, since I ran into a minor case-sensitivity issue with the Q&A value for one of the talks (live versus Live). This happened last year too and it should have been caught by the case-fold-search I thought I added to my configuration, but since that didn't seem to kick in, I should probably also deal with it on the input side. Idea: I want to validate that certain fields like QA_TYPE have only a specified set of values. I also probably need a validation function to make sure that newly-added talks have all the files that the streaming setup expects, like an overlay for OBS, and one that checks if I've set any properties outside the expected list.

Communication

After some revision, the call for participation went out on emacs-tangents, Emacs News, emacsconf-discuss, emacsconf-org, Reddit, lobste.rs, and System Crafters. (Thanks!) People also mentioned it in various meetups, and there were other threads leading up to it (Reddit, HN, lemmy.world, @fsf)

Once the speakers confirmed the tentative schedules worked for them, I published the schedule on emacsconf.org on Oct 24, as sceduled. But I forgot to announce the schedule on emacsconf-discuss and other places, though. I probably felt a little uncertain about announcing the schedule because it was in such flux. There was even a point where we almost cancelled the whole thing. I also got too busy to reach out to podcasts. I remembered to post it to foss.events, though! Idea: I can announce things and trust that it'll all settle down. I can spend some time neatening up our general organizers-notebook so that there's more of a step-by-step-process. Maybe org-clone-subtree-with-time-shift will be handy.

There were also a few posts and threads afterwards:

For communicating with speakers and volunteers, I reused the mail merge from previous years, with a few more tweaks. I added a template for thanking volunteers. I added some more code for mailing all the volunteers with a specific tag. Some speakers were very used to the process and did everything pretty independently. Other speakers needed a bit more facilitation.

I could get better at coordinating with people who want to help. In the early days, there wasn't that much to help with. A few people volunteered to help with captions for specific videos, so I waited for their edits and focused on other tasks first. I didn't want to pressure them with deadlines or preempt them by working on those when I'd gotten through my other tasks, but it was hard to leave those tasks dangling. They ended up sending in the edits shortly before the conference, which still gave me enough time to coordinate with speakers to review the captions. It was hard to wait, but I appreciate the work they contributed. In late November and early December, there were so many tasks to juggle, but I probably could have e-mailed people once a week with a summary of the things that could be done. Idea: I can practice letting people know what I'm working on and what tasks remain, and I can find a way to ask for help that fits us. If I clean up the design of the backstage area, that might make it easier for people to get started. If I improve my code for comparing captions, I can continue editing subtitles as a backup if I want to take a break from my other work, and merge in other people's contributions when they send them.

I set up Mumble for backstage coordination with other organizers, but we didn't use it much because most of the time, we were on air with someone, so we didn't want to interrupt each other.

There was a question about our guidelines for conduct and someone's out-of-conference postings. I forwarded the matter to our private mailing list so that other volunteers could think about it, because at that point in time, my brain was fried. That seemed to have been resolved. Too bad there's no edebug-on-entry for people so we can figure things out with more clarity. I'm glad other people are around to help navigate situations!

Schedule

Like last year, we had two days of talks, with two tracks on the first day, and about 15-20 minutes between each talk. We had a couple of last-minute switches to live Q&A sessions, which was totally fine. That's why I set up all the rooms in advance.

A few talks ended up being a bit longer than their proposed length. With enough of a heads-up, I could adjust the schedule (especially as other talks got cancelled), but sometimes it was difficult to keep track of changes as I shuffled talks around. I wrote some code to calculate the differences, and I appreciate how the speakers patiently dealt with my flurries of e-mails.

Scheduling some more buffer time between talks might be good. In general, the Q&A time felt like a good length, though, and it was nice that people had the option of continuing with the speaker in the web conference room. So it was actually more like we had two or three or four tracks going on at the same time.

Having two tracks allowed us to accept all the talks. I'm glad I kept the dev track to a single day, though. I ended up managing things all by myself on Sunday afternoon, and that was hard enough with one track. Fortunately, speakers were comfortable navigating the Etherpad questions themselves and reading the questions out loud. Sometimes I stepped in during natural pauses to read the next question on the list (assuming I managed to find the right window among all the ones open on my screen).

Idea: If I get better at setting up one window per ongoing Q&A session and using the volume controls to spatialize each so that I can distinguish left/middle/right conversations, it might be easier for me to keep track of all of those. I wasn't quite sure how to arrange all the windows I wanted to pay attention even with an external screen (1920x1200 + my laptop's 1920x1080). I wonder if I'd trust EXWM to handle tiling all the different web browser windows, while keeping the VNC windows floating so that they don't mess with the size of the stream. Maybe I can borrow my husband's ultrawide monitor. Maybe I can see if I can use one of those fancy macropads for quick shortcuts, like switching to a specified set of windows and unmuting myself. Maybe I can figure out how to funnel streaming captions into IRC channels or another text form (also a requested feature) so that I can monitor them that way and quickly skim the history… Or I can focus on making it easier for people to volunteer (and reminding myself that it's okay to ask for their help!), since then I don't have to split my attention all those different ways and I get to learn from other people's awesomeness.

If we decide to go with one track next year, we might have to prioritize talks, which is hard especially if some of the accepted speakers end up cancelling anyway. Alternatively, a better way might be to make things easier for last-minute volunteers to join and read the questions. They don't even need any special setup or anything; they can just join the BigBlueButton web conference session and read from the pad. Idea: A single Etherpad with all the direct BBB URLs and pad links will make this easier for last-minute volunteers.

Also like last year, we added an open mic session to fill in the time from a last-minute cancellation, and that went well. It might be nice to build that into the schedule earlier instead of waiting for a cancellation so that people can plan for it. We moved the closing remarks earlier as well so that people didn't have to stay up so late in other timezones.

I am super, super thankful we had a crontab automatically switching between talks, because that meant one less time-sensitive thing I had to pay attention to. I didn't worry about cutting people off too early because people could continue off-stream, although this generally worked better for Q&A sessions done over BigBlueButton or on Etherpad rather than IRC. I also improved the code for generating a test schedule so that I could test the automatic switching.

It was probably a good thing that I didn't automatically write the next session time to the Etherpad, though, because people had already started adding notes and questions to the pad before the conference, so I couldn't automatically update them as I changed the schedule. Idea: I can write a function to copy the heads-up for the next talk, or I can add the text to a checklist so that I can easily copy and paste it. Since I was managing the check-ins for both streams as well as doing the occasional bit of hosting, a checklist combining all the info for all the streams might be nice. I didn't really take advantage of the editability of Etherpad, so maybe putting it into HTML instead will allow me to make it easier to skim or use. (Copy icons, etc.)

Like before, I offset the start of the dev track to give ourselves a little more time to warm up, and I started Sunday morning with more asynchronous Q&A instead of web conferences. Not much in terms of bandwidth issues this year.

We got everyone's time constraints correctly this year, hooray! Doing timezone conversions in Emacs means I don't have to calculate things myself, and the code for checking the time constraints of scheduled sessions worked with this year's shifting schedules too. Idea: It would be great to mail iCalendar files (.ics) to each speaker so that they can easily add their talk (including check-in time, URLs, and mod codes) to their calendar. Bonus points if we can get it to update previous copies if I've made a change.

This is what the schedule looked like:

(with-temp-file (expand-file-name "schedule.svg" emacsconf-cache-dir)
  (let ((emacsconf-use-absolute-url t))
    (svg-print
     (emacsconf-schedule-svg
      800 300
      (emacsconf-publish-prepare-for-display
       (emacsconf-get-talk-info))))))

I added a vertical view to the 2025 organizers notebook, which was easier to read. I also added some code to handle cancelling a talk and keeping track of rescheduled talks.

Graphical view of the scheduleSchedule for SaturdaySaturday 9:00- 9:10 Saturday opening remarkssat-open 9:10- 9:20 Making Org-Babel reactiveorg-babel 9:30- 9:55 Emacs as a fully-fledged reference managerreference10:15-10:40 org-gmail: A deep integration of Gmail into your Org Modegmail10:50-11:15 Reading and writing emails in GNU Emacs with Gnusgnus11:25-11:45 LaTeX export in org-mode: the overhaullatex 1:00- 1:25 Basic Calc functionality for engineering or electronicscalc 1:35- 2:15 Blee-LCNT: An Emacs-centered content production and self-publication frameworkblee-lcnt 2:35- 2:40 GNU Emacs Greader (Gnamù Reader) mode is the best Emacs mode in existencegreader 2:50- 3:40 Open sessionopen-mic 4:00- 4:10 Saturday closing remarks / open sessionsat-close 9:30- 9:55 One year progress update Schemacs (formerly Gypsum)schemacs10:15-10:35 Juicemacs: exploring speculative JIT compilation for ELisp in Javajuicemacs10:45-11:10 Swanky Python: Interactive development for Pythonswanky11:20-11:40 Interactive Python programming in Emacspython 1:00- 1:25 Emacs, editors, and LLM driven workflowsllm 1:45- 2:05 Emacs and private AI: a great matchprivate-ai 2:25- 2:55 Common Lisp images communicating like-a-human through shared Emacs slime and eevcommonlisp 3:05- 3:30 Modern Emacs/Elisp hardware/software accelerated graphicsgraphics9 AM10 AM11 AM12 PM1 PM2 PM3 PM4 PM5 PMSchedule for SundaySunday 9:00- 9:10 Sunday opening remarkssun-open 9:10- 9:30 Some problems of modernizing Emacsmodern 9:40-10:15 An introduction to the Emacs Readerreader10:35-10:45 Weightlifting tracking with Emacs on Androidweights11:05-11:25 corfu+yasnippet: Easier than I thoughtcompletion 1:00- 1:25 Zettelkasten for regular Emacs hackerszettelkasten 1:45- 2:15 Questions and answers to help you fly with Hyperbolehyperboleqa 2:15- 2:35 Gardening in Emacs: A Windows user's tale of tending, tweaking, and triumphgardening 2:45- 3:20 Bookclub tapasbookclub-tapas 3:40- 3:50 Sunday closing remarkssun-close9 AM10 AM11 AM12 PM1 PM2 PM3 PM4 PM5 PM

Idea: I still haven't gotten around to localizing times on the watch pages. That could be nice.

Recorded introductions

Recording all the introductions beforehand was extremely helpful. I used subed-record.el to record and compile the audio without having to edit out the oopses manually. Recording the intros also gave me something to do other than worry about missing videos.

A few speakers helped correct the pronunciations of their names, which was nice. I probably could have picked up the right pronunciation for one of them if I had remembered to check his video first, as he had not only uploaded a video early but even said his name in it. Next time, I can go check that first.

This year, all the intros played the properly corrected files along with their subtitles. The process is improving!

Recorded videos

As usual, most speakers sent in pre-recorded videos this year, although it took them a little bit longer to do them because life got busy for everyone. Just like last year, speakers uploaded their files via PsiTransfer. I picked up some people's videos late because I hadn't checked. I've modified the upload instructions to ask the speakers to email me when they've uploaded their file, since I'm not sure that PsiTransfer can automatically send email when a new file has been uploaded. We set up a proper domain name, so this year, people didn't get confused by trying to FTP to it.

I had to redo some of the re-encodings and ask one speaker to reupload is video, but we managed to catch those errors before they streamed.

I normalized all the audio myself this year. I used Audacity to normalize it to -16 LUFS. I didn't listen to everything in full, but the results seemed to have been alright. Idea: Audio left/right difference was not an issue this year, but in the future, I might still consider mixing the audio down to mono.

All the files properly loaded from the cache directory instead of getting shadowed by files in other directories, since I reused the process from last year instead of switching mid-way.

People didn't complain about colour smearing, but it looks like the Calc talk had some. Ah! For some reason, MPV was back on 0.35, so now I've modified our Ansible playbook so that it insists on 0.38. I don't think there were any issues about switching between dark mode or light mode.

There was one last-minute upload where I wasn't sure whether there were supposed to be captions in the first part. When I toggled the captions to try to reload them once I copied over the updated VTT, I think I accidentally left them toggled them off, but fortunately the speaker let me know in IRC.

For the opening video, I made the text a bit more generic by removing the year references so that I can theoretically reuse the audio next year. That might save me some time.

I modified our mpv.conf to display the time remaining in the lower right-hand corner. This was a fantastic idea that made it easy to give the speaker a heads-up that their recorded talk was about to finish and that we were about to switch over to the live Q&A session. Because sometimes we weren't able to spare enough attention to host a session, I usually just added the time of the next session to the Etherpad to give speakers a heads-up that the stream would be switching away from their Q&A session. Then I didn't need to make a fancy Javascript timer either.

Captioning

The next step in the process was to caption each uploaded video. While speech recognition tools give us a great headstart, there's really no way around the work of getting technical topics right.

We used WhisperX for speech-to-text again. This time, I used the --initial_prompt argument to try to get it to spell things properly: "Transcribe this talk about Emacs. It may mention Emacs keywords such as Org Mode, Org Roam, Magit, gptel, or chatgpt-shell, or tech keywords such as LLMs. Format function names and keyboard shortcut sequences according to Emacs conventions using Markdown syntax. For example: control h becomes \`C-h\`.". It did not actually do the keyboard shortcut sequences. (Emacs documentation is an infinitesimal fraction of the training data, probably!) It generally did a good job of recognizing Emacs rather than EMAX and capitalizing things. Idea: I can experiment with few-shot prompting techniques or just expand my-subed-fix-common-errors to detect the patterns.

This year, we used Anush V's sub-seg tool to split the subtitles into reasonably short, logically split phrases. I used to manually split these so that the subtitles flowed more smoothly, or if I was pressed for time, I left it at just the length-based splits that WhisperX uses. sub-seg was much nicer as a starting point, so I wrote a shell script to run it more automatically. It still had a few run-on captions and there were a couple of files that confused it, so I manually split those.

Shell script for calling sub-seg

#!/bin/bash ~/vendor/sub-seg/.venv/bin/python3 ~/vendor/sub-seg/src/prediction.py "$1" tmp/subseg-predict.txt ~/vendor/sub-seg.venv/bin/python3 ~/vendor/sub-seg/src/postprocess_to_single_lines.py "\(1" /tmp/subseg-predict.txt /tmp/subseg-cleaned.txt grep -v -e "^\)" /tmp/subseg-cleaned.txt > "${1%.*}–backstage–split.txt"

I felt that it was also a good idea to correct the timing before posting the subtitles for other people to work on because otherwise it would be more difficult for any volunteers to be able to replay parts of the subtitles that needed extra attention. WhisperX often gave me overlapping caption timestamps and it didn't always have word timestamps I could use instead. I used Aeneas to re-align the text with the audio so that we could get better timestamps. As usual, Aeneas got confused by silences or non-speech audio, so I used my subed-word-data.el code to visualize the word timing and my subed-align.el code to realign regions. Idea: I should probably be able to use the word data to realign things semi-automatically, or at least flag things that might need more tweaking. There were a few chunks that weren't recognized at all, but I was able to spot them and fix them when I was fixing the timestamps. Making this more automated will make it much easier to share captioning work with other volunteers. Alternatively, I can also post the talks for captioning before I fix the timestamps, because I can fix them while other people are editing the text.

While I was correcting the timestamps, it was pretty tempting for me to just go ahead and fix whatever errors I encountered along the way. From there on, it seemed like only a little bit more work was needed in order to get it ready for the speaker to review, and besides, doing subtitles is one of the things I enjoy about EmacsConf. So the end result is that for most of the talks, by the time I finished getting it to the point where I felt like someone who was new to captioning could take over, it was often quite close to being done. I did actually manage to successfully accept some people's help. The code that I wrote for showing me the word differences between two files (sometimes the speaker's script or the subtitles that were edited by another volunteer) was very useful for last-minute merges.

Working on captions is one of my favourite parts. Well-edited captions are totally a nice-to-have, but I like it when people can watch the videos (or skim them) and not worry about not being able to hear or understand what someone said. I enjoy sitting down and spending time with people's presentations, turning them into text that we can search. Captioning helps me feel connected with some of the things I love the most about the Emacs community.

I really appreciated how a number of speakers and volunteers helped with quality control by watching other videos in the backstage area. Idea: I can spend some time improving the design of the backstage area to make it more pleasant and to make it easier for people to find something to work on if they have a little time.

Of course, some talks couldn't be captioned beforehand because they were live. For live conferences and for many of the Q&A sessions, we used BigBlueButton.

BigBlueButton web conference

We used BigBlueButton again this year instead of switching over to something like Galene. I moved the node from bandali's Linode account to mine so that I wouldn't feel as guilty bringing it up and down throughout the year for various Emacs meetups. That also meant that the actual setup was fairly stable since it had survived a lot of meetups before EmacsConf, and I didn't have to spend as much time before the event worrying about it. I still worried a little, as after the November OrgMeetup, I noticed a technical issue that I couldn't nail down. Fortunately, that happened after the meetup had already ended. I also used my meetup crontab to schedule test sessions with some speakers so that they could record their presentation or doublecheck their sharing setup.

I resized the BigBlueButton early Friday afternoon this year so that speakers could have a few more hours to test their setups if they wanted to, especially since one speaker had mentioned having a hard time sharing his screen on Wayland.

I thought I had --allow_auto_disk_resize true in the bbb-prod shell-script I used to resize the node, but I don't think linode-cli actually resized the disk (maybe I ran a different shell script), and I forgot to double-check that before the conference. Fortunately, we had just enough space for all the recordings. I noticed only when I was waiting for the recordings to finish processing, since some of them were failing. Idea: Next time, I should manually check that the disk has resized, and I can probably tweak my checklist too.

Like before, we used moderator codes so that speakers could let themselves into the room and get everything set up just in case. Idea: I wonder if there's a way to specify the moderator code in the URL so that I can link to that directly. Maybe I can modify the web interface to fill that in with a little bit of Javascript.

Oddly, the moderator codes didn't let people start or stop recording, but fortunately I was able to log in and take care of all of that. I mostly remembered to start the recording, except for one instance where I started recording a little bit late.

Code for reporting BBB usage
(emacsconf-extract-bbb-report
 (seq-remove (lambda (o)
               (string-match "backups" o))
             (directory-files-recursively emacsconf-extract-bbb-raw-dir "events.xml")))
2023 2024 2025  
62 107 35 Max number of simultaneous users
6 7 5 Max number of simultaneous meetings
27 25 14 Max number of people in one meeting
84 102 55 Total unique users
36 40 27 Total unique talking

I might be able to get away with a Linode 8 GB node (USD 0.072/hour) instead of a Linode 16 GB node (USD 0.144/hour), but keeping it at the current size is probably okay.

I'll go into more detail in the budget section, but the total was USD 14.02 to host BigBlueButton ourselves in December, and between USD 5 to USD 8 / month to run it the rest of the time (including upsizing it for meetups), so that was much less than what it would have cost for BigBlueButton-specific hosting.

Checking speakers in

To keep the live talks and Q&A sessions flowing smoothly, there's a bit of a scramble behind the scenes. We asked speakers to check in at least half an hour before they need to go live, and most of them were able to find their way to the BigBlueButton room using the provided moderator codes. I mostly handled the check-ins, with some help from Corwin when two people needed to be checked in at the same time. We generally didn't have any tech issues, although a couple of people were missing during their Q&A sessions. (We just shrugged and continued; too much to take care of to worry about anything!)

Check-ins are usually good opportunities to chat with speakers, but because I needed to pay attention to the other streams as well as check in other people, it felt a bit more rushed and less enjoyable. I missed having those opportunities to connect, but I'm glad speakers were able to handle so much on their own.

Hosting

Corwin did a lot of the on-stream hosting with a little help from Amin on Saturday. I occasionally jumped in and asked the speakers questions from the pad, but when I was busy checking people in or managing other technical issues cropping up, the speakers also read the questions out themselves so that I could match things up in the transcript afterwards.

No crashes this time, I think. Hooray!

Infrastructure

I used September and October to review all the infrastructure and see what made sense to upgrade. The BigBlueButton instance is on a virtual private server that's dedicated to it, since it doesn't like to share with any other services. Since I set it up from scratch following the recommended configuration, the server uses a recent version of Ubuntu. Some of the other servers use outdated Debian distributions that no longer get security updates. They have other services on them, so I'll leave them to bandali to upgrade when he's ready.

Streaming

I am so, so glad that we had our VNC+OBS setup this year, with two separate user accounts using OBS to stream each track from a virtual desktop on a remote server. We switched to this setup in 2022 so that I could handle multiple tracks without worrying about last-minute coordination or people's laptop specs. If we had had our original setup in 2019, with hosts streaming from their personal computers, I think we'd have been dead in the water. Instead, our scripts took care of most of the on-screen actions, so I just needed to rearrange the layout. (Idea: If I can figure out how to get BigBlueButton to use our preferred layout, that would make it even better.)

I used MPV to monitor the streams in little thumbnails. I set those windows to always be on top, and I set the audio so that the general track was on my left side and the development track was o my right. I used some shortcuts to jump between streams reliably, taking advantage of how I bound the Windows key on my laptop to the Super modifier. I used KDE's custom keyboard shortcuts to set Super-g to raise all of my general-track windows and Super-d to do the same for all of the development-track ones. Those were set to commands like this:

/home/sacha/bin/focus_or_launch "emacsconf-gen - TigerVNC"; /home/sacha/bin/focus_or_launch gen.webm; /home/sacha/bin/focus_or_launch "gen.*Konsole"

Code for focus_or_launch

#!/bin/bash

############# GLOBVAR/PREP ###############

Executable="\(1" ExecutableBase="\)(basename "$Executable")" Launchcommand="$2" Usage="\ Usage: $(basename $0) command [launchcommand] [exclude] E.g.: $(basename $0) google-chrome\ " ExcludePattern="$3"

################ MAIN ####################

if ; then MostRecentWID="$(printf "%d" $(wmctrl -xl | grep "$ExecutableBase" | tail -1 2> /dev/null | awk '{print \(1}'))" else MostRecentWID="\)(printf "%d" $(wmctrl -xl | grep -ve "$ExcludePattern" | grep "$ExecutableBase" | tail -1 2> /dev/null | awk '{print $1}'))" fi

if ; then if ; then "$Executable" > /dev/null 2>&1 & else $LaunchCommand > /dev/null 2>&1 & fi disown else if xdotool search –class "\(ExecutableBase" | grep -q "^\)(xdotool getactivewindow)$"; then xdotool sleep 0.050 key "ctrl+alt+l" else

xdotool windowactivate "$MostRecentWID" 2>&1 | grep failed \ && xdotool search –class "$ExecutableBase" windowactivate %@ fi fi

(Idea: It would be great to easily assign specific windows to shortcuts on my numeric keypad or on a macropad. Maybe I can rename a window or manually update a list that a script can read…)

To get the video streams out to viewers, we used Icecast (a streaming media server) on a Linode 64GB 16 core shared CPU server again this year, and that seemed to work out. I briefly contemplated using a more modern setup like nginx-rtmp, Ant Media Server, or SRS if we wanted HLS (wider support), adaptive bitrate streaming, or lower latency, but I decided against it because I didn't want to add more complexity. Good thing too. This year would not have been a good time to experiment with something new.

Like before, watching the stream directly using mpv, vlc, or ffplay was smoother than watching it through the web-based viewers. One of the participants suggested adding more detailed instructions for VLC so that people can enjoy it even without using the command-line, so we did.

The 480p stream and the YouTube stream were all right, although I forgot to start one of the YouTube streams until a bit later. Idea: Next time, I can set all the streams to autostart.

Corwin had an extra server lying around, so I used that to restream to Toobnix just in case. That seems to have worked, although I didn't have the brainspace to check on it.

I totally forgot about displaying random packages on the waiting screen. Idea: Maybe next year I can add a fortune.txt to the cache directory with various one-line Emacs tips.

I might be able to drop the specifications down to 32GB 8 core if we wanted to.

Publishing

People appreciated being able to get videos and transcripts as soon as each talk aired. Publishing the video files and transcripts generally worked out smoothly, aside from a few times when I needed to manually update the git repository. I modified the code to add more links to the Org files and to walk me through publishing videos to YouTube.

I uploaded all the videos to YouTube and scheduled them so that I didn't have to manage that during the conference. I did not get around to uploading them to Toobnix until after the conference since dealing with lots of duplicated updates is annoying. I've been writing a few more functions to work with the Toobnix API, so it might be a little easier to do things like update descriptions or subtitles next year.

Etherpad

As usual, we used Etherpad to collect questions from conference partcipants, and many speakers answered questions there as well.

I used the systemli.etherpad Ansible role to upgrade to Etherpad 2.5. This included some security fixes, so that was a relief.

I added pronouns and pronunciations to the Etherpad to make it easier for hosts to remember just in case.

I did not get to use emacsconf-erc-copy to copy IRC to Etherpad because I was too busy juggling everything else, so I just updated things afterwards.

Idea: Just in case, it might be good to have a backup plan in case I need to switch Etherpad to authenticated users or read-only use. Maybe I can prepare questions beforehand, just in case we get some serious griefing.

IRC

The plain-text chat channels on IRC continued to be a great place to discuss things, with lots of discussions, comments, and encouraging feedback. My automated IRC system continued to do a good job of posting the talk links, and the announcements made it easier to split up the log by talk.

Planning for social challenges is harder than planning for technical ones, though. libera.chat has been dealing with spam attacks recently. Someone's also been griefing #emacs and other channels via the chat.emacsconf.org web interface, so we decided to keep chat.emacsconf.org dormant until the conference itself. If this is an issue next year, we might need to figure out moderation. I'd prefer to not require everyone to register accounts or be granted voice permissions, so we'll see.

Extracting the Q&A

We recorded all the Q&A sessions so that we could post them afterwards. As mentioned, I only started the recording late once. Progress! I generally started it a few minutes early. As I got more confident about paying attention to the start of a session and rearranging the layout on screen, I also got better at starting the recording shortly before turning it over to the speaker. That made it easier to trim the recordings afterwards.

It took me a little longer to get to the Q&A sessions this year. Like last year, getting the recordings from BigBlueButton was fairly easy because I could get a single processed video instead of combining the audio, screenshare, and webcam video myself. This year the single-file video downloads were .m4v files, so I needed to modify things slightly. I think my workflow last year assumed I started with .webm files. Anyway, after some re-encoding, I got it processed. Now I've modified the /usr/local/bigbluebutton/core/scripts/video.yml to enable webm. I wonder if it got wiped after my panic-reinstall after November's OrgMeetup. Idea: I should add the config to my Ansible so that it stays throughout reinstalls and upgrades.

I wrote a emacsconf-subed-copy-current-chapter-text function so that I can more easily paste answers into the Q&A… which turned out to be a superset of the emacsconf-extract-subed-copy-section-text I mentioned in last year's notes and totally forgot about. This tells me that I need to add it to my EmacsConf - organizers-notebook notes so that I actually know what to do. I did not use my completion functions to add section headings based on comments either. Apparently this was emacsconf-extract-insert-note-with-question-heading, which I do have a note about in my organizer notebook.

Audio mixing was reasonable. I normalized the audio in Audacity, and I manually fixed some sections where some participants' audio volumes were lower.

Budget

Hosting a conference online continues to be pretty manageable. Here are our costs for the year (including taxes where applicable):

Code for calculating BBB node costs
(append
'(("Node" "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" "Total") hline)
(mapcar
 (lambda (group)
   (let ((amounts (mapcar
          (lambda (file)
            (format "%.2f"
                    (apply '+
                           (seq-keep (lambda (row)
                                       (when (string-match (car group) (car row))
                                         (string-to-number (elt row 8))))
                                     (cdr (pcsv-parse-file file))))))
          (directory-files (format "~/proj/emacsconf/2025/invoices/%s/" (cdr group))
                           t "\\.csv"))))
   (append (list (car group))
           amounts
           (list (format "%.2f" (apply '+ (mapcar 'string-to-number amounts)))))))
 '(("meet" . "sacha")
   ("front0" . "bandali")
   ("live0" . "bandali")))
   nil
   )
Node Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total
meet 2.17 7.55 6.78 6.74 7.13 6.95 7.19 7.27 6.75 7.19 7.56 14.02 87.30
front0 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 18.79 73.79
live0 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 32.89 87.89

Grand total for 2025: USD 248.98

Server configuration during the conference:

Node Specs Hours upscaled CPU load
meet 16GB 8core shared 52 peak 172% CPU (100% is 1 CPU)
front 32GB 8core shared 47 peak 47% CPU (100% is 1 CPU)
live 64GB 16core shared 48 peak 440% CPU (100% is 1 CPU)
res 46GB 12core   peak 60% total CPU (100% is 12 CPUs); each OBS ~3.5 CPUs), mem 7GB used
media 3GB 1core    

These hosting costs are a little higher than 2024 because we now pay for hosting the BigBlueButton server (meet) year-round. That's ~ 5 USD/month for a Linode 1 GB instance and an extra USD 2-3 / month that lets us provide a platform for OrgMeetup, Emacs APAC, and Emacs Berlin by alternating between a 1 GB Linode and an 8 GB Linode as needed. The meetups had previously been using the free Jitsi service, but sometimes that has some limitations. In 2023 and most of 2024, the BigBlueButton server had been provided by FossHost, which has since shut down. This time, maintaining the server year-round meant that we didn't have to do any last-minute scrambles to install and configure the machine, which I appreciated. I could potentially get the cost down further if I use Linode's custom images to create a node from a saved image right before a meetup, but I think that trades about USD 2 of savings/month for much more technical risk, so I'm fine with just leaving it running downscaled.

If we need to cut costs, live0 might be more of a candidate because I think we'll be able to use Ansible scripts to recreate the Icecast setup. I think we're fine, though. Also, based on the CPU peak loads, we might be able to get away with lower specs during the conference (maybe meet: 8 GB, front: 8 GB, live: 32 GB), for an estimated savings of USD 27.76, with the risk of having to worry about it if we hit the limit. So it's probably not a big deal for now.

I think people's donations through the Working Together program can cover the costs for this year, just like last year. (Thanks!) I just have to do some paperwork.

In addition to these servers, Ry P provided res.emacsconf.org for OBS streaming over VNC sessions. The Free Software Foundation also provided media.emacsconf.org for serving media files, and yang3 provided eu.media.emacsconf.org.

If other people are considering running an online conference, the hosting part is surprisingly manageable, at least for our tiny audience size of about 100 peak simultaneous viewers and 35 web conference participants. It was nice to make sure that everyone can watch without ads or Javascript.

Behind the scenes: In terms of keeping an eye on performance limits, we're usually more CPU-bound than memory- or disk-bound, so we had plenty of room this year. Now I have some Org Babel source blocks to automatically collect the stats from different servers. Here's what that Org block looks like:

#+begin_src sh :dir /ssh:res:/ :results verbatim :wrap example
top -b -n 1 | head
#+end_src

I should write something similar to grab the Icecast stats from http://live0.emacsconf.org:8001/status.xsl periodically. Curl will do the trick, of course, but maybe I can get Emacs to add a row to an Org Mode table.

Tracking my time

As part of my general interest in time-tracking, I tracked EmacsConf-related time separately from my general Emacs-related time.

Calculations
(append (list '("Year" "Month" "Hours") 'hline)
(seq-mapcat
 (lambda (year)
   (mapcar
    (lambda (group)
      (list
       year
       (car group)
       (format "%.1f"
               (apply '+
                      (mapcar (lambda (o) (/ (alist-get 'duration o) 3600.0))
                              (cdr group))))))
    (seq-group-by (lambda (o)
                    (substring (alist-get 'date o) 5 7))
                  (quantified-records
                   (concat year "-01-01")
                   (concat year "-12-31")
                   "&filter_string=emacsconf&split=keep&order=oldest"))))
 '("2024" "2025")))
Year Month Hours
2024 01 2.5
2024 07 2.8
2024 08 0.6
2024 09 7.0
2024 10 14.4
2024 11 30.7
2024 12 46.2
2025 01 9.7
2025 02 1.4
2025 04 0.9
2025 06 0.8
2025 07 6.0
2025 08 3.6
2025 09 10.9
2025 10 1.2
2025 11 21.0
2025 12 64.3
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(data[1:], columns=data[0])
df = pd.pivot_table(df, columns=['Month'], index=['Year'], values='Hours', aggfunc='sum', fill_value=0)
df = df.reindex(columns=range(1, 13), fill_value=0)
df['Total'] = df.sum(axis=1)
df = df.applymap(lambda x: f"{x:.1f}" if x != 0 else "")
return df
Year 1 2 3 4 5 6 7 8 9 10 11 12 Total
2024 2.5           2.8 0.6 7.0 14.4 30.7 46.2 104.2
2025 9.7 1.4   0.9   0.8 6.0 3.6 10.9 1.2 21.0 64.3 119.8

This year, I spent more time doing the reencoding and captions in December, since most of the submissions came in around that time. I didn't even listen to all the videos in real time. I used my shortcuts to skim the captions and jump around. It would have been nice to be able to spread out the work a little bit more instead of squeezing most of it into the first week of December, since that would have made it easier to coordinate with other volunteers without feeling like I might have to do more last-minute scrambles if they were busier than expected.

I was a little bit nervous about making sure that the infrastructure was all going to be okay for the conference as well as double checking the videos for possible encoding issues or audio issues. Stress tends to make me gloss over things or make small mistakes, which meant I had to slow down even more to double-check things and add more things to our process documentation.

I'm glad it all worked out. Even if I switched that time to working on Emacs stuff myself, I don't think I would have been able to put together all the kinds of wonderful tips and experiences that other people shared in the conference, so that was worthwhile.

(Here's a longer-term analysis time going back to 2012.)

Thanks

  • Thank you to all the speakers, volunteers, and participants, and to all those other people in our lives who make it possible through time and support.
  • Thanks to other volunteers: 
    • Corwin and Amin for helping with the organization
    • JC Helary, Triko, and James Endres Howell for help reviewing CFPs
    • Amitav Krishna, Rodion Goritskov, jay_bird, and indra for captions
    • yang3 for the EU mirror we're setting up
    • Bhavin Gandhi, Michael Kokosenski, Iain Young, Jamie Cullen, Ihor Radchenko (yantar92), FlowyCoder for other help
  • Thanks to the Free Software Foundation for the mailing lists, the media server, and of course, GNU Emacs.
  • Thanks to Ry P for the server that we're using for OBS streaming and processing videos.
  • Thanks to the many users and contributers and project teams that create all the awesome free software we use, especially:
  • Thanks to shoshin for the music.
  • Thanks to people who donated via the FSF Working Together program: Scott Ranby, Jonathan Mitchell, and 8 other anonymous donors!

Overall

I've already started hearing from people who enjoyed the conference and picked up lots of good tips from it. Wonderful!

EmacsConf 2025 was a bit more challenging this year. The world has gotten a lot busier. Return-to-work mandates, job market turmoil, health challenges, bigger societal changes… It's harder for people to find time. For example, the maintainers of Emacs and Org are too busy working on useful updates and bugfixes to rehash the news for us, so maybe I'll get back to doing Emacs News Highlights next year. I'm super lucky in that I can stand outside most of all of that and make this space where we can take a break and chat about Emacs. I really appreciated having this nice, cozy little place where people could get together and bump into other people who might be interested in similar things, either at the event itself or in the discussions afterwards. I'm glad we started with a large schedule and let things settle down. I'd rather have that slack instead of making speakers feel stressed or guilty.

I love the way that working on the various parts of the conference gives me an excuse to tinker with Emacs and figure out how to use it for more things.

As you can tell from the other sections in this post, I tend to have so much fun doing this that I often forget to check if I've already written the same functions before. When I do remember, I feel really good about being able to build on this accumulation of little improvements.

I didn't feel like I really got to attend EmacsConf this year, but that's not really surprising because I don't usually get to. I think the only time I've actually been able to take proper notes during EmacsConf itself was back in 2013. It's okay, I get to spend a little time with presentations before anyone else does, and there's always the time afterwards. Plus I can always reach out to the speakers myself. It might be nice to be able to just sit and enjoy it and ask questions. Maybe someday when I've automated enough to make this something that I can run easily even on my own.

So let's quickly sketch out some possible scenarios:

  • I might need to do it on my own next year, in case other organizers get pulled away at the last minute: I think it's possible, especially if I can plan for some emergency moderation or last-minute volunteers. I had a good experience, despite the stress of juggling things live on stream. (One time, one of the speakers had a question for me, and he had to repeat it a few times before I found the right tab and unmuted.) Still, I think it would be great to do it again next year.
  • Some of the other organizers might be more available: It would be nice to have people on screen handling the hosting. If people can help out with verifying the encoding, normalizing the audio, and shepherding videos through the process, that might let me free up some time to coordinate captions with other volunteers even for later submissions.
  • I might get better at asking for help and making it easier for people to get involved: That would be pretty awesome. Sometimes it's hard for me to think about what and how, so if some people can take the initiative, that could be good.

This is good. It means that I can probably say yes to EmacsConf even if it's just me and whoever wants to share what they've been learning about Emacs this year. That's the basic level. We're still here, amazing! Anything else people can add to that is a welcome bonus. We'll make stone soup together.

EmacsConf doesn't have to be snazzy. We don't need to try to out-market VS Code or whatever other editors emerge over the next 10 years. We can just keep having fun and doing awesome things with Emacs. I love the way that this online conference lets people participate from all over the world. We like to focus on facilitating sharing and then capturing the videos, questions, answers so that people can keep learning from them afterwards. I'm looking forward to more of that next year.

I'd love to hear what people thought of it and see how we can make things better together. I'd love to swap notes with organizers of other conferences, too. What's it like behind the scenes?

My next steps are:

  • Extract part of this into a report for the emacsconf.org website, like EmacsConf - 2024 - EmacsConf 2024 Report.
  • Announce the resources and report on emacsconf-discuss.
  • Catch up on the other parts of my life I've been postponing.
  • Start thinking about EmacsConf 2026 =)
View org source for this post

Emacs Lisp: Making a multi-part form PUT or POST using url-retrieve-synchronously and mm-url-encode-multipart-form-data

| emacs

I spent some time figuring out how to submit a multipart/form-data form with url-retrieve-synchronously with Emacs Lisp. It was surprisingly hard to find an example of working with multi-part forms. I had totally forgotten that I had figured something out last year: Using Emacs Lisp to export TXT/EPUB/PDF from Org Mode to the Supernote via Browse and Access. Well, I still had to spend some extra time dealing with the quirks of the PeerTube REST API. For toobnix.org, having = in the boundary didn't seem to work. Also, since I had newlines (\n) in my data, I needed to replace all of them with \r\n, which I could do with encode-coding-string and the utf-8-dos coding system. So here's an example I can use for the future:

(let* ((boundary (format "%s%d" (make-string 20 ?-) (time-to-seconds)))
       (url-request-method "PUT")       ; or POST
       (url-request-extra-headers
        (append
         (list
          (cons "Content-Type"
                (concat "multipart/form-data; boundary=" boundary))
          ;; put any authentication things you need here too, like
          ;; (cons "Authorization" "Bearer ...")
          )
         url-request-extra-headers
         nil))
       (url-request-data
        (mm-url-encode-multipart-form-data
         `(("field1" .
            ,(encode-coding-string "Whatever\nyour value is" 'utf-8-dos)))
         boundary))
       (url "http://127.0.0.1"))        ; or whatever the URL is
    (with-current-buffer (url-retrieve-synchronously url)
      (prog1 (buffer-string)
        (kill-buffer (current-buffer)))))

I've also added it to my local elisp-demos notes file (see the elisp-demos-user-files variable) so that helpful can display it when I use C-h f to describe mm-url-encode-multipart-form-data.

Here I'm using it to update the video description in emacsconf-toobnix.el:

emacsconf-toobnix-update-video-description: Update the description for TALK.
(defun emacsconf-toobnix-update-video-description (talk &optional type)
  "Update the description for TALK.
TYPE is 'talk or 'answers."
  (interactive
   (let ((talk (emacsconf-complete-talk-info)))
     (list
      talk
      (if (plist-get talk :qa-toobnix-url)
          (intern (completing-read "Type: " '("talk" "answers")))
        'talk))))
  (setq type (or type 'talk))
  (let* ((properties
          (pcase type
            ('answers (emacsconf-publish-answers-video-properties talk 'toobnix))
            (_ (emacsconf-publish-talk-video-properties talk 'toobnix))))
         (id
          (emacsconf-toobnix-id-from-url
           (plist-get talk (pcase type
                             ('answers :qa-toobnix-url)
                             (_ :toobnix-url)))))
         (boundary (format "%s%d" (make-string 20 ?-)
                           (time-to-seconds)))
         (url-request-method "PUT")
         (url-request-extra-headers
          (cons (cons "Content-Type"
                      (concat "multipart/form-data; boundary=" boundary))
                (emacsconf-toobnix-api-header)))
         (url-request-data
          (mm-url-encode-multipart-form-data
                     `(("description" .
                        ,(encode-coding-string
                          (plist-get properties :description)
                          'utf-8-dos)))
                     boundary))
         (url (concat "https://toobnix.org/api/v1/videos/" id)))
    (with-current-buffer (url-retrieve-synchronously url)
      (prog1 (buffer-string)
        (kill-buffer (current-buffer))))))

View org source for this post

J'apprécie les gens d'Emacs / I appreciate the people of Emacs

| emacs, french
En français

J'aime bien l'éditeur Emacs. C'est si personnalisable. Comme il est tellement personnalisable, quand on lit les fonctions, on peut avoir un aperçu de la vie des autres, de leurs objectifs, et des défis dont ils sont venus à bout avec les fonctions. En lisant le code, on découvre une petite partie de leur univers. Parfois on peut rencontrer des gens sur les blogs (l'agrégateur Planet Emacslife est très utile), les vidéos, les réunions virtuelles ou la conférence annuelle EmacsConf. J'aime particulièrement la série Prot Asks où il converse avec quelques personnes de tout et de rien. Les gens qui sont intéressés par Emacs sont toujours également intéressés par d'autres choses passionnantes. Même s'ils sont dispersés physiquement et sont occupés, ce qui fait que la coopération est très rare, j'apprécie qu'ils existent, ils créent, ils partagent…

Qui m'a le plus influencé ? C'est probablement John Wiegley. Son Planner Mode m'a aidée à organiser mes notes à l'université et m'a inspirée à l'utiliser et à faire du bénévolat. Son Ledger CLI m'a aidée à budgétiser, ce qui m'a permis cette expérience de la vie indépendante. Son idée pour Emacs News continue de me connecter à la communauté Emacs. J'ai pu le rencontrer en 2013 à l'EmacsConf à Londres. Quelle chance !

Beaucoup d'autres personnes me réchauffent le cœur. J'apprécie aussi Jon Snader pour toujours écrire beaucoup de commentaires sur son blog Irreal, et j'apprécie beaucoup de blogueurs, créateurs de vidéos, et ceux qui partagent des liens. J'apprécie kensanata qui entretient EmacsWiki, les modérateurs du salon #emacs et d'autres canaux d'IRC, et les bénévoles qui font de la modération sur les listes de diffusion. Ils font énormément de travail en coulisses pour rendre l'expérience plus plaisante pour nous. J'apprécie Eli Zaretskii et les autres mainteneurs d'Emacs, yantar92 qui entretient Org Mode, et les mainteneurs d'autres packages. Je suis toujours étonnée de voir que les gens partagent leur temps avec nous.

Bien sûr, il y a des difficultés. L'intelligence artificielle peut aider les gens à comprendre et à créer beaucoup de choses, mais ça peut aussi nous inonder de contenu insipide. Étrangement, certaines personnes ont du mal à être polies. Mais je ne dois pas leur laisser gâcher ma reconnaissance pour le reste. J'aime bien lire les billets de blog sur Emacs et les autres sujets, donc je dois ajouter plus de blogs à mon agrégateur.

Ensuite ? Je travaille lentement à copier les discussions d'EmacsConf. Je continue de publier le bulletin Emacs News. Un jour je veux enregistrer des vidéos et écrire des billets. Cette année semble plus difficile pour les gens : plus occupés, plus stressés… Peut-être qu'EmacsConf devrait aussi s'adapter aux temps changeants. Je me demande ce qui pourrait me faciliter la tâche. Cela me stresse surtout à cause de l'administration système, la conversion des vidéos et la gestion de plusieurs choses à la fois pendant la conférence, particulièrement en direct sur scène. Si je limite ça à une piste, elle sera peut-être plus gérable. Nous nous organisons ensemble.

Hourra pour les gens d'Emacs!

In English

I really like the Emacs editor. It's so customizable. Because it's so customizable, when you read functions, you can get a glimpse into other people's lives, their goals, and the challenges they've overcome with those functions. By reading the code, you discover a small part of their world. Sometimes you can meet people on blogs (the Planet Emacslife aggregator is very useful), videos, virtual meetings, or at the annual EmacsConf conference. I particularly like the Prot Asks series where he chats with various people about everything. People who are interested in Emacs are always also interested in other interesting things. Even if they're spread far apart and pretty busy, which makes collaboration very rare, I appreciate that they exist, they create, they share…

Who has influenced me the most? Probably John Wiegley. His Planner Mode helped me organize my notes in university, and it inspired me to use Emacs and volunteer. His Ledger CLI helped me budget, which allowed me to experiment with this independent life. His idea for Emacs News continues to connect me to the Emacs community. I got to meet him in 2013 at EmacsConf in London - how lucky!

Many other people warm the cockles of my heart. I appreciate Jon Snader for writing lots of comments on his Irreal blog. I'm grateful for bloggers, video creators, and people who share links. I appreciate kensanata for maintaining EmacsWiki, the moderators of the #emacs channel and other IRC channels, and the volunteers who moderate the mailing lists. They do a tremendous amount of work behind the scenes to make the experience more enjoyable for us. I appreciate Eli Zaretskii and other Emacs maintainers, yantar92 who maintains Org Mode, and the maintainers of other packages. I'm always amazed that people share their time with us.

Of course, there are challenges. Artificial intelligence can help people understand and create many things, but it can also flood us with slop. Some people struggle with politeness. But I shouldn't let that spoil my appreciation for everything else. I enjoy reading blog posts about Emacs and other topics, so I should probably add more blogs to my aggregator.

What's next? I'm slowly working on copying the EmacsConf discussions. I'll continue putting together Emacs News. Someday, I'd like to record more videos and write more blog posts. This year seems harder for people: busier, more stressed… Perhaps EmacsConf should also adapt to the changing times. I'm wondering what could make things easier for me. I get particularly stressed because of system administration, video conversion, and managing multiple things at once during the conference, particularly on stream. If I limit it to one track, it might be more manageable. We'll work it out together.

Hooray for the people of Emacs!

This was inspired by the Emacs Carnival theme for December, The People of Emacs. Thanks to George Jones for hosting!

(Thanks to bandali for helping me fix some typos!)

View org source for this post

La semaine du 22 au 28 décembre

| french

Lundi, le vingt-deux décembre

Comme d'habitude, mon mari a cuisiné des petites crêpes épaisses. Nous les avons mangées avec un œuf frit au milieu. Mon mari l'a appelé « Egg McCrumpet Sandwich ». Quand ma fille s'est levée, elle m'a demandé de cuisiner des crêpes. Donc je les ai cuisinées pour de vrai. Elle a mis de la tartinade aux noisettes sur une crêpe. Elle a dit que c'était délicieux.

J'ai amélioré mon outil pour la synthèse vocale. Maintenant, je peux cliquer sur un mot pour l'écouter. J'ai pratiqué les phrases pour la prononciation que ma tutrice a remarqué la semaine dernière et toutes mes entrées pour cette semaine. Au moins, lors de notre rendez-vous, ce ne sera pas la première fois que je prononcerai ces mots.

Après le rendez-vous, nous avons fait les courses. Ma fille avait envie de yaourts brassés, donc elle a mis longtemps à comparer les différents types. Je vais cuisiner des lasagnes puisque les magasins seront fermés, donc j'ai acheté les ingrédients.

Pour le souper, j'ai cuisiné des bébés pak-choïs et du saumon. Curieusement, j'ai oublié un bok choy dans le sac, je suis bête. Mon mari m'a donné des conseils pour cuisiner pendant qu'il cuisinait des muffins anglais. Après le souper, ma fille a préparé de la pâte pour des biscuits. J'apprécie l'expérience de cuisiner ensemble, même si je dois préparer mon bulletin sur l'Emacs plus tard.

J'ai accidentellement abîmé ma brosse à dents électrique. Alors, je pense que j'avais oublié de la nettoyer suffisamment, donc hier soir, elle a arrêté de fonctionner. Quand je l'ai démontée pour en trouver la cause, la pièce qui tient la tête de brosse s'est séparée du corps. J'ai essayé de la réparer, mais ma fille est devenue impatiente et grincheuse. Elle est allée dans sa chambre et s'est assise contre sa porte pour que je ne puisse pas entrer. Je l'entends lire des livres toute seule, au moins, donc elle pratiquait l'autorégulation émotionnelle, qui est si importante dans la vie. Quand elle a fermé la porte, elle a dit qu'elle pouvait se débrouiller toute seule, et à cette occasion, je pense qu'elle peut gérer ça, bien sûr. Je regrette d'avoir laissé ce problème détourner mon attention, mais parfois les choses arrivent, et peut-être qu'elle doit aussi apprendre à gérer quand mon attention est nécessaire ailleurs.

Je me suis sentie embarrassée, hésitante, et un peu consternée, incapable et préoccupée. Mais c'est la vie, il y a des hauts et des bas.

Mardi, le vingt-trois de décembre

Hier soir, ma fille est revenue tard dans la nuit. Elle a eu froid, donc elle s'est blottie contre moi. Elle a aussi volé mon oreiller. Mais je l'aime malgré cela et malgré ses orteils froids. Elle a beaucoup de couvertures dans sa chambre, mais je suppose qu'elle veut se rapprocher, donc ça ne me dérangeait pas. Je ne dors jamais bien quand elle est dans le même lit parce qu'elle me collait par réflexe tout au long de la nuit, donc nous avons fait la grasse matinée.

Ma fille a encore écrit une liste avec enthousiasme, donc je l'ai aidée. Nous avons déblayé la neige qui est très lourde parce que la température était au-dessus de zéro. Le chasse-neige est passé, mais il y avait beaucoup de neige qui restait.

Après l'exercice, nous avons préparé des biscuits. Ma fille a utilisé des emporte-pièces pour faire des étoiles, des anges, des cœurs, des cercles et des ovales. Elle s'améliore à placer les emporte-pièces pour minimiser l'espace entre eux. Pendant qu'elle mettait les emporte-pièces, j'ai fait cuire des biscuits. Naturellement, nous avons testé des biscuits pour le contrôle de la qualité. Nous avons laissé les biscuits refroidir avant de les glacer.

Pendant ce temps-là, j'ai fini le bulletin sur Emacs pour cette semaine et elle a joué à Minecraft.

J'ai préparé du glaçage royal à la poudre de meringue. Ma fille a décoré les biscuits avec grand plaisir et énormément de vermicelles. Je n'accepte pas souvent de faire des biscuits glacés, uniquement pour les occasions spéciales. C'est très festif. Un plus grand contrôle de la qualité a été nécessaire, bien sûr. Mon mari nous a aidées à tester les biscuits plusieurs fois.

J'ai aussi préparé des lasagnes. J'aime faire ça avec plus de fromage. Quand j'étais enfant et que j'habitais aux Philippines avec ma famille, nous préparions souvent des lasagnes pendant la période des fêtes. Même si j'habitais avec une colocataire en résidence, j'ai préparé des petites fournées de lasagnes dans le petit four. Maintenant, ma fille aime aussi les lasagnes, donc je les cuisine de temps en temps pendant les mois plus froids.

Ma fille est revenue pendant que les lasagnes étaient dans le petit four. Elle était déçue parce qu'elle voulait m'aider. Ce problème a été résolu facilement. Nous avons fait les courses puis nous avons cuisiné de nouvelles lasagnes. Elle a aimé les assembler. On peut toujours les partager ou les congeler.

Sur l'apprentissage du français :

Idéalement, un jour je pratiquerai tous les aspects chaque jour : la lecture, l'écoute, l'écriture, et l'expression orale. Mais je trouve que prendre du temps pour la lecture et la compréhension orale est difficile. Je me sens motivée pour écrire parce que c'est une façon de repenser à ma journée et de me souvenir des moments. Je pratique l'expression orale chaque semaine, mais chaque jour, c'est mieux. Toutefois, il y a toujours un compromis à faire parce que mon temps est limité. Je veux enrichir mon vocabulaire et apprendre plus de grammaire pour pouvoir exprimer plus de choses. Si je trouve quelque chose que j'aime bien écouter, peut-être que je peux écouter en faisant la vaisselle ou en me promenant. Trouver le temps pour la lecture juste pour le plaisir est plus difficile, sauf si je peux faire ça sur mon portable, ce qui signifie que je dois améliorer la lecture en français jusqu'à ce que ce soit assez facile pour que je la choisisse au lieu de scroller. J'ai déjà souvent choisi d'écrire mon journal en français ou de revoir les cartes d'Anki avant de scroller, donc il y a de l'espoir. L'app ReadLang avec les blogs et SmartBook avec les EPUBs semblent utiles.

Mercredi, le vingt-quatre décembre

Le soleil brillait, donc nous sommes allés à la bibliothèque à pied pour emprunter un livre pour mon mari. Puis, nous avons fait les courses pour des bombes de chocolat chaud que ma fille veut boire demain après avoir déballé ses cadeaux. Nous avons conversé avec nos voisins, et ma fille a donné plusieurs biscuits à un voisin. (L'autre voisin était déjà parti.)

J'ai passé prendre mon vélo cargo au magasin de cycles. Il n'y a pas de pneu spécialisé pour le verglas, mais la vendeuse a dit que ça peut aller si je fais du vélo attentivement. La vendeuse est aussi bénévole pour Bike Brigade, donc nous avons un peu bavardé. Elle a dit qu'un autre vendeur lisait mon blog. Comme c'est gentil. Je dois écrire une entrée sur ma deuxième année avec mon vélo cargo. Selon mon compteur, j'ai parcouru plus de 4 100 km à vélo en un peu plus de deux ans, ce qui est uniquement possible parce que ma fille peut m'accompagner dans mon vélo cargo. Le vélo cargo est très pratique. J'aime mieux faire du vélo que prendre le métro ou marcher. Cette année, la voiture de mon mari a arrêté de fonctionner et a été mise à la casse, donc nous n'avons pas de voiture. La voiture ne nous a pas du tout manqué. Mon mari a loué une voiture quand nous sommes allés à l'événement familial à l'extérieur de la ville. Pour le reste, on s'en est sortis surtout à vélo. Aujourd'hui l'entretien de mon vélo a coûté environ 300 dollars, ce qui est toujours beaucoup d'argent, mais moins cher que pour la voiture.

J'ai téléchargé la base de données Lexique et l'ai chargée dans SQLite pour récupérer les données rapidement. J'ai créé une brève fonction pour chercher le genre et le nombre du mot. Ça semble utile pour écrire. Je dois assigner un raccourci clavier pour la fonction. Lequel serait le plus pratique…

Une réflexion sur les gens d'Emacs :

J'aime bien l'éditeur Emacs. C'est si personnalisable. Comme il est tellement personnalisable, quand on lit les fonctions, on peut avoir un aperçu de la vie des autres, de leurs objectifs, et des défis dont ils sont venus à bout avec les fonctions. En lisant le code, on découvre une petite partie de leur univers. Parfois on peut rencontrer des gens sur les blogs (l'agrégateur Planet Emacslife est très utile), les vidéos, les réunions virtuelles ou la conférence annuelle EmacsConf. J'aime particulièrement la série Prot Asks où il converse avec quelques personnes de tout et de rien. Les gens qui sont intéressés par Emacs sont toujours également intéressés par d'autres choses passionnantes. Même s'ils sont dispersés physiquement et sont occupés, ce qui fait que la coopération est très rare, j'apprécie qu'ils existent, ils créent, ils partagent…

Qui m'a le plus influencé ? C'est probablement John Wiegley. Son Planner Mode m'a aidée à organiser mes notes à l'université et m'a inspirée à l'utiliser et à faire du bénévolat. Son Ledger CLI m'a aidée à budgétiser, ce qui m'a permis cette expérience de la vie indépendante. Son idée pour Emacs News continue de me connecter à la communauté Emacs. J'ai pu le rencontrer en 2003 à l'EmacsConf à Londres. Quelle chance !

Beaucoup d'autres personnes me réchauffent le cœur. J'apprécie aussi Jon Snader pour toujours écrire beaucoup de commentaires sur son blog Irreal, et j'apprécie beaucoup de blogueurs, créateurs de vidéos, et ceux qui partagent des liens. J'apprécie kensanata qui entretient EmacsWiki, les modérateurs du salon #emacs et d'autres canaux d'IRC, et les bénévoles qui font de la modération sur les listes de diffusion. Ils font énormément de travail en coulisses pour rendre l'expérience plus plaisante pour nous. J'apprécie Eli Zaretskii et les autres mainteneurs d'Emacs, yantar92 qui entretient Org Mode, et les mainteneurs d'autres packages. Je suis toujours étonnée de voir que les gens partagent leur temps avec nous.

Bien sûr, il y a des difficultés. L'intelligence artificielle peut aider les gens à comprendre et à créer beaucoup de choses, mais ça peut aussi nous inonder de contenu insipide. Étrangement, certaines personnes ont du mal à être polies. Mais je ne dois pas leur laisser gâcher ma reconnaissance pour le reste. J'aime bien lire les billets de blog sur Emacs et les autres sujets, donc je dois ajouter plus de blogs à mon agrégateur.

Et ensuite ? Je travaille lentement à copier les discussions d'EmacsConf. Je continue de publier le bulletin Emacs News. Un jour je veux enregistrer des vidéos et écrire des billets. Cette année semble plus difficile pour les gens : plus occupés, plus stressés… Peut-être qu'EmacsConf devrait aussi s'adapter aux temps changeants. Je me demande ce qui pourrait me faciliter la tâche. Cela me stresse surtout à cause de l'administration système, la conversion des vidéos et la gestion de plusieurs choses à la fois pendant la conférence, particulièrement en direct sur scène. Si je limite ça à une piste, elle sera peut-être plus gérable. Nous nous organisons ensemble.

Jeudi, le vingt-cinq décembre

Joyeux Noël ! Premièrement, ma fille a fait chauffer du lait pour des bombes de chocolat chaud. Elle a dit qu'elle avait besoin de combustible pour déballer les cadeaux. Le Père Noël a dû venir hier soir, parce que les cadeaux que nous avons laissés de côté sur le sapin peint sont dispersés partout dans la maison pour le jeu de piste. Les indices avaient un mot en français au moins ainsi que le surplus en anglais. Un cadeau était derrière le calendrier de l'avent, un autre était dans le chariot pour faire les courses, encore un autre était dans le micro-onde, le quatrième était dans l'atelier, et le dernier cadeau était dans le grand four. Ma fille a bien aimé le jeu de piste, et a particulièrement aimé le Gingerbread AT-AT. Elle a dit que c'est en rupture de stock, pourtant le Père Noël a réussi à l'obtenir. C'était très impressionnant. Elle a aussi reçu un hoodie, deux chemises, un autre jeu de LEGO, et un axolotl en peluche qui peut chauffer ou refroidir. Après le petit-déjeuner, ma fille a regardé la vidéo que la GoPro a enregistrée. Les cadeaux sont apparus magiquement accompagnés de lumières scintillantes et ont changé de place eux-mêmes. C'est la troisième année que ma fille essaie d'enregistrer le Père Noël. Je pense que les lumières scintillantes sont devenues plus sophistiquées chaque année.

Nous avons préparé des boules de pâté au fromage. Après le déjeuner, ma fille a construit ses jeux pendant que je faisais ma sieste de Noël traditionnelle. Je me suis couchée très tard et ma fille s'est blottie contre moi, donc j'étais fatiguée. Ensuite, nous avons joué encore aux LEGO, puis j'ai emmené ma fille à la patinoire pour jouer avec son amie. C'était un peu bondé, mais parfois elles ont pu jouer à chat avec le père de son amie. Elles ont pris beaucoup de plaisir. J'ai aimé voir ma fille apprécier toute la famille de son amie, y compris son chien.

Après être rentrées à la maison, ma fille a essayé le nouveau hoodie que sa tante lui a donné. Il était trop grand. Ma fille a dit que je peux le porter jusqu'à ce qu'elle grandisse.

Ensuite, j'ai préparé le bulletin de Bike Brigade et écrit cette entrée. Pour le souper, mon mari et ma fille ont cuisiné des burritos.

Ma fille a voulu acheter un boléro noir en velours et quelques autres habits. Je deviens souvent un peu grincheuse en faisant du shopping, donc c'est une bonne chose que ma fille ait ses propres économies et qu'elle puisse dire qu'elle veut payer elle-même. Comme son père, elle choisit facilement, mais je me retrouve souvent bloquée par l'indécision ou la surstimulation. Je dois approcher mes choix petit à petit. C'est bon que ma fille choisisse pour elle-même. Je lui donne une fraction de mes revenus de mon travail de consultante, donc elle peut gérer un budget raisonnable pour les jouets et d'autres choses.

Elle a aussi voulu acheter des appliqués comme celles que Rumi porte dans K-Pop Demon Hunters, mais il n'y avait pas beaucoup de choix et les produits sont un peu chers. Si j'apprends à peindre sur tissu, ce serait peut-être plus utile et intéressant. Peut-être que la broderie est trop chère ou trop difficile pour l'instant.

Elle m'a demandé de l'aider à laver ses cheveux à cause de ses nouveaux piercings. J'ai lavé ses cheveux par-dessus le côté du bain comme au salon de coiffure. Je n'ai pas de douchette, donc j'ai utilisé un pot de yaourt vide pour verser l'eau chaude sur ses cheveux. Après le petit spa, j'ai mis encore une couverture sur son lit parce qu'elle avait froid. La couverture est plus grande que son lit, donc maintenant elle peut être bien emmitouflée.

Elle a aussi reessayé l'érythromycine. L'autre jour, elle a pleuré parce que l'érythromycine lui a trop piqué les yeux. C'est ma faute. J'ai mis trop d'érythromycine pendant trop de temps parce que j'ai supposé que la conversation avec la pharmacienne était tout ce dont j'avais besoin. J'ai dû rechercher aussi les instructions. J'étais tellement soulagée qu'elle la réessayait. Cette fois, ça ne l'a pas dérangée, ce qui signifie que nous pouvons aussi l'utiliser un jour. Ma fille est plus courageuse que je ne le pensais.

Ma vie est belle, m'a-t-elle dit à l'heure du coucher. La mienne aussi, chérie, la mienne aussi..

Vendredi, le vingt-six décembre

J'ai rangé ma chambre, la commode dans la chambre de ma fille, et la salle de bain. Ma fille voulait un endroit où elle puisse utiliser son maquillage. J'ai débarrassé la surface de la commode pour qu'elle puisse ranger ses affaires. Elle est plus sophistiquée que je ne l'ai jamais été : elle recherche des produits en ligne, converse avec les vendeuses, choisit pour elle-même…

Ensuite, ma fille a terminé la construction de ses jouets. Ensuite, nous avons regardé un film ensemble.

J'ai écouté des enregistrements en français pendant que je déneigeais. J'ai dû le faire deux fois parce que la neige continuait de tomber. Je suppose que je n'ai pas besoin de vidéos d'exercice en hiver quand énormément de neige tombe. C'est une bonne occasion pour écouter, même si à un moment, mon écouteur Bluetooth s'est connecté par erreur au portable de ma fille quand elle a commencé un jeu.

Après avoir mangé les restes, elle a travaillé sur ses devoirs. (Finalement ! Je pense que c'était la première fois de ces vacances…) Pendant ce temps, je jouais à sa place à Ni No Kuni. Je me dis que c'est sa propre expérience. J'ai beaucoup de choses que je veux faire. Par exemple, je veux écrire plus en français, finir le travail de la conférence, réfléchir à mon année, rattraper mon retard… Je ne peux pas la forcer à vouloir quelque chose, comme la réussite scolaire. C'est particulièrement difficile pour moi, parce que je ne me concentrais pas sur mes études quand j'étais à l'école. Je dois être calme au lieu de m'inquiéter. Elle doit avoir le déclic. Elle veut ce qu'elle veut. Si je l'encourage et l'aide, au moins elle n'est pas seule. Je veux toujours la voir telle qu'elle est, ni comme ce que les autres attendent d'elle, ni selon ce qui est pratique pour les attentes du système. Peut-être qu'on attend le bulletin de notes pour avoir son propre bilan.

Samedi, le vingt-sept décembre

J'ai emmené ma fille au parc pour descendre la colline en luge. Nous avons descendu la grande colline ensemble quelques fois. Elle a descendu la petite colline de luge beaucoup de fois, et elle a aussi essayé à partir de la moitié de la grande colline beaucoup de fois toute seule. Nous avons vu un enfant percuter les bottes de foin autour d'un arbre. Heureusement, il avait l'air d'aller bien.

Après le chocolat chaud, elle a pilé la glace sur le chemin avec son grand bâton pendant que je pelletais. J'ai aussi mis du sel pour éviter le verglas.

J'ai créé une petite fonction pour rechercher des mots dans le dictionnaire dans Emacs. Thierry Volpiatto a publié un dictionnaire de traduction anglais-français qui a été converti à partir de Wiktionary. J'ai aussi créé quelques fonctions pour surligner et compter les nouveaux lemmes. C'était étonnamment facile de combiner les données de Lexique et les données de mon outil pour analyser mon journal. Ça facilitera probablement l'écriture de billets plus complexes. Mon objectif est d'apprendre vingt nouveaux lemmes chaque jour, ce qui correspond aux nouvelles cartes que je peux étudier dans Anki. Un peu plus, c'est bien aussi.

Ma fille m'a demandé une plus longue serviette à cheveux, donc je lui en ai cousu une. L'avantage de fabriquer quelque chose soi-même est que nous pouvons le faire comme on le veut. L'année prochaine, je coudrai plus souvent. C'est faisable, surtout parce que je ne trouve pas souvent ce que je veux acheter. On peut commencer par de petits projets comme les pantalons de pyjama. Ma fille pense toujours à beaucoup d'idées.

Malgré les morceaux de raisin quotidiens, la coccinelle s'est échappée de son bocal d'une façon ou d'une autre. Ma fille pense que l'étamine a dû se déplacer. Eh bien, bonne chance, petite coccinelle !

Dimanche, le vingt-huit décembre

Ma fille est encore venue pour se blottir contre moi. J'étais très fatiguée, donc après un bref câlin, je suis allée dans son lit pour y dormir. Peut-être que mes grandes couvertures sont plus faciles à garder pour elle. Ses couvertures étaient assez chaudes pour moi. J'ai mieux dormi que si je m'étais blottie contre elle toute la nuit, et elle avait assez chaud aussi.

J'ai emmené ma fille à la patinoire pour jouer avec son amie. Comme d'habitude, elles ont joué à chat avec le père de son amie. Il n'y avait pas beaucoup de monde, donc ça allait. Ensuite, elles ont joué avec le chien dans la neige. Le chien était très joueur.

À cause des oies qui passent là-haut en V (peut-être un peu tard dans la saison pour la migration ? ), son père et moi avons discuté du changement climatique et des autres défis. Nous avons aussi discuté de l'intelligence artificielle à l'école et au travail pendant que nous attendions les enfants. Je pense que le système actuel d'éducation doit s'adapter. Si on ne veut pas apprendre, il y a beaucoup de façons d'éviter le travail, avec l'IA ou non. L'école ne peut pas se limiter aux feuilles d'exercice ou aux rédactions que l'étudiant écrit seulement pour réussir les cours. Mais je ne peux pas encore penser à une bonne alternative. Pour moi, j'ai utilisé l'IA avec précaution à cause de ses limites. Je pense que la société a besoin de réflexion, mais je ne suis pas optimiste en ce moment. Qu'on se fasse avoir par le battage publicitaire ou qu'on doive obtempérer à cause des nécessités de la vie, je pense que ça ne va pas bien.

Parfois je pense que mon travail est de mettre ma fille à l'abri du tumulte des temps actuels (ou au moins d'atténuer le poids pour qu'il soit gérable) jusqu'à ce qu'elle puisse gérer les choses toute seule. Je vois qu'on ne peut pas compter sur des entreprises ou la société pour défendre nos intérêts dans l'ensemble. Si elle est prête pour trouver sa propre voie tout en appréciant les autres, c'est probablement assez bien. Ça signifie qu'elle doit trouver ses propres objectifs et raisons. Si elle se connaît elle-même et sait ce qu'elle veut, elle peut utiliser l'école ou le travail pour s'améliorer et accomplir ses objectifs. Mais elle est encore une enfant et les tentations sont plus fortes, on dit peut-être. C'est vrai, son cerveau mûrit toujours. Mais elle aspire à l'autodétermination, et je pense que c'est mieux qu'elle puisse expérimenter parce que les enjeux sont faibles.

Nous sommes rentrées à la maison. Mon mari a fait les courses, donc j'ai attendu jusqu'à son retour. Puis je suis allée au coin de la rue pour déneiger la congère que le chasse-neige a faite, parce qu'elle était très gênante. Les voisins du coin n'ont pas déneigé. Au lieu de ronchonner, j'ai déneigé une partie du trottoir. Quelques personnes m'ont remerciée. Quand je suis rentrée à la maison, mon mari est aussi sorti pour déneiger un autre coin. Sois le changement que tu veux voir dans le monde.

Pour le souper, j'ai préparé du tonkatsu. J'ai martelé des escalopes de porc et les ai panées. Mon mari a préparé des petits pak-choïs, y compris le pak-choï que j'ai oublié la dernière fois.

Ensuite, j'ai travaillé sur la conférence. J'ai téléchargé toutes les vidéos sur Toobnix et j'ai copié les discussions de l'IRC et de l'Etherpad vers les pages du wiki. J'ai créé une brève fonction pour automatiser l'ajout des sous-titres aux vidéos sur Toobnix. Seule la gestion de la liste de vidéos reste manuelle. Peut-être que l'année prochaine, je l'automatiserai aussi.

À l'heure du coucher, ma fille est devenue grincheuse parce qu'elle a réalisé qu'elle avait besoin de faire la lessive. C'était trop tard pour commencer. Elle avait d'autres vêtements, donc ce n'était pas grave, pourtant elle s'est barricadée dans sa chambre et a boudé. Eh bien, elle doit apprendre à gérer ces choses et ces émotions. Peut-être que je peux me coucher un peu plus tôt aujourd'hui.

Mes entrées de journal deviennent de plus en plus longues. Je me demande si je vais arriver à les caser dans mon rendez-vous d'une heure avec ma tutrice. Je ne peux pas parler plus rapidement parce que je vais juste ancrer les erreurs. C'est un problème de riche, bien sûr…

View org source for this post

2025-12-29 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

2025-12-22 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

La semaine du 15 décembre au 21 décembre

| french

Lundi, le quinze décembre

J'ai emmené ma fille à son cours de gymnastique. Elle a travaillé ses roues. Elle a aussi envie d'ajouter un cours de gymnastique aérienne. D'une part, j'avais dit que si nous gérions bien ses devoirs, ce serait plus facile de dire oui. D'autre part, c'est un bon exercice pour la santé. Je pense que l'entraînement individuel est meilleur pour ma fille parce qu'elle veut procéder à son propre rythme.

Pour le souper, nous avons préparé des sushis avec des edamames et de la soupe au miso.

Le mini-four a arrêté de fonctionner. Heureusement, c'est notre deuxième mini-four du même modèle, et nous avons le vieux mini-four dans l'abri de jardin pour les pièces détachées. Au lieu de faire ses devoirs, ma fille a aidé mon mari dans l'atelier et a appris des bases d'électronique. Ensuite, ma fille a aidé mon mari à faire du pain. Je me suis un peu inquiétée pour ses devoirs, mais je pense que passer du temps ensemble était tout aussi bien.

Ils ont découvert une coccinelle dans le vieux mini-four. Ils l'ont sauvée et l'ont placée dans un petit bocal. Je lui ai donné un morceau de raisin et un bout d'essuie-tout que j'ai humecté. Je ne sais pas si elle pourra survivre jusqu'au printemps, mais elle est là, donc nous essayons.

Mon mari s'est renseigné sur nos notes de latin que nous avons prises en 2011. Après une brève recherche, je les ai trouvées. Elles étaient dans un vieux format TiddlyWiki, donc je les ai transformées en format Org Mode pour les exporter en livre électronique. Je n'étudie plus le latin depuis longtemps, donc j'oublie tout.

J'ai réfléchi à l'aide : comment aider quelqu'un, comment recevoir de l'aide. Mon ami qui traversait une crise personnelle voulait de l'aide sous forme d'argent, mais je pense que l'aide qu'il a voulue ne lui sera pas utile. Ma fille n'a pas voulu d'aide avec ses devoirs. Peut-être que ma fille pense que ses efforts suffisent, et peut-être que cela lui suffit. Au lieu de m'inquiéter, je dois m'entraîner à recevoir de l'aide moi-même. C'est une des raisons pour lesquelles j'apprends le français avec ma tutrice, j'apprends à parler de mes sentiments avec ma thérapeute, et j'apprécie la façon dont ma famille m'aide à mûrir. Je peux améliorer les processus pour que les gens puissent m'aider. Par exemple, pour le traitement des vidéos de la présentation ou de la discussion en direct, je dois simplifier et documenter le processus. Si les gens sont occupés, ce n'est pas grave, je le fais lentement. Si les gens veulent aider, ils peuvent aider.

Mardi, le seize décembre

Aujourd'hui, j'ai repris une routine normale. J'ai travaillé sur Deck the Halls au piano, j'ai suivi une courte vidéo d'exercice, et j'ai finalement fait une longue promenade au parc. Je ne veux pas marcher sur le verglas parce qu'il est glissant, donc j'ai marché sur le trottoir autour du parc.

Quelqu'un a discuté de la modération du canal #emacs sur IRC. Il a semblé être frustré. Je ne peux pas faire grand-chose, mais j'ai conseillé quelques choses qu'il pouvait faire.

J'ai emmené ma fille à son dernier cours d'art. Elle était fière que son œuvre soit exposée dans la fenêtre. Elle a ramassé les autres œuvres dans son carton à dessins pour les transporter à la maison. Elle a apprécié le cours avec son amie, mais elle a parfois trouvé que c'était trop bruyant, donc elle ne veut pas continuer pour le moment. Nous allons garder un programme assez libre sans beaucoup de cours pour que nous puissions aller patiner ou jouer avec ses amies quand elle en a envie.

Dans la session de thérapie, nous avons discuté des sentiments. J'intellectualise des situations difficiles au lieu de les ressentir, donc mes devoirs pour les vacances de Noël comprennent de remarquer quand j'utilise ce mécanisme de défense. Je vais aussi écrire un journal des sentiments.

J'ai configuré un correcteur d'orthographe grâce au cours « Emacs expliqué à mes enfants » de @vincek.

Mercredi, le dix-sept décembre

J'ai écrit une petite fonction pour rechercher des mots dans quelques dictionnaires en ligne. Petit à petit, j'améliore mon environnement d'écriture.

Cet après-midi, j'ai un rendez-vous pour faire réviser mon vélo cargo. J'ai fait du vélo jusqu'au magasin de cycles. Le mécanicien m'a donné le devis pour le service et des conseils à propos de pneus spécialisés pour le verglas.

Ensuite, j'ai pris le métro, qui avait un problème. Au lieu d' attendre la navette à la station Keele, j'ai marché sur une courte distance jusqu'à la maison.

Je dois probablement traiter les vidéos de la conférence. Un peu de travail peut les rendre prêtes pour la publication. Je vais combiner les vidéos et les audios normalisés, revoir tout ça, et publier sur YouTube et sur notre site. Quelques vidéos ont eu quelques problèmes avec la conversion, donc je dois revoir les dernières minutes attentivement pour remarquer des erreurs.

・・・・・

Après l'école, j'ai emmené ma fille à la patinoire au parc pour jouer avec son amie. Elles ont pris beaucoup de plaisir à jouer à chat avec le père de son amie, qui était trop rapide pour elles. J'ai été heureuse de les regarder. Nous avons bu du chocolat chaud pendant que la surfaceuse préparait la glace.

Nous avons mangé des restes. Après le souper, j'ai travaillé sur les vidéos de la conférence. Deux vidéos ont eu des erreurs de codage, donc j'ai utilisé les vidéos originales et modifié notre processus. Ma prochaine étape est de convertir les vidéos au format WebM pour les télécharger sur notre serveur. Je dois aussi revoir le sous-titrage, mais ça peut être fait graduellement.

Jeudi, le dix-huit décembre

Une étape importante : je deviens plus à l'aise pour écrire en français sur mobile. Ça signifie que je peux ajouter à mon journal n'importe quand et n'importe où. Je recherche toujours des mots dans le dictionnaire, ce qui n'est pas si pratique sur mobile à cause du petit écran, mais c'est tolérable. Au moins, ça peut remplacer le défilement infini de Reddit pour l'énième fois. Un jour je pourrai dicter à mon portable, ce qui serait plus utile pendant les promenades en hiver, quand taper sera difficile.

J'ai encore fait une longue promenade au parc. Le médecin a dit que les promenades étaient bonnes pour la santé, donc j'essaie souvent d'en faire. Un jour je voudrais flâner pendant plusieurs heures, mais pour l'instant, une promenade de trente minutes ou une heure est suffisante.

Les expériences de mon mari avec le pain au levain continuent. Il a acheté quelques bannetons. Ma fille l'a aidé avec cette fournée pendant la pause récré. Elle aime scarifier des motifs variés sur le pain. C'est parfait : passer du temps ensemble, apprécier la nourriture et pratiquer l'art. Ça demande de la patience, mais c'est la vie et elle peut apprendre la valeur des choses qui prennent du temps. C'est probablement plus important que les notes élevées à l'école. (Ou du moins c'est ce que je me dis quand je m'inquiète.)

Quand je rentrerai à la maison, j'aurai trente minutes avant sa pause déjeuner. Je pourrai faire une courte tâche, comme envoyer des messages ou vérifier des vidéos. Ma routine matinale pour prendre soin de moi prend la majeure partie de la matinée. Je me demande comment les autres s'organisent.

・・・・・

J'ai décidé de cuisiner le déjeuner au lieu de faire de petites tâches. J'ai préparé des grilled-cheeses. On s'est régalés.

Après le déjeuner, j'ai travaillé sur les vidéos de la conférence. J'ai ajouté les chapitres à quelques vidéos et corrigé quelques sous-titres.

・・・・・

Après l'école, ma fille a voulu aller chez Sephora pour acheter de la brume parfumée. Elle en a cherché en ligne. Mon mari a voulu acheter du papier toilette à No Frills, donc nous avons pris le métro jusqu'au Dufferin Mall. Elle a appris à choisir par elle-même. C'est pour ça qu'elle a ses propres économies. Elle a choisi « darling » qui sent les fleurs. J'ai aimé voir ma fille gagner en confiance et en autodétermination. Elle a mis longtemps à choisir, mais j'ai été patiente parce que j'ai pu écrire mon journal sur mobile.

Ensuite, nous avons mangé un souper de pâtes au pesto à la tomate.

Puis nous avons joué à la marchande comme dans sa classe de théâtre. Nous avons lancé des idées pour les rôles, donc nous avons improvisé dans la situation qu'elle a choisie. Elle a dit que j'étais drôle.

J'ai travaillé sur d'autres vidéos, et j'ai corrigé une erreur dans le logiciel d'affichage des chapitres.

Vendredi, le dix-neuf décembre

Je me suis levée un peu tard parce que mon portable ne s'est pas rechargé correctement. Heureusement, il restait un peu de temps avant l'école, donc j'ai pu réveiller ma fille à temps pour un petit-déjeuner sur le pouce.

Pendant qu'elle participait à l'école virtuelle, j'ai fait ma routine matinale. Ensuite, j'ai travaillé sur le sous-titrage. Maintenant que les choses sont détendues, je peux prendre plaisir à la préparation des ressources. C'est le dernier jour avant sa pause d'hiver, donc je dois faire les tâches qui demandent de la concentration.

Ma fille a fait sa présentation sur le Nouvel An chinois. Elle était si fière. Elle a dit que ses camarades de classe avaient faim à cause de sa présentation sur la nourriture traditionnelle.

Par coïncidence, mon mari a préparé du riz gluant au poulet pour le déjeuner. On s'est régalés.

La coccinelle était plus active. Nous lui avons donné un morceau de raisin et un morceau de pomme. Ma fille a humidifié le bout d'essuie-tout.

Cet après-midi, j'ai continué le travail sur les vidéos. Elles étaient presque toutes faites, il n'en restait que quelques-unes.

En guise de promenade, j'ai fait les courses. Ensuite, j'ai joué aux cartes avec ma fille. Je gagnais toujours malgré mes efforts subtils. Ma fille est devenue un peu grincheuse. La prochaine fois, je proposerai à ma fille des jeux coopératifs comme Space Escape ou comme on joue au Pictionary ou aux charades ensemble. Comme ça, on ne peut pas vraiment gagner à tous les coups sinon quelqu'un va être fâché contre moi.

・・・・・

Elle s'est sentie mieux et elle est revenue pour manger des ailes de poulet. Elle avait froid aussi, donc elle avait envie de câlins.

Samedi, le vingt décembre

J'ai fait une diffusion en direct sur Twitch pendant que je travaillais sur les sous-titres qu'un intervenant a corrigés. J'ai écrit une courte fonction pour copier des textes dans son chapitre actuel. Trois spectateurs sont venus étonnamment, et ils ont fait quelques commentaires sur mon processus. Avant de faire plus de chapitres de vidéos, je pense que je dois copier les discussions d'IRC et de YouTube sur les pages du wiki pour les envoyer aux intervenants. Ensuite, je peux me remettre à faire les chapitres.

J'ai réfléchi un peu plus à l'aide. Le sous-titrage semble une occasion facile d'aider. J'ai documenté le processus et j'ai créé quelques outils. Mais c'est souvent plus facile si je continue moi-même parce que je ne dois pas attendre. Bon, c'est possible pour des personnes qui se portent volontaires pour faire les sous-titres de quelques vidéos. Je les laisse de côté et je travaille sur les autres vidéos avant elles. Est-ce que je veux inviter les volontaires à aider sur les vidéos restantes? Peut-être. Je dois améliorer la page des coulisses pour plus facilement choisir parmi les tâches restantes, et je dois documenter le processus pour aider les débutants. Il est tentant de travailler seul, mais il est bon de créer des occasions pour que d'autres personnes puissent aider. En plus, la documentation m'aidera quand j'aurai tout oublié d'ici l'année prochaine.

L'après-midi, je suis allée à la pharmacie pour une vaccination contre la grippe. Bien que la vaccination de cette année ne corresponde pas bien aux variations de grippe très courantes, c'est toujours un peu protecteur. Ma fille a marché avec moi à mi-chemin, puis elle est retournée à la maison et elle est allée avec mon mari chez le perceur. Elle voulait porter des boucles d'oreilles. Elle est assez âgée pour choisir par elle-même. Je l'ai aidée pour le nettoyage avec la solution saline.

J'ai préparé le bulletin d'information pour la Bike Brigade. Puisque personne ne s'est porté volontaire, je suis revenue à mon processus qui est plus automatique. Je déteste tous les processus qui demandent plusieurs clics et offrent plusieurs occasions de faire des erreurs. Lorsqu'un bénévole s'engagera, je restaurerai le processus manuel.

Nous avons aussi joué à une simulation de petit café sur Minecraft avec sa tante. Ma fille s'occupait du service, ma sœur s'occupait des salades, et je m'occupais d'alterner les crêpes et les gâteaux. On a bien géré dans les temps. Après ma routine du soir, nous avons aussi joué au Space Escape. Nous avons gagné ensemble !

Dimanche, le vingt-et-un décembre

Après la vaccination d'hier, j'ai un peu mal au cou, donc je me la coule douce aujourd'hui. Je vais faire la lessive et peut-être copier des discussions de la conférence. Mais avant tout, peut-être que je vais étudier un peu le français.

Mon logiciel d'analyse de mon journal a dit que j'ai écrit cinquante-deux entrées jusqu'à présent. Ça nous fait un total de 10.766 mots (1.381 lemmes). J'ai commencé à apprendre le français pour peut-être aider ma fille, mais je trouve que j'apprécie la stimulation d'écriture dans une autre langue. C'est certain que j'écris plus d'entrées à propos de ma vie. L'analyse de mon vocabulaire m'encourage à essayer de nouveaux mots et de plus longues entrées. En 2012, lors d'une conférence sur Quantified Self, j'ai rencontré une personne qui met son journal sur son système de répétition espacée pour aider à s'en souvenir. Après chaque rendez-vous avec ma tutrice, je mets mes phrases sur Anki pour étudier du vocabulaire. En cours de route, je me remémore ces moments. Je ne peux pas encore parler aisément. Peut-être que je dois pratiquer l'expression orale et trouver ma propre méthode pour pratiquer la compréhension orale. Répéter en même temps que l'audio semble utile.

L'outil d'IA que j'ai essayé est sorti de sa phase bêta et a maintenant besoin d'un abonnement de 29 dollars chaque mois. En ce moment, je me demande si je veux l'utiliser, ou si je veux utiliser d'autres outils comme ChatGPT ou Gemini, ou si je veux créer mon propre outil. Je pense que pour le moment, je me concentre principalement sur l'écriture. À cause de COVID et du côté chronophage de l'éducation de mon enfant, je ne suis pas intéressée par des sujets fréquents comme commander au restaurant, les voyages, ou même la présentation et le bavardage. Je veux écrire et écouter des informations sur Emacs et d'autres sujets techniques, donc je peux commencer à lire « Emacs expliqué à mes enfants ». Je peux aussi utiliser la synthèse vocale pour transformer mon journal en audio, que je peux utiliser pour m'entraîner. J'ai ajouté une fonction pour attendre après chaque phrase pendant un multiple du temps initial pour pouvoir répéter plus facilement. Même si peut-être penser à écouter la prononciation quand je cherche des mots dans le dictionnaire en ligne serait suffisant quand j'utilise mon portable, ce qui arrive plus souvent.

Je ne peux pas me concentrer sur mon travail, donc j'ai fait une sieste l'après-midi. Après deux heures, ma fille m'a réveillée parce qu'elle était fière d'avoir aidé mon mari à mettre en conserve les betteraves qu'il avait achetées il y a deux semaines. Ils ont utilisé l'autocuiseur. Puisqu'un bocal ne s'est pas bien scellé, il l'a mis au réfrigérateur. Ils ont aussi fait un gâteau aux ananas et aux betteraves, que ma fille aime bien.

Après le souper, j'ai récupéré un peu d'énergie. J'ai joué à la simulation de petit café sur Minecraft avec ma fille et ma sœur, comme hier. Cette fois, notre jeu se déroule bien. Ma sœur a fait beaucoup de salades par lots. Elle a dit : « Dix salades grecques sont prêtes » et ma fille les a servies aux clients. Moi, j'ai préparé des crêpes et des gâteaux nature sans cesse, et je les ai combinés avec d'autres ingrédients pour chaque commande, donc j'ai souvent dit : « Le gâteau au chocolat et à la banane sur le comptoir. » Nous avons franchi facilement deux étapes de plus. Je pense qu'il reste une étape.

View org source for this post