Write, share, and publish documents with HedgeDoc

Tutorial – HedgeDoc

Author(s):

HedgeDoc lets you write documents collaboratively in Markdown and publish them online.

Markdown syntax [1] provides an easy way to create rich text documents out of plain text files. The magic of Markdown (see the "Markdown" box) is more than mere paragraphs, titles, and subtitles – you can also work with high-end features such as slideshows and embedded videos.

Markdown

Markdown files are plain text files, but they allow much more structure than an ordinary plain text file. I say "structure" instead of "formatting"; Markdown's real power lies in not caring about the actual formatting.

With Markdown, you add typographic detail to your text in the most generic way. Markdown makes it easy to write or generate text that is easily converted to any other document format. With just one click or command, a Markdown file can become a web page, a PDF file, a database record, a note in a mind-mapping application, and much more.

The Markdown cheat sheet in Figure 1 shows how Markdown works. For instance, a line starting with one or more hash characters denotes a chapter or subchapter header, text inside two asterisks is bold, square brackets followed by parentheses enclose a hyperlink, and so on.

Figure 1: The Markdown syntax supports most of the elements required by complex documents.

Several available tools help users create, read, and edit Markdown files, but one of my favorites is HedgeDoc [2], a web-based Markdown editor and online publisher. HedgeDoc, the open source version of the online editing service HackMD [3], lets you create Markdown documents and publish them online from any browser. In addition, HedgeDoc lets you work collaboratively, making it useful for schools or organizations that need to create shared documents in a reusable format. HedgeDoc is also a privacy-friendly alternative to Google Docs or other commercial document services.

Workspace

HedgeDoc is a website, usable from desktop, tablet, and mobile devices, that looks and acts like a text editor or simple word processor. While HedgeDoc is reminiscent of Google Docs and Etherpad, HedgeDoc has the ability to show both the actual Markdown source code and the HTML web page preview (Figure 2).

Figure 2: HedgeDoc let's you see both the Markdown source (on the left) and rendered HTML (on the right).

HedgeDoc also lets you choose the privacy settings for each Markdown document, which HedgeDoc calls a "note." Privacy settings range from Freely (everyone can read, write, and eventually publish the note) to fully Private (Figure 3). If you set a note's permission to Editable, all you need to do to invite others to work on the note is to send them the note's URL. On the other hand, if you want the note to be read-only, you can share it by pressing the Publish button and using the URL it generates.

Figure 3: As a collaborative editing tool, HedgeDoc provides several levels of access to each note.

HedgeDoc's user interface (Figure 4) is as simple as it is functional. The toolbar located above the text input offers all the common formatting options, from bold and italic to lists, links, images, and tables. While these tools are great for beginners, expert Markdown users will rarely use them because typing the Markdown codes is faster. However, the tools do come in handy for all users when it comes to making tables and formatting images.

Figure 4: The HedgeDoc interface: Everything you need to edit and publish text, and nothing more.

Above the toolbar, you'll find the workspace mode buttons. There are two modes for all device types: View and Edit. Clicking on the View button (the eye icon) displays only the formatted HTML text, and the Edit button (the pencil icon) displays only Markdown text. On a desktop or tablet (sorry, mobile devices), you have a third option: the Both button (the split-screen icon) shows you both the HTML and Markdown side-by-side. Rounding out the display modes are the half-moon icon, which lets you toggle between night (the default) and day mode for the menus and the HTML pane, and the question mark icon for help and documentation.

On the right side of the top bar, you'll find New and Publish buttons, a drop-down menu with some essential functions, and the Online button, which tells you how many users are working on the current document (more on this later).

Drop-down menu options of interest include Revision, Clipboard, download options, and Slide Mode, which I'll cover in the "Slide Show" section. Selecting Revision shows a note's existing revisions, with all changes highlighted, plus the option to download any revision. Clipboard lets you copy text taken from another source (a web page or document) and then paste it into your note in Markdown format.

You also have the option to download a note on your computer, saving it as Markdown, HTML, or Raw HTML. I strongly recommend saving each note's Markdown source code on your computer, unless you choose to use a script, which I'll address at the end of this article.

In my opinion, two things that could be improved in HedgeDoc's user interface are located in the toolbar. Resizing the browser window below a certain width makes some or all elements of the top buttonbar disappear. Also, the button that lets you switch between night and day mode for the Edit view is located at the very bottom of the window, instead of at the top for the other two views.

TOC, Two Ways

HedgeDoc offers two table of contents (TOC) options. You can embed a clickable TOC anywhere in your Markdown note using the [TOC] syntax (Figure 5, item 1). Alternatively, you can use HedgeDoc's autogenerated TOC. Pressing the hamburger icon in the bottom right corner of the HTML pane (Figure 5, item 2) opens a collapsible outline. Unlike the embedded TOC, the autogenerated TOC is a part of the HedgeDoc interface, which lets you navigate anywhere in the document down to three levels of headers without adding the [TOC] syntax to your Markdown code.

