gamburg / margin

Lightweight markup designed for an open mind
https://margin.love
MIT License
190 stars 9 forks source link

Philosophy

Margin is a lightweight markup language for hierarchically structured thought, like notes and to-do lists.

Its platform-independent structure is both human- and machine-readable.

This means that Margin can thrive within any plain text editor, and on any hardware -- even paper.

However unpredictably a thinker prefers to indent, ornament, number, or label their text, Margin will interpret their items predictably:

Favorite Movies
   Eyes Wide Shut
   Black Narcissus
   Adaptation

[Is equivalent to...]

Favorite Movies:
  - Eyes Wide Shut
  - Black Narcissus
  - Adaptation

[Is equivalent to...]

** Favorite Movies **
    > Eyes Wide Shut
    > Black Narcissus
    > Adaptation

This allows the thinker to adopt whatever visual grammar they prefer.

Items can also be assigned arbitrary annotations, which can store meta data:

Favorite Movies
   Eyes Wide Shut [year: 1999]
   Black Narcissus [year: 1947]
   Adaptation [year: 2002]

Annotations can also signal how items should be interpreted, e.g. as tasks:

Movies to watch:
   [x] Shoplifters
   [ ] Lawrence of Arabia
   [ ] Inland Empire

Margin is especially useful for applications that wish to be less prescriptive in their mental models, leaving it to the user to determine how they'd like to interpret the hierarchical structure.

Margin aims to shepherd apps away from the tendency to overcomplicate and over-define.

Points of frustration that led to Margin {docsify-ignore}

There are plenty of well-known, powerful applications that force their own organizational philosophy on the user. And there's nothing inherently wrong with that.

Nevertheless, when an application's user-facing models of thought...

  1. cannot be easily mapped to the user's own mental models, or
  2. are not justified for the user,

it can lead to frustration. For example:

I use and love all of the above applications. Their specialization is their strength. Margin's philosophy simply asserts that there is space for a more adaptable standard for stuctured thought.

In this respect, Margin promotes a common sense approach to modeling thought: simply place the thinker's preferences first.

This approach begins with a flexible plain text standard. After that, it is the application's job to improve the thinker's experience through specialized tools and prescriptive user-facing models -- as long as the underlying source material remains portable and human-readable.

Margin is free and open-source.


Syntax

Margin employs an ordered tree data structure whose nodes are called items. Indentation forms the basis of the syntax.

Items

Each line represents an item:

Shirt
Pants
Shoes

Each item can have a single parent and multiple children. Indentation alone determines this hierarchy:

Shirt
  Collar
  Sleeves
  Buttons
Pants
  Belt loop
  Pockets
Shoes
  Tongue
  Laces

Leading & trailing dashes, colons, asterisks, chevrons, underscores and whitespaces, as well as blank lines, are ignored:

    ** Key Takeaways **
    -------------------
       Feel free to use plain text decorations freely in order to:
         - Help structure your thinking
         - Make your plain text documents more easily scannable

See the list of all ignored characters.

Annotations

An annotation is any childless item wrapped in square brackets:

I'm a plain old item
   [and I'm an annotation]

Annotations can be used to store meta data:

The Crying of Lot 49
   [author: Thomas Pynchon]
   [publication year: 1966]
   [publisher: J. B. Lippincott & Co.]

An annotation is the child of any inline, non-annotation item:

Items:
  - Item A
  - [I belong to Item B] Item B [I also belong to Item B]
  - Item C
      [I belong to Item C]

Because annotations cannot have children, an indented item following an annotation is considered that annotation's parent:

Items:
  - Item Y
        [I belong to Item Y]
  - [I belong to Item Z]
        Item Z

Escape an annotation with a backslash:

This is an item \[but this is not an annotation]

Any text up until the (optional) first colon in an annotation may safely be interpreted as the annotation type.

Annotations with type population:

Continents
   Asia          [population: 4,601,371,198]
   Africa        [population: 1,308,064,195]
   Europe        [population: 747,182,751]
   South America [population: 427,199,446]
   North America [population: 366,600,964]
   Oceania       [population: 42,128,035]

Annotations with types waiter and host:

Restaurant Staff
  Christine [waiter]
  Steven [waiter]
  Jessica [host]

An annotation whose type is not understood by the interpreting application may safely be ignored (but should not be discarded):

[For example: this annotation won't be utilized unless the app has an interpreter for type "For example".]

An annotation cannot be nested:

[This entire sentence [including this text] represents a single annotation]

Interpreting Items

While there are no hard-and-fast rules about how items should be interpreted, the following are good guidelines for most applications.

Tasks

A task is any item that parents an annotation of type x or empty string:

Daily Rituals
  [x] Meditate
  [ ] Work Out
  [ ] Read for 10 minutes

Links

An annotation of type http or https represents a link:

Some people choose to set their homepage to [http://www.google.com].

Text to the left of the annotation not separated by an empty string is the link's label:

I rarely use Yahoo[http://www.yahoo.com] for search anymore.

For multi-word labels, wrap the entire label in parentheses:

Sometimes I do read (Yahoo News)[https://news.yahoo.com], though.

Indexes

An index is any item that parents an annotation of type filter:

Now Playing [filter: release date is before tomorrow]
Coming Soon [filter: release date is after today]

An application may use the specified query to filter for certain nodes under certain conditions of interaction. For most applications, the default filter for a given task (when no filter is specified) would be that task's children. But this is outside the scope of the markup language itself.

Document Parent

Every Margin document has an implied document parent, an item that parents every top-level item in the document. This item can also have annotations, which can be useful as document-level meta data. These annotations are defined as the first apparently parentless annotation in the document:

[Kid Reader Pro]
[Reader Name: Kit Mapache]

Read:
 - The Phantom Tollbooth
 - A Wrinkle in Time
 - Charlotte's Web

Unread:
 - Where the Wild Things Are

Try it out

The Margin JavaScript parser is currently in alpha. You can try it out for yourself here, but note that some functionality defined in this spec will not yet function properly.

Implementations

Questions

Why not TaskPaper?

TaskPaper is a great, minimal app for creating to-do lists. Some readers might feel that Margin's capabilities are redundant, but I believe Margin stands apart in several key ways:

Indentation? Human-readable? Won't a complicated Margin document just end up as a jumbled mess of deeply indented text blocks and annotations?

Margin isn't meant for storing complex databases. It's meant to make text-based structured thought portable and platform-independent. In the same way that Markdown is built to translate into HTML, but you wouldn't build a web app in Markdown, so Margin too has its limitations. The idea is to de-formalize any unnecessary syntactic requirements, leaving only indentations and a select number of special operators to dictate the parsing of the language. Keeping it simple has its benefits, but it also has its costs.

What is the preferred extension for Margin files?

Margin files use the extension .margin.

Does Margin support multi-line items?

No. But if you're writing in Margin and you really want items to span multiple lines, feel free to use whatever syntax appeals to you to acheive that. Margin certainly doesn't care what you do in the privacy of your own plain text editor. Just don't expect those multi-line items to be interpreted properly by a given application.

Where can I send feedback?

Please submit any feedback as an issue on Margin's public GitHub repository.