WEBVTT captioned by jc, checked by sachac
NOTE Introduction
00:00:00.000 --> 00:00:04.320
Hello, everyone.
00:00:04.320 --> 00:00:07.280
This talk is on literate documentation
00:00:07.280 --> 00:00:10.320
with Emacs and org-mode.
00:00:10.320 --> 00:00:12.080
I'm going to take just a moment here
00:00:12.080 --> 00:00:14.279
to unpack what I just said.
00:00:14.280 --> 00:00:17.800
Emacs, as most of us probably already know,
00:00:17.800 --> 00:00:21.360
is a powerful text editor and list programming environment
00:00:21.360 --> 00:00:23.480
from the 1970s.
00:00:23.480 --> 00:00:25.800
Chances are, if you're attending this talk,
00:00:25.800 --> 00:00:28.819
you already know a bit about Emacs.
00:00:28.820 --> 00:00:32.640
org-mode is an Emacs major mode and authoring tool
00:00:32.640 --> 00:00:36.360
that helps you write documents in a plain text markup
00:00:36.360 --> 00:00:37.739
language called Org.
00:00:37.740 --> 00:00:40.200
These Org documents can be exported
00:00:40.200 --> 00:00:42.520
to a number of different document formats,
00:00:42.520 --> 00:00:48.520
like HTML, PDF, ODT, Markdown, and more.
00:00:48.520 --> 00:00:51.160
org-mode has a lot of features.
00:00:51.160 --> 00:00:54.240
It can be an outliner, a to-do list manager,
00:00:54.240 --> 00:00:57.760
an agenda, organizer, and much more.
NOTE Org Babel and literate programming
00:00:57.760 --> 00:00:59.600
Today, we're going to be demonstrating
00:00:59.600 --> 00:01:03.360
what I consider to be org-mode's killer feature called
00:01:03.360 --> 00:01:04.840
Org Babel.
00:01:04.840 --> 00:01:07.879
Babel allows you to take human language prose,
00:01:07.880 --> 00:01:11.400
computer language source code blocks, and their outputs
00:01:11.400 --> 00:01:13.840
and weave them together seamlessly
00:01:13.840 --> 00:01:16.160
to form a cohesive document.
00:01:16.160 --> 00:01:19.080
It is seriously cool.
00:01:19.080 --> 00:01:21.880
Literate documentation is a play on the term
00:01:21.880 --> 00:01:25.280
literate programming, popularized by Donald Knuth
00:01:25.280 --> 00:01:27.379
in the early 1980s.
00:01:27.380 --> 00:01:29.280
Knuth's literate programming idea
00:01:29.280 --> 00:01:31.920
was that computer programs could be
00:01:31.920 --> 00:01:34.880
expressed in a natural language and be
00:01:34.880 --> 00:01:38.800
human-readable documents rather than written exclusively
00:01:38.800 --> 00:01:40.799
for machines to read.
00:01:40.800 --> 00:01:43.000
In a traditional program, you might
00:01:43.000 --> 00:01:45.680
have a bunch of machine-readable source code
00:01:45.680 --> 00:01:48.560
and a handful of human-readable comments,
00:01:48.560 --> 00:01:51.600
which attempt to describe what the program is doing.
00:01:51.600 --> 00:01:54.360
Literate programming flips this on its head.
00:01:54.360 --> 00:01:56.680
A literate program is a document that
00:01:56.680 --> 00:02:01.160
describes how the program works with machine-readable source
00:02:01.160 --> 00:02:02.880
code blocks inside of it.
00:02:02.880 --> 00:02:04.800
These source code blocks are later
00:02:04.800 --> 00:02:08.440
tangled out of the document and submitted to the machine
00:02:08.440 --> 00:02:14.080
either to be compiled or interpreted and ultimately run.
NOTE This presentation
00:02:14.080 --> 00:02:15.600
Throughout this presentation, you'll
00:02:15.600 --> 00:02:19.400
see my browser window here on the left side of the screen.
00:02:19.400 --> 00:02:22.240
And on the right side, I've got a terminal session
00:02:22.240 --> 00:02:23.960
running tmux.
00:02:23.960 --> 00:02:28.039
This allows us to have a virtual terminal window connected
00:02:28.040 --> 00:02:35.040
to two separate Linux machines, one running Ubuntu Server 2204
00:02:35.040 --> 00:02:39.720
and another running Fedora Server 38.
00:02:39.720 --> 00:02:43.240
I've specifically chosen these two distributions for my demo
00:02:43.440 --> 00:02:46.720
because they are representative of the two dominant flavors
00:02:46.720 --> 00:02:49.880
of GNU Linux, Debian and RedHat.
00:02:49.880 --> 00:02:53.120
In both cases, these are bare-bones server additions
00:02:53.120 --> 00:02:55.440
with the stock packages installed.
00:02:55.440 --> 00:03:00.200
I've manually installed a few packages like Git, emacs-noex
00:03:00.200 --> 00:03:04.000
to get the terminal version of emacs, and tmux.
00:03:04.000 --> 00:03:06.000
But otherwise, these Linux installs
00:03:06.000 --> 00:03:08.719
are what you'd get right out of the box.
00:03:08.720 --> 00:03:12.480
For this demo, I've created a literate org-mode document
00:03:12.480 --> 00:03:16.360
that describes how to build GNU Emacs from its source code
00:03:16.360 --> 00:03:19.939
on both Debian and RedHat-based systems.
00:03:19.940 --> 00:03:22.920
While both operating systems are very similar,
00:03:22.920 --> 00:03:25.440
they differ substantially on which packages
00:03:25.440 --> 00:03:29.080
are installed out of the box, how optional packages are
00:03:29.080 --> 00:03:32.600
named, searched, and installed, and of course,
00:03:32.600 --> 00:03:34.240
the distributions have different names,
00:03:34.240 --> 00:03:36.800
like Ubuntu or Fedora.
00:03:36.800 --> 00:03:39.200
I chose building Emacs from source
00:03:39.200 --> 00:03:41.640
as a topic for this demonstration
00:03:41.640 --> 00:03:43.800
because while the process is largely
00:03:43.800 --> 00:03:46.880
the same on both RedHat and Debian,
00:03:46.880 --> 00:03:49.360
there are a lot of minor little differences
00:03:49.360 --> 00:03:52.680
that need to be accounted for, which really prohibits you
00:03:52.680 --> 00:03:57.120
from hard coding names of packages and package management
00:03:57.120 --> 00:04:01.200
tools and distributions into your document.
00:04:01.200 --> 00:04:05.320
I suppose you could create two versions of the same document,
00:04:05.320 --> 00:04:09.960
one specifically for RedHat and one specifically for Debian,
00:04:09.960 --> 00:04:13.280
but that would be really tedious to maintain.
00:04:13.280 --> 00:04:16.280
Like if, for example, you updated some prose
00:04:16.280 --> 00:04:18.720
in one document, you'd have to remember
00:04:18.720 --> 00:04:20.280
to do it in the other one too.
00:04:20.280 --> 00:04:22.920
And if you weren't careful, the two documents
00:04:22.920 --> 00:04:25.259
could drift out of sync.
00:04:25.260 --> 00:04:27.720
In this demo, I'll show you techniques
00:04:27.720 --> 00:04:30.960
for creating dynamic, literate documents that
00:04:30.960 --> 00:04:34.619
can change based on parameters and constants embedded
00:04:34.620 --> 00:04:38.439
into the non-exported regions of the document.
00:04:38.440 --> 00:04:41.800
I'll show how with a single org-mode source document,
00:04:41.800 --> 00:04:44.800
you can press a couple of keys to configure
00:04:44.800 --> 00:04:48.720
it to export a RedHat-specific version of my building
00:04:48.720 --> 00:04:53.479
Emacs from source essay or a Debian-specific version.
NOTE Getting started
00:04:53.480 --> 00:04:55.320
All right, let's get started.
00:04:55.320 --> 00:04:58.720
We'll begin by firing up a new terminal Emacs session
00:04:58.720 --> 00:05:00.639
on my Ubuntu machine.
00:05:00.640 --> 00:05:04.600
Now, I installed Emacs on this machine using apt-get.
00:05:04.600 --> 00:05:07.960
And doing that, you get version 27.1,
00:05:07.960 --> 00:05:10.640
which is, hey, only two major versions
00:05:10.640 --> 00:05:13.010
behind the current version of Emacs.
00:05:13.011 --> 00:05:15.000
This is another reason why I thought
00:05:15.000 --> 00:05:18.080
writing a guide on how to build Emacs from source code
00:05:18.080 --> 00:05:19.719
might be a good idea.
00:05:19.720 --> 00:05:22.720
You can get a much newer version of Emacs on Ubuntu
00:05:22.720 --> 00:05:25.800
if you install it via Snap, but, uh, Snaps.
00:05:25.800 --> 00:05:28.239
Don't get me started.
00:05:28.240 --> 00:05:30.921
Now, I wanted to use a completely vanilla
00:05:30.922 --> 00:05:34.619
terminal mode install of Emacs for this demonstration
00:05:34.620 --> 00:05:38.040
because my personal Emacs config has a ton of packages
00:05:38.040 --> 00:05:41.199
installed and is heavily modified.
00:05:41.200 --> 00:05:43.640
I want folks to be able to follow along
00:05:43.640 --> 00:05:47.579
with a bog-standard, out-of-the-box Emacs config.
00:05:47.580 --> 00:05:49.520
The Emacs config on this Ubuntu machine
00:05:49.520 --> 00:05:51.200
has just two settings.
00:05:51.200 --> 00:05:55.240
I require org-tempo because my fingers are hardwired
00:05:55.240 --> 00:05:58.719
to use some of the handy shortcuts that it provides.
00:05:58.720 --> 00:06:00.520
And I also turn off the menu bar
00:06:00.520 --> 00:06:03.139
because I just can't stand to look at it.
00:06:03.140 --> 00:06:07.040
Let's begin by opening a file called buildemacs.org,
00:06:07.040 --> 00:06:08.480
which will be the source code
00:06:08.480 --> 00:06:11.079
for our literate org-mode document.
00:06:11.080 --> 00:06:12.840
Now, in preparation for this talk,
00:06:12.840 --> 00:06:14.960
I've already written this document,
00:06:14.960 --> 00:06:17.979
and we'll take a look at the finished product
00:06:17.980 --> 00:06:19.160
here in a bit, but let's first take a look
00:06:19.160 --> 00:06:22.408
at how we might approach this task.
00:06:22.409 --> 00:06:24.400
We'll start at the top of the document
00:06:24.400 --> 00:06:27.119
by filling out some export keywords.
00:06:27.120 --> 00:06:30.520
These keywords are something that every backend exporter,
00:06:30.520 --> 00:06:35.000
be it LaTeX or plain text or ODT or whatever, understands,
00:06:35.000 --> 00:06:38.120
and they're essentially document metadata.
00:06:38.120 --> 00:06:42.120
As you can see, I'm typing `#+`
00:06:42.120 --> 00:06:43.760
followed by a couple characters
00:06:43.760 --> 00:06:45.880
and then `M-TAB` to auto-complete.
00:06:45.880 --> 00:06:50.360
If you hit #+ by itself and then M-TAB,
00:06:50.360 --> 00:06:53.119
you can see all the possible completions.
00:06:53.120 --> 00:06:55.779
And as you can see, there's a lot.
NOTE README
00:06:55.780 --> 00:06:58.520
The next thing we're gonna do is make a README section
00:06:58.520 --> 00:06:59.760
at the top of this document.
00:06:59.760 --> 00:07:02.240
This section is intended for folks
00:07:02.240 --> 00:07:04.280
who are looking at the org-mode document,
00:07:04.280 --> 00:07:06.679
trying to figure out what it's for.
00:07:06.680 --> 00:07:09.600
We don't want to actually export the section heading,
00:07:09.600 --> 00:07:13.859
so we're gonna tag it with the :noexport: tag.
00:07:13.860 --> 00:07:15.640
And then here, we just write something quick
00:07:15.640 --> 00:07:17.760
to let folks know that this document
00:07:17.760 --> 00:07:19.800
can potentially execute code
00:07:19.800 --> 00:07:23.499
and just a little something about what the document is for.
NOTE Writing a code block
00:07:23.500 --> 00:07:26.059
Okay, so now that we've written some text,
00:07:26.060 --> 00:07:29.599
let's try our hand at writing a code block.
00:07:29.600 --> 00:07:31.288
I'm getting pretty sick of looking at
00:07:31.289 --> 00:07:32.939
the default Emacs theme.
00:07:32.940 --> 00:07:35.440
All that blue and purple in the document
00:07:35.440 --> 00:07:37.879
makes it look bruised.
00:07:37.880 --> 00:07:40.320
Let's make an Emacs Lisp code block
00:07:40.320 --> 00:07:41.400
that switches the theme
00:07:41.400 --> 00:07:44.560
to one of my favorite built-in themes, Leuven.
00:07:44.560 --> 00:07:48.400
Leuven was created by my man, Fabrice Niessen,
00:07:48.400 --> 00:07:52.120
who I personally have learned a ton of org-mode stuff about
00:07:52.120 --> 00:07:54.039
just by studying his work.
00:07:54.040 --> 00:07:56.360
Now, if we cruise back up to the code block,
00:07:56.360 --> 00:07:58.840
we should be able to hit `C-c C-c`,
00:07:58.840 --> 00:08:00.379
and have it execute.
00:08:00.380 --> 00:08:03.880
And there you have it, a high-contrast color theme
00:08:03.880 --> 00:08:06.979
that was designed to look great in org-mode.
00:08:06.980 --> 00:08:08.080
So that's great and all,
00:08:08.080 --> 00:08:10.459
but there are a couple of things I don't like.
NOTE :results none
00:08:10.460 --> 00:08:13.599
First of all, we don't need to see a #+RESULTS block here,
00:08:13.600 --> 00:08:15.280
and that's because we're not really interested
00:08:15.280 --> 00:08:18.720
in what the Emacs Lisp function `load-theme` returns.
00:08:18.720 --> 00:08:22.200
I mean, it's great it returned t and all to indicate success,
00:08:22.200 --> 00:08:23.720
we just don't need to see it.
00:08:23.720 --> 00:08:26.560
We can slap a `:results none` header arg
00:08:26.560 --> 00:08:30.039
on the code block to keep things nice and clean.
00:08:30.040 --> 00:08:32.560
There are a lot of different header args,
00:08:32.560 --> 00:08:35.360
and I often confuse and misremember them.
00:08:35.360 --> 00:08:38.920
So I'll always refer back to the org-mode manual
00:08:38.920 --> 00:08:40.319
when working with them.
NOTE Confirmation
00:08:40.320 --> 00:08:42.160
The second thing I don't like is that
00:08:42.160 --> 00:08:45.999
when we hit C-c C-c to execute the block,
00:08:46.000 --> 00:08:49.600
Emacs prompted us if we really wanted to run the block.
00:08:49.600 --> 00:08:52.040
Emacs Lisp is Emacs' mother tongue,
00:08:52.040 --> 00:08:53.920
and I don't wanna be hassled when speaking
00:08:53.920 --> 00:08:55.379
my native language.
00:08:55.380 --> 00:08:57.520
There's a variable that controls this
00:08:57.520 --> 00:09:00.680
called `org-confirm-babel-evaluate`.
00:09:00.680 --> 00:09:03.960
And this can be either set to t or nil
00:09:03.960 --> 00:09:06.840
to either always confirm or never confirm.
00:09:06.840 --> 00:09:10.920
If however, you provided a lambda, an anonymous function,
00:09:10.920 --> 00:09:14.560
Org will call your function with the name of the language
00:09:14.560 --> 00:09:16.840
and the source block that it's about to run.
00:09:16.840 --> 00:09:19.080
And your function can make the decision
00:09:19.080 --> 00:09:24.200
about if Emacs should ask you for confirmation or not.
00:09:24.200 --> 00:09:27.840
What I'm doing here is setting `org-confirm-babel-evaluate`
00:09:27.840 --> 00:09:30.539
as a "file local variable".
00:09:30.540 --> 00:09:33.320
This means whenever the file is opened by Emacs,
00:09:33.320 --> 00:09:38.059
it'll set this variable to be a lambda that returns nil,
00:09:38.060 --> 00:09:42.859
meaning don't confirm, on Elisp code blocks.
00:09:42.860 --> 00:09:45.920
As you can see, the variable is currently set
00:09:45.920 --> 00:09:50.879
to its default value of t, meaning always confirm.
00:09:50.880 --> 00:09:53.640
Now if we save the buffer, exit Emacs,
00:09:53.640 --> 00:09:55.040
and pop back in again,
00:09:55.040 --> 00:10:00.120
`org-confirm-babel-evaluate` should be set how we like it.
00:10:00.120 --> 00:10:02.640
We were however prompted for confirmation
00:10:02.640 --> 00:10:04.400
on setting the file-local variable,
00:10:04.400 --> 00:10:06.280
which controls if we're prompted
00:10:06.280 --> 00:10:09.699
for Elisp source code block evaluation.
00:10:09.700 --> 00:10:12.679
I feel like there's a Yo Dawg joke here somewhere.
00:10:12.680 --> 00:10:15.240
When we were prompted, we hit the exclamation mark,
00:10:15.240 --> 00:10:18.400
which automatically marks this variable as being safe.
00:10:18.400 --> 00:10:21.520
So you won't be bothered the next time you open this file.
00:10:21.520 --> 00:10:26.760
This variable is called `safe-local-variable-values`
00:10:26.760 --> 00:10:29.560
and if we pop over to our .emacs file,
00:10:29.560 --> 00:10:32.520
you can see that Emacs' customize tooling
00:10:32.520 --> 00:10:36.959
helpfully updated this variable in our config file for us.
NOTE Running blocks automatically
00:10:36.960 --> 00:10:38.120
Now that's great and all,
00:10:38.120 --> 00:10:42.120
but I really don't like having to hit `C-c C-c`
00:10:42.120 --> 00:10:45.160
on that source block every time I open this document
00:10:45.160 --> 00:10:47.739
just to bring up the Leuven theme.
00:10:47.740 --> 00:10:50.520
Let's have this source block run automatically
00:10:50.520 --> 00:10:53.179
every time the document is opened.
00:10:53.180 --> 00:10:54.999
Now I know what you're thinking.
00:10:55.000 --> 00:10:57.640
Shouldn't you just put all of this configuration stuff
00:10:57.640 --> 00:11:01.159
in your .emacs file and keep it out of the document?
00:11:01.160 --> 00:11:04.760
Well, that's what I've done with my personal Emacs config,
00:11:04.760 --> 00:11:08.160
but we want this document to be able to be used by folks
00:11:08.160 --> 00:11:11.040
with a completely vanilla Emacs setup,
00:11:11.040 --> 00:11:13.440
or even a completely tricked out Emacs setup,
00:11:13.440 --> 00:11:16.059
so we can't assume anything.
00:11:16.060 --> 00:11:19.800
The idea is if the Emacs user who opens the document
00:11:19.800 --> 00:11:22.400
agrees to setting all of the variables
00:11:22.400 --> 00:11:24.359
and running all of the code within,
00:11:24.360 --> 00:11:26.560
they'll be able to export the document
00:11:26.560 --> 00:11:28.840
as well as run all of the code blocks inside of it
00:11:28.840 --> 00:11:30.799
just as we intended.
00:11:30.800 --> 00:11:33.880
And the differences in base Emacs configuration
00:11:33.880 --> 00:11:35.979
will be completely minimized.
00:11:35.980 --> 00:11:39.080
Now it's worth pointing out that the file-local variables
00:11:39.080 --> 00:11:43.023
we're setting here are local, in this case, buffer-local.
00:11:43.024 --> 00:11:45.280
The configuration we use in this document
00:11:45.280 --> 00:11:48.280
won't override someone's carefully constructed
00:11:48.280 --> 00:11:49.499
org-mode setup.
00:11:49.500 --> 00:11:50.800
The first thing we're gonna wanna do
00:11:51.000 --> 00:11:53.080
in order to make this block execute
00:11:53.080 --> 00:11:55.988
when the document is loaded is to give it a name.
00:11:55.989 --> 00:11:58.800
It's always a good idea to give every source block
00:11:58.800 --> 00:12:01.337
you create in your document a unique name,
00:12:01.338 --> 00:12:03.400
even if you don't refer to it elsewhere.
00:12:03.700 --> 00:12:06.960
I do this because when I'm debugging my documents,
00:12:07.160 --> 00:12:10.019
Emacs will prompt me about running a block.
00:12:10.020 --> 00:12:12.960
If the block has a name, Emacs mentions it,
00:12:12.960 --> 00:12:15.960
and I know there's a problem with the result caching
00:12:15.960 --> 00:12:17.840
or something with the "foo" block.
00:12:17.840 --> 00:12:20.280
But if the block doesn't have a name,
00:12:20.280 --> 00:12:22.160
it can be really hard to figure out
00:12:22.160 --> 00:12:24.579
which block Emacs is complaining about.
00:12:24.580 --> 00:12:27.459
So I always name my blocks.
00:12:27.460 --> 00:12:30.360
Now we're gonna add another file local variable,
00:12:30.360 --> 00:12:32.115
but this one is special.
00:12:32.116 --> 00:12:34.360
If your "variable"
00:12:34.360 --> 00:12:36.320
just happens to be named "eval",
00:12:36.320 --> 00:12:38.760
it means that Emacs should evaluate
00:12:38.760 --> 00:12:40.800
the Lisp expression that follows.
00:12:40.800 --> 00:12:43.240
Here we'll use the progn function
00:12:43.240 --> 00:12:46.040
to sequentially run two elisp functions
00:12:46.040 --> 00:12:48.760
and return the value of the last one executed.
00:12:48.760 --> 00:12:53.320
The first function is `org-babel-goto-named-source-block`,
00:12:53.320 --> 00:12:55.440
which jumps us to the startup block.
00:12:55.440 --> 00:12:59.280
The second one is `org-babel-execute-src-block`,
00:12:59.280 --> 00:13:02.092
which executes the current source block.
00:13:02.093 --> 00:13:03.630
That should get the job done.
00:13:03.631 --> 00:13:05.840
Now all we have to do is save the document,
00:13:05.840 --> 00:13:08.199
exit Emacs, jump back in,
00:13:08.200 --> 00:13:10.280
and once we've confirmed that we're willing
00:13:10.280 --> 00:13:14.239
to run the new "eval" line in our file local variables,
00:13:14.240 --> 00:13:15.859
we're good to go.
00:13:15.860 --> 00:13:18.480
Now if we want to add new configuration stuff
00:13:18.480 --> 00:13:21.839
to the document, we can just add it to the startup block
00:13:21.840 --> 00:13:24.880
and not have to muck about with confirmations
00:13:24.880 --> 00:13:28.679
or adding new file-local variables or whatever.
00:13:28.680 --> 00:13:31.960
And just like before, we'll let Emacs' customize system
00:13:31.960 --> 00:13:34.939
save this decision to our .emacs file.
00:13:34.940 --> 00:13:37.760
Now that all that business with confirmations,
00:13:37.760 --> 00:13:40.080
file-local variables, and the startup block
00:13:40.080 --> 00:13:41.120
are out of the way,
00:13:41.120 --> 00:13:44.120
we can get on with writing our introduction.
00:13:44.120 --> 00:13:47.880
We'll create a new top level headline called introduction
00:13:47.880 --> 00:13:51.440
and explain to the reader of the exported document
00:13:51.440 --> 00:13:52.600
what this is all about.
NOTE Export options
00:13:53.000 --> 00:13:55.640
Now as you can see, we've actually hard-coded
00:13:55.640 --> 00:13:58.280
the name of the Linux distro in our prose.
00:13:58.280 --> 00:14:00.880
I promised you a single document that could be
00:14:00.880 --> 00:14:03.720
for either RedHat or Debian distros,
00:14:03.720 --> 00:14:05.319
so we can't have this.
00:14:05.320 --> 00:14:08.840
Astute members in the audience have probably been uneasy
00:14:08.840 --> 00:14:11.280
ever since I hard coded the name "Debian"
00:14:11.280 --> 00:14:13.859
in the README section above.
00:14:13.860 --> 00:14:17.520
One way of solving this problem is by using exclude tags.
00:14:17.520 --> 00:14:21.960
Let's add the `#+EXCLUDE_TAGS` export keyword to our document.
00:14:21.960 --> 00:14:24.200
This keyword tells the exporter,
00:14:24.200 --> 00:14:27.959
"Hey, if you see a headline tagged with any of these tags,
00:14:27.960 --> 00:14:29.600
don't export it."
00:14:29.600 --> 00:14:33.559
By default, the tag `:noexport:` is excluded.
00:14:33.560 --> 00:14:36.480
And if you'll notice, we tagged our README section
00:14:36.480 --> 00:14:38.360
with that tag, so it doesn't show up
00:14:38.360 --> 00:14:40.339
in the exported document.
00:14:40.340 --> 00:14:42.280
We'll keep this tag in the list,
00:14:42.280 --> 00:14:47.080
but we'll also add the tag `:redhat:` as a tag to exclude.
00:14:47.080 --> 00:14:50.400
Now it's just a matter of creating two introduction
00:14:50.400 --> 00:14:53.960
sections, one for Debian, one for RedHat.
00:14:53.960 --> 00:14:56.520
And if you want the RedHat version of the document,
00:14:56.520 --> 00:14:59.200
you can just modify the `#+EXCLUDE_TAGS` line
00:14:59.200 --> 00:15:00.440
at the top of the document.
00:15:00.440 --> 00:15:02.339
Awesome, right?
00:15:02.340 --> 00:15:03.539
Right?
00:15:03.540 --> 00:15:05.544
OK, this is not that great.
00:15:05.545 --> 00:15:07.387
Well, it does work.
00:15:07.388 --> 00:15:10.081
And you can see if we export the document,
00:15:10.082 --> 00:15:12.840
we'll get something that only references Debian,
00:15:12.840 --> 00:15:15.188
and the `:noexport:` and `:redhat:`
00:15:15.189 --> 00:15:17.450
tagged headlines are omitted.
00:15:17.451 --> 00:15:19.319
This strategy would work great
00:15:19.320 --> 00:15:22.120
when the RedHat- and Debian-specific sections
00:15:22.120 --> 00:15:24.400
are substantially different, but that's not
00:15:24.400 --> 00:15:26.198
the case with the introduction.
00:15:26.199 --> 00:15:28.640
We definitely don't want to have to maintain
00:15:28.640 --> 00:15:30.824
two distinct introductions.
00:15:30.825 --> 00:15:34.080
I also noticed that the export tags are included
00:15:34.080 --> 00:15:36.519
in the exported document.
00:15:36.520 --> 00:15:38.720
That's a terrible default. We'll fix that,
00:15:38.720 --> 00:15:42.040
and we'll also ensure that my email address appears
00:15:42.040 --> 00:15:43.371
at the top of the document.
00:15:43.372 --> 00:15:45.440
Let's also take this opportunity to get rid
00:15:45.440 --> 00:15:47.354
of the table of contents.
00:15:47.355 --> 00:15:48.867
We don't need it.
00:15:48.868 --> 00:15:51.120
These are all export option settings
00:15:51.120 --> 00:15:53.800
and can be modified using the options keyword
00:15:53.800 --> 00:15:55.508
at the top of the doc.
00:15:55.509 --> 00:15:57.480
The manual is really your friend here,
00:15:57.480 --> 00:16:00.979
as there are a ton of export options.
00:16:00.980 --> 00:16:03.120
Now when we export the document again,
00:16:03.120 --> 00:16:05.699
it should look a lot better.
NOTE Substituting constants
00:16:05.700 --> 00:16:09.059
Now that we've cleaned up the look of the exported document,
00:16:09.060 --> 00:16:10.640
we'll take a look at a better way
00:16:10.640 --> 00:16:13.377
of solving the problem with the introduction.
00:16:13.378 --> 00:16:15.518
Thinking like a programmer for a moment,
00:16:15.519 --> 00:16:19.734
what I really want here is a way of specifying a constant.
00:16:19.735 --> 00:16:22.640
Rather than hard-coding the name "Debian" or "RedHat"
00:16:22.640 --> 00:16:24.569
or whatever into my document,
00:16:24.570 --> 00:16:28.234
I want to substitute that text with a symbolic constant,
00:16:28.235 --> 00:16:31.960
named something like "distro", that can dynamically change
00:16:31.960 --> 00:16:36.120
to "Debian" or "RedHat" or "Slackware" or whatever,
00:16:36.120 --> 00:16:38.689
depending on how the document is configured.
00:16:38.690 --> 00:16:41.640
In the past, I've come up with some pretty cumbersome ways
00:16:41.640 --> 00:16:44.640
of doing this, but eventually I stumbled upon the idea
00:16:44.640 --> 00:16:46.639
of using Org-mode properties
00:16:46.640 --> 00:16:49.409
as a way of storing these constants.
00:16:49.410 --> 00:16:53.059
Like it says in the docs, properties are key-value pairs
00:16:53.060 --> 00:16:55.169
that are associated with an entry
00:16:55.170 --> 00:16:58.379
and they live in a collapsible properties drawer.
00:16:58.380 --> 00:17:00.699
Let's do a bit of cleanup on our document
00:17:00.700 --> 00:17:02.600
and we'll put things into sections.
00:17:02.600 --> 00:17:14.000
We'll also add a section for document constants.
00:17:14.000 --> 00:17:19.560
And that's where we'll put the properties drawer
00:17:19.560 --> 00:17:25.739
with the "distro" property.
NOTE Getting the properties
00:17:25.740 --> 00:17:27.120
Now the question is,
00:17:27.120 --> 00:17:30.099
how do we reference these properties in the document?
00:17:30.100 --> 00:17:32.520
It turns out there's an Elisp function
00:17:32.520 --> 00:17:35.440
called `org-property-values`, which does what we want.
00:17:35.440 --> 00:17:38.840
If we run it and give it the name of our property,
00:17:38.840 --> 00:17:42.679
it returns a list with the string "Debian" in it.
00:17:42.680 --> 00:17:45.919
It's worth noting that this function is named
00:17:45.920 --> 00:17:49.989
`org-property-values` with values being plural.
00:17:49.990 --> 00:17:52.889
In org-mode, there could be a property named "foo"
00:17:52.890 --> 00:17:55.880
that has different values depending on which heading level
00:17:55.880 --> 00:17:57.609
you're at in the document,
00:17:57.610 --> 00:17:59.720
which is why the function returns a list.
00:17:59.720 --> 00:18:01.289
For our purposes though,
00:18:01.290 --> 00:18:04.480
we can just pull off the first value in the list with car
00:18:04.480 --> 00:18:05.680
and we're good to go.
00:18:05.680 --> 00:18:10.040
Now we'll make an Emacs Lisp list function called `get_prop`
00:18:10.040 --> 00:18:11.440
that does just that.
00:18:11.440 --> 00:18:14.160
This function takes one argument called `prop`,
00:18:14.160 --> 00:18:15.920
which is the property to look up
00:18:15.920 --> 00:18:18.519
and we'll give it a default value of "distro".
00:18:18.520 --> 00:18:20.960
So we can hit `C-c C-c` on the block
00:18:20.960 --> 00:18:23.149
to verify that it works.
00:18:23.150 --> 00:18:25.480
Now we just have to make an inline call
00:18:25.480 --> 00:18:26.920
to our `get_prop` function
00:18:26.920 --> 00:18:29.559
within the prose of the introduction section.
00:18:29.560 --> 00:18:31.659
And that should get us much closer
00:18:31.660 --> 00:18:35.619
to not hard coding distro names into our document.
00:18:35.620 --> 00:18:36.869
But before we do that,
00:18:36.870 --> 00:18:39.849
I need to clean up something that's been bothering me.
00:18:39.850 --> 00:18:42.909
By default, Emacs' `fill-column` variable
00:18:42.910 --> 00:18:44.989
is set to 70 characters,
00:18:44.990 --> 00:18:47.720
which may have been appropriate for 1970,
00:18:47.720 --> 00:18:51.319
but it's not great for 2023.
00:18:51.320 --> 00:18:53.920
We'll just cruise up to our startup block
00:18:53.920 --> 00:18:56.539
and set the variable there.
00:18:56.540 --> 00:18:58.800
We'll hit `C-c C-c`,
00:18:58.800 --> 00:19:02.289
and now our document will wrap at 100 columns,
00:19:02.290 --> 00:19:05.829
which for our purposes, I think is much more reasonable.
00:19:05.830 --> 00:19:09.320
The org-mode syntax for making an inline function call
00:19:09.320 --> 00:19:13.059
within the prose of your document is `call_`,
00:19:13.060 --> 00:19:15.000
followed by the name of the function,
00:19:15.000 --> 00:19:17.040
some optional header arguments,
00:19:17.040 --> 00:19:19.719
and then the function arguments.
00:19:19.720 --> 00:19:21.680
Now, when we export the document,
00:19:21.680 --> 00:19:26.049
we see that it's replaced our previously hard coded "Debian"
00:19:26.050 --> 00:19:29.409
with the value from the property. Huzzah!
00:19:29.410 --> 00:19:32.959
Now this is close to, but not exactly what we want.
00:19:32.960 --> 00:19:36.720
You can see that "Debian" is surrounded by a backtick
00:19:36.720 --> 00:19:37.800
and a single quote,
00:19:37.800 --> 00:19:40.320
which is the plain text exporters way
00:19:40.320 --> 00:19:43.029
of showing you verbatim text.
00:19:43.030 --> 00:19:45.600
In more sophisticated document backends,
00:19:45.600 --> 00:19:49.379
verbatim text is rendered in monospace.
00:19:49.380 --> 00:19:54.080
We can fix that by adding a ":results raw" header argument
00:19:54.080 --> 00:19:56.459
to the inline call.
00:19:56.460 --> 00:19:58.239
Now, when we export the document,
00:19:58.240 --> 00:20:00.289
it looks like what we'd expect.
00:20:00.290 --> 00:20:02.960
Now this is getting better, but it's still not great.
NOTE Macros
00:20:03.060 --> 00:20:05.840
The `call_` syntax is pretty cumbersome,
00:20:05.840 --> 00:20:08.560
and it's a lot to type every time we want
00:20:08.560 --> 00:20:09.849
to reference a constant
00:20:09.850 --> 00:20:13.219
and not have it be marked up as verbatim.
00:20:13.220 --> 00:20:17.169
This is where org-mode macros come to our rescue.
00:20:17.170 --> 00:20:19.469
If we head to the top of the document,
00:20:19.470 --> 00:20:21.480
we can create a couple of macros
00:20:21.480 --> 00:20:24.699
using the `#+MACRO:` export keyword.
00:20:24.700 --> 00:20:27.600
We'll define two macros with short names.
00:20:27.600 --> 00:20:30.240
One named "p" for "property",
00:20:30.240 --> 00:20:34.640
and the other one named "pr" for "property raw".
00:20:34.640 --> 00:20:39.160
Org-mode macros are expanded when the document is exported,
00:20:39.160 --> 00:20:41.640
and any positional arguments provided
00:20:41.640 --> 00:20:43.559
are referenced by their number.
00:20:43.860 --> 00:20:45.160
Now in the introduction,
00:20:45.160 --> 00:20:47.880
we can use the macro replacement syntax,
00:20:47.880 --> 00:20:49.800
which is three curly braces,
00:20:49.800 --> 00:20:52.760
followed by the macro name and any arguments,
00:20:52.760 --> 00:20:55.559
and then three ending curly braces.
00:20:55.560 --> 00:20:58.699
You see why I kept the macro name short.
00:20:58.700 --> 00:21:01.280
That's six curly braces in total we're typing,
00:21:01.280 --> 00:21:05.239
which still takes up a fair amount of space.
NOTE Properties in practice
00:21:05.240 --> 00:21:07.120
Now let's take a look at how we might use
00:21:07.120 --> 00:21:09.159
these properties in practice.
00:21:09.160 --> 00:21:10.920
Debian and RedHat distros differ
00:21:11.120 --> 00:21:12.929
on how they install packages.
00:21:12.930 --> 00:21:16.120
So we're gonna want an "install" property,
00:21:16.120 --> 00:21:24.579
where in Debian we use `sudo apt-get install -qq`,
00:21:24.580 --> 00:21:26.939
and on RedHat we'll use something like
00:21:26.940 --> 00:21:33.119
`sudo dnf install -y`.
00:21:33.120 --> 00:21:35.329
Now development packages
00:21:35.330 --> 00:21:38.049
also have a different naming convention.
00:21:38.050 --> 00:21:40.760
For example, the `ncurses` library on Debian
00:21:40.760 --> 00:21:43.520
is called `libncurses-dev`,
00:21:43.520 --> 00:21:48.259
where on RedHat it's called `ncurses-devel`.
00:21:48.260 --> 00:21:49.640
There are likely going to be
00:21:49.640 --> 00:21:52.120
many more little differences like this
00:21:52.120 --> 00:21:55.339
that we'll need to solve with properties.
00:21:55.340 --> 00:21:58.609
Now I already don't like where this is going.
00:21:58.610 --> 00:22:00.880
Switching between the Debian and RedHat
00:22:00.880 --> 00:22:03.160
versions of the document is gonna mean
00:22:03.160 --> 00:22:05.200
commenting and uncommenting out
00:22:05.200 --> 00:22:06.989
a bunch of different properties,
00:22:06.990 --> 00:22:09.019
which is pretty janky.
NOTE Using a prefix
00:22:09.020 --> 00:22:11.079
Luckily we can solve this problem
00:22:11.080 --> 00:22:14.439
with a little bit of Emacs Lisp.
00:22:14.440 --> 00:22:16.879
We'll start by modifying our properties,
00:22:16.880 --> 00:22:19.140
so their property names are prefixed
00:22:19.141 --> 00:22:23.119
with either `deb_` or `rh_`
00:22:23.120 --> 00:22:27.719
to signify which distro the property applies to.`
00:22:27.720 --> 00:22:31.160
We'll also create a single property called "prefix",
00:22:31.160 --> 00:22:34.589
which will be prepended to the property name
00:22:34.590 --> 00:22:36.529
by the `get_prop` function
00:22:36.530 --> 00:22:39.509
if the requested property is not found.
00:22:39.510 --> 00:22:42.200
This way, when we want to switch between
00:22:42.200 --> 00:22:45.349
the Debian and RedHat versions of the document,
00:22:45.350 --> 00:22:49.029
we just need to change the prefix property.
00:22:49.030 --> 00:22:51.379
So now we'll change the Elisp code.
00:22:51.380 --> 00:22:55.209
So we'll use a let expression with two bound variables.
00:22:55.210 --> 00:22:56.919
The first one is called ret,
00:22:56.920 --> 00:22:59.160
which determines if the initial call
00:22:59.160 --> 00:23:01.949
to `org-property-values` succeeds.
00:23:01.950 --> 00:23:04.039
The second variable is called prefix,
00:23:04.040 --> 00:23:06.219
which is the prefix property.
00:23:06.220 --> 00:23:09.120
If the first call to `org-property-values` succeeds,
00:23:09.120 --> 00:23:11.159
we return it as normal.
00:23:11.160 --> 00:23:14.249
If not, we concatenate the property value
00:23:14.250 --> 00:23:15.920
that was passed into the function
00:23:15.920 --> 00:23:18.969
onto the prefix and try again.
00:23:18.970 --> 00:23:23.800
Now when we call the `get_prop` function with "distro"
00:23:23.800 --> 00:23:26.360
as the prop argument, it won't be found.
00:23:26.360 --> 00:23:29.689
So the code will slap our prefix tag on the front,
00:23:29.690 --> 00:23:33.249
making it something like `rh_distro`,
00:23:33.250 --> 00:23:35.329
and it will be found and returned.
00:23:35.330 --> 00:23:39.999
Let's see that in action.
00:23:40.000 --> 00:23:42.009
All right, now we're talking.
NOTE Switching distributions
00:23:42.010 --> 00:23:44.419
This setup is starting to look pretty good,
00:23:44.420 --> 00:23:46.040
but there are just a few things
00:23:46.040 --> 00:23:48.659
that I want to add before we move on.
00:23:48.660 --> 00:23:51.240
First of all, I think the document should have a subtitle,
00:23:51.240 --> 00:23:53.960
something that tells you if you're looking at the RedHat
00:23:53.960 --> 00:23:56.160
or the Debian version of the document.
00:23:56.160 --> 00:23:57.880
I also think it would be great
00:23:57.880 --> 00:24:00.520
if the file name of the exported document
00:24:00.520 --> 00:24:04.999
reflected the distribution as well.
00:24:05.000 --> 00:24:08.040
I also want to add a quick Debian only section
00:24:08.040 --> 00:24:11.799
to the document that explains how it got its name.
00:24:11.800 --> 00:24:17.739
Now let's see what happens when we export the document.
00:24:17.740 --> 00:24:20.439
This did not work out as we wanted.
00:24:20.440 --> 00:24:23.360
As you can see, the macro we used in the subtitles
00:24:23.360 --> 00:24:24.959
didn't expand properly,
00:24:24.960 --> 00:24:28.640
and as a result, our subtitle didn't render right.
00:24:28.640 --> 00:24:30.640
Sadly, you can't use macros
00:24:30.640 --> 00:24:32.909
or inline function calls everywhere.
00:24:32.910 --> 00:24:34.680
And one place where they don't work
00:24:34.680 --> 00:24:37.189
is inside of certain export keywords.
00:24:37.190 --> 00:24:43.219
So we're gonna have to hard code them here.
00:24:43.220 --> 00:24:46.320
Another mistake that we made is we forgot to update
00:24:46.320 --> 00:24:49.099
the `#+EXCLUDE_TAGS` export keyword,
00:24:49.100 --> 00:24:51.439
because with the RedHat version of the document,
00:24:51.440 --> 00:24:54.509
we want to exclude the Debian tag.
00:24:54.510 --> 00:24:56.400
Now when we export the document,
00:24:56.400 --> 00:24:57.839
everything should be correct.
00:24:57.840 --> 00:25:00.619
The word RedHat should appear in the subtitle,
00:25:00.620 --> 00:25:04.799
and the Debian fun fact section should not be present.
00:25:04.800 --> 00:25:06.960
Now we just need to add a section to the README
00:25:06.960 --> 00:25:09.280
that explains the steps you need to take
00:25:09.280 --> 00:25:11.000
in order to switch the document
00:25:11.000 --> 00:25:12.759
from RedHat to Debian.
00:25:12.760 --> 00:25:14.000
Okay, let's see here.
00:25:14.000 --> 00:25:18.309
We have to change `#+SUBTITLE`, change the `#+EXCLUDE_TAGS`,
00:25:18.310 --> 00:25:20.429
change the `#+EXPORT_FILE_NAME`,
00:25:20.430 --> 00:25:23.289
and change the `prefix` property.
00:25:23.290 --> 00:25:26.289
This is OK, but it's not great.
00:25:26.290 --> 00:25:29.429
Emacs Lisp can once again come to our rescue.
00:25:29.430 --> 00:25:32.080
What we'll do is make an Elisp code block
00:25:32.080 --> 00:25:35.480
that will invite the user to hit `C-c C-c` on.
00:25:35.480 --> 00:25:39.520
And the code block will essentially make all these changes
00:25:39.520 --> 00:25:40.919
in the document for them.
00:25:40.920 --> 00:25:43.280
This code block, which we'll call `switch_distro`,
00:25:43.280 --> 00:25:45.680
takes one argument called `os`,
00:25:45.680 --> 00:25:48.689
which by default is set to "Debian".
00:25:48.690 --> 00:25:50.760
It starts out with a let expression
00:25:50.760 --> 00:25:53.029
that defines three bound variables.
00:25:53.030 --> 00:25:55.969
The `debian` variable is a boolean that is true
00:25:55.970 --> 00:25:58.699
if the distro we're switching to is Debian.
00:25:58.700 --> 00:26:00.360
Based on the value of this boolean,
00:26:00.360 --> 00:26:04.169
we'll set the `noexport` and `prefix` variables accordingly.
00:26:04.170 --> 00:26:06.720
The `save-excursion` block tells Emacs
00:26:06.720 --> 00:26:09.199
that we're going to be moving around in the document
00:26:09.200 --> 00:26:11.680
and to remember to put our point back where we started
00:26:11.680 --> 00:26:13.429
when the block finishes.
00:26:13.430 --> 00:26:16.249
After that, we essentially go to the top of the document
00:26:16.250 --> 00:26:19.839
and search and replace the subtitle, `exclude_tags`,
00:26:19.840 --> 00:26:22.499
`export_file_name`, and the `prefix`.
00:26:22.500 --> 00:26:23.389
Pretty cool.
00:26:23.390 --> 00:26:25.029
Let's see this in action.
00:26:25.030 --> 00:26:27.869
If we hit `C-c C-c` on this block,
00:26:27.870 --> 00:26:30.480
we should see the document automatically change a bit.
00:26:30.480 --> 00:26:32.320
And now when we export it,
00:26:32.320 --> 00:26:36.089
we get the Debian version of the doc.
00:26:36.090 --> 00:26:37.629
If we want to change it back,
00:26:37.630 --> 00:26:39.880
we can just head back over to the code block
00:26:39.880 --> 00:26:43.149
and change the default value for the os variable
00:26:43.150 --> 00:26:47.619
from "Debian" to "RedHat" and hit `C-c C-c` again.
00:26:47.620 --> 00:26:49.919
And now when we re-export,
00:26:49.920 --> 00:26:52.909
we're looking at the RedHat version of the document.
00:26:52.910 --> 00:26:55.859
Just as an aside, if you ever thought to yourself,
00:26:55.860 --> 00:26:58.159
"I should learn Emacs Lisp someday"
00:26:58.160 --> 00:27:01.289
Make it someday soon. You'll be happy you did.
00:27:01.290 --> 00:27:03.769
Not only is it a fun programming language,
00:27:03.770 --> 00:27:06.679
but you can do powerful things with it in Emacs,
00:27:06.680 --> 00:27:12.149
which I hope is a point that folks take away from this talk.
00:27:12.150 --> 00:27:14.149
All right, that was a lot.
NOTE A tour
00:27:14.150 --> 00:27:16.840
Now that we've spent the past 20 minutes or so
00:27:16.840 --> 00:27:19.409
digging into some of the tips and tricks I used
00:27:19.410 --> 00:27:22.879
when creating my build Emacs from source document,
00:27:22.880 --> 00:27:26.279
we'll say goodbye to this document we've been working on
00:27:26.280 --> 00:27:27.480
and we'll start a tour
00:27:27.480 --> 00:27:29.960
of the actual literate document I wrote.
00:27:29.960 --> 00:27:33.080
A document that I'll demonstrate actually downloading
00:27:33.080 --> 00:27:35.659
and building a new Emacs when I export it
00:27:35.660 --> 00:27:38.959
on both my Ubuntu and RedHat virtual machines.
00:27:38.960 --> 00:27:41.689
I'll also show you how org-mode can generate
00:27:41.690 --> 00:27:44.519
slick professional looking PDF files
00:27:44.520 --> 00:27:46.579
through the power of LaTeX.
00:27:46.580 --> 00:27:49.619
We'll start here at the orgdemo2 directory,
00:27:49.620 --> 00:27:51.229
which I've cloned from GitLab.
00:27:51.230 --> 00:27:55.599
This repository has all the source materials for this talk.
00:27:55.600 --> 00:27:59.040
The buildemacs.org file is where most of the good stuff is.
00:27:59.040 --> 00:28:01.479
So that's where we'll start.
00:28:01.480 --> 00:28:03.360
There's a lot of file-local variables
00:28:03.360 --> 00:28:04.800
that we'll need to confirm.
00:28:04.800 --> 00:28:06.439
So we'll do that too.
00:28:06.440 --> 00:28:07.560
So the first thing we're gonna do
00:28:07.560 --> 00:28:10.080
is hit `C-u TAB` twice,
00:28:10.780 --> 00:28:13.360
which will give us a top-level overview
00:28:13.360 --> 00:28:15.139
of all of our headings.
00:28:15.140 --> 00:28:16.600
As you can see, we've got a lot
00:28:16.600 --> 00:28:20.119
of the same familiar export keywords we had before.
00:28:20.120 --> 00:28:23.099
`#+TITLE`, `#+SUBTITLE`, `#+AUTHOR`, `#+EMAIL`,
00:28:23.100 --> 00:28:25.359
plus a few we haven't seen before.
00:28:25.360 --> 00:28:27.720
For example, I've squirreled away
00:28:27.720 --> 00:28:30.619
a lot of the `#+LATEX_HEADER` export keywords
00:28:30.620 --> 00:28:33.539
in this file called latex.setup.
00:28:33.540 --> 00:28:36.539
And I did this just so they don't clutter up the document.
00:28:36.540 --> 00:28:38.320
Much of the LaTeX magic
00:28:38.320 --> 00:28:40.909
that makes the exported document look good
00:28:40.910 --> 00:28:42.589
is in these headers.
00:28:42.590 --> 00:28:45.119
LaTeX commands begin with a backslash.
00:28:45.120 --> 00:28:49.679
And a common one we use a lot here is `\usepackage`.
00:28:49.680 --> 00:28:52.200
This lets us bring in packages like geometry,
00:28:52.200 --> 00:28:56.539
svg for the cool SeaGL SVG logo,
00:28:56.540 --> 00:28:58.440
`fancyhdr` and fancy verbatim [`fancyvrb`]
00:28:58.440 --> 00:29:00.689
to keep things looking pretty fancy.
00:29:00.690 --> 00:29:03.200
Using a scalable vector image format
00:29:03.200 --> 00:29:05.720
makes it possible for us to do really cool things
00:29:05.720 --> 00:29:09.269
like having a scaled-down version of the SeaGL logo
00:29:09.270 --> 00:29:11.979
appear in the fancy footer below.
00:29:11.980 --> 00:29:15.360
I also include some macros in a separate file
00:29:15.360 --> 00:29:18.120
just to help keep things tidy in the main document.
00:29:18.120 --> 00:29:20.600
Here I've got the familiar macros
00:29:20.600 --> 00:29:23.399
we've seen before for `get_prop`.
00:29:23.400 --> 00:29:25.520
But here I use different permutations
00:29:25.520 --> 00:29:28.160
depending on if I want results raw
00:29:28.160 --> 00:29:31.869
or raw verbatim or just verbatim.
00:29:31.870 --> 00:29:35.069
I also have a couple of macros here at the top of the file
00:29:35.070 --> 00:29:40.280
that are for pulling strings out of results blocks
00:29:40.280 --> 00:29:41.920
and then trimming them
00:29:41.920 --> 00:29:44.719
so there's no white space on either side.
00:29:44.720 --> 00:29:46.440
Like in the version of the document
00:29:46.440 --> 00:29:48.429
we worked on at the start of this talk,
00:29:48.430 --> 00:29:51.079
the real document also has a README section
00:29:51.080 --> 00:29:53.469
marked with the `:noexport:` tag.
00:29:53.470 --> 00:29:55.400
It also has a section about choosing
00:29:55.400 --> 00:29:57.909
which version of the document to export
00:29:57.910 --> 00:30:00.599
and a code block on how to switch between them.
00:30:00.600 --> 00:30:03.000
It's also got a lot of helpful information in it
00:30:03.000 --> 00:30:05.819
like what OS and Emacs versions
00:30:05.820 --> 00:30:09.559
the document has been tested to "run" on,
00:30:09.560 --> 00:30:12.329
a section on the LaTeX prerequisites
00:30:12.330 --> 00:30:14.080
and the section on executing
00:30:14.080 --> 00:30:16.199
the document's various code blocks.
NOTE TeX and LaTeX
00:30:16.200 --> 00:30:19.199
The latter two sections we'll take a look at now.
00:30:19.200 --> 00:30:22.579
Out of the box on Fedora and Ubuntu server distros,
00:30:22.580 --> 00:30:24.709
the TeX typesetting system
00:30:24.710 --> 00:30:27.669
also by noted computer scientist Donald Knuth
00:30:27.670 --> 00:30:28.859
is not installed.
00:30:28.860 --> 00:30:31.719
So we'll need to install some packages.
00:30:31.720 --> 00:30:34.449
Starting out we'll need the `texlive` package
00:30:34.450 --> 00:30:37.459
which gets you a fully featured TeX setup.
00:30:37.460 --> 00:30:39.289
This also gets you LaTeX
00:30:39.290 --> 00:30:42.789
which can be viewed as a distribution of TeX macros.
00:30:42.790 --> 00:30:44.899
You'll also need XeTeX.
00:30:44.900 --> 00:30:49.779
This gets you Unicode support and lets you use modern fonts.
00:30:49.780 --> 00:30:52.809
We'll also want to install pdfTeX.
00:30:52.810 --> 00:30:57.209
This gets us the ability to generate PDFs from TeX sources.
00:30:57.210 --> 00:31:01.299
And finally, we're gonna need to install latexmk
00:31:01.300 --> 00:31:02.400
which is a Perl script
00:31:02.400 --> 00:31:05.139
that knows how to run LaTeX multiple times
00:31:05.140 --> 00:31:09.249
in order to properly deal with intra-document links.
NOTE Other prerequisites
00:31:09.250 --> 00:31:11.069
But wait, there's more.
00:31:11.070 --> 00:31:12.960
We're also gonna need Inkscape
00:31:12.960 --> 00:31:15.520
to rasterize our SeaGL vector logo
00:31:15.520 --> 00:31:17.339
at different resolutions.
00:31:17.340 --> 00:31:20.360
And we're gonna need the JetBrains Mono font
00:31:20.360 --> 00:31:23.059
to make our source code look snazzy.
00:31:23.060 --> 00:31:24.680
We'll also need the Inter font
00:31:24.680 --> 00:31:28.039
to make our prose look snazzy as well.
00:31:28.040 --> 00:31:31.299
I've helpfully added a bash code block in the README
00:31:31.300 --> 00:31:35.739
that you can hit C-c C-c on to install.
00:31:35.740 --> 00:31:38.520
This really does lock up Emacs for a few minutes
00:31:38.520 --> 00:31:40.329
and it's sort of annoying.
00:31:40.330 --> 00:31:43.040
When we export the document and turn off all caching
00:31:43.040 --> 00:31:45.599
and it actually builds Emacs for real,
00:31:45.600 --> 00:31:48.769
Emacs can be locked up for tens of minutes.
00:31:48.770 --> 00:31:50.880
There's a package called ob-async
00:31:50.880 --> 00:31:54.259
that I've been meaning to check out that might help here.
00:31:54.260 --> 00:31:55.760
But since I wanted this document
00:31:55.760 --> 00:31:58.000
to work on bog-standard Emacs setups,
00:31:58.000 --> 00:32:00.059
I didn't get around to it.
NOTE Caching
00:32:00.060 --> 00:32:03.139
Before we get into talking about running the document,
00:32:03.140 --> 00:32:06.449
let's talk briefly about results caching.
00:32:06.450 --> 00:32:08.839
We'll take a look at the section of the document
00:32:08.840 --> 00:32:13.139
where we talk about Git tags for an example.
00:32:13.140 --> 00:32:15.760
The `num_tags` bash code block determines
00:32:15.760 --> 00:32:19.039
how many tags there are in the Emacs Git repo.
00:32:19.040 --> 00:32:21.600
And when I hit C-c C-c on that block
00:32:21.600 --> 00:32:25.059
several days ago, when I was first creating the document,
00:32:25.060 --> 00:32:28.019
that number was 183.
00:32:28.020 --> 00:32:32.169
That result has remained cached in the document since then.
00:32:32.170 --> 00:32:34.899
And you can see a snippet of the SHA1 hash
00:32:34.900 --> 00:32:38.389
of the contents of the source block below.
00:32:38.390 --> 00:32:40.800
You can see where I referenced the result
00:32:40.800 --> 00:32:44.960
using the `sr` for string raw macro in the prose below,
00:32:44.960 --> 00:32:50.509
and how it gets rendered in the exported PDF document.
00:32:50.510 --> 00:32:52.880
All the source blocks in the exported sections
00:32:52.880 --> 00:32:56.559
of the document include cached results like this.
00:32:56.560 --> 00:33:01.389
If I export the document now, it won't take that long to do
00:33:01.390 --> 00:33:03.800
because while there are a ton of code blocks
00:33:03.800 --> 00:33:09.069
in the exported sections, they're all cached.
00:33:09.070 --> 00:33:11.560
Now let's get back to the section of the README
00:33:11.560 --> 00:33:14.909
that explains how to execute the code in the document.
00:33:14.910 --> 00:33:17.640
Here I explain that if you want to build Emacs
00:33:17.640 --> 00:33:20.189
on your computer using this document,
00:33:20.190 --> 00:33:22.019
you've got a couple of options.
00:33:22.020 --> 00:33:25.649
The first option is to manually invalidate the caches
00:33:25.650 --> 00:33:28.960
and take C-c C-c on every code block
00:33:28.960 --> 00:33:30.959
in the main document.
00:33:30.960 --> 00:33:33.160
This lets you supervise the entire process,
00:33:33.160 --> 00:33:36.939
and it also creates new cached result blocks,
00:33:36.940 --> 00:33:39.239
but it's time consuming.
00:33:39.240 --> 00:33:43.440
There is also an internal link to the main document here,
00:33:43.440 --> 00:33:47.379
and you can jump to it with C-c C-o.
00:33:47.380 --> 00:33:50.040
This is one of those intra-document links
00:33:50.040 --> 00:33:52.999
that is really tricky to get right with LaTeX,
00:33:53.000 --> 00:33:56.989
and is why we opted to use the latexmk Perl script
00:33:56.990 --> 00:34:00.049
to build the PDF version of the document.
00:34:00.050 --> 00:34:01.920
I'm mentioning it specifically here
00:34:01.920 --> 00:34:05.629
because it took me forever to figure this out.
00:34:05.630 --> 00:34:07.269
The second option you've got
00:34:07.270 --> 00:34:09.280
is to change the default header arg
00:34:09.280 --> 00:34:13.739
from `:cache yes` to `:cache no` at the top of the document.
00:34:13.740 --> 00:34:16.269
If we cruise up to the top of the document,
00:34:16.270 --> 00:34:19.129
you can see that this header argument property
00:34:19.130 --> 00:34:22.440
basically says that unless a code block
00:34:22.440 --> 00:34:24.160
explicitly says otherwise,
00:34:24.160 --> 00:34:27.118
it's by default supposed to be cached.
00:34:27.119 --> 00:34:29.440
That's how we were able to export the document
00:34:29.440 --> 00:34:31.558
before so quickly.
00:34:31.559 --> 00:34:34.819
The code block named `no_cache_no_confirm`
00:34:34.820 --> 00:34:38.618
uses the `save-excursion` and regex replace trick
00:34:38.619 --> 00:34:40.348
that I demonstrated earlier
00:34:40.349 --> 00:34:42.819
to munch the default cache header arg
00:34:42.820 --> 00:34:45.409
from "cache yes" to "cache no".
00:34:45.410 --> 00:34:49.299
And it also turns off confirmations on bash code blocks.
00:34:49.300 --> 00:34:51.939
Let's do that now.
00:34:51.940 --> 00:34:54.559
Now we'll export the document to PDF,
00:34:54.560 --> 00:34:57.439
which will ignore the cache result blocks
00:34:57.440 --> 00:35:00.319
and clone the Git repository on Savannah,
00:35:00.320 --> 00:35:01.760
create a branch that points
00:35:01.760 --> 00:35:05.459
to the most recently tagged version of Emacs 29,
00:35:05.460 --> 00:35:07.759
run configure a handful of times,
00:35:07.760 --> 00:35:10.720
installing packages to fix missing dependencies
00:35:10.720 --> 00:35:12.399
along the way,
00:35:12.400 --> 00:35:16.099
build Emacs, install Emacs in our home directory,
00:35:16.100 --> 00:35:19.339
verify that it has successfully built a binary,
00:35:19.340 --> 00:35:22.549
run it in batch mode with some sample Elisp
00:35:22.550 --> 00:35:26.869
and show the file sizes and dates of the generated files.
00:35:26.870 --> 00:35:28.339
This is gonna take a while.
00:35:28.340 --> 00:35:32.829
And while it's running, we'll pop over to our Fedora box.
00:35:32.830 --> 00:35:34.680
All right, now we'll fire up Emacs,
00:35:34.680 --> 00:35:39.280
hit `C-c C-c` on the `configure_document` code block
00:35:39.280 --> 00:35:41.849
to configure the document for RedHat
00:35:41.850 --> 00:35:45.709
since Fedora here is a RedHat based distro.
00:35:45.710 --> 00:35:47.040
Then what we'll do is we'll pop down
00:35:47.040 --> 00:35:49.589
and hit `C-c C-c`
00:35:49.590 --> 00:35:53.699
on the `rh_install_latex` code block
00:35:53.700 --> 00:35:56.229
to install the LaTeX prerequisites
00:35:56.230 --> 00:35:58.459
for this Fedora virtual machine.
00:35:58.460 --> 00:36:02.589
Finally, we'll execute the `no_cache_no_confirm` block
00:36:02.590 --> 00:36:05.049
and then kick off the export.
00:36:05.050 --> 00:36:07.280
Then we'll go and check back on what's happening
00:36:07.280 --> 00:36:09.529
on the Ubuntu box.
00:36:09.530 --> 00:36:11.240
Ooh, top looks pretty quiet.
00:36:11.240 --> 00:36:14.039
I think the export is complete.
00:36:14.040 --> 00:36:17.559
Ooh, those are the words I love to see in the status area,
00:36:17.560 --> 00:36:20.609
PDF file produced!
NOTE Looking at the PDF
00:36:20.610 --> 00:36:22.600
Now I can't use my web browser
00:36:22.600 --> 00:36:24.959
to take a look at this PDF file
00:36:24.960 --> 00:36:27.080
because I haven't set up a web server
00:36:27.080 --> 00:36:30.759
or anything like that on the Ubuntu virtual machine.
00:36:30.760 --> 00:36:34.439
I can, however, use TRAMP with the ssh method
00:36:34.440 --> 00:36:36.560
to poke around on the ubuntu host
00:36:36.560 --> 00:36:39.120
on my personal version of Emacs.
00:36:39.120 --> 00:36:40.939
So let's do that.
00:36:40.940 --> 00:36:44.809
Okay, so now if we go into the source directory
00:36:44.810 --> 00:36:48.039
and then we hop into the orgdemo2 directory
00:36:48.040 --> 00:36:51.619
and then we look at the deb version of the PDF,
00:36:51.620 --> 00:36:54.149
there she blows.
00:36:54.150 --> 00:36:58.160
Now, if we go down to the Building Emacs section,
00:36:58.160 --> 00:37:00.129
we can see that it built.
00:37:00.130 --> 00:37:03.839
And if we look in the bin directory,
00:37:03.840 --> 00:37:06.779
we can see that at 17:01,
00:37:06.780 --> 00:37:11.379
that's when all of those files got created.
00:37:11.380 --> 00:37:15.589
Also the file creation date on the PDF is 17:01.
00:37:15.590 --> 00:37:18.720
So all of this code executed roughly the same time
00:37:18.720 --> 00:37:21.159
the PDF was created.
00:37:21.160 --> 00:37:25.339
All right, so now let's head back over to the Fedora box
00:37:25.340 --> 00:37:27.920
and then we'll navigate to the source directory,
00:37:27.920 --> 00:37:30.119
the orgdemo2 directory,
00:37:30.120 --> 00:37:35.719
and there is our RedHat version of the built Emacs PDF.
00:37:35.720 --> 00:37:38.219
And Bob's your uncle.
00:37:38.220 --> 00:37:42.549
And you can see it is the RedHat version of the document
00:37:42.550 --> 00:37:44.939
because this is a RedHat box.
00:37:44.940 --> 00:37:51.639
And if we go over to the What did we install? section,
00:37:51.640 --> 00:37:56.049
you can see that these binaries were built at 17:35.
00:37:56.050 --> 00:37:58.699
And now if we pop open dired
00:37:58.700 --> 00:38:00.739
and we take a look at the PDF,
00:38:00.740 --> 00:38:07.329
we can see it also was created at 17:35.
00:38:07.330 --> 00:38:10.039
All right, in the couple minutes remaining,
00:38:10.040 --> 00:38:11.640
I thought it would be a good idea
00:38:11.640 --> 00:38:15.739
just to take a look at the document
00:38:15.740 --> 00:38:19.000
and maybe just go through some of what it actually does
00:38:19.000 --> 00:38:22.579
in explaining how to build Emacs from source.
00:38:22.580 --> 00:38:27.139
We'll look at the RedHat version since we're here.
00:38:27.140 --> 00:38:28.160
And the first thing you do is
00:38:28.160 --> 00:38:31.539
you have to get access to the source code.
00:38:31.540 --> 00:38:32.840
And before you can do anything,
00:38:32.840 --> 00:38:35.419
this is a RedHat-specific section
00:38:35.420 --> 00:38:38.299
where you need to install some development tools.
00:38:38.300 --> 00:38:41.539
And this development tools group actually has Git.
00:38:41.540 --> 00:38:44.640
Now I installed Git earlier, but if you didn't do that,
00:38:44.640 --> 00:38:46.939
that would be the first thing that you need to do.
00:38:46.940 --> 00:38:50.039
We create a source directory, we cd into it,
00:38:50.040 --> 00:38:53.059
we clone the repo from Savannah.
00:38:53.060 --> 00:38:56.059
And then we start to take a look at some of the Git tags.
00:38:56.060 --> 00:38:58.560
And we showed this before where we check out
00:38:58.560 --> 00:39:00.369
how many different tags there are.
00:39:00.370 --> 00:39:02.400
And then we run this kind of funky Git command
00:39:02.400 --> 00:39:06.040
to sort of list all the tags that begin with 'emacs-29',
00:39:06.040 --> 00:39:08.759
and we sort them by when they were tagged.
00:39:08.760 --> 00:39:12.400
So we can see that Emacs 29.1.pretest
00:39:12.400 --> 00:39:14.439
is the most recent version.
00:39:14.440 --> 00:39:15.880
So that's the one we grab
00:39:15.880 --> 00:39:18.659
and that's the one we decide to build.
00:39:18.660 --> 00:39:22.779
And then we create a branch that is based on this tag.
00:39:22.780 --> 00:39:27.479
And this is dynamically generated based on what we saw here.
00:39:27.480 --> 00:39:29.439
So that's what we use here.
NOTE Errors
00:39:29.440 --> 00:39:32.920
In this case, we're piping standard error
00:39:32.920 --> 00:39:35.099
to where standard out goes.
00:39:35.100 --> 00:39:36.069
That's another trick.
00:39:36.070 --> 00:39:39.559
If you want to actually see an error get created,
00:39:39.560 --> 00:39:44.119
org-mode will capture any errors that code blocks produce,
00:39:44.120 --> 00:39:46.819
and it will show you the error message in a buffer.
00:39:46.820 --> 00:39:49.240
So if you actually wanna show what it looks like
00:39:49.240 --> 00:39:53.059
when something errors out, this is the trick you have to use.
00:39:53.060 --> 00:39:56.200
And then what we do is we look for a configure script
00:39:56.200 --> 00:39:57.419
and there isn't one.
00:39:57.420 --> 00:39:58.599
And then we realize,
00:39:58.600 --> 00:40:00.909
uh-oh, we're gonna have to deal with autotools.
00:40:00.910 --> 00:40:05.560
So, you know, we run the autogen script and it complains
00:40:05.560 --> 00:40:08.679
because we're missing some prerequisites.
00:40:08.680 --> 00:40:11.349
So we have to install autoconf,
00:40:11.350 --> 00:40:13.019
and then we run it again,
00:40:13.020 --> 00:40:15.959
and finally it generates a configure script.
00:40:15.960 --> 00:40:19.019
And this is another case where I pull this number
00:40:19.020 --> 00:40:21.979
right here into the actual prose.
00:40:21.980 --> 00:40:24.840
And I can see it's, oh, it's, you know, this how many bytes.
00:40:24.840 --> 00:40:26.800
When was the last time you wrote a shell script
00:40:26.800 --> 00:40:29.579
that was this many bytes long?
00:40:29.580 --> 00:40:31.320
And then we configure the build process.
00:40:31.320 --> 00:40:33.760
And, you know, it's not gonna work right away
00:40:33.760 --> 00:40:36.699
because we don't have GNU Texinfo installed.
00:40:36.700 --> 00:40:41.439
So we gotta do that, which we do with `dnf install` here.
00:40:41.440 --> 00:40:44.320
And then there's this section that is either RedHat-
00:40:44.320 --> 00:40:48.919
or Debian-specific that talks about, like,
00:40:48.920 --> 00:40:51.240
if you don't know the name of a package
00:40:51.240 --> 00:40:55.160
that contains a given file name, how do you query it?
00:40:55.160 --> 00:40:59.519
And in the RedHat world, you use `dnf provides makeinfo`.
00:40:59.520 --> 00:41:02.289
In the Debian world, you do something entirely different.
00:41:02.290 --> 00:41:06.639
And then we have to install the `ncurses` binary.
00:41:06.640 --> 00:41:10.299
And finally we get like a minimal configuration
00:41:10.300 --> 00:41:13.699
and you can see that there's a whole bunch of nos here.
00:41:13.700 --> 00:41:15.200
So, you know, we don't have cairo,
00:41:15.200 --> 00:41:18.799
we don't have imagemagick, we don't have dbus,
00:41:18.800 --> 00:41:20.600
you know, there's a whole bunch of stuff we don't have.
00:41:20.600 --> 00:41:23.880
We don't have X, we don't have libjansson, no tree-sitter.
00:41:23.880 --> 00:41:25.960
This is really a bare-bones Emacs
00:41:25.960 --> 00:41:28.639
that is strictly terminal mode.
00:41:28.640 --> 00:41:30.800
Then we actually build Emacs, which is, you know,
00:41:30.800 --> 00:41:33.259
kind of boring, we're just gonna type make
00:41:33.260 --> 00:41:35.259
and then make is gonna run successfully.
00:41:35.260 --> 00:41:37.880
And make is gonna spew a ton of output, right?
00:41:37.880 --> 00:41:41.099
So here's where I do that /dev/null trick,
00:41:41.100 --> 00:41:42.600
where I pipe everything to /dev/null
00:41:42.600 --> 00:41:45.819
and then I, or I pipe standard output to /dev/null
00:41:45.820 --> 00:41:47.520
and then I pipe standard error
00:41:47.520 --> 00:41:50.239
to wherever standard output's going.
00:41:50.240 --> 00:41:52.799
And then at the end to say that it ran successfully,
00:41:52.800 --> 00:41:55.379
I say "Make ran successfully!"
00:41:55.380 --> 00:41:57.799
Then we take a look at the Emacs binary
00:41:57.800 --> 00:41:59.879
and you know, it's an elf binary.
00:41:59.880 --> 00:42:01.720
And, you know, because this is running on my Mac,
00:42:01.720 --> 00:42:06.619
this is an ARM-based machine, this virtual machine is.
00:42:06.620 --> 00:42:10.519
Oops, and this is a bug.
00:42:10.520 --> 00:42:12.200
This really should be a macro call,
00:42:12.200 --> 00:42:14.800
but I think I have the wrong number of curly braces
00:42:14.800 --> 00:42:16.159
or something in there.
00:42:16.160 --> 00:42:19.129
I need to figure out why that's not right.
00:42:19.130 --> 00:42:21.109
I'll look into that later.
00:42:21.110 --> 00:42:23.979
And then we install Emacs and then we kind of show
00:42:23.980 --> 00:42:27.719
like the file sizes of everything in the home directory.
00:42:27.720 --> 00:42:31.989
And then we, you know, show the binaries that got installed.
NOTE Final thoughts
00:42:31.990 --> 00:42:35.599
Anyway, so this is the final thoughts section.
00:42:35.600 --> 00:42:39.219
And my final thoughts are, is I hope you enjoyed this talk
00:42:39.220 --> 00:42:42.379
and I hope you actually learned a thing or two.
00:42:42.380 --> 00:42:43.360
All right, thanks everybody.
00:42:43.360 --> 00:42:45.200
And I'll see you all next time.