gamburg / margin

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

Links/anchors #10

Closed xkortex closed 4 years ago

xkortex commented 4 years ago

Links, being an essential part of hypermedia, ought to be first-class citizens in Margin. I can see a few ways of doing this:

Markdown-compatible (would require modifying parser, but less friction for md users): [example.com](my example)

Quasi-HTML (works with parser, harder to "wrap" text to make it a link) [a:example.com]

My vote is for the former. Basically, simple [] is treated as an annotation, while the []() pattern is treated as a link.

I found this cool thing called [Margin](github.com/gamburg/margin)

would parse as

{
               "raw_data": "   I found this cool thing called [Margin](github.com/gamburg/margin)",
               "value": "I found this cool thing called Margin",
               "annotations": {},
               "links": [
                    {"ref": "github.com/gamburg/margin", "value": "Margin"}
               ],
               "children": []
}
vlmutolo commented 4 years ago

I think there’s a lot of value to keeping Margin small and simple. The annotations syntax is really powerful. Adding a special case for links seems a bit cluttered when [a: example.com] works so well.

It seems like the real issue is that there’s no way to attach annotations to only part of an item. Maybe the syntax for that could look like a variant of Markdown’s links.

item A has a (link [a: example.com])
item B has regular (text with parentheses)

This is nice because it’s flexible and applies to arbitrary kinds of annotations. Another example:

Calendar
    I have a (doctor’s [name: Dr. Smith]) appointment
vlmutolo commented 4 years ago

Another thought: the parser should probably return regular text for these types of annotations (spanned annotations? restricted? partial? idk what the right name is). And it should also return another field with a list of “spans” and annotations for those spans. The spans should probably be utf8 byte ranges. Not sure how well JS supports that, though.

Example:

A (B [a: example.com])

would be parsed as

{
    "raw_data": …,
    "value": "A B",
    "spans": [
        {
            "start": 2,
            "end": 3,
            "annotations": [{"type": "a", "val":"example.com"}]
        }
    ]
}

That way, applications can easily ignore the spanned annotations.

mtsknn commented 4 years ago

I agree with @xkortex that supporting links might be good.

I also agree with @vlmutolo that adding special syntax for links would be unwarranted if annotations could be used instead. An additional benefit of annotations is that there can be many of them:

Do you use (DuckDuckGo [a: duck.com] [title: A nice search engine])?

The syntax might be too ambiguous though. Maybe one of these or something similar would be clearer while still maintaining simple syntax:

Calendar
    I have a #(doctor’s [name: Dr. Smith]) appointment

Calendar
    I have a {doctor’s [name: Dr. Smith]} appointment

These could be escaped with \#( ... ) and \{ ... }. That's better than having to escape regular parentheses.

xkortex commented 4 years ago

Yeah, working links into the annotation syntax definitely helps keep the complexity down. At some point it just becomes Markdown.

I wouldn't use # inline syntactically (other than for #hashtags of course).

Curly braces are definitely more programmer-y than parens.

It seems like the real issue is that there’s no way to attach annotations to only part of an item.

Agreed. If you have a long paragraph, such as a research paper with in-line citations, you probably want to keep track of where in the text those annotations are, if you plan on e.g. piping this into pandoc. Solving that would solve links as well, since links are really just a specific kind of annotation.

There's a nice symmetry about {text [a: uri] [foo: bar] [spam: eggs]}. It maps well to html: <a href=uri foo=bar spam=eggs>text</a>. In terms of parser design, parsing (finite) nested bracketing symbols {[]} is easier than constructions like []() (and way easier than <tag>text</tag>). At least I think it is(I'm a bit rusty). The former is an s-expression. The latter requires branching once you encounter ](, and is a little less intuitive to process.

The question is how do you notate that in the json. Gotta think on that one.

gamburg commented 4 years ago

I worry about specifying a special annotation type for links, since it's not how most of us store URLs in our plain text notes.

How about adding suggested annotation types http and https to the spec?

If we went this direction, here's how interpreting applications (who conform to the suggested annotation types in the spec) would display the following markup:


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

→ I rarely use Yahoo anymore.


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

→ Sometimes I do read Yahoo News, though.


If you want to check out a search alternative, try https://duckduckgo.com.

→ If you want to check out a search alternative, try https://duckduckgo.com. This one is up to the interpreting application, but most apps would likely choose to hyperlink this text.


DuckDuckGo[duckduckgo.com] has an emphasis on privacy. Feel free to (check out their values)[www.duckduckgo.com/about].

DuckDuckGo has an emphasis on privacy. Feel free to check out their values. Also totally up to the interpreting app, since these annotations are of type duckduckgo.com and www.duckduckgo.com/about (an annotation's type is whatever comes before the first optional :). But most apps would likely choose to hyperlink any annotation whose type appeared to be a link.


This would require no changes to the json notation, as the parsing of the link and its placement could be done by the interpreting application at the value level.

In other words, I propose leaving this largely up to the interpreting application, but giving users who really want their links to be tied to specific text a basic syntax for that (i.e. parentheses).