DEV Community

Cover image for How I made a Markdown - HTML dual file format (Modulo.js Development)

Posted on

How I made a Markdown - HTML dual file format (Modulo.js Development)

Markdown-HTML is a sort of miniature "dual file format" that is as portable as HTML and as easy-to-edit as Markdown, by being both simultaneously. Read on for an explanation and example.

The Problem

Last summer, I was working on 3 projects:

  1. I was writing documentation in Markdown

  2. I was developing curriculum of zip files filled with markdown instructions, and I wanted students without text editors to be able to view the markdown as well (less teacher time helping students)

  3. I was working on a project for a client that would require the integration of a GUI CMS interface for the client's content team (on Netlify, so Decap CMS)


It might seem like a magic trick:

  1. A file that can be seamlessly opened/saved from a GUI Markdown editor
  2. The source file can be double-clicked on and open in the browser (that is, file:// protocol support), so it's as "easy" to distribute internally as a word document
  3. For developers or "low code" dev team members, it can be edited in a text editor in version control, like a normal Markdown file

The secret ingredient: Frontmatter syntax

How to accomplish this? Well, it's no magic trick, it's just taking advantage of flexibility in front-matter syntax. We can make the Markdown ignore the HTML that's crammed in a line at the top of the file, and since Modulo can be "bootstrapped" in few characters, we can have all the above at once!

Most markdown parsers supports a concept called "frontmatter", which is metadata you put at the top of a markdown file. It often looks like this:

author: Jane Doe
title: Lorem ipsum

# Intro to article

Lorem *ipsum*....
Enter fullscreen mode Exit fullscreen mode

Markdown has many dialects. This means that the above is just one of several "front-matter" syntax, which also means that Markdown editors (notably, Decap) can be configured to accept custom syntax.

Which leads us to the "trick" to get this all to work: Markdown-HTML is just another Markdown frontmatter syntax.

Expressed generally, the rule would be like: The first line of a file that starts with the string <!DOCTYPE html><script Modulo and ends with the string ---\n, or for a regexp: /^<!DOCTYPE html><script Modulo[^\n]+---\n/i

The potential

The results? When opened in the browser, the user sees only the final rendered page (not the markdown source), complete with the markdown converted into HTML, with potential for CSS, custom code, etc applied. When opened with a text editor,
these files resemble Markdown files, as long as you ignore the first line. This means that true novice coders, who are only comfortable using text editors but not comfortable with HTML or CSS, can edit these files as long as they don't touch the first line.

Furthermore, if you configure them to accept that long HTML string as the frontmatter deliminator, it will hide it from the user and editing the file will be like any other markdown file. This allows for properly configured GUI Markdown editors to open up and transparently edit these Markdown-HTML files as well, while enforcing that the "magic" words at the top that make it an HTML file as well remain.

The code

(Original file)

I made an example for the Modulo Jamstack template. Check out the source code to this example project template I made:

<!DOCTYPE HTML><script Modulo src="/static/js/Modulo.js" -src="/static/components/cms/">/script><cms-MarkdownPage><script type=md>---
title: The Example Article
subtitle: Why this is the example ever and why you should like it
author: Author Authorino, PhD in Authoring
This is an example markdown page. Here is an image:
Enter fullscreen mode Exit fullscreen mode


The first line can get even shorter, as well. Some potential variations:


<script Modulo src="" -src="/static/"></script><x-MDP><script type=md>---
Enter fullscreen mode Exit fullscreen mode

Adding a compiled component bundle to the same directory:

<script src="./M.js"></script><x-MDP><script type=md>---
Enter fullscreen mode Exit fullscreen mode

Keeping it KISS

The Modulo framework tries to be KISS (Keep it simple, silly!). The src/ directory for the static site builder is as 1:1 with the output build/ path structure as possible. Basically, if you have a src/whatever.html you will get a build/whatever.html that is the built or SSR version of that page (and can be served at /whatever if you have .html auto-extension enabled). This is as opposed to having the paths be built out based on a separate content directory, JSON files, etc. I wanted to avoid this, since it's less 1:1 and KISS, and does not "ramp up" from plain static sites in the same way that the Modulo workflow is intended.

For my client, keeping it KISS has a potential for a real win in terms of developer time: There's the potential for the more technically minded of the content team to make and test small copy changes, etc, without my intervention, from editing source directly on GitHub. If the source code is simple enough, you won't have any "no-coders" left on the team!

Thanks for reading, that's all for now! This article is already long enough, so I'll discuss more on this format in future posts. This is the first blog post in what will be a series on Modulo.js development. If you find this interesting, then the next posts might include how to configure the editor, and breaking down how the browser can bootstrap everything from that one line.

Top comments (0)