,,,,,,

Featherdown

Updated on (created ) — Filed under: Docs Internal Post Resource Software Syntax

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 played with interactively.

Shall Featherdown be useful to you too, fell free to with any questions.

Headings can be added in ATX or Setex-like fashion. If both formats are used in the same header, the latter one wins.

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.

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 1hash#################
heading 2hash-equal#=#=#=#=#=#=#=#=#
heading 3equal=================
heading 4equal-dash=-=-=-=-=-=-=-=-=
heading 5dash-----------------
heading 6dash-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 are automatically placed around consecutive lines of text, as long as they do not match any other block element nor contain particular html tags.

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!

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 present a block of text across an automatic number of (newspaper-like) columns, useful for ultra-long lists:

Heading, ATX-like

Heading, Setex-like

Paragraph

Table

Grid

Polycolumn

Quotation

List

Figure, block

Figure, inline

Link, fragment

Link, inner

Link, outer

Code, fenced block

Code, inline

Verbatim

Admonition

Emoji

Typographical replacements

Caption

Definition

Shorthand

Comment

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.

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.

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 are declared by writing a single dash -.

1 2 -
4-6
-89

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. (tap) or (click) it to search in the next available table the bold keyword.

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.

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" }

Inline code snippets are added by wrapping a bit of code in two acutes, like so ´´ some code ´´.

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.

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:

the Featherdown logo

One extra line of captioned text may be added below a block figure to specify the maximum horizontal image size, under the following formats:

captioned text formats for sizing figures
Format Example Example result
Textsmall (also medium)
Pixels20px
Percent10%
Em units5em
Viewport units5vw or 5vh

Images can also be referenced and sized inline (but without a caption). Alternatively, the I shorthand can be used anywhere, with captions.

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~~redacted sentence text
++recent insertion (ins)++newly added++newly added text
||spoiler||hidden||hidden but revealed on click
^superscript (sup)basis^exponentbasisexponent
^^long superscriptsome ^^long super.^^some long super.
¨subscript (sub)log¨2log2
¨¨long subscript¨¨long subsc.¨¨text with a long subscript
´´code´´code snippet´´inline code snippet

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.

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/⌘CCtrl/⌘V.

A list of gestures exists.

Simultaneous keys or gestures are split by spaces, e.g. [[Ctrl tap]] to yield Ctrl/⌘Tap.

Sequential keys or gestures are split by commas, e.g. [[Alt, F]] to yield Alt/⌥F.

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 @@.

Enclosing any sentence in triple at signs, e.g @@@ ask about featherdown @@@ will yield a contact button: .

Site and page properties can be accessed directly by subsetting: page.  or site. as deeply as needed. Some examples:

  • site.name: Pedro's Works
  • page.title: Featherdown
  • site.author: Pedro
  • page.update:

Certain properties are automatically formatted , by default, e.g page.title is always bold and dates are recognised as usual.

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.

A button can be created in the form [some content]›››FunctionCall(). For instance [Press me!]›››alert(”Featherdown”) yields the following button:

Dates are autodetected via the following patterns, and combinations thereof:

Pattern name Example Result
DD-MM-YYYY (day-month-year)17-10-2022
reversed order2022-10-17
slashed17/10/2022
month named, short17-Oct-202217-Oct-2022
ordinals17th October 202217th October 2022

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»
RSSD«2022-10-17|RSS»
DD-MM-YYYYD«2022-10-17|DD-MM-YYYY»
YYYY-MM-DDD«2022-10-17|YYYY-MM-DD»
DD/MM/YYYYD«2022-10-17|DD/MM/YYYY»
YYYY/MM/DDD«2022-10-17|YYYY/MM/DD»

Finally, you can use the verbatim operator to write a date precisely as you wish.

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:

2023-09-06 Changestreams added to Featherdown

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
fragmentlink[#link]link#link
''inline link[inline link|#link]inline link''
outerexample.com[example.com]example.comexample.com
''for example[for example|example.com]for example''
pageFeatherdown[featherdown]Featherdownfeatherdown
''Featherdown Page[Featherdown Page|featherdown]Featherdown Page''
local filefeatherdown.js[featherdown.js|codes/core/featherdown.js]featherdown.jscodes/core/featherdown.js
page+innerlink table[link table|featherdown#links]link tablefeatherdown#links
new tab (all types)Featherdown[featherdown|]Featherdownfeatherdown

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 (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.

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 (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.

To force any link to open in a new tab, end with an additional separator |] .

A footnote link is just a fragment link to a special footnote section. The short and long 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.

Longer footnotes can be created as a superscriptedsecond fragment link, like so: ^[#second]. If not superscripted, it still works as a normal fragment link.

All footnotes should be added to footnote sections, fenced by three or more circumflexes (pointing up) ^^^:

1 This is the first footnote, referenced just like any fragment link second This is the second footnote, referenced as a superscripted fragment link 3 This footnote references the first1 and second footnotes

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.

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.

Any sequence of lines starting with becomes a quotation.

The featherdown

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 are single lines wrapped in ((double parentheses)), which can be added to:

Idea allow inline captions, after any item

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.

Some commonly used symbols can be typed faster with these replacements.

Name Syntax Result
em dash--
ellipsis...
interrobang!?
irony?!
ditto’’
Name Syntax Result
approx. equal~=
plus or minus+-±
minus or plus-+
per mille%%
basis point%%%
multiplication:*: or :x:×
Name Syntax Result
arrow left‹-
arrow right-›
arrow both‹-›↔︎
copyright(c)©
registered trademark(r)®
trademark(tm)

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.

Naturally, emojis can be directly typed ⭐!

Tip: press . (meta+dot) to launch the emoji palette on windows.

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:🐰

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
ideaidea, soon, futurely💡 purple| **Idea** This is a novel idea 
infotip, nb, note, informationℹ blue| **info** This is an important note 
passsuccess, check, right, do, correct, yes, passed✔ green| :check: This is very correct
warnwarning, beware, careful⚠ yellow| :warning: This is the last warning
faildanger, 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 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.

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 hellos into his, across the page.

Any line starting with // will be ignored.

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.

2022-10-29 Featherdown's logo was upgraded — it now describes itself, mirroring the syntax behaviour 2022-10-27 Featherdown now enables warping to the line and column in the source code corresponding to the page's cursor position, even within nested elements, another step towards full live editing. 2022-10-17 A new version of feather with many new features was crafted. 2023-09-29 The parser is now more robust against missing references (Random 8) 2024-11-04 All data-related items are now asynchronous via placeholders (once the data arrives, it is replaced everywhere), solving a concurrency issue (PinkHoodie, Justimagineit, Random 8) 2024-11-16 Removed grids, since they were not much used, for simplicity and also to eliminate an existing conflict.