Featherdown
Featherdown is a light syntax inspired by Markdown — easy to type, nice to read and rich in shorthands, yet compatible with HTML and javascript's template literals and amenable to live editing.
As new ideas are incorporated in Featherdown, this page and the companion Cheatsheet will be kept up-to-date.
Their sources, obviously written in Featherdown, can be read with Ctrl/⌘U, or
Shall Featherdown be useful to you too, fell free to with any questions.
Headings
Headings can be added in ATX or Setex-like fashion. If both formats are used in the same header, the latter one wins.
ATX-like headings
Any line starting with an hash #
, followed by some text, is recognised as an header. The number of hashes determines depth:
Depth | Syntax |
---|---|
heading 1 | # heading 1 |
heading 2 | ## heading 2 |
heading 3 | ### heading 3 |
… | … |
Extra spaces around the hashes or after the heading text are ignored.
Setex-like headings
Headings are also recognised whenever any line is underlined by another line containing the following long sequences of symbols, in decreasing order of visual density:
Depth | Underline type | Visual density test |
---|---|---|
heading 1 | hash | ################# |
heading 2 | hash-equal | #=#=#=#=#=#=#=#=# |
heading 3 | equal | ================= |
heading 4 | equal-dash | =-=-=-=-=-=-=-=-= |
heading 5 | dash | ----------------- |
heading 6 | dash-space | - - - - - - - - - |
The length of the underline must be at least 3 characters, excluding spaces. When the underline consists of different symbols, their precise order and relative amount does not matter.
Paragraphs
Paragraphs are automatically placed around consecutive lines of text, as long as they do not match any other block element nor contain particular html tags.
Left-aligned (default) or justified
Within a paragraph, text-alignment can be specified by the amount of tabs that precede it, the default (zero) resulting in left-aligned text.
Left-aligned: 0 tabs (default).
1 — 4 tabs will result in a completely justified block of text. Shall you have the habit of indenting the first line of a paragraph with a few tabs for visual clarity, you won't have trouble remembering this setting.
Left and justified paragraphs are automatically punctuated, unless they already end with a punctuation sign!
Centered or right-aligned
Start a line with a substantial amount of tabs to produce a different alignment.
Centered
5 — 9 tabs
notice the blank lines
how they are
mostly kept
Right-aligned
10 or more tabs
Contrary to left-aligned and justified lines, no blank lines are needed to separate right- or left-aligned lines.This feels more natural when writing poetry, for example.
In addition, most blank lines are displayed, this affords a little extra creative freedom.
A single ↹ (tab) is the same as (space) → (space) → (space) → (space).
Polycolumns
Polycolumns present a block of text across an automatic number of (newspaper-like) columns, useful for ultra-long lists:
Heading, ATX-like
Heading, Setex-like
Figure, block
Figure, inline
Link, fragment
Link, inner
Link, outer
Code, fenced block
Code, inline
Fence any sequence of lines with 3 or more vertical bars: |||
to create a polycolumn like the above.
Any blank lines are ignored; in case they aid you organise the information visually.
Tables
Two or more consecutive lines containing tab-separated text convert automatically into table rows. Adding one or more empty lines between consecutive rows is possible. Consecutive tabs, even if mixed with whitespace, count as one. Some rows may skip the last columns freely.
Table header
To mark the first row as an header row, add an empty line between the first and the second row. Alternatively, if the majority of the characters in the upper row are UPPERCASE, it will also be recognised as an header row.
Empty cells
Empty cells are declared by writing a single dash -
.
1 | 2 | - |
---|---|---|
4 | - | 6 |
- | 8 | 9 |
Input labels
Input labels can be added anywhere in a table (or another searchable area) to automatically add or remove a tag from the search field.
The following code #bold
creates a label.
bold
keyword.
Column rewrites
Append ›››Function
to any header to rewrite all cells in that column (by applying that Function
individually to the resulting string).
Idea Generalise the ›››
operator to other situations, and maybe use a different symbol.
Code
Code blocks
Fenced code blocks may be added by sandwiching some lines between two fences: lines only containing three or more acutes ´´´
.
{
this:is,
a:javascript,
object:"in a fenced code block"
}
Code snippets
Inline code snippets are added by wrapping a bit of code in two acutes, like so ´´ some code ´´
.
Figures
Figures are recognised whenever the full path and the image extension ( .jpg, .png, .gif, .svg) are written, either as a block figure or an inline image.
The default image folder is images
, so a simple image path like feather.svg
resolves into images/featherdown.svg
automatically.
Info: Image paths containing spaces cannot be automatically recognised.
Block figure
A single line containing a path to an image, with an optional caption and optional sizing in the lines below:
images/featherdown.svg
((the Featherdown logo))
((small))
This renders as:
Sizing images
One extra line of captioned text may be added below a block figure to specify the maximum horizontal image size, under the following formats:
Format | Example | Example result |
---|---|---|
Text | small (also medium ) | |
Pixels | 20px | |
Percent | 10% | |
Em units | 5em | |
Viewport units | 5vw or 5vh |
Inline images
Images can also be referenced and sized inline (but without a caption). Alternatively, the I shorthand can be used anywhere, with captions.
Style blocks
Style blocks follow a similar syntax as markdown.
Symbol | Style | Syntax | Example result |
---|---|---|---|
** | bold (b) | **emphatic text** | emphatic text |
// | italics (em) | //oblique text// | oblique text |
== | highlight (mark) | ==highlighted== | highlighted text |
__ | underline (u) | __underlined text__ | underlined text |
~~ | strikethrough (s) | ~~redacted sentence~~ | |
++ | recent insertion (ins) | ++newly added++ | newly added text |
|| | spoiler | ||hidden|| | hidden but revealed on click |
^ | superscript (sup) | basis^exponent | basisexponent |
^^ | long superscript | some ^^long super.^^ | some long super. |
¨ | subscript (sub) | log¨2 | log2 |
¨¨ | long subscript | ¨¨long subsc.¨¨ | text with a long subscript |
´´ | code | ´´code snippet´´ | inline code snippet |
Verbatim
Any expression can be written exactly as typed, without any symbol replacements (i.e. verbatim or escaped) by enclosing it in double curly braces {{}}
.
NB: Empty curly braces display themselves rather than an empty space.
Shorthands
Keyboard and gesture shortcuts
Enclose any sequence of keyboard key combinations (or gestures) in double square brackets to produce nice visual keyboard-key icons, like [[Ctrl C,Ctrl V]]
: Ctrl/⌘C → Ctrl/⌘V.
Simultaneous
Simultaneous keys or gestures are split by spaces, e.g. [[Ctrl tap]]
to yield Ctrl/⌘Tap.
Sequential
Sequential keys or gestures are split by commas, e.g. [[Alt, F]]
to yield Alt/⌥ → F.
People
A known person may be referenced by prefixing @
to an alphanumeric alias — name or social network handle, without spaces (underscores allowed).
In addition, any number of aliases , split by commas, may be surrounded in two at-signs to produce an enumeration, like so @@ Person 1, Person 2 @@
.
Contact button
Enclosing any sentence in triple at signs, e.g @@@ ask about featherdown @@@
will yield a contact button:
.
Site and Page properties
Site and page properties can be accessed directly by subsetting: page.
or site.
as deeply as needed. Some examples:
site.name
: Pedro's Workspage.title
: Featherdownsite.author
: Pedropage.update
:
Certain properties are automatically formatted , by default, e.g page.title
is always bold and dates are recognised as usual.
Functions
Any function can be called by name by enclosing its arguments in guillemets « »
, pipe-separated (|
), like this: MyFunction«arg1|arg2|...»
. Arguments will be assumed strings, not wrapped in quotes.
Buttons
A button can be created in the form [some content]›››FunctionCall()
. For instance [Press me!]›››alert(”Featherdown”)
yields the following button:
Dates
Dates are autodetected via the following patterns, and combinations thereof:
Pattern name | Example | Result |
---|---|---|
DD-MM-YYYY (day-month-year) | 17-10-2022 | |
reversed order | 2022-10-17 | |
slashed | 17/10/2022 | |
month named, short | 17-Oct-2022 | 17-Oct-2022 |
ordinals | 17th October 2022 | 17th October 2022 |
Date formats
To present a date differently, use the D« »
function with a format as the second argument.
Format | Code | Result |
---|---|---|
short date (default) | D«2022-10-17|Short» | |
long date (superscripted) | D«2022-10-17|Super» | |
long date (text only) | D«2022-10-17|Normal» | |
RSS | D«2022-10-17|RSS» | |
DD-MM-YYYY | D«2022-10-17|DD-MM-YYYY» | |
YYYY-MM-DD | D«2022-10-17|YYYY-MM-DD» | |
DD/MM/YYYY | D«2022-10-17|DD/MM/YYYY» | |
YYYY/MM/DD | D«2022-10-17|YYYY/MM/DD» |
Finally, you can use the verbatim operator to write a date precisely as you wish.
Changestream
A changestream is a chronological log of changes, one per line:
- starting with a bold date (date of change)
- containing some text afterwards (change summary)
Thus the following snippet **2023-09-06** Changestreams added to [featherdown]
will be formatted as:
Links
Three types of links are recognised: Outer links point to external pages, Page links point to other pages in the current domain, and Inner links point to page sections.
Links can be declared inline in a multitude of ways, using the []
operator and splitting arguments with |
.
Type | Full link | Code | Text shown | Reference |
---|---|---|---|---|
fragment | link | [#link] | link | #link |
'' | inline link | [inline link|#link] | inline link | '' |
outer | example.com | [example.com] | example.com | example.com |
'' | for example | [for example|example.com] | for example | '' |
page | Featherdown | [featherdown] | Featherdown | featherdown |
'' | Featherdown Page | [Featherdown Page|featherdown] | Featherdown Page | '' |
local file | featherdown.js | [featherdown.js|codes/core/featherdown.js] | featherdown.js | codes/core/featherdown.js |
page+inner | link table | [link table|featherdown#links] | link table | featherdown#links |
new tab (all types) | Featherdown | [featherdown|] | Featherdown | featherdown |
Fragment Links
As an additional shorthand to link to any heading in the page, enclose the first word from the desired heading in hashed brackets [#like this]
. Include more words at will - it just works. So frag ([#frag]
), fragment links ([#fragment links]
) or fragment links GALORE ([#fragment links GALORE]
) all point to the same heading.
With great power comes great responsibility: do not give two headings the exact same names, or only the first one will be referenceable. Likewise, linking a single word requires precision, because [#Inner]
becomes ambiguous when more than one heading starts with the word Inner.
Outer Links
Outer links (to external pages) open in new tabs by default. Anything starting with http
or that looks like a url will be usually recognised an outer link.
Auto outer links
If your url starts with http(s)
, and does not require a special title, you can even drop the brackets [ ]
, it will be recognised anyway. E.g. https://pedros.works/featherdown-cheatsheet
displays as pedros.works/featherdown-cheatsheet .
To prevent auto-linking, enclose the url in verbatim tags {{}}
.
Inner Links
Inner links (to other pages or files in this domain) open in the same page tab by default. Anything not recognised as an outer link will be seen as a inner link.
New tab links
To force any link to open in a new tab, end with an additional separator |]
.
Footnotes
Footnote Links
A footnote link is just a fragment link to a special footnote section. The short and long form.
Short form
To add a quick footnote, simply any integer inside a pair of square brackets 1 like so [1]
. Notice how it becomes automatically superscripted.
Long form
Longer footnotes can be created as a superscriptedsecond fragment link, like so: ^[#second]
. If not superscripted, it still works as a normal fragment link.
Footnote Sections
All footnotes should be added to footnote sections, fenced by three or more circumflexes (pointing up) ^^^
:
Footnote sections can be placed anywhere in the document, but typically appear at the end of a page or chapter.
If at the end of a document, the closing ^^^
fence may be omitted.
Implicit links
Currently, the first word/number of each line in a footnote is used to generate the target for the corresponding footnote link(s) in the document.
Automatic linking will be improved in the future TBA.
Footnote sections are.
Quotations
Any sequence of lines starting with
›
becomes a quotation.
This is written as follows. Captions, if added just below, specify authorship.
Obviously, trailing ›
are discarded, and spaces do not matter.
>>> Any sequence of lines starting with ´´>´´ becomes a quotation.
((The feather))
Captions
Captions are single lines wrapped in ((double parentheses))
, which can be added to:
Idea allow inline captions, after any item
Lists
Unnumbered lists
Unnumbered lists are recognised for any lines starting with an hyphen -
possibly preceded by tabs to indicate sublist depth.
Tabs or 4 spaces are interchangeable.
-´´- first element´´
-second element
-3^rd element
-3.1 (nested)
-´´3.2´´
-and deeper, as
-there is ==no nesting limit==...
-going // back one level//
-or //several levels at once//
This generates the list:
- first element
- second element
- 3rd element
- 3.1 (nested)
3.2
- and deeper, as
- there is no nesting limit…
- going back one level
- or several levels at once
Depth levels should be sequential, otherwise the closest sequential depth level will be used.
Typographical replacements
Some commonly used symbols can be typed faster with these replacements.
Punctuation
Name | Syntax | Result |
---|---|---|
em dash | -- | — |
ellipsis | ... | … |
interrobang | !? | ‽ |
irony | ?! | ⸮ |
ditto | ’’ | 〃 |
Math
Name | Syntax | Result |
---|---|---|
approx. equal | ~= | ≈ |
plus or minus | +- | ± |
minus or plus | -+ | ∓ |
per mille | %% | ‰ |
basis point | %%% | ‱ |
multiplication | :*: or :x: | × |
Miscellaneous
Name | Syntax | Result |
---|---|---|
arrow left | ‹- | ← |
arrow right | -› | → |
arrow both | ‹-› | ↔︎ |
copyright | (c) | © |
registered trademark | (r) | ® |
trademark | (tm) | ™ |
Ordinals
Writing a number followed by a th
, st
, nd
or rd
will automatically superscript the latter, correcting some possible errors: 11st
becomes 11th and 21th
becomes 21st.
Emoji
Natural emoji
Naturally, emojis can be directly typed ⭐!
Tip: press ⊞. (meta+dot) to launch the emoji palette on windows.
Named emoji
Emoji are referenced with :emoji-name:
. The first emoji matching (containing) the name is picked. This allows for very short abbreviations, but also more specificity where available.
Name | Syntax | Emoji |
---|---|---|
grin | :grin: | 😀 |
grin | :GRinniNG: | 😀 |
grin | :grinning-face: | 😀 |
rabbit | :rabb: | 🐇 |
rabbit | :rabbit: | 🐇 |
rabbit face | :rabbit-face: | 🐰 |
Admonitions
Prepend a single pipe |
to one or more lines to add an admonition:
The CSS class will be derived from the first word (or emoji), which won't be shown. The four classic admonition styles are:
Name | Recognised aliases | Emoji & colour | Example code |
---|---|---|---|
idea | idea, soon, futurely | 💡 purple | | **Idea** This is a novel idea |
info | tip, nb, note, information | ℹ blue | | **info** This is an important note |
pass | success, check, right, do, correct, yes, passed | ✔ green | | :check: This is very correct |
warn | warning, beware, careful | ⚠ yellow | | :warning: This is the last warning |
fail | danger, don't, wrong, no, nope, failed | ❌ orange | | :wrong: This is totally wrong |
ℹ If the first word is not a recognised name, it will form the basis for a new, custom css class.
Horizontal rules / line breaks
Horizontal rules mark a change in content, such as different chapters in a story or a thematic change.
A single line of 10+ underscores ________________
is recognised as one.
Invisible elements
Replacement rules
Any line containing the sequence :=
will be detected as replacement rule. These help minimise repetitive typing.
For example, the replacement rule hello:=hi
, replaces all hello
s into hi
s, across the page.
Comments
Any line starting with //
will be ignored.
Blanks
Blank lines are those containing nothing or just tabs and spaces.
They are almost never rendered, except amidst centered and right-aligned text.
That's a lot of info to take in. Luckily, there's a cheatsheet and a live Featherdown Playground.
You may also wish to read the technical notes, check the references.