mbakeranalecta / sam

Semantic Authoring Markdown
Other
79 stars 8 forks source link

Syntax of inserts by reference #161

Closed mbakeranalecta closed 6 years ago

mbakeranalecta commented 6 years ago

I think the syntax of inserts is incorrect. Currently, a direct insert is:

>(image foo.gif)

To which you can add attributes:

>(image foo.gif)(#foo)

But if you want to insert by reference, it is currently:

>(#foo)

This is inconsistent with the rest of the language where we use a citation to dereference an identifier. It also means that (#foo) in the first position means the opposite of what it means in the second position. In fact, you could end up with an expression like this:

>(#foo)(#bar)

In this case, the (#foo) and (#bar) would have opposite semantics, the first dereferencing a name and the second creating one.

More consistent syntax for this would be:

>[#foo]

There is still the question of how this serializes, however. It does not serialize to a regular citation but to:

<inline-insert nameref="foo"/>

And it does not support the full range of citation syntax. For instance, you can't do:

>[Melville 1884]

Or:

>[#foo page 6]

This would obviate #160

mbakeranalecta commented 6 years ago

Of course, there is the possibility of someone doing this:

>[#foo][Melville 1884]

I'm not really sure what they would be trying to achieve with this, but that is an application layer problem. I don't think it has any bearing on the syntax question.

mbakeranalecta commented 6 years ago

Need to consider that this would affect insertion of strings and fragments as well:

>[$foo]

>[~foo]

We should note the difference is between this and the regular use of citations.

 [#foo] 

resolves to a reference to an object #foo ( "see figure Foo" for example)

>[#foo] 

inserts the contents of an object #foo (that is, inserts figure Foo at this location in the document

This seems to be consistent with this useage.

It does raise questions about what a bald citation of a string or fragment would mean. Since these are not referenceable things, you cannot create a reference to them. You can only insert them. So these forms should be syntactically invalid, which, in fact, they are.

mbakeranalecta commented 6 years ago

Implemented in 6579adbaa5edbfb15eacf3e288d4ddc89a17c4ef.

mbakeranalecta commented 6 years ago

I'm beginning to think this was resolved the wrong way. I find myself getting the insert syntax wrong all the time because I type >(*foo) because I am used to typing direct inserts as >(image foo.gif).

Both the reference form and the direct form serialize as inline inserts, meaning we have two different syntaxes for inline inserts. It also means that the syntax of a citation does not always resolve to a citation.

This was all in aid of solving the problem of what this means:

(#foo)(#bar)

The problem being that by the old syntax, the first (# dereferences a name while the second defines one.

This is a significant issue, so we can't just roll back the change. A few alternatives occur to me if we go back to parens for inserts by reference:

No attributes on inserts

We could simply outlaw attributes on inserts altogether. There is no obvious reason that an insert needs a name or an id. What would you do with it? Use it to insert a copy of the original insert? The only possible reason I can think of to add an attribute would be to make the insert conditional. That could be handled using a fragment.

~~~(?bob)
     >>>(*bar)

That does not work for conditional inline inserts though.

No names or IDs on inserts

Since there is no clear advantage to ids or names on inserts, and since the confusion only exists for ids and names (you can't insert a condition, and you can't create a key with an attribute). This is a bit eccentric but might be cleanest. There is also a very good chance it won't break the semantics of any existing documents. (Clearly they will have to change syntactically.)

Different brackets for inserts

Use different brackets for inserts, thus avoiding any confusions with parens. The problem is a lack of candidates. [], {}, amd () are all in use. That leaves <>. I just don't like:

>>><#foo>

No brackets for inserts by reference

This is only really an issue for inserts by reference. Technically, since references are name tokens, and can be delineated by a space or non-name-token character, we don't actually need parens at all:

>>>#foo

>>>*bar(?bob)

Perfectly clear, but I still find it more lucid to have parens:

>>>(#foo)

>>>(*bar)(?bob)

That just seems more SAM-like.

Return to the old syntax anyway

Sure, >(#foo)(#bar) is a bit eccentric. But if you parse it as >(#foo) vs (#bar) then the syntax actually is different. Is this really confusing enough to make a different different solution necessary for what seems to be an unlikely use case anyway?

mbakeranalecta commented 6 years ago

Implemented switch back to >(...) syntax as of 32b73f2a19e978746cfe8b893f29867b7da92a64

mbakeranalecta commented 6 years ago

Documented in 1c75cbc4a61a7bfbb82c3d77216f4a7b2975150e