This book describes how this site is written, in Org-mode, with ox-hugo, and bits of Literate Programming.
This site is built with:
The GitHub/Gitea actions file includes all its dependencies declaratively.
To build locally, you must install Emacs (29+), and hugo (v0.120+), using your package manager, or by downloading directly from their respective project pages. Please be aware that hugo has two editions: standard and extended, and this build requires the extended edition (TODO: verify this - I had some problems before - but maybe they are resolved - I am still using the extended edition for now).
Read the Linux Workstation chapter for setting up Emacs.
Please note that your package manager may container an old version of Hugo that is incompatible with the Relearn theme. You can install the latest version of Hugo from the Hugo GitHub releases page.
For example, to download the X86_64 release of hugo v0.123.8
:
You will also need to clone the git source of this website to your workstation:
Change into the directory where you cloned the source:
Run the install method to download the theme:
Build the site:
Run the development server:
This site is automatically published to GitHub Pages via the included
action file: .github/workflows/deploy.yaml. You can fork the
repository and enable the action to run on your behalf and publish to
your own site automatically, whenever you run git push
.
If you don’t want to use GitHub pages, you can alternatively publish to any webserver via SFTP.
To do so, you must install Rclone.
For example, on Fedora:
Once installed, you need to configure the remote SFTP server you want to publish to:
Follow the prompts to setup your SFTP remote, or you can see the example SFTP documentation for doing this. You must set all of the following details:
- The unique name of the remote (eg.
book
) - The hostname of the SFTP server (eg.
sftp.example.com
) - The SFTP username, password, or SSH key, and whether to use the SSH agent (recommended!)
The connection details are saved in your clone config file (eg.
~/.config/rclone/rclone.conf
)
The included Makefile has a variable at the top called
PUBLISH_RCLONE_REMOTE
(default book
). Make sure this is the same
as the name of the rclone remote you configured (edit the Makefile if
it is not).
Once everything is configured, simply run make publish
to publish
your site to the SFTP remote.
Your webserver document root needs to be configured to use the same path that the SFTP server is configured for.
If you don’t have a webserver or SFTP server, you can use the following from d.rymcg.tech:
Here are some tips on using Org-mode and Emacs.
Many of these tips are found in the Org Manual.
One of the easiest ways of navigating an Org document, isn’t even an Org feature. Just search for the text you’re looking for and jump right to it.
- Press
C-s
(orM-x isearch-forward
)
Of course, you might not always know the exact text (or it might not be unique enough to take you right there), so its useful to know some other ways of navigating Org documents.
Another great way to navigate your Org documents is by traversing the headers. My emacs config sets the default startup visibility to folded, so you can always get back to a folded state:
- Press
C-u C-u TAB
(orM-x org-set-startup-visibility
)
Cycle the visibility of the headers (foldedness):
- Press
TAB
to cycle the folding of the selected header (your cursor has to be on a header). - Press
C-u TAB
to cycle the folding of the headers in the whole buffer (cursor can be anywhere). - Press
C-u C-u C-u TAB
(or =M-x org-show-all) to show the entire buffer unfolded.
If you’re in the middle of a paragraph, and want to move to the header of the current section:
- Press
s-<up>
(orC-c C-p
orM-x org-previous-visible-heading
) - Press it again to go to the section before that, etc.
To move to the next section:
- Press
s-<down>
(orC-c C-n
orM-x org-next-visible-heading
)
Moving to the next higher heading is very useful:
- Press
C-c C-u
(orM-x outline-up-heading
).
From the parent heading you get to see the outline of the outer
context of what you’re currently writing about. From here you can
press Tab
twice to fold all all the sibling sections and get an
overview.
- Press
C-c C-u TAB TAB
.
Here are some other header movement commands:
C-c C-f
(M-x org-forward-heading-same-level
)C-c C-b
(M-x org-backward-heading-same-level
)
You may frequently find yourself needing to jump around in a document, but don’t want to lose your current place.
- Press
C-c C-j
(orM-x org-goto
). Mnemonic “jump”. - Immediately press
Enter
to close the org-goto menu (theres advanced searching functions in there, but you ignore that for now).
This will save your current place, allowing you to go find the place you need to temporarily go to.
When you’re done, and you want to go back to to where you were:
- Press
C-c &
. (orM-x org-mark-ring-goto
).
One mnemonic for &
is that it is the same syntax for a C pointer
reference.
One of the advantages of Org-mode is you can organize lots of different articles into one big file. This is also a disadvantage when you are trying to focus on just one of them. It is easy to get lost.
As an example, open the other book named d.rymcg.tech.org (found in
this same directory). Let’s say we want to focus on the chapter named
Traefik Proxy
.
- Press
C-x 4 c
. (orM-x clone-indirect-buffer-other-window
).
You now have two buffers open for the same file:
d.rymcg.tech.org
(the original) and d.rymcg.tech.org<2>
(the
clone), and you are automatically switched focus to the newly cloned
buffer.
Rename the new buffer to traefik
so you don’t get confused:
- Press
C-x x r
(orM-x rename-buffer
). - Type the new name:
traefik
.
Now find the chapter you want to focus on:
- Navigate to the chapter heading named
* Traefik Proxy
, make sure your cursor is now somewhere on this line.
Narrow the buffer to the selected subtree:
- Press
C-x n s
(orM-x org-narrow-to-subtree
).
You have now completed the process of narrowing the content of this
buffer to only the Traefik Proxy article. It is important to know that
the traefik
buffer is still an indirect clone of the original
d.rymcg.tech.org
buffer, and they are both simultaneously editing
the same underlying file. But now you know how to focus on a bite
sized peice of a larger file. Go ahead and create more buffers to work
on other parts you frequently need to focus on.
If you need to widen the buffer again:
- Press
C-x n w
(orM-x widen
)
To add hyperlinks to documents, I find it easiest to type the text first, and then add the link.
- Type the link text.
- Navigate point to the last character of the link text.
- Press
C-SPC
(Control Spacebar) to mark the position. - Navigate point to the first character of the link text.
- The link text should now be selected.
- Press
C-c o i
(orM-x org-insert-link
). - Enter the hyperlink URL.
- Absolute URLs should start with
https://
. - Relative URLs can reference the root of the domain with
/
. - Just remember, since all links are going through Hugo, links have to be in the context of what the web browser can find, not all local Org links are valid.
This chapter serves as an example of various shortcodes/markup for Ox-Hugo and the Hugo Relearn theme.
This chapter is broken into several sub-chapters to discuss the various Hugo related features.
A couple examples ripped from the ox-hugo docs.
This is a normal paragraph.
This is another normal paragraph.
This paragraph has some
in it.
This section shows some hidden details:
you want.
Here are some example usage of the shortcodes provided by the Hugo Relearn theme. Shortcodes are a native feature of Hugo and Hugo themes. For use with Ox-Hugo, you need to set the#+hugo_paired_shortcodes
(For examples, see Ox-hugo docs or the top
of this source file).
You can only use the icon names from the “free” set provided by fontawesome.
Math with MathJax:
Visualize your API with swagger spec.
This is a deeply nested sub-chapter. Take a look at the Org source. It requires that you create several headings and create the index in a sub-heading of the same name. It is a strangeness about ox-hugo that this is required. If you make a strictly hierarchical outline, the content will be duplicated, however the structure we’re using hides the nested content on the index pages, leaving it for the nested page only.
This is another deeply nested sub-chapter as a sibling of the one before it.
This is another deeply nested sub-chapter as a sibling of the one before it.