Figure 5: You can embed a TOC as HTML code anywhere in a HedgeDoc note (1) or use HedgeDoc's autogenerated TOC (2).

Choice of Editors

HedgeDoc can emulate three different editors: Sublime (the default), Emacs, and Vim. To switch between editor modes, click on the editor button (EMACS in Figure 5) in the toolbar at the bottom of the Markdown editor pane, and select your editor of choice from the drop-down menu that opens. Besides having its own keymap, each editing mode can collapse chapters or subchapters (when you click on the arrow symbol to the left of the header). The editors also support auto-completion for several types of markup. For example, if you type #, you will get the pop-up window with auto-completion hints as shown in Figure 6.

Figure 6: Auto-completion makes writing Markdown even faster.

Special Formatting

In addition to regular text, HedgeDoc lets you format source code, emojis, and images using Markdown syntax. To format software code, you use three backticks (```) at the beginning and end of a code block. The code will be highlighted according to the language used. For emojis, you type : at the beginning of the line. An ! at the beginning of a line tells HedgeDoc to insert the code to embed an image in that position.

When embedding an image, its source location affects how HedgeDoc embeds the image. If the image is already online (on the same or another server), you just insert the image's URL in the Markdown code that HedgeDoc auto-inserts after the exclamation mark. If the image is on your computer, click on the Upload Image button in the toolbar and upload the image to the HedgeDoc server (or to an alternative location as described in the "Self-Hosting" section). Alternatively, you may drag and drop an image from your file manager directly to where you want it to appear in the note.

At time of writing, HedgeDoc 1.8.2 still lets you embed YouTube videos, as follows:

{%youtube ID_NUMBER_OF_YOUTUBE_VIDEO %}

However, this specific markup is officially deprecated. It should soon be replaced by embedding "plain links" (the meaning of which is currently unclear).

Metadata

Similar to most Markdown-capable applications, HedgeDoc supports adding metadata to files to set browser behavior. For the metadata to be recognized, it must be placed in a special section, called "frontmatter," at the beginning of each file.

You use YAML to format the frontmatter. The syntax to mark the start of the frontmatter is three dashes, and three dashes mark the end of the frontmatter. The YAML metadata goes inside, with one key/value pair on each line, separated by a colon, as follows:

---
title: real title
tags: tutorial, open source, writing
description: Another useful tutorial
robots: nofollow
---

HedgeDoc will use the title value as the HTML note's title, overriding the first level 1 heading (which would be used if there were no metadata). These tags can be used by any system (including search engines) that catalogs the notes by topic. The values of the description and robots keys will be added in the HTML note's header, to make search engines properly index the note and the links it contains. However, you can set robots to noindex if you don't want the page indexed. Set robots to nofollow if you do not want the pages linked from the current page to be indexed. In addition to these metadata tags, HedgeDoc recognizes many other tags. For more information, consult the documentation on HedgeDoc's website [2].

Diagrams and Mathematical Expressions

In addition to text, source code, and images, HedgeDoc can also format diagrams and charts, as well as complicated mathematical expressions. In my PlantUML tutorial [4], for example, I showed how to create a sequence diagram out of a text file as shown in Listing 1.

Listing 1

PlantUML Sequence Diagram Format

01 @startuml
02 Alice -> Bob  : Hello, is the store open?
03 Bob   -> Alice: Yes, it is. What do you want to buy?
04 Alice -> Bob  : I want to buy some jeans.
05 Alice <- Bob  : Please tell me the color.
06 Alice -> Bob  : Black
07 Alice <- Bob  : Now please tell me the size.
08 Alice -> Bob  : 42
09 @enduml

With HedgeDoc, you can obtain the same results by inserting sequence diagram text, but you use ```sequence at the beginning instead of @startuml and ``` at the end instead of @enduml, as shown in Listing 2.

Listing 2

HedgeDoc Sequence Diagram Format

```sequence
Alice->Bob: Hello, is the store open?
Bob->Alice: Yes, it is. What do you want to buy?
Alice->Bob: I want to buy some jeans.
Bob->Alice: Please tell me the color.
Alice->Bob: Black
Bob->Alice: Now please tell me the size.
Alice->Bob: 42
```

The sequence keyword following the backticks at the beginning of Listing 2 is what actually creates the diagram shown in Figure 7. If you left sequence out, HedgeDoc would treat the diagram text as source code. To learn about all the diagram types that HedgeDoc supports, see the many examples available online [5].

Figure 7: The Markdown syntax in the left pane generates the sequence diagram on the right.

HedgeDoc also supports mathematical expressions by using the MathJax library [6]. MathJax reads plain text descriptions in MathML, LaTeX, or AsciiMath formats and renders them as complex mathematical expressions. Depending on the situation, the expression is rendered using a combination of HTML code with special CSS stylesheets, web fonts, MathML code, or scalable vector graphics (SVG).

Because MathJax support is built into HedgeDoc, you can easily enter a mathematical expression in any of the source formats and immediately see how it looks. Figure 8 demonstrates the rendered expression from the LaTeX expressions shown in Listing 3.

Listing 3

LaTeX Expressions

$$\sum_{i=1}^n i^2 = \frac{n(n+1)(2n+1)}{6}$$
$$\int_{a}^b\int_{c}^d f(x,y)dxdy$$
Figure 8: The Markdown syntax (left) results in a beautiful formula (right).

The value HedgeDoc offers in rendering mathematical expressions can't be overestimated. Math students and teachers worldwide have been using LaTeX formulas for years, with thousands of expressions scattered inside countless LaTeX files. HedgeDoc offers an easy way to write and publish any paper based on these formulas.

Slide Shows

At time of writing, slide show support in HedgeDoc is in beta. However, as demonstrated by a screenshot from the official HedgeDoc slide show demo [7] (Figure 9), it is already possible to turn a HedgeDoc note into a simple slide show viewable in any browser. To create a slide show, you must declare the note type as slide in the frontmatter. You can specify how the slides should look in the frontmatter using the following options:

slideOptions:
  transition: fade
  theme: white
Figure 9: You can also turn Markdown text into an online slide show.

For more details on slideshows, please see the HedgeDoc documentation and demo.

Collaborative Editing

After logging in (see the "Self-Hosting" section for information on how to create an account), HedgeDoc greets you with the default homepage (Figure 10). From here, you can create a new note. You can also search for an existing note using tags (from the note's frontmatter) or generic keywords (from the note's text), with the results ordered by time or title.

Figure 10: The HedgeDoc's default homepage after login.

If you are working collaboratively with other users, perhaps simultaneously, on the same note, you will see something similar to the two browser windows in Figure 11. In the left window, after logging in as a registered user (mfioretti), I created a sample note as a test. Then I opened the same note in another window but this time as an anonymous guest. Note that HedgeDoc assigns guests an arbitrary name (e.g., Pena in Figure 11).

Figure 11: A HedgeDoc note edited by two users simultaneously: one logged in and one an anonymous guest.

The large blue button in the top right corner of each window lets you know who is currently working on a note. Clicking this button lists all users currently working on the active note, with each registered assigned a color (light brown for mfioretti). As shown in Figure 11, the paragraphs I wrote working in the left window as mfioretti are marked with a vertical light brown bar to the right of the line number. Both guests and registered users see changes made by each other in real time.

Figure 11 also highlights a problem with HedgeDoc's interface. Based on this screenshot, it looks like only registered users have the Publish button. This is not true. If a window (on the right Figure 11) is below a certain width, some elements of the top toolbar disappear. With a wider screen, I would have seen two identical toolbars; even the anonymous guest should have the Publish button because I had set the note's permission to Freely, which gives all users permission to do whatever they want with the note. In this example, the only difference between a registered user and an anonymous guest is that only the registered user, who created the note, can change the permissions.

Self-Hosting

Instead of using the web-based app, you can self-host HedgeDoc. At time of writing, the current stable 1.x version is available in several formats, including a Cloudron app [8]. However, the simplest way to host a standalone HedgeDoc instance appears to be the official Docker images [9] (although they are only available for the AMD64 architecture). Almost all the screenshots in this tutorial come from HedgeDoc v1.8.2 running in a Docker container on an Ubuntu 21.04 system.

The recommended way to install a Docker container consists of downloading the sample configuration file (in YAML format) from the HedgeDoc Docker page [10], customizing it according to your needs, and then launching Docker with it. As an example of what you can do with this configuration file see the excerpt shown in Listing 4.

Listing 4

docker-compose.yml (Excerpt)

version: '3'
services:
  database:
    image: postgres:9.6-alpine
    environment:
      - POSTGRES_USER=hedgedoc
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=hedgedoc
....
  app:
    # Make sure to use the latest release from https://hedgedoc.org/latest-release
    image: quay.io/hedgedoc/hedgedoc:1.8.2
    environment:
      - CMD_DB_URL=postgres://hedgedoc:password@database:5432/hedgedoc
      - CMD_DOMAIN=localhost
...
    ports:
      - "3000:3000"

To summarize the instructions in Listing 4: Because HedgeDoc needs a PostGreSql database, you need to download an additional container for PostGreSQL. You then start both containers, making HedgeDoc listen on TCP port 3000. A complete configuration file can contain much more than what is shown in Listing 4.

The HedgeDoc Docker configuration page [10] describes all the variables you can set in the configuration file. I recommend first testing HedgeDoc without changing anything in the configuration file. Once you understand how it works, you can customize the variables.

To download the container and start it as described in the configuration file, run the docker-compose command:

#> sudo docker-compose up -f /absolute/path/to/docker-compose.yml

Unless you see an error message, this should be enough to let you load the homepage of your very own HedgeDoc instance by pointing your browser to https://localhost:3000 (if you installed it on your own computer) or replacing the localhost with the URL of the server where you started the container.

After setting up your instance, you need to create user accounts for you and your team if you want to keep private at least some of the notes that you and your team create. There are two ways to do this. One option is to have each user self-register from the HedgeDoc homepage and receive a password via email. For this option to work, you have to set both self-registration and email delivery in the container configuration file, as described in the HedgeDoc documentation.

The other method, which I personally prefer, involves logging in to the container that runs HedgeDoc and then adding as many users as needed with the command-line utility, manage_users, which is bundled with HedgeDoc. To create my personal account, after launching the container, I found the container's identification code with the ps option of the docker command (Listing 5).

Listing 5

Finding the Container Identification Code

#> sudo docker ps
[sudo] password for marco:
CONTAINER ID    IMAGE                                COMMAND                     CREATED    STATUS      PORTS     NAMES
572918fbff01    quay.io/hedgedoc/hedgedoc:1.8.2      "/usr/local/bin/dock..."    ..

Then I used that code (572918fbff01) to log in to the container, inside a Bash shell, as shown in Listing 6.

Listing 6

Logging in to the Container

#>  sudo docker exec -it 572918fbff01 /bin/bash
root@572918fbff01:/hedgedoc#
#> root@572918fbff01:/hedgedoc# ./bin/manage_users --pass testing --add mfioretti@nexaima.net
Using password from commandline...
Created user with email mfioretti@nexaima.net
root@572918fbff01:/hedgedoc#

Then I ran manage_users to create a HedgeDoc account with my email address as the username and testing as the password. You can also use manage_users to delete users or reset their passwords.

Another thing to do the first time you log in to the container is to look at the internal configuration file, files/config.json. In this file, you can tell HedgeDoc to, among other things, do the following:

  • Accept user logins via LDAP, Facebook, Twitter, or GitHub
  • Store notes in Dropbox instead of locally
  • Store images inside Imgur, Minio, or S3 accounts.

The HedgeDoc main configuration page [11] describes all the values for each of these options. Keep in mind that these options can all be overwritten with environmental variables, which normally have a CMD_ prefix (e.g., CMD_DB_URL or CMD_DOMAIN in Listing 4).

Scripting HedgeDoc

Besides managing users, you can also manage HedgeDoc notes using the command line or shell scripts. You can use hedgedoc-cli [12] to publish or save an existing note as a PDF file, to create new notes from existing local files, or to quickly import all the pads in an Etherpad account into HedgeDoc [13]. For instance, these two commands:

#> hedgedoc import /path/to/markdown/file.md abcdef
#> hedgedoc publish abcdef
exampleid

create a note that would be editable at https://HEDGEDOC_URL/abcdef and readable at https://HEDGEDOC_URL/s/exampleid.

Conclusion

If you ask me, Markdown is so easy, powerful, and flexible that it is a shame more people do not already use it as their preferred text formatting language. HedgeDoc makes Markdown even easier to use, and possibly also to teach to others, so give it a try!

Infos

  1. Markdown: http://www.markdownguide.org
  2. HedgeDoc: https://hedgedoc.org/
  3. HackMD: https://hackmd.io
  4. "Drawing Diagrams with PlantUML" by Marco Fioretti, Linux Magazine, issue 235, June 2020, https://www.linux-magazine.com/Issues/2020/235/PlantUML-Diagrams
  5. Diagrams examples: https://bramp.github.io/js-sequence-diagrams/
  6. MathJax: https://www.mathjax.org/
  7. Slideshow demo: https://demo.hedgedoc.org/p/slide-example
  8. HedgeDoc Cloudron app: https://docs.cloudron.io/apps/hedgedoc/
  9. HedgeDoc Docker images: https://quay.io/repository/hedgedoc/hedgedoc
  10. HedgeDoc Docker configuration: https://docs.hedgedoc.org/setup/docker/
  11. HedgeDoc general configuration: https://docs.hedgedoc.org/configuration/
  12. hedgedoc-cli: https://github.com/hedgedoc/cli
  13. How to import Etherpad pads into HedgeDoc:https://docs.hedgedoc.org/guides/migrate-etherpad/

The Author

Marco Fioretti (http://mfioretti.com) is a freelance author, trainer, and researcher based in Rome, Italy. He has been working with free/open source software since 1995 and on open digital standards since 2005. Marco also is a Board Member of the Free Knowledge Institute (http://freeknowledge.eu) and blogs about digital rights at https://stop.zona-m.net.