Some style and format suggestions for Markdown files
[ Introducing | Encoding | Headings | Paragraphs | Lists and tables | Linking | Hints ]
First things first, the main rule we have to format a Markdown file for our website is – we have no rules, no policies or anything like that. Because useful but probably badly formatted content is always better than helpful but unshared informations and experiences. Nevertheless there are some minimal requirements that must be met to not confuse the underlying processor (Liquid), respectively Markdown parser (kramdown).
Also note, we are not the grammar police, i.e. nobody will be blamed. The site
content will be irregularly reviewed and corrected but you can also help by
taking the following points to your heart. Those are only suggestions to
hopefully increase the source file consistency, its readability and making
reviewing less time consuming. So, in the end from the beginning, we get
content which is easier to handle and to maintain.
The kramdown parser is configured to support GitHub Flavoured Markdown (GFM) which we prefer and slightly differs from standard Markdown. It’s absolutely not necessary but if your are interested in, the kramdown syntax page mention all differences where applicable but the quick reference is more than enough.
Which file encoding to use is up to you and depends on what kind of text to write and if you have to use a multibyte character set (MBCS) for special symbols. Even it’s not the most frugal encoding representation (relating to storage space), Unicode – more precisely, UTF-8 character encoding – is preferred due to its wide range of code points but please, use it without a byte order mark (BOM) signature! Otherwise parsers may stumble.
Beside the file encoding you have to choose a file name and a common extension
but that’s easy. Use .md
(lower case) for the latter and build from alphanumeric,
hyphen and underscore characters a descriptive name.
A single (not too long) line between the title and the first section contains some kind of description to introduce the page. The background, it looks nicer when all sub-pages starts with the same structure and as a bonus, will reduce vertical ‘header jumping’ while navigating through internal pages.
A short structure visualisation:
---
remark: This is a so called YAML front matter (will be processed by Jekyll).
status: wip
---
# A Capitalised Page Title
This description introduce the page and doesn't end with a full stop
## Normalised page heading
Level 2 headers (like titles) do not start numbered and end without a full stop
(like the description line). Unlike titles, only the first word is capitalised.
Proper names and nouns, e.g. our NeoMutt, are written as in paragraph context.
If it cannot be avoided, only well known acronyms and abbreviations should be
used in titles and headings.
...
As you can see, all elements are separated by one empty line. The header of
our Markdown pages are created by using the
atx- not setext-style notation and without the optional
end mark (#
). This style supports more header levels and is easier to match
with regular expressions (RegEx) in the case of future section restructuring.
Style | Level 1 | Level 2 | Level 3 | … | Level 6 |
---|---|---|---|---|---|
atx-style | # Header # |
## Header ## |
### Header ### |
… | ###### Header ###### |
setext-style |
Header ======
|
Header ------
|
— | … | — |
Every page has exactly one level 1 and one or more level 2 header. Any further
subsections follows the rule level n+1, i.e. no levels will be skipped and, e.g.
a level 3 section cannot contain a level 2 header.
Although the usage of line wrapping and endings, multiple or trailing whitespace(s) has no meaning for paragraphs in the rendered HTML page – it could for those whose looking at the source. Make it a pleasure to read or review your work – both, as rendered result just as in source file.
It’s a common convention to:
Note: In Markdown several characters are associated with a special meaning
to mark text as emphasised, header, list, etc. To repeal their special
attribute prepend a backslash to characters like #`*_.-+
and ()[]{}
.
For instance, an escaped asterisk \*
will be handled literally and not as
start for a list item or an emphasis. Because our output format is HTML, also
consider escaping of <>&
to avoid they’ll be treated as tag or HTML/XML entity.
For line wrapping keep track of every line start to not produce unwanted results. For instance:
The answer to "What is the meaning of life, the universe and everything?" is
42. Douglas Adams was...
become a numbered listing point:
The answer to “What is the meaning of life, the universe and everything?” is
1. Douglas Adams was… ... Solution: avoid line break or escape 42\.
If you want to be perfect, try to avoid widows and orphans.
They are easy to overlook and could be eliminated by inserting an earlier line
break or a no-break space (
). The latter adds some kind of distortion
but also makes clear what you’ve tried to achieve. Read also about
its friends.
Whitespace usage depends on its context – remember the goal is consistency and readability. It’s mandatory for nested lists to get a proper indentation result, tables could be hard to read in source without it. Also, there might be use cases to indent or align something horizontally (in source):
[irc]:␣␣␣␣␣␣</dev/newbie-tutorial#irc>
[issues]:␣␣␣<https://github.com/neomutt/neomutt/issues>
but use it sparely and with single spaces – they are preferred to tab stops.
Paragraphs that contains tons of acronyms or abbreviations interrupt the text flow and thus, are mostly hard to read and may even worst to understand, especially when they are unknown by the reader because they haven’t been introduced on its first usage.
Sometimes it’s difficult to introduce half of a dozen acronyms, e.g. in a table
row or a short listing point. To get out of this let the parser automatically
convert it to HTML abbreviation tags (<abbr title="Line Feed">LF</abbr>
) by
placing their definitions:
*[ANSI]: American National Standards Institute
*[ASCII]: American Standard Code for Information Interchange
*[UTF-8]: 8-Bit UCS Transformation Format
somewhere into the Markdown file – the end of file (EOF) is a good location for this. Tip: A certainly incomplete list of definitions can be found in our glossary.
One note about abbreviations and contractions, commonly, well known of those (a.k.a., etc., vs, …) doesn’t and thus, shouldn’t have to be introduced. Try to use complete words, e.g. write ‘configuration files’, ‘contribution’, ‘documents’ instead of ‘configs’, ‘contrib’, ‘docs’ – it looks more correct in a treatise, doesn’t mislead spell checks and won’t trick regular expression pattern, …
Emphasised text passages are a nice way to direct readers attention to several important notes. Use emphasis but also don’t overdo it, be always consistent, i.e. use the same specific style for the same kind of text passages.
For example (inline):
Style | Emphasis Sample | Markdown Syntax | Example Use Case |
---|---|---|---|
code: | neomutt -F /dev/null -D -S |
`neomutt -F /dev/null -D -S` |
command, file/path names, code, … |
light: | NeoMutt or Issue #42 |
*NeoMutt* or _Issue #42_
|
names, pseudo header, issue, comment |
strong: | See also: or Note: |
**See also**: or __Note__:
|
hints, key in key/value pairs, … |
Even it is possible, avoid usage of:
```three backticks delimiter```
for inline code emphasis –
it’s redundant. Indeed, they are not reserved but should only be used for
code blocks:
# Convert mails from mbox to Maildir format using NeoMutt
# Notice the prepended backslash to bypass a probably defined NeoMutt alias
\neomutt -f /path/to/mbox-file -e 'set mbox_type=maildir; \
set confirmcreate=no; set delete=no; \
push "<tag-pattern>.*<enter>;<save-message>/path/to/Maildir-directory<enter><quit>"'
For practical command examples be kindly and:
~~~
) for code blocks – we use the triple backticks**\***
instead of a more readable __\*__
.While writing it may be useful to comment out different versions of a text section or similar. But simply, you cannot because Markdown, as a plain text formatting syntax, does not define comments.
If you cannot resist:
Note: empty line below is mandatory
[•]: # comment line 1 ... square brackets should contain document wide unique text
[•]: # comment line 2 ... this 'anchor definition' doesn't appear in HTML source
<!--
Multi line HTML comment which appears in HTML source
-->
{% comment %}
and {% endcomment %}
tags. These kind of comments will not be placed into the
HTML source.Remark: Don’t forget to strip out those hacks, it’s beyond the specification or Liquid markup not Markdown!
Both styling elements supports a lazy notation:
·2·4·6·8·0·2·4·6·8 │ ·2·4·6·8·0·2·4·6·8·0·2·4·6·8·0·2·4·6·8·0· │
────────────────────┼────────────────────────────────────────────│
1. point 1 │ |left|center|right| │
1. point 2 │ |:-|:-:|-:| │
1. point 2.1 │ |Teaching an|cell 1.2|cell 1.3| │
1. point 2.2 │ |cell 2.1|Old Dog|cell 2.3| │
1. point 3 │ |cell 3.1|cell 3.2|New Tricks| │
which is easily extendable but hard to read, so don’t be lazy:
·2·4·6·8·0·2·4·6·8 │ ·2·4·6·8·0·2·4·6·8·0·2·4·6·8·0·2·4·6·8·0· │
────────────────────┼────────────────────────────────────────────│
1. point 1 │ | left | center | right | │
2. point 2 │ | :---------- | :------: | ----------: | │
1. point 2.1 │ | Teaching an | cell 1.2 | cell 1.3 | │
2. point 2.2 │ | cell 2.1 | Old Dog | cell 2.3 | │
3. point 3 │ | cell 3.1 | cell 3.2 | New Tricks | │
because our goal is readability and consistency in rendered results and source files.
Markdown supports three different formats, named: ordered (a.k.a. numbered), unordered (a.k.a. bullet) and definition (a.k.a. association) lists. They all have their special use case but the most used type is the bullet list.
Lists are great to present several informations in a compact and easy to follow form instead of writing (and reading) walls of text. Use it to describe simple contexts and probably alternatively to tables with long text cells which doesn’t support line wrapping in source and thus, runs out of the screen.
Common remarks
*-+
) for list levels (helpful when indent gets lost)Numbered list
Bullet list
Definition list
Like lists, tables are useful to give a quick overview and looks mostly neat and clean as long as they are small. Also tables may have some drawbacks on small screens and source readability or alternating could be a pain.
Fill up table cells with single spaces until all columns are exactly vertical aligned. With a good editor it should be achievable – if not, this wheel has been already invented and several helpers exists, e.g. as table generator, Vim plugin or browser extension.
Whichever way you go, look at the results of those helpers (beside their learning curve or usability). As shown above, we use a single space around each inner table pipe character and after/before the outer ones. For the sake of our own little laziness, table cells are mostly left aligned but for different length numbers or similar it may be worth to take the work and right align those in source files.
Neither table rows nor cells can be wrapped so it becomes visually easier to
perceive in source. To force a line break in the rendered table cell use the
HTML break tag (<br>
). Note, the kramdown parser picks the right form
internally, so in this context there is no difference to its XHTML variant
(<br />
).
Conclusion/Remarks
—
),
‘undefined’, …By linking parts of text you’ll valorise your work and have the chance to substantiate or enhance your examples and statements. Links should be used for additional references, not as a replacement for information.
Markdown and GFM provides several link definitions:
Link Type | Definition (inline) | Result |
---|---|---|
explicit | [NeoMutt](https://neomutt.org "NeoMutt’s Home Page") |
NeoMutt link with a balloon tip |
implicit |
[https://neomutt.org] or <https://neomutt.org>
|
https://neomutt.org |
Reference | Definition (somewhere) | Usage (inline) |
link |
[lnk_id]: <https://neomutt.org> "NeoMutt’s Home Page" |
explicit: [NeoMutt][lnk_id] implicit: [lnk_id]
|
image | [img_id]: </images/mutt-48x48.png> "Mutt’s stroll" |
[![img_id]][lnk_id] |
footnote | [^fn_id]: "Teaching an Old Dog New Tricks" |
NeoMutt [^fn_id] |
An explicit link definition is basically preferred to an implicit one because
it is apparent as a declaration of intent.
A line length of 80 characters, as suggested in Paragraphs section above, often doesn’t provide enough room to hold both, the link and a bunch of meaningful text. In those cases consider to put the whole link definition on a separate line even it breaks the visual text flow of that paragraph.
Alternatively define a link reference with a small, unique and meaningful ID at the EOF, especially when you refer to the same URL more than once in the file. Now you are able to implicit link to a link reference by using the shortest possible link notation at all. This is very useful where space is rare, like in table cells.
Instead of making a proposal which implicit URL link notation to prefer, try it out or take a guess:
Link 1: <https://neomutt.org>
Link 2: [https://neomutt.org]
[https://neomutt.org]: <https://www.example.net> "View NeoMutt’s Home Page"
Suggestions
Just write (maybe only pure text) but in team-like speaking, don’t think about styling, format or output-targets, so hopefully you won’t get sidetracked and no idea will be lost. Afterwards, while the review, is time for formatting, fixing and testing. When you ‘markdownify’ your work resist to achieve a certain appearance or behaviour, e.g. to align, colourise or indent something. That’s the domain of cascading style sheets (CSS) and when those are changing or the user just zooming the page, your ‘tuning’ may look no longer as originally intended.
Remark: Don’t treat the source file for this page as a reference for a proper Markdown – it isn’t. It uses uncommon and not portable notations to realise some of the highlighted examples.
Writing pure Markdown has a huge advantage over a pollution with a mix of HTML and Liquid elements. It can be used as what it is – a plain text formatting syntax. One source for multiple targets (HTML, PDF, email, issue comments, …) without any kind of refitting for one specific scenario.
OK, that’s often an unreachable ideal and with our website we also have a clearly defined single target. Here are some applicable notes, use:
\\
instead of <br />
to force a line break (not possible in
tables)```
for code blocks rather than
<pre><code>...</code></pre>
or
{% highlight %}...{% endhighlight %}
*[CC]: Carbon Copy
instead of <abbr title="Carbon Copy">CC</abbr>
Note: One exception currently exists – internal anchor definitions. Because our home page includes a fixed banner at its top, site links needs an offset to display anchored text below the banner. To define a section targeting anchor, write:
## Section name <a id="sec_name"></a>
and use it in source with look at [Section name](#sec_name) to ...
as usually.
Even it’s worth to strive for pure Markdown, sometimes we need more control where line wrapping happens or must insert certain characters like symbols and pictographs. The kramdown Markdown parser supports typographic symbol transformation for often used characters:
Source | Result | Name | HTML Entity | NCR hex. | NCR dec. |
---|---|---|---|---|---|
-- |
– | en dash | – |
– |
– |
--- |
— | em dash | — |
— |
— |
... |
… | ellipsis | … |
… |
… |
<< |
« | guillemet | « |
« |
« |
>> |
» | guillemet | » |
» |
» |
' …’ |
‘ | quote | ‘ |
‘ |
‘ |
‘…'
|
’ | quote | ’ |
’ |
’ |
" …” |
“ | quote | “ |
“ |
“ |
“…"
|
” | quote | ” |
” |
” |
Because these characters are easy to type, results in typographical correct
symbols, we use it always although some of them requires more space and the
dashes may a little bit unfamiliar. Abstain from inserting their Unicode or
HTML/XML counterparts directly – it’s not necessary.
Note: The guillemets, when used with leading/trailing spaces, becomes
‘«
’ and ‘
»’. This is typographical wrong for
<< French quotation >>
marks. Consider to use
<< French quotation >>
to be pedantic but get a correct
« French quotation » until CSS does this job.
It is difficult to frame a common rule for the other unlisted and printable non-ASCII/non-ANSI characters because their visualisation within the site and source file depends on support in browsers, editors and installed fonts.
Basically favour to insert those ones directly instead of using their entities. When all goes well they mostly occupy only the width of a single character (cell in terminal) and thus, won’t impair reading fluency in source like an unnatural and syntax highlighted HTML/XML entity will. When in doubt or have to use high code points, e.g. for funny pictographs, take entities. Also have a look at the several character references out there, notice replacement characters like �.
Notable control, hyphen and space characters:
Name | Wrap | HTML Entity | NCR hex. | NCR dec. |
---|---|---|---|---|
no-break space | no | |
  |
  |
en space | yes |   |
  |
  |
em space | yes |   |
  |
  |
figure space ¹ | no | — |   |
  |
thin space | yes |   |
  |
  |
zero-width non-joiner | yes | ‌ |
‌ |
‌ |
zero-width joiner | yes | ‍ |
‍ |
‍ |
non-breaking hyphen (‑) | no | — | ‑ |
‑ |
narrow no-break space | no | — |   |
  |
word joiner ² | no | — | ⁠ |
⁠ |
1. occupy same width as a digit in the current font (en quad – half of an em)
2. replaces deprecated zero-width no-break space (
/
),
a.k.a. BOM code point (when used at file start)
The non-printable characters and the non-breaking hyphen are useful, for, e.g. line break control, character grouping and micro-typographical correctness, to ensure well wrapped tokens/paragraphs and therefore, an ease of reading in resulting page.
As probably still said, use it:
2,219 × 656,749
in ‘2,219 × 656,749 = “NeoMutt’s Birthday as Unix time”’mail‑client⁠/⁠neomutt
in ‘try mail‑client/neomutt package’f‌f‌i
/f‌f‌l
in ‘ffi/ffl’ to avoid ffi/ffl ligaturesGo back to top or file an issue.