
Show HN: Margin – A lightweight, flexible markup language for structured thought - nobody_nothing
https://margin.love
======
nobody_nothing
Hey Show HN!

I'd love some early feedback on Margin, a markup language for hierarchically
structured thought.

Margin came out of my desire to build a lightweight to-do app – though I soon
realized what I _really_ wanted was a markup language to capture structured
thought. One that was not only human-readable, but also easily machine
parsable.

Most importantly, Margin doesn't impose strict hierarchical categories (eg.
"Header 1", "Project", "Task"). Instead it allows the user/application to
define those categories. The ultimate goal is to democratize your to-do lists,
notes, writing, etc. making them portable and platform-independent.

Aside from feedback on the specs & philosophy of Margin, which would be very
appreciated, I could use some serious help with the parser
([https://margin.love/parser/](https://margin.love/parser/)). I'm only a
casual coder, so this problem was a difficult one for me. The parser is both
incomplete and buggy, but hopefully it gets across the basics of how Margin is
supposed to work.

Thanks!

~~~
macintux
Did you look at org-mode? That seems to me like the closest existing
implementation to what you’re attempting.

~~~
nobody_nothing
Org mode looks great, thanks for calling my attention to it. For anyone
looking for a brief introduction, they have a compact guide[1] on their site
that took me a minute to find.

It looks great for coders who are ready to learn new syntax. Though what I'd
really like to avoid with Margin is anything that makes the language more
complex than it needs to be.

For example, org mode defines headlines as:

    
    
        The headlines in Org start with one or more stars, on the left margin. For example:
        * Top level headline
        ** Second level
        *** Third level
    

With Margin, there's no concept of a "headline." For the thinker, the headline
could be represented by any level of the plain text hierarchical tree. And the
thinker would then be free to choose (or conform to) any Margin-based app that
corresponds with their model. In other words, it works best however you want
to use it.

[1] [https://orgmode.org/guide/](https://orgmode.org/guide/)

~~~
macintux
I understand the different approach, but the ecosystem that leverages it
aligns quite nicely with your goals. It’s anything from a todo app to a recipe
book to a financial planner.

I doubt there’s any way to take advantage of the common objectives, but if you
look at how the libraries build on the syntax, there might be lessons to be
shared.

------
pgcj_poster
I'm very eager to see this project develop. Looking at the examples, here are
my thoughts:

\- It seems like annotations should be excluded from the "value" field. If I
write something like "Frankenstein [author:Mary Shelley]", I'm probably going
to want to access the title "Frankenstein" on its own after parsing.

\- It would be nice to be able to omit the brackets when there's no whitespace
inside an annotation. For example, you could write "broccoli type:vegetable"
instead of "broccoli [type: vegetable]"

\- I like that you can use different list decorators, like -, >, or *. But
these don't show up anywhere except the "raw_data" field—it would be nice if
there was a field that contained just the decorator, something like:

    
    
       {
           "raw-data" : "\t- Some Item",
           "value" : "Some Item",
           "decorator" : "-",
           "annotations": {},
           "children": []
       }
    

Then you could easily use different decorators to encode semantic information.
For instance, a Pros/Cons list could use '+' for Pros and '-' for Cons, and
that distinction would be easy to access programmatically. If you do this, I
think "[ ]" and "[x]" should be end up in the decorator field. Or maybe it
could be a "prefix" field and "suffix" field, to hold decorators at either the
beginning or end?

~~~
harrisi
Just wanted to say, I think the second point is more awkward than it's worth.
Some examples:

\- check that video Alice mentioned at time 3:42 \- don't forget to text Bob
O:) \- my favorite thing is:strawberries

It makes parsing more complicated, as well as creating unexpected results in
non-obvious cases (for example the last one could just be a typo, and what if
it was instead written as 'is:strawberries, cake'?). It also isn't intuitive
in the case of your first example, since I think of Mary Shelley as a single
thing.

Alternatively, annotations could just read to EOL, unless it's explicitly
guarded off. That would depend on how people use it, I suppose.

~~~
pgcj_poster
This is the syntax used in todo.txt, which I've found works well, especially
if with syntax highlighting to guard against typos. You're right that it would
be harder to parse, especially if you carved out an exception for digits and
special characters to account for the examples you mentioned. I'll admit that
I'm not especially well positioned to weigh the benefit of syntactic sugar
versus the development cost of parsing, so perhaps you're right.

------
gorgoiler
Very enjoyable idea. The _ideas first, tidy up later_ ethos is one with which
many other software engineers will agree.

I haven’t written any Margin — I’ve only read through you documentation — but
maybe this feedback may be useful. (Apologies if you’re already doing all of
this, in which case it may be helpful to others at least.)

I love the idea of flexibility in how Margin can be used. Because if this
though, you will find emergent behavior among your user base. People will do
things you could never have imagined and expect Margin not to break their
workflow.

If you capture these as a standard test suite or set of test cases, it will be
very helpful to anyone implementing a Margin parser in another language.

You already have a reference parser in JS and if you get to the million user
mark (!) you might like to provide it in C instead. Something like libSYCK did
for YAML.

For now, having a test suite is the next best thing. While Margin is not
prescriptive about how you use it, you’ll want Margin _parsers_ to be strictly
in agreement in how they interpret Margin, for it to be widely adopted! Then
when someone sees Margin, finds it to be a good idea to use in their language
of choice, and writes their own parser they can confidently announces “
_passes 100% of the Margin test suite!_ ”.

~~~
nobody_nothing
Very elegant way to encourage adoption of the language! This is now on the
list[1], thanks.

[1]
[https://github.com/gamburg/margin/issues/4](https://github.com/gamburg/margin/issues/4)

------
Animats
"An outliner (or outline processor) is a specialized type of text editor (word
processor) used to create and edit outlines, which are text files which have a
tree structure, for organization."[1]

[1]
[https://en.wikipedia.org/wiki/Outliner](https://en.wikipedia.org/wiki/Outliner)

~~~
nobody_nothing
This is awesome! Thanks for sending, I actually didn't know about these.

The big difference here would be that Margin isn't an app, but a markup
language that's meant to be used as an open & portable storage system for
apps. A storage system that is, by design, human readable plain text.

I do love that there's an (albeit niche) interest in apps that let you
think/notate in this way.

------
tathougies
There should be an internet law that every supposedly new invention can be
found pretty much wholesale in GNU emacs

------
fomojola
Quite promising: one thing that would probably accelerate adoption would be to
provide at least one language parser that can go to/from the format to a data
structure of some kind.

~~~
nobody_nothing
Agreed! This is my biggest need. If you want to contribute, or know of any
open source libraries that might help me build a more robust parser, let me
know -- I'm only a casual coder, and this project really stretched my
capabilities of recursive thought ::o

The parser in its current form is here:
[https://github.com/gamburg/margin/blob/master/parser/js/Marg...](https://github.com/gamburg/margin/blob/master/parser/js/MarginParser.js)

~~~
oefrha
You could consider parsing into Pandoc AST (just need to output the JSON
representation of it). Then you can automatically interface with all the
output formats supported by Pandoc, including HTML. See pandoc --from json,
and [https://pandoc.org/using-the-pandoc-api.html](https://pandoc.org/using-
the-pandoc-api.html)

~~~
nobody_nothing
Thanks! This is useful.

------
nihilazo
As a long time user of vimwiki with an awful lot of hacks and plugins to work
for doing something like this, margin seems like the kind of thing I was
originally looking for. Vimwiki is great but suffers from having almost no
machine readability, which makes integrating it with things like time tracking
difficult without large, complex plugins.

However, margin doesn't really seem to have any equivalent of links between
files, which I find essential for organising thoughts in anything beyond small
notes. This seems like something that's contrary to the philosophy in a sense,
but what would be the margin-ish equivalent of something like that, and
(following from that) things like file tags? Would those be done with
annotations?

~~~
nobody_nothing
Good question. I do think this would be achievable through annotations if an
application were determined to do it. Annotations are sort of the catch-all
for added functionality.

The philosophical question is an interesting one. I think for the most part,
if items are meaningfully related, the Margin philosophy would probably be to
store them within the same document parent (or file).

------
pipingdog
This shows great promise. I've been looking for various ways to impose
semantics on markdown for note taking, and they all turn out to be too
complex. This is very simple, has goals which are distinct from markdown, and
has the potential to build something queryable.

------
brigandish
I like this a lot and will think about using it in an app I'm planning to
build, but I have one quibble with something in the docs:

> you wouldn’t build a web app in markdown

I'm willing to bet it's been done and has already been a Show HN. After all,
there's "My blog is now generated by Google Docs"[1] currently on the front
page of HN. If not then it's only a matter of time :)

[1]
[https://news.ycombinator.com/item?id=23134101](https://news.ycombinator.com/item?id=23134101)

~~~
nobody_nothing
Great to hear you'd consider using it. If when building the app you find
yourself wanting to contribute to the js parser[1] in any way (or even any non
javascript-based parser), it'd be much appreciated. That's my biggest need
right now, is actually writing a good parser that'll encourage people to try
this out.

And fair, re: "you wouldn’t build a web app in markdown". I'm sure it's been
done :)

[1]
[https://github.com/gamburg/margin/blob/master/parser/js/Marg...](https://github.com/gamburg/margin/blob/master/parser/js/MarginParser.js)

------
kortex
This is excellent! The one thing I really like is the annotations. Been
looking for a way to embed k:v attributes in a parseable markdown, for making
metadata of codebases and datasets.

How are URL's handled? One solution would be to just reuse Markdown's
[link](text) notation, as a subset of annotations. That would be the least-
mental-friction route for markdown users.

~~~
nobody_nothing
Love this idea! Thanks for adding it to the GitHub.

------
rcthompson
You mention that apps can safely ignore annotations of unknown types, but you
should probably specify that they are still expected to preserve such
annotations even if they don't use them for anything, i.e. ignore doesn't mean
"discard".

~~~
nobody_nothing
Added[1]! Thank you.

[1]
[https://github.com/gamburg/margin/commit/d9abf003f665627d392...](https://github.com/gamburg/margin/commit/d9abf003f665627d39288ff5036ee2af49abd9fd)

------
beshrkayali
Alternately, use Org mode.

------
solarkraft
On first look this appears like a great foundation for a new ecosystem of
outliners. Awesome!

The processing of my 6000 lines Dynalist export (perfectly compatible due to
the permissive syntax!) took about 1 second on an i7 from 2015.

------
cborenstein
This project looks awesome. I created bytebase.io, a notes app that shares
much of the same philosophy - flexible hierarchy, simplicity, user control.

We'll definitely consider supporting import/export to Margin.

~~~
nobody_nothing
Beautiful site. And I agree, very similar philosophy to Margin. Just requested
access, excited to give it a try.

------
michael-ax
I'd love to post these notes from my phone to my server, translated into org-
mode as they go :)

------
fernly
Does it deal in any fashion with longer blocks of text than a single line?
Paragraphs under a heading?

~~~
nobody_nothing
Not yet, but it's on the list!
[https://github.com/gamburg/margin/issues/2](https://github.com/gamburg/margin/issues/2)

Definitely a necessary feature if people are going to use this to store text.
Do let me know if you have any ideas about what kind of syntax might be best
for multiline blocks -- keeping in mind it should be both easy to type and
easy to read (eg. ideally avoiding '\n' or special newline characters, for
example).

------
auggierose
For Mac users, I found that these two apps together cover a lot of my needs:
Things 3 and Quiver.

------
ipsum2
This is awesome! I've had thoughts along these lines, I like your annotation
idea. Excited to see how this project grows.

------
alphachloride
My understanding is that this is a nested list parser. Nested lists are
defined by the indentation level. Metadata for items can be specified by
square brackets.

I don't see how this is different than just opening notepad.exe and writing
stuff.

~~~
nobody_nothing
Exactly! The idea here is to formalize the already intuitive way many of us
use plain text. Once the syntax is formalized, it can be utilized by
applications. This way your data remains in a portable, non-proprietary format
that can be reliably parsed - whether you choose to use notepad.exe or a
Margin-specific application, you already have everything you need.

------
math0ne
My first thought is I hate tabs.

~~~
zapzupnz
So use spaces. Solved.

------
mirimir
Is it possible to run locally?

~~~
OJFord
Run what?

> Lightweight markup

> The plain text language

> Margin is a lightweight markup language

> Margin can thrive within any plain text editor

> Margin is not an app, but a markup language.

The author's experimental parser? It's linked:
[https://github.com/gamburg/margin](https://github.com/gamburg/margin)

