summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--2021/captions/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.vtt979
-rw-r--r--2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--chapters.vtt31
-rw-r--r--2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.vtt565
-rw-r--r--2021/info/dashboard-schedule.md10
-rw-r--r--2021/info/invoice-schedule.md2
-rw-r--r--2021/info/project-schedule.md12
-rw-r--r--2021/schedule-details.md6
7 files changed, 1594 insertions, 11 deletions
diff --git a/2021/captions/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.vtt b/2021/captions/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.vtt
new file mode 100644
index 00000000..4f0147b2
--- /dev/null
+++ b/2021/captions/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.vtt
@@ -0,0 +1,979 @@
+WEBVTT
+
+00:00.000 --> 00:01.567
+Hi everyone! I'm Mehmet Tekman,
+
+00:01.567 --> 00:02.483
+and I'm here to talk to you
+
+00:02.483 --> 00:03.700
+about using Amazon Kindles
+
+00:03.700 --> 00:05.040
+as a productivity dashboard for
+
+00:05.040 --> 00:07.359
+your various projects.
+
+00:07.359 --> 00:09.519
+In a nutshell, you describe your machines,
+
+00:09.519 --> 00:11.317
+your commands, and your schedules
+
+00:11.317 --> 00:13.120
+in an Org-Mode file,
+
+00:13.120 --> 00:14.933
+and then you just initialize
+
+00:14.933 --> 00:16.960
+your Kindle devices.
+
+00:16.960 --> 00:18.367
+These devices are asleep
+
+00:18.367 --> 00:19.117
+most of the time,
+
+00:19.117 --> 00:20.720
+but they wake up at scheduled times
+
+00:20.720 --> 00:22.033
+to retrieve content
+
+00:22.033 --> 00:24.800
+from the centralized server.
+
+00:24.800 --> 00:27.599
+Content can be Org mode and Emacs-based,
+
+00:27.599 --> 00:29.500
+or it can be from Web content,
+
+00:29.500 --> 00:42.840
+or it can just be static images and WAV.
+
+00:42.840 --> 00:45.600
+If you, like me, struggle to
+
+00:45.600 --> 00:46.833
+keep your life under tabs,
+
+00:46.833 --> 00:48.300
+or find it very hard to separate
+
+00:48.300 --> 00:49.417
+your work life from your home life,
+
+00:49.417 --> 00:51.283
+then you, like me, likely need
+
+00:51.283 --> 00:52.917
+some kind of passive background service
+
+00:52.917 --> 00:54.083
+that reminds you of where you are
+
+00:54.083 --> 00:55.267
+and what you are supposed to be doing.
+
+00:55.267 --> 00:56.960
+Even if it's just a sign saying,
+
+00:56.960 --> 00:58.640
+"You're at home! Relax!"
+
+00:58.640 --> 01:00.400
+An Amazon Kindle is perfect for this.
+
+01:00.400 --> 01:01.717
+In a nutshell, it's a cheap
+
+01:01.717 --> 01:03.117
+black and white e-ink device
+
+01:03.117 --> 01:03.800
+that can go for weeks
+
+01:03.800 --> 01:05.033
+without needing a single charge.
+
+01:05.033 --> 01:06.767
+Every year, Amazon brings out
+
+01:06.767 --> 01:07.983
+an incrementally better model,
+
+01:07.983 --> 01:09.333
+which makes the old devices obsolete,
+
+01:09.333 --> 01:11.067
+and you can find these older models
+
+01:11.067 --> 01:13.360
+for 5 euros on second-hand websites.
+
+01:13.360 --> 01:15.360
+Plus it runs Linux, has WiFi networking,
+
+01:15.360 --> 01:16.987
+and has a dedicated forum of hackers
+
+01:16.987 --> 01:19.200
+for getting the most out of the device.
+
+01:19.200 --> 01:20.366
+Some drawbacks of this is that
+
+01:20.366 --> 01:22.799
+the device often comes with unwanted bloat:
+
+01:22.799 --> 01:24.050
+over-the-air updates,
+
+01:24.050 --> 01:25.833
+it phones home to Amazon regularly,
+
+01:25.833 --> 01:27.033
+it has a secret microphone
+
+01:27.033 --> 01:27.983
+embedded in the device,
+
+01:27.983 --> 01:29.433
+and it has a bunch of creepy
+
+01:29.433 --> 01:30.633
+seemingly interdependent
+
+01:30.633 --> 01:31.439
+background processes,
+
+01:31.439 --> 01:34.083
+where killing one kind of kills the others
+
+01:34.083 --> 01:36.560
+risking that you will break the device.
+
+01:36.560 --> 01:37.799
+But this is where the community
+
+01:37.799 --> 01:38.883
+really shines through,
+
+01:38.883 --> 01:40.483
+since the friendly (and not-so-friendly)
+
+01:40.483 --> 01:41.583
+users (and developers)
+
+01:41.583 --> 01:43.200
+from the MobileRead forums have pretty much
+
+01:43.200 --> 01:44.560
+scraped out a good portion of the
+
+01:44.560 --> 01:46.960
+harmful Amazon scripts from the device.
+
+01:46.960 --> 01:48.550
+Some of the devices even use
+
+01:48.550 --> 01:49.483
+Awesome Window Manager,
+
+01:49.483 --> 01:50.800
+meaning you can really play around
+
+01:50.800 --> 01:51.620
+with the existing system
+
+01:51.620 --> 01:52.633
+without having to create
+
+01:52.633 --> 01:54.233
+your own X11 server.
+
+01:54.233 --> 01:55.377
+This then empowers users
+
+01:55.377 --> 01:57.600
+to display whatever they want on the device.
+
+01:57.600 --> 01:59.040
+One project that really got this going
+
+01:59.040 --> 02:00.560
+was the Kindle-Dash dashboard from
+
+02:00.560 --> 02:02.320
+Pascal Widdershoven, who really refined a
+
+02:02.320 --> 02:03.483
+lot of the internal scripts
+
+02:03.483 --> 02:05.439
+to stabilize the device.
+
+02:05.439 --> 02:06.600
+However, the project then
+
+02:06.600 --> 02:07.650
+puts the onus on the device
+
+02:07.650 --> 02:08.560
+to retrieve the data from
+
+02:08.560 --> 02:09.950
+somewhere else over the internet,
+
+02:09.950 --> 02:10.753
+and so you still need to
+
+02:10.753 --> 02:11.440
+generate the content
+
+02:11.440 --> 02:13.200
+and place it on the web somewhere.
+
+02:13.200 --> 02:14.640
+Plus you need to do this and manage it
+
+02:14.640 --> 02:17.360
+for every Kindle device that you have.
+
+02:17.360 --> 02:18.500
+Kindle-Sync, however,
+
+02:18.500 --> 02:19.867
+is an entirely different beast,
+
+02:19.867 --> 02:21.800
+albeit one that builds off of the works
+
+02:21.800 --> 02:23.440
+of the aforementioned projects.
+
+02:23.440 --> 02:24.800
+It assumes that instead of just having
+
+02:24.800 --> 02:26.050
+one Kindle device around
+
+02:26.050 --> 02:27.133
+that you wish to re-purpose
+
+02:27.133 --> 02:28.080
+for productivity purposes,
+
+02:28.080 --> 02:28.983
+that you actually have
+
+02:28.983 --> 02:30.117
+multiple Kindle devices
+
+02:30.117 --> 02:30.794
+that you want to manage
+
+02:30.794 --> 02:32.720
+and configure in tandem.
+
+02:32.720 --> 02:33.633
+Everything is managed
+
+02:33.633 --> 02:35.667
+from a dedicated server (or a raspberry pi)
+
+02:35.667 --> 02:37.440
+which distributes jobs to multiple Kindles,
+
+02:37.440 --> 02:39.519
+running on different update timers.
+
+02:39.519 --> 02:40.786
+These timers are all managed
+
+02:40.786 --> 02:41.486
+from the server,
+
+02:41.486 --> 02:43.017
+and all the Kindle device has to do is:
+
+02:43.017 --> 02:45.200
+to wake up, power on the WiFi,
+
+02:45.200 --> 02:47.280
+receive some media, display the media, and
+
+02:47.280 --> 02:49.680
+receive a barebones RTC sleep request.
+
+02:49.680 --> 02:51.040
+Then it sleeps for the requested time,
+
+02:51.040 --> 02:52.800
+consuming no power, whilst displaying the
+
+02:52.800 --> 02:55.200
+desired media. That is maybe 10 seconds
+
+02:55.200 --> 02:57.599
+of awake time between each request.
+
+02:57.599 --> 02:58.933
+Cron does not actually run
+
+02:58.933 --> 02:59.933
+on the Kindle device itself,
+
+02:59.933 --> 03:01.600
+simply because it does not reliably work.
+
+03:01.600 --> 03:04.050
+All of this is handled by the server.
+
+03:04.050 --> 03:05.599
+With the server-client model,
+
+03:05.599 --> 03:08.000
+it also tries to restrict Amazon access.
+
+03:08.000 --> 03:09.517
+SSH keys are shared
+
+03:09.517 --> 03:11.217
+only from the client to the server,
+
+03:11.217 --> 03:12.517
+but not from the server to the client,
+
+03:12.517 --> 03:13.920
+so the Kindle cannot connect
+
+03:13.920 --> 03:16.319
+to the Raspberry Pi without a password.
+
+03:16.319 --> 03:18.033
+IPtables rules are also set
+
+03:18.033 --> 03:19.483
+so that the Kindle cannot phone home
+
+03:19.483 --> 03:20.667
+to Amazon, and the connections
+
+03:20.667 --> 03:23.200
+are restricted to just the LAN.
+
+03:23.200 --> 03:24.820
+So I got very curious at one point
+
+03:24.820 --> 03:26.133
+and decided to see how long
+
+03:26.133 --> 03:27.599
+a Kindle could last on a single charge
+
+03:27.599 --> 03:28.560
+in such an arrangement,
+
+03:28.560 --> 03:30.640
+so that every 15 minutes for 18 hours,
+
+03:30.640 --> 03:31.599
+I tested the device
+
+03:31.599 --> 03:32.959
+by sending a media item
+
+03:32.959 --> 03:35.200
+and recording the battery level.
+
+03:35.200 --> 03:36.159
+The Kindle doesn't seem to
+
+03:36.159 --> 03:36.959
+report the battery level
+
+03:36.959 --> 03:37.760
+very continuously,
+
+03:37.760 --> 03:39.040
+but at discrete percentages,
+
+03:39.040 --> 03:39.840
+so that you could end up with
+
+03:39.840 --> 03:42.159
+a graph that looks like this.
+
+03:42.159 --> 03:43.617
+Assuming you have half the charge,
+
+03:43.617 --> 03:45.200
+and use it once every hour -
+
+03:45.200 --> 03:48.319
+it will drop by 10% battery in 76 hours,
+
+03:48.319 --> 03:49.760
+which is roughly three days.
+
+03:49.760 --> 03:50.640
+It's hard to extrapolate
+
+03:50.640 --> 03:52.400
+with only three good summarized data points,
+
+03:52.400 --> 03:53.519
+of which the number of requests
+
+03:53.519 --> 03:54.879
+per battery level appear to diminish
+
+03:54.879 --> 03:56.640
+as shown in the table below,
+
+03:56.640 --> 03:58.560
+but the final result yields 76 requests
+
+03:58.560 --> 04:00.799
+with an average loss of 0.5% battery life
+
+04:00.799 --> 04:02.273
+per request. Which is not bad!
+
+04:02.273 --> 04:04.400
+Assuming you do a request every 2 hours
+
+04:04.400 --> 04:06.000
+from 8am to 8pm,
+
+04:06.000 --> 04:07.040
+and let it sleep at night,
+
+04:07.040 --> 04:09.040
+then that's approximately 6 requests a day,
+
+04:09.040 --> 04:10.400
+which could easily last a device
+
+04:10.400 --> 04:11.280
+for a month.
+
+04:11.280 --> 04:12.586
+The ksync script does
+
+04:12.586 --> 04:13.200
+essentially everything:
+
+04:13.200 --> 04:14.799
+from generating and fetching the media,
+
+04:14.799 --> 04:16.720
+to initializing all Kindle devices,
+
+04:16.720 --> 04:18.160
+generating the server cronjobs,
+
+04:18.160 --> 04:19.199
+log report summaries,
+
+04:19.199 --> 04:20.400
+editing the config tables,
+
+04:20.400 --> 04:21.199
+and much more.
+
+04:21.199 --> 04:22.880
+The media operations are comparatively
+
+04:22.880 --> 04:23.680
+much more complex
+
+04:23.680 --> 04:25.280
+and encompass a few media use cases
+
+04:25.280 --> 04:26.400
+such as fetching the weather
+
+04:26.400 --> 04:28.560
+(though only from Open Weather Maps)
+
+04:28.560 --> 04:30.000
+and retrieving Google Calendar views
+
+04:30.000 --> 04:32.000
+by week, month, agenda, and four day view.
+
+04:32.000 --> 04:33.199
+You can retrieve Org-Mode data
+
+04:33.199 --> 04:34.639
+from an Emacs instance on the server,
+
+04:34.639 --> 04:35.360
+which in my case
+
+04:35.360 --> 04:36.720
+I produce views for an agenda
+
+04:36.720 --> 04:39.360
+or a sparse tree of my main projects file.
+
+04:39.360 --> 04:41.120
+Finally we have gallery and wavfile,
+
+04:41.120 --> 04:42.240
+which are static resources
+
+04:42.240 --> 04:44.000
+which will never change once generated.
+
+04:44.000 --> 04:45.199
+The idea is that you feed it
+
+04:45.199 --> 04:46.400
+text and an image location,
+
+04:46.400 --> 04:47.040
+and it generates
+
+04:47.040 --> 04:48.720
+a Kindle-compatible image
+
+04:48.720 --> 04:51.280
+using imagemagick as a backend for it.
+
+04:51.280 --> 04:52.240
+In the case of the wavfile,
+
+04:52.240 --> 04:54.160
+it uses espeak on the backend.
+
+04:54.160 --> 04:55.280
+The below is summarized
+
+04:55.280 --> 04:56.317
+from the help-me text
+
+04:56.317 --> 04:57.199
+in the main ksync file,
+
+04:57.199 --> 04:58.160
+but essentially, you need to
+
+04:58.160 --> 04:59.919
+define your config in the CSV files,
+
+04:59.919 --> 05:01.440
+which we talk about in the next section;
+
+05:01.440 --> 05:03.120
+initialize all your Kindle devices,
+
+05:03.120 --> 05:04.720
+i.e. copy over SSH keys,
+
+05:04.720 --> 05:06.160
+kill all the unnecessary services,
+
+05:06.160 --> 05:07.840
+and prime them for media collection;
+
+05:07.840 --> 05:08.720
+and ensure that you have
+
+05:08.720 --> 05:10.080
+all your static media generated
+
+05:10.080 --> 05:11.440
+and fetchable; and finally
+
+05:11.440 --> 05:12.720
+you then refresh the scheduling
+
+05:12.720 --> 05:14.240
+on the server.
+
+05:14.240 --> 05:15.759
+Okay, so this is all good and well,
+
+05:15.759 --> 05:17.039
+and we now know what the server does
+
+05:17.039 --> 05:18.400
+and how to probe and inspect it -
+
+05:18.400 --> 05:19.759
+but how does the server generate
+
+05:19.759 --> 05:21.120
+much of the content?
+
+05:21.120 --> 05:22.080
+So a lot of the content
+
+05:22.080 --> 05:23.360
+will be dynamically generated,
+
+05:23.360 --> 05:24.639
+meaning it cannot be cached
+
+05:24.639 --> 05:26.720
+and is likely to change from hour to hour.
+
+05:26.720 --> 05:28.400
+The media content that is generated here
+
+05:28.400 --> 05:29.759
+are mostly PNG images
+
+05:29.759 --> 05:30.567
+and have a timestamp
+
+05:30.567 --> 05:32.320
+embedded in their filenames.
+
+05:32.320 --> 05:33.520
+The Emacs-specific content
+
+05:33.520 --> 05:34.560
+consists of a few views,
+
+05:34.560 --> 05:36.000
+namely the org-gcal views,
+
+05:36.000 --> 05:37.600
+org-agenda, and org-calories --
+
+05:37.600 --> 05:39.520
+essentially anything that Emacs can display
+
+05:39.520 --> 05:42.000
+and that you want to capture into an image.
+
+05:42.000 --> 05:43.360
+Emacs can't (as far as I know)
+
+05:43.360 --> 05:44.639
+render graphics in a headless way,
+
+05:44.639 --> 05:45.600
+so what we do instead
+
+05:45.600 --> 05:48.240
+is run Emacs in a dummy minimal X11 session
+
+05:48.240 --> 05:50.080
+via "xvrb-run."
+
+05:50.080 --> 05:51.680
+From inside, you can take screenshots
+
+05:51.680 --> 05:52.233
+as you would in
+
+05:52.233 --> 05:53.440
+a normal desktop environment,
+
+05:53.440 --> 05:54.400
+but with the benefit that
+
+05:54.400 --> 05:56.479
+you don't actually need to invoke a desktop
+
+05:56.479 --> 05:58.560
+or interfere with an existing one.
+
+05:58.560 --> 05:59.840
+The minimal elisp shown here
+
+05:59.840 --> 06:00.720
+is all that is required
+
+06:00.720 --> 06:02.400
+to output your desired image from Emacs
+
+06:02.400 --> 06:04.479
+and configure it for the Kindle environment.
+
+06:04.479 --> 06:05.360
+On the web side of things,
+
+06:05.360 --> 06:06.400
+we don't really need to invoke
+
+06:06.400 --> 06:07.520
+a dummy X11 session
+
+06:07.520 --> 06:09.120
+because Chromium can run headless
+
+06:09.120 --> 06:09.919
+and can be controlled
+
+06:09.919 --> 06:11.600
+by the node library "puppeteer"
+
+06:11.600 --> 06:13.039
+to render dynamic content,
+
+06:13.039 --> 06:14.560
+focus on regions of the webpage,
+
+06:14.560 --> 06:16.080
+and take snapshots.
+
+06:16.080 --> 06:17.600
+The static content comprises
+
+06:17.600 --> 06:19.600
+of two types: images and audio.
+
+06:19.600 --> 06:21.520
+The content is accessed by a key,
+
+06:21.520 --> 06:22.560
+in this case Batman,
+
+06:22.560 --> 06:23.600
+and the content information
+
+06:23.600 --> 06:25.199
+is given by the "--extra" parameter
+
+06:25.199 --> 06:26.960
+which describes either or both
+
+06:26.960 --> 06:30.880
+an image and text.
+
+06:30.880 --> 06:32.248
+Okay, so now we have content,
+
+06:32.248 --> 06:33.600
+how do we schedule this content
+
+06:33.600 --> 06:34.960
+to appear on our desired machines
+
+06:34.960 --> 06:36.400
+at desired times?
+
+06:36.400 --> 06:37.759
+Everything is run via cron.
+
+06:37.759 --> 06:38.720
+So previously we saw that
+
+06:38.720 --> 06:40.880
+we only needed the tables MACHINES.csv,
+
+06:40.880 --> 06:43.440
+COMMANDS.csv, and multiple TIME_*.csv tables
+
+06:43.440 --> 06:44.880
+for the shell script to work.
+
+06:44.880 --> 06:46.479
+But Org-Mode does this far easier,
+
+06:46.479 --> 06:47.919
+since you can just have everything
+
+06:47.919 --> 06:49.039
+in the same file,
+
+06:49.039 --> 06:50.720
+and with the helper minor-mode,
+
+06:50.720 --> 06:51.360
+manage everything
+
+06:51.360 --> 06:53.120
+from a single Org-Mode document.
+
+06:53.120 --> 06:55.120
+Here I have 4 kindles and their shortnames.
+
+06:55.120 --> 06:56.160
+Yes, I even have a Kindle
+
+06:56.160 --> 06:57.520
+hanging outside my door.
+
+06:57.520 --> 06:58.960
+I have 11 defined commands
+
+06:58.960 --> 07:00.800
+which represent the views I want to see,
+
+07:00.800 --> 07:02.319
+and there are 4 timetables I use,
+
+07:02.319 --> 07:02.800
+but you can have
+
+07:02.800 --> 07:04.319
+everything on one, if you like.
+
+07:04.319 --> 07:05.360
+Rows are machine names,
+
+07:05.360 --> 07:06.800
+and columns are corresponding hours
+
+07:06.800 --> 07:07.840
+at which they run.
+
+07:07.840 --> 07:09.440
+Trust me, it's easier to configure
+
+07:09.440 --> 07:10.960
+repeating tasks just by repeating them
+
+07:10.960 --> 07:12.720
+multiple times, because at least this way,
+
+07:12.720 --> 07:13.680
+it's human readable,
+
+07:13.680 --> 07:14.880
+and the script which converts these
+
+07:14.880 --> 07:15.759
+to a cronjob
+
+07:15.759 --> 07:18.800
+collapses the repeating tasks by itself.
+
+07:18.800 --> 07:20.560
+The ksync script can be called
+
+07:20.560 --> 07:23.120
+from within the config.org file
+
+07:23.120 --> 07:24.683
+using this convenient
+
+07:24.683 --> 07:26.960
+use-package declaration.
+
+07:26.960 --> 07:28.319
+All that one needs to do
+
+07:28.319 --> 07:30.560
+is to configure the ENVIRONMENT_VARIABLES
+
+07:30.560 --> 07:32.880
+by setting them in this table
+
+07:32.880 --> 07:34.479
+where you set the repo name,
+
+07:34.479 --> 07:36.160
+the config directory,
+
+07:36.160 --> 07:37.599
+where the media shall go,
+
+07:37.599 --> 07:38.960
+and the server IP,
+
+07:38.960 --> 07:39.919
+although this can be
+
+07:39.919 --> 07:41.360
+automatically detected.
+
+07:41.360 --> 07:42.240
+The package allows you
+
+07:42.240 --> 07:43.440
+to export your tables
+
+07:43.440 --> 07:46.720
+by running C-c C-c on them,
+
+07:46.720 --> 07:49.199
+and allows you to update all the jobs
+
+07:49.199 --> 07:52.319
+related to each of your clients.
+
+07:52.319 --> 07:53.759
+You can also initialize clients
+
+07:53.759 --> 07:55.120
+using this package --
+
+07:55.120 --> 07:56.479
+for either all of them
+
+07:56.479 --> 07:58.479
+or individual clients --
+
+07:58.479 --> 07:59.599
+and the package comes with
+
+07:59.599 --> 08:01.120
+some convenience functions
+
+08:01.120 --> 08:02.720
+to do this automatically
+
+08:02.720 --> 08:06.720
+for all tables in the buffer.
+
+08:06.720 --> 08:08.319
+With this, I want to say a big thank you
+
+08:08.319 --> 08:09.840
+to Takaaki Ishikawa
+
+08:09.840 --> 08:11.520
+for his fantastic "org-tree-slide"
+
+08:11.520 --> 08:12.879
+presentation package.
+
+08:12.879 --> 08:14.136
+To Pascal Widdershoven
+
+08:14.136 --> 08:15.803
+and David Hamp-Gonsalves,
+
+08:15.803 --> 08:16.633
+for their fantastic
+
+08:16.633 --> 08:17.840
+kindle-dash repositories,
+
+08:17.840 --> 08:19.903
+for which some of my internal Kindle scripts
+
+08:19.903 --> 08:20.720
+are derived from.
+
+08:20.720 --> 08:22.160
+Also a big thanks to the friendly
+
+08:22.160 --> 08:23.520
+and not-so-friendly users and hackers
+
+08:23.520 --> 08:24.960
+in the MobileRead forums.
+
+08:24.960 --> 08:25.919
+And finally, a big thanks
+
+08:25.919 --> 08:26.960
+to the Emacs community
+
+08:26.960 --> 08:28.270
+and the conference organizers.
+
+08:28.270 --> 08:31.120
+Thank you! [captions by Mehmet]
diff --git a/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--chapters.vtt b/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--chapters.vtt
new file mode 100644
index 00000000..1850cce5
--- /dev/null
+++ b/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--chapters.vtt
@@ -0,0 +1,31 @@
+WEBVTT
+
+00:00:01.040 --> 00:00:10.558
+Introduction
+
+00:00:10.559 --> 00:01:42.719
+How we build and budget project proposals
+
+00:01:42.720 --> 00:02:58.399
+Org mode template with embedded Emacs Lisp
+
+00:02:58.400 --> 00:03:37.279
+The project plan
+
+00:03:37.280 --> 00:04:40.719
+Effort
+
+00:04:40.720 --> 00:06:07.439
+Hourly rates
+
+00:06:07.440 --> 00:07:28.159
+Totals
+
+00:07:28.160 --> 00:08:21.038
+Payment structure
+
+00:08:21.039 --> 00:09:07.999
+Export
+
+00:09:08.000 --> 00:09:09.000
+Advantages
diff --git a/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.vtt b/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.vtt
new file mode 100644
index 00000000..16aa366c
--- /dev/null
+++ b/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.vtt
@@ -0,0 +1,565 @@
+WEBVTT
+
+00:01.040 --> 00:00:02.800
+Hi, I am Adolfo Villafiorita.
+
+00:00:02.800 --> 00:00:04.799
+I am the co-founder of Shair.Tech,
+
+00:00:04.799 --> 00:00:07.200
+an innovative-- a socially-vocated
+
+00:00:07.200 --> 00:00:10.558
+innovative startup in Italy.
+
+00:00:10.559 --> 00:00:13.280
+Today I'm gonna talk about the way in which
+
+00:00:13.280 --> 00:00:17.680
+we use Org mode to budget our projects.
+
+00:00:17.680 --> 00:00:19.039
+First, I need to introduce the way
+
+00:00:19.039 --> 00:00:21.279
+in which we build our project budget.
+
+00:21.279 --> 00:00:22.480
+We start from the goals
+
+00:00:22.480 --> 00:00:24.720
+and the work to be performed,
+
+00:24.720 --> 00:00:29.840
+and we split it into different tasks
+
+00:29.840 --> 00:00:31.920
+which may be grouped in different ways,
+
+00:31.920 --> 00:00:33.440
+according to our needs.
+
+00:00:33.440 --> 00:00:36.800
+It could be user stories or functional groups
+
+00:00:36.800 --> 00:00:40.719
+or packages, and then for each task,
+
+00:00:40.719 --> 00:00:44.000
+we compute the effort.
+
+00:44.000 --> 00:00:45.440
+Then from the effort,
+
+00:00:45.440 --> 00:00:49.840
+we derive the project cost and price
+
+00:49.840 --> 00:00:52.239
+according to two different approaches.
+
+00:52.239 --> 00:00:53.280
+The first approach:
+
+00:00:53.280 --> 00:00:56.320
+we allocate the effort to each resource
+
+00:56.320 --> 00:00:59.680
+and we multiply the effort of the resource
+
+00:00:59.680 --> 00:01:01.359
+by the price of the results.
+
+00:01:01.359 --> 00:01:04.320
+We sum all the efforts together,
+
+00:01:04.320 --> 00:01:07.280
+and then we sum all the tasks together,
+
+00:01:07.280 --> 00:01:09.600
+the prices of all the tasks together.
+
+00:01:09.600 --> 00:01:11.200
+In the second approach,
+
+00:01:11.200 --> 00:01:16.400
+we use a generic effort estimation
+
+00:01:16.400 --> 00:01:20.799
+for each task, without allocating the effort
+
+00:01:20.799 --> 00:01:22.560
+to any specific person,
+
+00:01:22.560 --> 00:01:25.119
+and we multiply this effort
+
+00:01:25.119 --> 00:01:29.040
+by the average price of the resource.
+
+01:29.040 --> 00:01:34.720
+In both cases, the price is computed
+
+01:34.720 --> 00:01:40.079
+by summing cost to overheads and profit.
+
+00:01:40.079 --> 00:01:41.040
+We're a small company.
+
+00:01:41.040 --> 00:01:42.719
+We can choose our toolchain.
+
+00:01:42.720 --> 00:01:44.960
+So we decided to use Org mode
+
+00:01:44.960 --> 00:01:47.360
+for writing our proposals.
+
+01:47.360 --> 00:01:49.200
+We built a template.
+
+00:01:49.200 --> 00:01:54.159
+The template has got a fixed structure
+
+01:54.159 --> 00:01:56.880
+which allows us to do a lot of reuse,
+
+01:56.880 --> 00:01:59.600
+and some Emacs Lisp code
+
+00:01:59.600 --> 00:02:01.040
+and Org mode features
+
+00:02:01.040 --> 00:02:04.079
+to build the project tables.
+
+00:02:04.079 --> 00:02:07.600
+Let me show you, without further ado,
+
+00:02:07.600 --> 00:02:11.760
+the template which is shown here.
+
+02:11.760 --> 00:02:15.520
+Basically it is a fairly standard
+
+02:15.520 --> 00:02:17.750
+Org mode document.
+
+02:20.800 --> 00:02:23.760
+There are some sections here.
+
+02:23.760 --> 00:02:28.879
+Let me show you the structure here.
+
+02:28.879 --> 00:02:30.000
+There are some sections,
+
+00:02:30.000 --> 00:02:34.959
+some of which are not exported /
+
+00:02:34.959 --> 00:02:36.640
+shown to the client,
+
+02:36.640 --> 00:02:39.519
+because they are of no interest to them,
+
+02:39.519 --> 00:02:41.040
+such as, for instance,
+
+00:02:41.040 --> 00:02:43.280
+the plaintext of each
+
+00:02:43.280 --> 00:02:45.440
+ledger accounting entries
+
+02:45.440 --> 00:02:47.440
+we generate for the project
+
+02:47.440 --> 00:02:53.680
+or some info about the detailed budget data,
+
+00:02:53.680 --> 00:02:56.319
+while others are shared with the clients
+
+00:02:56.319 --> 00:02:58.399
+to form a project proposal.
+
+00:02:58.400 --> 00:03:00.400
+Now the structure is not really important
+
+00:03:00.400 --> 00:03:02.720
+in the sense that the only constraint
+
+00:03:02.720 --> 00:03:05.360
+and requirement we set
+
+00:03:05.360 --> 00:03:07.599
+is that there has to be a section
+
+03:07.599 --> 00:03:10.800
+with an ID named plan,
+
+03:10.800 --> 00:03:15.840
+which will contain the project plan.
+
+03:15.840 --> 00:03:21.040
+Here, for instance, we have a project plan
+
+00:03:21.040 --> 00:03:23.599
+made of a user story
+
+03:23.599 --> 00:03:25.360
+whose development is split into
+
+00:03:25.360 --> 00:03:27.360
+three different tasks.
+
+03:27.360 --> 00:03:30.080
+For each task, let me show you
+
+00:03:30.080 --> 00:03:33.200
+just the structure
+
+00:03:33.200 --> 00:03:37.279
+before the application of the template.
+
+03:37.280 --> 00:03:45.200
+For each task, you need to define the effort.
+
+00:03:45.200 --> 00:03:47.360
+Here, for instance, we have an effort,
+
+00:03:47.360 --> 00:03:50.480
+a generic effort not allocated to any person.
+
+03:50.480 --> 00:03:52.400
+We use Org mode duration,
+
+00:03:52.400 --> 00:03:54.799
+60 stands for 60 minutes,
+
+03:54.799 --> 00:03:57.680
+and here we have an effort profile.
+
+00:03:57.680 --> 00:04:02.000
+So in task 1.2, Adolfo will work 10 days
+
+00:04:02.000 --> 00:04:04.159
+and Michele 20 days.
+
+04:04.159 --> 00:04:06.000
+These are working days,
+
+00:04:06.000 --> 00:04:07.439
+so one working day
+
+00:04:07.439 --> 00:04:09.760
+corresponds to eight hours.
+
+04:09.760 --> 00:04:13.519
+This is standard. We might revise these
+
+04:13.519 --> 00:04:15.040
+to become more compliant
+
+00:04:15.040 --> 00:04:19.759
+with the definition given by Org mode.
+
+00:04:19.759 --> 00:04:23.040
+Notice that you can or cannot,
+
+00:04:23.040 --> 00:04:26.720
+you may or may not use TODO keywords here,
+
+00:04:26.720 --> 00:04:29.199
+if you want. We don't usually use them
+
+00:04:29.199 --> 00:04:31.360
+because the final document
+
+00:04:31.360 --> 00:04:34.720
+looks nice to the customer without TODO.
+
+00:04:34.720 --> 00:04:38.479
+We then add them when we move to
+
+00:04:38.479 --> 00:04:40.719
+a later stage.
+
+04:40.720 --> 00:04:43.040
+So once you define the plan
+
+00:04:43.040 --> 00:04:45.600
+with the effort allocation,
+
+04:45.600 --> 00:04:51.440
+you can go back to the Emacs Lisp part
+
+00:04:51.440 --> 00:04:55.680
+where you can set three different variables
+
+04:55.680 --> 00:04:59.680
+to define the hourly rates of your team.
+
+04:59.680 --> 00:05:02.880
+So for instance, here I am taking
+
+00:05:02.880 --> 00:05:06.160
+10 euros per hour
+
+00:05:06.160 --> 00:05:09.680
+(not real rate, actually), and Michele at 20.
+
+05:09.680 --> 00:05:11.360
+And then you can set the profit
+
+00:05:11.360 --> 00:05:14.560
+as a percentage on top of the hourly rate
+
+00:05:14.560 --> 00:05:16.160
+and profit as a percentage
+
+00:05:16.160 --> 00:05:19.360
+on top of hourly rates.
+
+05:19.360 --> 00:05:24.000
+The ballpark effort allocation here
+
+00:05:24.000 --> 00:05:28.880
+is used to compute the average tariff,
+
+05:28.880 --> 00:05:32.160
+our average hourly rate,
+
+05:32.160 --> 00:05:33.600
+as a weighted average.
+
+00:05:33.600 --> 00:05:36.320
+So here I'm saying that on average,
+
+00:05:36.320 --> 00:05:40.639
+I will work 30% of the effort of each task,
+
+00:05:40.639 --> 00:05:42.400
+while Michele will take care of
+
+00:05:42.400 --> 00:05:47.280
+the remaining 70%, and the hourly rate
+
+00:05:47.280 --> 00:05:48.720
+is computed by multiplying
+
+00:05:48.720 --> 00:05:57.120
+30% by 10 + 70% by 20.
+
+05:57.120 --> 00:06:00.880
+If I do a C-c C-c here, I execute
+
+00:06:00.880 --> 00:06:05.440
+the Emacs Lisp code
+
+00:06:05.440 --> 00:06:07.439
+in the source code block.
+
+00:06:07.440 --> 00:06:08.880
+As you can see,
+
+00:06:08.880 --> 00:06:15.759
+Emacs put back the properties
+
+06:15.759 --> 00:06:17.840
+that transform the effort
+
+00:06:17.840 --> 00:06:19.600
+into a total amount:
+
+00:06:19.600 --> 00:06:22.800
+namely, the effort is first transformed
+
+00:06:22.800 --> 00:06:24.479
+into working hours,
+
+06:24.479 --> 00:06:27.280
+the rates and costs are computed,
+
+06:27.280 --> 00:06:28.880
+overhead computed,
+
+00:06:28.880 --> 00:06:32.160
+and everything contributes
+
+00:06:32.160 --> 00:06:34.639
+to the total amount.
+
+06:34.639 --> 00:06:37.600
+Same thing here.
+
+00:06:37.600 --> 00:06:41.440
+The cost is slightly more complex
+
+00:06:41.440 --> 00:06:45.360
+because we use profiled effort,
+
+06:45.360 --> 00:06:47.199
+and so on and so forth.
+
+00:06:47.199 --> 00:06:49.680
+This information here
+
+00:06:49.680 --> 00:06:56.960
+can be then grouped up
+
+06:56.960 --> 00:06:59.759
+to form the project plan
+
+00:06:59.759 --> 00:07:01.599
+and project budget.
+
+00:07:01.599 --> 00:07:03.039
+As you can see,
+
+07:03.039 --> 00:07:06.880
+this is something we do not export
+
+07:06.880 --> 00:07:09.440
+in the project proposal to the client,
+
+07:09.440 --> 00:07:10.880
+because we prefer to do
+
+00:07:10.880 --> 00:07:13.199
+some rounding by hand
+
+07:13.199 --> 00:07:14.880
+in order to build a budget
+
+00:07:14.880 --> 00:07:20.880
+which is, let's say, more reasonable.
+
+07:20.880 --> 00:07:24.639
+This table here computes VAT
+
+00:07:24.639 --> 00:07:28.159
+on total amounts by C-c C-c once again.
+
+00:07:28.160 --> 00:07:31.120
+Then this table here, the payment structure
+
+00:07:31.120 --> 00:07:36.080
+is used to compute the amount to be paid
+
+00:07:36.080 --> 00:07:39.280
+according to the different payments
+
+00:07:39.280 --> 00:07:40.800
+we want to set in the project.
+
+00:07:40.800 --> 00:07:42.160
+Here, for instance, we are setting
+
+00:07:42.160 --> 00:07:45.919
+three payments with the following percentages,
+
+00:07:45.919 --> 00:07:49.199
+and the table, you set the dates and amounts,
+
+00:07:49.199 --> 00:07:53.440
+and the table keeps track of the rest
+
+00:07:53.440 --> 00:07:56.479
+by looking at the total amount
+
+07:56.479 --> 00:08:00.800
+it finds here in the budget table,
+
+00:08:00.800 --> 00:08:03.280
+so the payment structure and budget
+
+00:08:03.280 --> 00:08:07.280
+are then used by this piece of code here
+
+08:07.280 --> 00:08:12.000
+to build the entries
+
+00:08:12.000 --> 00:08:16.720
+used for our internal accounting,
+
+08:16.720 --> 00:08:21.038
+which is based on hledger.
+
+08:21.039 --> 00:08:23.759
+We did everything here by hand,
+
+08:23.759 --> 00:08:26.400
+but it is not necessary, of course,
+
+08:26.400 --> 00:08:31.280
+because if you export the document
+
+00:08:31.280 --> 00:08:34.880
+using C-c C-e and then, for instance,
+
+00:08:34.880 --> 00:08:39.760
+l for LaTeX and p for PDF,
+
+08:39.760 --> 00:08:43.279
+Org mode takes care of evaluating
+
+00:08:43.279 --> 00:08:46.480
+each piece of code in the document
+
+00:08:46.480 --> 00:08:50.720
+and generate the updated documents.
+
+00:08:50.720 --> 00:08:52.000
+Here, for instance, you can see
+
+00:08:52.000 --> 00:08:55.680
+that the PDF generated from the template
+
+00:08:55.680 --> 00:08:57.440
+which contains all the tables, budget,
+
+00:08:57.440 --> 00:08:59.920
+and payment schema, everything,
+
+00:08:59.920 --> 00:09:02.240
+which we use to make an offer
+
+00:09:02.240 --> 00:09:07.999
+to our clients.
+
+09:08.000 --> 00:09:10.000
+There are various advantages,
+
+00:09:10.000 --> 00:09:12.640
+the first, the main one being that
+
+00:09:12.640 --> 00:09:15.600
+we keep all the information in one place,
+
+09:15.600 --> 00:09:17.920
+and that we can version
+
+00:09:17.920 --> 00:09:20.399
+the different versions.
+
+00:09:20.399 --> 00:09:21.680
+You can use source control
+
+00:09:21.680 --> 00:09:24.640
+to version different iterations
+
+00:09:24.640 --> 00:09:26.080
+on the document.
+
+09:26.080 --> 00:09:28.000
+If you want, you can find the document here.
+
+00:09:28.000 --> 00:09:33.120
+Thank you for your attention,
+
+00:09:33.120 --> 00:09:34.120
+and I'm open to questions.
+
+00:09:34.120 --> 00:09:37.279
+[captions by sachac]
diff --git a/2021/info/dashboard-schedule.md b/2021/info/dashboard-schedule.md
index 5d05fa98..15074565 100644
--- a/2021/info/dashboard-schedule.md
+++ b/2021/info/dashboard-schedule.md
@@ -1,10 +1,14 @@
<!-- Automatically generated by conf-create-info-pages -->
Q&A: live Q&A and Matrix Chat (@mtekman:matrix.org)
-Status: Captions added to video
+Status: Now playing
Duration: 8:31
-<div class="times" start="2021-11-27T21:20:00Z" end="2021-11-27T21:29:00Z">Saturday, Nov 27 2021, ~ 4:20 PM - 4:29 PM EST<br />Saturday, Nov 27 2021, ~ 1:20 PM - 1:29 PM PST<br />Saturday, Nov 27 2021, ~ 9:20 PM - 9:29 PM UTC<br />Saturday, Nov 27 2021, ~10:20 PM - 10:29 PM CET<br />Saturday, Nov 27 2021, ~11:20 PM - 11:29 PM EET<br />Sunday, Nov 28 2021, ~ 2:50 AM - 2:59 AM IST<br />Sunday, Nov 28 2021, ~ 5:20 AM - 5:29 AM +08<br />Sunday, Nov 28 2021, ~ 6:20 AM - 6:29 AM JST<br /><a href="/2021/">Find out how to watch and participate</a></div>
-# Description
+
+<div class="mainVideo"><div class="video-card vid" id="mainVideo" data-id="mainVideo"><figure><video controls preload="metadata">
+<source src="https://media.emacsconf.org/2021/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.webm"><track label="English" kind="captions" srclang="en" src="/2021/captions/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.vtt" default>
+</video></figure>
+<div class="files resources"><ul><li><a href="https://media.emacsconf.org/2021/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.webm">Download .webm video (8:31, 5.2MB)</a></li><li><a href="https://media.emacsconf.org/2021/emacsconf-2021-dashboard--productivity-dashboards-with-emacs-and-kindle--mehmet-tekman--main.vtt">Download --main.vtt</a></li></ul></div></div>
+</div># Description
diff --git a/2021/info/invoice-schedule.md b/2021/info/invoice-schedule.md
index cf8f966e..a9969295 100644
--- a/2021/info/invoice-schedule.md
+++ b/2021/info/invoice-schedule.md
@@ -1,7 +1,7 @@
<!-- Automatically generated by conf-create-info-pages -->
Q&A: answering after the conference
-Status: Now playing
+Status: Finished
Duration: 9:59
[[!inline pages="internal(2021/inline-alternate)" raw="yes"]]
diff --git a/2021/info/project-schedule.md b/2021/info/project-schedule.md
index 8d356e80..f842a218 100644
--- a/2021/info/project-schedule.md
+++ b/2021/info/project-schedule.md
@@ -1,10 +1,14 @@
<!-- Automatically generated by conf-create-info-pages -->
-Status: Captions added to video
-Duration: 9:35
-<div class="times" start="2021-11-27T21:07:00Z" end="2021-11-27T21:17:00Z">Saturday, Nov 27 2021, ~ 4:07 PM - 4:17 PM EST<br />Saturday, Nov 27 2021, ~ 1:07 PM - 1:17 PM PST<br />Saturday, Nov 27 2021, ~ 9:07 PM - 9:17 PM UTC<br />Saturday, Nov 27 2021, ~10:07 PM - 10:17 PM CET<br />Saturday, Nov 27 2021, ~11:07 PM - 11:17 PM EET<br />Sunday, Nov 28 2021, ~ 2:37 AM - 2:47 AM IST<br />Sunday, Nov 28 2021, ~ 5:07 AM - 5:17 AM +08<br />Sunday, Nov 28 2021, ~ 6:07 AM - 6:17 AM JST<br /><a href="/2021/">Find out how to watch and participate</a></div>
+Status: Now playing
+Duration: 9:37
+
[[!inline pages="internal(2021/inline-alternate)" raw="yes"]]
-# Description
+<div class="mainVideo"><div class="video-card vid" id="mainVideo" data-id="mainVideo"><figure><video controls preload="metadata">
+<source src="https://media.emacsconf.org/2021/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.webm"><track label="English" kind="captions" srclang="en" src="/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.vtt" default><track kind="chapters" label="Chapters" srclang="en" src="/2021/captions/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--chapters.vtt" default onload="displayChapters(this)">
+</video></figure>
+<div class="files resources"><ul><li><a href="https://media.emacsconf.org/2021/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.webm">Download .webm video (9:37, 15.3MB)</a></li><li><a href="https://media.emacsconf.org/2021/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--main.vtt">Download --main.vtt</a></li><li><a href="https://media.emacsconf.org/2021/emacsconf-2021-project--budgeting-project-monitoring-and-invoicing-with-org-mode--adolfo-villafiorita--chapters.vtt">Download --chapters.vtt</a></li></ul></div><ol class="chapters"></ol></div>
+</div># Description
diff --git a/2021/schedule-details.md b/2021/schedule-details.md
index a5b04e1f..24cb7099 100644
--- a/2021/schedule-details.md
+++ b/2021/schedule-details.md
@@ -25,9 +25,9 @@
<tr><td>done</td><td width=100>~ 3:21 PM</td><td><a href="/2021/talks/babel">Babel for academics</a></td><td>Asilata Bapat</td></tr>
<tr><td>done</td><td width=100>~ 3:33 PM</td><td><a href="/2021/talks/research">Managing a research workflow (bibliographies, note-taking, and arXiv)</a></td><td>Ahmed Khaled</td></tr>
<tr><td>done</td><td width=100>~ 3:42 PM</td><td><a href="/2021/talks/molecular">Reproducible molecular graphics with Org-mode</a></td><td>Blaine Mooers</td></tr>
-<tr><td>now playing</td><td width=100>~ 3:53 PM</td><td><a href="/2021/talks/invoice">Finding Your (In)voice: Emacs for Invoicing</a></td><td>Bala Ramadurai</td></tr>
-<tr><td>captioned</td><td width=100>~ 4:07 PM</td><td><a href="/2021/talks/project">Budgeting, Project Monitoring and Invoicing with Org Mode</a></td><td>Adolfo Villafiorita</td></tr>
-<tr><td>captioned</td><td width=100>~ 4:20 PM</td><td><a href="/2021/talks/dashboard">Productivity Dashboards with Emacs and Kindle</a></td><td>Mehmet Tekman</td></tr>
+<tr><td>done</td><td width=100>~ 3:53 PM</td><td><a href="/2021/talks/invoice">Finding Your (In)voice: Emacs for Invoicing</a></td><td>Bala Ramadurai</td></tr>
+<tr><td>done</td><td width=100>~ 4:03 PM</td><td><a href="/2021/talks/project">Budgeting, Project Monitoring and Invoicing with Org Mode</a></td><td>Adolfo Villafiorita</td></tr>
+<tr><td>now playing</td><td width=100>~ 4:14 PM</td><td><a href="/2021/talks/dashboard">Productivity Dashboards with Emacs and Kindle</a></td><td>Mehmet Tekman</td></tr>
<tr><td>captioned</td><td width=100>~ 4:32 PM</td><td><a href="/2021/talks/nyxt">Emacs with Nyxt: extend your editor with the power of a Lisp browser</a></td><td>Andrea</td></tr>
<tr><td>captioned</td><td width=100>~ 4:44 PM</td><td><a href="/2021/talks/dev-update">Emacs development updates</a></td><td>John Wiegley</td></tr>
<tr><td>captioned</td><td width=100>~ 4:55 PM</td><td><a href="/2021/talks/design">On the design of text editors</a></td><td>Nicolas P. Rougier</td></tr>