Android-FileBrowser-FilePicker
Android-FileBrowser-FilePicker copied to clipboard
Proposal: a new general purpose Block extension
I haven't solidified the proposal yet, but I am envisioning something like a fenced code block (except its not for code and would use different delimitators) which might support two different block types:
- Element Block: The user would define the HTML element (tag) and any attributes. This would be simpler to deal with (read, write and parse) that md_in_html as it avoids lots of HTML tags in your Markdown.
- Templated Block: The user would define the block 'type' and any attributes. So long as a template exists for the 'type', then the content is inserted into the template after being parsed as Markdown.
Therefore, if the user provided div (for an element block), the content is parsed as Markdown and then wrapped in a div element with any additional attributes being set on the div. However, if the user provides a 'type' of admonition, then the admonition template is used. Presumably the template would expect a set of attributes (including the admonition type), a title and a body and insert those values into the HTML template. Other templates might accept other options.
This would also allow users to use the CSS provided by whichever CSS framework they are using. For example, the MkDocs default theme is using Bootstrap, which provides it own set of alerts. However, MkDocs doesn't use them, but instead also provides CSS for Rst style admonitions because that is what the admonition extension expects. With a new block extension, a Bootstrap alert template could allow Bootstrap's CSS to be used along with all of Bootstrap's alert features (icons, dismissal, etc) removing the need for the MkDocs theme to also include the Rst based CSS.
A few additional things to note:
I would prefer to not add any new extensions to the core library. So I would expect this to be developed in a separate repo. However, I mention it here because it could effect how we proceed with #1174. Also, I would appreciate any feedback on the idea and/or input on a possible syntax proposal.
My initial proposal suggests that these blocks are different from fenced code blocks, but another option would be to use the fenced code block delimitators and also provide for a 'code' type. In our implementation, a user could provide their own 'code' template which might allow them to provide their own custom syntax highlighting solution. If we went this way, the user would simply use this extension instead of the fenced_code extension, avoiding any conflicts.
I am undecided which way to go on this. Do we overload fenced code blocks, or create a completely new and different fenced block? Similar approaches (overloading fenced code blocks) have been taken by other implementations. For example r-markdown uses fenced code blocks to define the r code which is executed with its output being included in the rendered document. I have also seen at least one Markdown-to-reStructuredText bridge which used overloaded fenced code blocks to replicate directives (sorry, I don't recall which one). To my mind, the primary benefit of overloading fenced code blocks is that when a document using the blocks are parsed by other Markdown implementations, the block is simply parsed as a plain code block. In contrast, introducing a completely new syntax could result in some weird output from other implementations. The only reason the existing admonitions extension mostly avoids this is because the content is indented and becomes a code block. But I would prefer to not indent the content of the new block.
In general, when I went through the pain of getting fenced blocks to work under lists and such via SuperFences, I just made it so that users could create custom fences to generate whatever kind of block they wanted. With that said, it still doesn't run inline with normal block processors, so it has some limitations as the content is stored under placeholders like code.
I'd love an approach that uses the normal block processors, and if it is possible, I'd love to see how that would work.
- The way Python Markdown currently normalizes line breaks and such between blocks is frustrating for code blocks as any code blocks with multiple empty lines always get normalized to one.
- Even in Admontions there is still a degree of complexity involved with appending additional blocks as children and accounting for lists and such. I think this is partly due to how Python Markdown consumes blocks.
Anyways, I'm at least interested to see how this may potentially work.
@facelessuser you make some valid points. I have not looked too closely at how you implemented superfences, and was curious how you worked around the problems with the existing block parser. Sounds like you didn't. It may not make sense to even attempt this until after we refactor how blocks are parsed. However, I'm not really interested in tackling that problem right now. Mostly I am simply trying to get my ideas recorded at this point. I haven't given much thought to how it might be implemented.
See also Pandoc Markdown's Divs and Spans https://pandoc.org/MANUAL.html#divs-and-spans which have a bit different but similar idea.
@facelessuser you make some valid points. I have not looked too closely at how you implemented superfences, and was curious how you worked around the problems with the existing block parser. Sounds like you didn't. It may not make sense to even attempt this until after we refactor how blocks are parsed. However, I'm not really interested in tackling that problem right now. Mostly I am simply trying to get my ideas recorded at this point. I haven't given much thought to how it might be implemented.
Yeah, I accomplish everything through the preprocessor still. It's a bit hacky, but it was the only way to avoid the above issues. Anyways, I think this is a good idea, and generally, if/when block parsers are able to handle blocks better, this will be a good addition on top of it.
As a user, I think this is a wonderful idea!
I'm currently migrating a mediawiki site to git/markdown. For admonitions, the pandoc mediawiki→markdown converter produced ::: warning, which is the same that markdown-it, docusaurus and some others use. It'll take time to update hundreds of wiki pages to !!! warning and indented content that mkdocs uses. Also, if I ever need to switch away from mkdocs in the future, I'll have to convert the content once more.
The ::: class (and the ::: tag) ideas are so powerful, that will probably make !!! admonitions obsolete if they're implemented! I hope we can see this in production soon! :)
Just stumbled upon MyST, a Commonmark parser which is intended as a reStructuredText replacement. I've seen many before, but this is the first one where I like the directives syntax. It is very similar to what I was trying to accomplish here. See also, their optional colon_fence extension, which looks similar to (but not the same as) Pandoc's syntax.
Also of interest is their discussion of various existing proposals and implementations out in the wild and why they chose what they did.
Just stumbled upon MyST, a Commonmark parser which is intended as a reStructuredText replacement. I've seen many before, but this is the first one where I like the directives syntax. It is very similar to what I was trying to accomplish here. See also, their optional colon_fence extension, which looks similar to (but not the same as) Pandoc's syntax.
Unfortunately, us doing code this way, without a huge overhaul of the parser to get block handling where we want, may not be possible. And I definitely wouldn't try to use the ```{directive} format unless the block handling was refactored as the only real way to properly preserve code is using the PreProcessor, and that syntax will conflict with fenced code (at least as things are currently).
But, if you don't need to preserve empty lines and such for code blocks and you just want to handle normal Markdown content, it may be possible to cook something up now. I've been considering possibly tinkering with a way to pull this off now that I've had some time to think about it, at least the logic in regards to the handling of the "fences". Assuming some sort of prototype could be pulled off, we'd at least have something to work with now.
So, I actually started to play around with this, and it is in a very early prototype stage. I wanted to make sure I could get it to work in lists and such. I kind of played with the directive syntax some. I'm not sure if anything below, syntax or behavior-wise, will be the final implementation, but this is currently just exploratory.
The thing I like is that you don't have to do indentations for admonitions and such, and it doesn't break my editor's syntax highlighting :). I guess some common admonitions could be created like warning and if people want something different, they could use the generic admonition type. Anyways, this was a simple test:
-
::::{admonition} This is really important!
---
type: warning
---
Don't do that, for these reasons:
-
:::{details} Here is a summary
This is nested!
:::
::::
:::{html} div
---
attributes: {id: some-id, class: these are classes}
---
Some other content
:::
Results
<ul>
<li>
<div class="admonition warning">
<div class="admonition-title">This is really important!</div>
<p>Don't do that, for these reasons</p>
<ul>
<li>
<details>
<summary>Here is a summary</summary>
<p>This is nested!</p>
</details>
</li>
</ul>
</div>
<div class="these are classes" id="some-id">
<p>Some other content</p>
</div>
</li>
</ul>
So far the directives are pretty simple objects. They have on_create events and on_end events. You can store the content as you accumulate it and then process it once you hit on_end, or not store it and let the Markdown parser just parse it as Markdown content. That's really it.
class DirectiveTemplate:
"""Directive template."""
# Set to something if argument should be split.
# Arguments will be split and white space stripped.
ARG_DELIM = ''
NAME = ''
STORE = False
def __init__(self, length):
"""Intitialize."""
self.store = []
self.length = length
def config(self, args, **options):
"""Parse configuration."""
self.args = [a.strip() for a in args.split(self.ARG_DELIM)] if args and self.ARG_DELIM else [args]
self.options = options
def on_create(self, el):
"""On create event."""
def on_end(self, el):
"""Perform action on end."""
Anyways, I figured I share it and see if people had any thoughts.
Yeah, it is pretty easy to just derive to create shortcut for Note admonitions and such:
class Admonition(DirectiveTemplate):
"""Admonition."""
NAME = 'admonition'
def on_create(self, parent):
"""Create the element."""
el = etree.SubElement(parent, 'div')
t = self.options.get('type', '').lower()
title = self.args[0] if self.args and self.args[0] else t.title()
classes = [c for c in self.options.get('classes', '').split(' ') if c]
if t != 'admonition':
classes.insert(0, t)
classes.insert(0, 'admonition')
ad_title = etree.SubElement(el, 'div', {'class': 'admonition-title'})
ad_title.text = title
el.set('class', ' '.join(classes))
return el
class Note(Admonition):
"""Note."""
NAME = 'note'
def config(self, args, **options):
"""Parse configuration."""
super().config(args, **options)
self.options['type'] = 'note'
And then this:
:::{admonition} This is really important!
---
type: warning
---
Don't do that!
:::
:::{note}
Just a note
:::
:::{note} With a title
And some words.
:::
Becomes this:
<div class="admonition warning">
<div class="admonition-title">This is really important!</div>
<p>Don't do that!</p>
</div>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Just a note</p>
</div>
<div class="admonition note">
<div class="admonition-title">With a title</div>
<p>And some words.</p>
</div>
Very cool. Although, when I initially proposed a template block, I meant to actually use a template. Something like the following, which would allow the end user to define any layout they want.
<div class="admonition {{ type }}>
<div class="admonition-title">{{ title }}</div>
{{ body }}
</div>
Of course, that would ideally end up as part of the etree, which adds additional complications, so I understand why you haven't taken that approach. It's just that requiring users to use the etree API to define their own custom blocks narrows the target audience. Although, I suppose for specific predefined block types like admonitions, using the etree API is probably more performant. However, a wrapper around what you have so far could provide a more general purpose system which uses actual templates. I just wouldn't name what you have "template."
However, a wrapper around what you have so far could provide a more general purpose system that uses actual templates. I just wouldn't name what you have "template."
Yeah, the idea of templates wasn't really laid out, and I do realize what I have isn't a template. The naming is quite wrong in that regard. I haven't even thought about true templates yet. I'm still working through getting the blocks to not get messed up when passing through lists. There are always list corner cases...always 😢 .
I feel there is an advantage to more advanced, non-template type variants, but I can also see the attraction for actual tempaltes.
I did get "templating" working. But it seems to offer a host of troublesome situations. We have to create a temporary div to let Markdown figure out the context and properly wrap things in <p> and such, but it doesn't have any intelligence to know which variables need escaping and which will be handled by Markdown. Also, what if you insert the content into something that requires preserving the text (like in a code block).
It's all kind of a pain. I haven't even bothered to try and figure out all the templating cases, just wanted to see if we could utilize the existing system to convert templates into directives:
TEST = """
<div class="{directive}">
<div class="test-title">{arg0}</div>
{body}
</div>
"""
:::{test} A title
Some **content**
More content
This is code
:::
<div class="test">
<div class="test-title">A title</div>
<p>Some <strong>content</strong></p>
<p>More content</p>
<pre><code>This is code
</code></pre>
</div>
So, could it kind of sort of work? Yeah, is there a lot more intelligence that would have to be added? Probably. Is it worth the effort? 🤷🏻 How much motivation do I have to plow through and get a fully working template approach? :shrug:
Knowing that a template approach is probably viable is probably enough for me right now. I think my main concern is making sure the general flow is fairly sound and maybe putting up an experimental branch over at pymdown-extensions.
I think I have most major list flow issues solved.
I guess you could maybe make available an escaped-body and a body that could dictate what kind of temporary element gets created to store the content. For the rest, you just have to kind of assume the user won't feed in bad content as there is no way to be for sure about context.
If the user is creating a series of elements that require their own different body each with different requirements...too bad 🙃 . I think the template case shouldn't be allowed to be that complicated. If they have a greater need, they shouldn't use the template approach.
I guess I should state that currently, templates with nested directives fail...not sure why though. I'll have to dig a bit deeper.
I think leaving templates as something to tackle later is a reasonable approach. My initial proposal was simply trying to present an ideal situation from the user's perspective with no thought to how it would be implemented. I'm sure its possible, but it may not be worth the effort.
Yeah, that sounds good. That's probably going to be my approach for now. I think my current issue is the fact I'm swapping out the placeholder with the real template element during the block processor phase...but maybe that kind of operation shouldn't happen until after the block processor phase is over...
I'm certain it s doable, but I think getting a sound base before I burn up my motivation is key 🙂.
Anyways, I'll keep experimenting as I have time and then pair down to what I think is most useful once it seems the obvious issues are resolved.
I've found something particular about list handling that won't allow:
- ::::{admonition} This is really important!
---
type: warning
class: some-class
---
It gets all messed up and turns them to hr blocks and such. This doesn't happen outside of lists.
I'm going to prototype with ~~~ for now:
- ::::{admonition} This is really important!
~~~
type: warning
class: some-class
~~~
I forgot that ~~~ is an alternate code format 🤦🏻 . But it seems I can get away with two (--) which is not quite what I'm looking for, but will allow me to finish making sure the logic is okay....Somehow hr is getting a hold of it before we see can get it under a list.
This is somewhat surprising as I would expect that hr wouldn't touch the content of a list until we've started processing the content as list blocks, but I guess maybe it preprocesses the blocks before lists...
Yep, hr is processed before lists, this is likely to catch - - - before lists as I think --- shouldn't trigger lists. Sigh, well that limits using --- unless someone has a clever workaround.
If we really wanted to use --- Python Markdown would need to split up HR handling I think. Handle loose HR - - - prior to lists and tight --- after lists. I think that is the only way. I'll just use -- for now as it sits safely between list and HR.
I have an experimental branch up here: https://github.com/facelessuser/pymdown-extensions/pull/1777
I ended up monkey patching HR so we could use the --- format. Nothing we are doing is set in stone. Ideally, I'd like Markdown to make the HR change as I don't currently see a reason not to, but worst case, we could always use --.
Feel free to try it out.
Just an overall description of how the current prototype is laid out. I think I'm ready to discuss the syntax.
:::{directive-name} arguments
---
option1: value
option2: value
---
content
:::
-
Fencing of blocks requires 3 or more
:. If nesting blocks, the outer block should have a greater length of:than the child blocks. Currently, if a closing fence is encountered that is greater than or equal to the starting fence, it is sufficient to close the current fence. -
directive-nameis currently the name of whatever directive you are using. It is case insensitive. -
argumentscan be one or many arguments, and the given directive would specify required delimiters if required. -
The optional frontmatter containing options is YAML-ish bock that comes immediately after the header, or better put, is part of the header when specified. We currently went with YAML-ish to avoid pulling in PyYAML as a requirement. I'm kind of going with simpler is better right now.
Due to limitations of the Python Markdown parser, it must be a "tight" config (no empty new lines). This also means there should be no newline after the initial header line.
The key value pairs are similar to the
metaextension (though I haven't yet made them multi-line, was considering this).The directive would impose any specific rules that these options require: delimiter split list, etc.
-
content: any valid content can be used, even nested directives. There does not have to be a separation between the header and the content, but can be if desired.
Examples
Note with no content
:::{warning} All we need is a title!
:::
:::{warning} This is important!
Read this notice.
:::
:::{warning}
Arguments are optional with some directives!
:::
:::{figure} some/image.png
---
width: 300
---
I'm a figure caption, and you can specify optional settings for your directives as well!
:::
::::{tip} Here's a secret
:::{note}
You can nest directives as well
:::
::::
I did end up allowing the other format for options as well.
:::{admonition} Title
:class: note
This is a note
:::
I had to add some intelligence so it knew how to handle insertion into different kinds of parents: spans, blocks, etc. I also switched to just using PyYAML for option parsing for now.
Anyways, this is all of course assuming we decide to keep the Myst approach, but I think we are modeling the format as well as Python Markdown can. I may hold off and wait and see if I get some feedback on the format and such before plowing forward much more.
It ended up being a surprisingly more complex endeavor than I thought at first, but I think the hard part is over. Even if we completely rework everything, I think generally the flow is working.
I think I'm ready to discuss the syntax.
I like the general idea here. Overall, it seems like a great start. I will address each item in turn below. Note that the following is all my personal option and preferences. As this is your third-party extension, I am not dictating that you must use my preferences. However, I am sharing them as a means to provide feedback. In the end, I could work with the syntax as you have it now.
- Fencing of blocks requires 3 or more
:. If nesting blocks, the outer block should have a greater length of:than the child blocks. Currently, if a closing fence is encountered that is greater than or equal to the starting fence, it is sufficient to close the current fence.
I'm curious why you chose colons. Personally, they are not my favorite character for this but I don't have any specific reasons why and I don't have any better suggestions.
However, I was surprised by your nesting rule. Yes, nesting should be supported, but why must the nested blocks increase in length? Why not just require that they be different? I realize that the current syntax makes it simpler for a human to read (longer means deeper nesting), but there is no such requirement for fenced code blocks, which this is modeled after. I don't know, maybe we should have followed this pattern when developing the fenced code block syntax years ago. But we didn't and... well, I'm not sure what to think about this.
directive-nameis currently the name of whatever directive you are using. It is case insensitive.
I'm assuming wrapping the directive-name in curly braces is to separate it from the arguments. I probably would have just used a space and required that directive names can't contain spaces. But maybe the braces are better.
argumentscan be one or many arguments, and the given directive would specify required delimiters if required.
You have arguments plural, So far I only see examples with a single argument. What would it look like with multiple arguments? I see one example (figure) uses a URL while the rest all use a title. I'm wondering it just naming it title would be better and arguments should be the name of the "frontmatter." Of course, that would eliminate the use case for figure, but I wonder if perhaps the URL argument would better fit in the frontmatter anyway.
4. The optional frontmatter containing options is YAML-ish bock that comes immediately after the header, or better put, is part of the header when specified.
I'm very torn about this. On the one hand, using YAML is clearly better. On the other hand, that requires a hard dependency, which I prefer to avoid. Also, I don't love the requirement for YAML delimitators (---) and would prefer to avoid them altogether. On the other hand, if your are using YAML, then it makes sense for them to exist. Your alternate syntax (:class: note) is interesting, but seems non-standard to me. What was your inspiration for it?
In the end I could live with either. However, if I hadn't used the syntax in a while and didn't look it up, I'm more likely to remember the YAML syntax than :class: note (I'm likely to forget the opening colon).
The key value pairs are similar to the
metaextension (though I haven't yet made them multi-line, was considering this).
Note that I don't personally use or recommend the meta extension any more. Instead, I think that the correct approach is something like waylan/docdata. Of course, that would not be usable here, but I point to is because MkDocs uses a variation on that, Specifically I like how it differentiates between Multimarkdown metadata and YAML metadata. I'm not sure if we want to support both here, but it is prior art. I would hesitate to introduce another new way to define key/value pairs in Markdown.
5.
content: any valid content can be used, even nested directives. There does not have to be a separation between the header and the content, but can be if desired.
Personally, I would have started out by requiring a blank line to separate the header from the content. That would eliminate the need to require some other delimitator for the frontmatter. But again, I can live with it either way. Personally, I would be inclined to include a blank line whether it was required or not.
It ended up being a surprisingly more complex endeavor than I thought at first
Doesn't it often. In any event, you made some great progress on this. When I get a change, I'll look over your code.
I'm curious why you chose colons. Personally, they are not my favorite character for this but I don't have any specific reasons why and I don't have any better suggestions.
I was simply using Myst as a reference. I am open to suggestions. Myst allows fenced blocks, which we simply can't do as it will conflict with existing fenced block implementations which must be done as preprocessor to preserve multiple newlines, avoid things like HR from getting converted, etc. They also allowed for a ::: variation, we simply copied what they are doing.
With that said, we don't have to do what they do anyways. They modeled something similar to RST. Not that we had we have to do what they do. I am open to specific alternative suggestions though. Coming up with a syntax that everyone will like is hard, so I'm open to other suggestions.
However, I was surprised by your nesting rule. Yes, nesting should be supported, but why must the nested blocks increase in length? Why not just require that they be different? I realize that the current syntax makes it simpler for a human to read (longer means deeper nesting), but there is no such requirement for fenced code blocks, which this is modeled after. I don't know, maybe we should have followed this pattern when developing the fenced code block syntax years ago. But we didn't and... well, I'm not sure what to think about this.
It doesn't have to. I think I initially had it not have this requirement, but I think it certainly helps visually. I'm open to dropping this requirement.
You have arguments plural, So far I only see examples with a single argument. What would it look like with multiple arguments? I see one example (figure) uses a URL while the rest all use a title. I'm wondering it just naming it title would be better and arguments should be the name of the "frontmatter." Of course, that would eliminate the use case for figure, but I wonder if perhaps the URL argument would better fit in the frontmatter anyway.
The reference allows multiple arguments, you could define a directive to have space delimited arguments:
:::{name} arg1 arg2
:::
Or delimit them in some other way if arguments require spaces, maybe commas or semicolons. Again, this is all assuming the current modeling against Myst which models its approach against RST (for better or for worst).
Your alternate syntax (:class: note) is interesting, but seems non-standard to me. What was your inspiration for it?
It's directly modeled after Myst: https://myst-parser.readthedocs.io/en/latest/syntax/roles-and-directives.html#parameterizing-directives
They don't specifically show it's used with the ::: syntax, but it is implied on that page. It's more how parameters in general are specified, which work for both ``` format and :::.
Note that I don't personally use or recommend the meta extension any more. Instead, I think that the correct approach is something like waylan/docdata. Of course, that would not be usable here, but I point to is because MkDocs uses a variation on that, Specifically I like how it differentiates between Multimarkdown metadata and YAML metadata. I'm not sure if we want to support both here, but it is prior art. I would hesitate to introduce another new way to define key/value pairs in Markdown.
This is a response to before I switched to YAML. I was simply referencing that I originally tried to avoid a YAML dependency, and considered parsing the options in a similar method. I ended up using YAML, but that is not set in stone yet. I can take a look at you links. I haven't yet looked.
Personally, I would have started out by requiring a blank line to separate the header from the content. That would eliminate the need to require some other delimitator for the frontmatter. But again, I can live with it either way. Personally, I would be inclined to include a blank line whether it was required or not.
This could still happen. If someone has a well-thought-out syntax, I'm interested in evaluating it. The plan was simply to prototype the Myst approach as a starting point. I am open to another syntax. Right now, nothing I've submitted for discussion is any different than what is offered under Myst. The only thing we can't do yet is to insert a raw text block without an HTML wrapper element, but I think this could be accomplished. Do we need this? I don't know, but I was working towards creating something as flexible to understand what we could do, and then pair back if we felt it necessary.
The syntax was kind of the same. There was one that existed, so I could prototype it, test what was possible, and then decide if we wanted a brand new syntax or to follow an existing approach.
Okay, I just checked out the MkDocs link that uses Multi-Markdown type params. I get what you mean. That is actually what I was doing before importing PyYAML, and what the meta extension more or less does. We could definitely do this.
Assuming we don't want to model an existing syntax like Myst, and just take inspiration from it, we could:
- Use a Multi-Markdown like syntax for headers.
- Require content to be after a newline to separate content from header parameters.
If we are absolutely not using YAML, then we no longer need --- in the header and we no longer need :key: value behavior.
This would of course take YAML off the table. This limits you somewhat if care about data types, but then you also have to sometimes "cast" data types for user experiences (user typed 300, but they really just want to assign that as a string to an HTML width attribute).
I'm not sure if we care about multi-line parameters (like preserving new lines in parameters), but the Multi-Markdown approach would prevent such an option as well.
Okay, the reference implementation does use increasing levels of colons. It also clearly shows the shorthand parameter format too (:key: value): https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#code-fences-using-colons
So, as of right now, we are duplicating their syntax.
So far there have been a number of proposals, so I'll summarize them below:
-
Don't use
:::, but no alternative has been suggested yet. Open to alternate proposals. -
Don't require a different amount of (currently colons) when for nested elements. The reference implementation does this, and I think this would make things harder to read.
-
Don't require directive name in
{}, but is this more confusing?:::name some argument(s) ::: -
These are kind of related. Don't use YAML, and maybe use something like Multi-Markdown format, require a blank new line between the header (which includes the parameters) and the content.
This would eliminate the need for a YAML dependency, YAML fences
---, and alternative:key: valueformat.:::{name} some argument(s) class: additional classes some-option: whatever content :::
Ah, I had missed that this is copying a pre-existing implementation (Myst). Now it makes more sense to me. The one concern I have is that Myst is specifically intended as a "Markdown for Docutils." Therefore, it is intended to be a direct replacement for Rest directives. Whereas we are looking for something this is more "inspired by" than a direct replacement.
That being the case, I think the :key: syntax should be out as that is a direct copy of Rest directive syntax. Presumably it is supported in Myst so that a user could copy a Rest directive to a Markdown document and not need to alter it.
Regarding the YAML vs. MultiMarkdown issue, I prefer YAML. In fact, IIRC MultiMarkdown has more recently been updated and it now uses YAML parsing. I don't see the point in adding support for an old standard in a new location where is has never existed before. YAML also gives us types out-of-the-box, which is better in my opinion (for example, if the user needs a string containing a number, they can wrap in in quotes and we don't need to explicitly build support for that into the parser). The one thing I don't love about YAML is the delimitators (---). Personally, I would simply require a blank line between the header and the content. Anything before the blank line and the first line would be assumed to be YAML. I suppose you could allow the delimitators optionally for those who want to use them.
Don't use
:::, but no alternative has been suggested yet. Open to alternate proposals.Don't require a different amount of (currently colons) when for nested elements. The reference implementation does this, and I think this would make things harder to read.
Don't require directive name in
{}, but is this more confusing?
I can see both sides of these, but I don't have any better suggestions either. To me they all feel like "we jut copied Myst" which in some ways is unsatisfying for the reasons stated above. But, without a better proposal, it is completely understandable.
That being the case, I think the :key: syntax should be out as that is a direct copy of Rest directive syntax. Presumably it is supported in Myst so that a user could copy a Rest directive to a Markdown document and not need to alter it.
Yeah, I'm not a huge fan of all the config lines with : either. I barely tolerate block quotes requiring this.
To me they all feel like "we jut copied Myst" which in some ways is unsatisfying for the reasons stated above.
I certainly understand this. It's much easier to implement the guts sometimes than it is to come up with syntax. Copying Myst allowed me to think about how I would approach the guts, but was not necessarily meant to be the final syntax, but I didn't have any great ideas for syntax yet either.
TBH, I don't like having to come up with new syntax, so I procrastinated, hoping the "committee" method would turn out something better 🙃.
I don't care about specifically being compatible with Myst or RST. I do feel you need some sort of generic fencing, you need some sort of way to indicate which general block you are defining, and some way to tweak options. I think options should come before content so we can properly setup the target element(s), so I think having the options specified as part of the header is a good idea.
Internally, it needs to be flexible. And I think what I currently have can handle simple things like admonitions, and much more complex block structures if required. It's just figuring out the Markdown syntax that doesn't make people claw their eyes out or throw their keyboard out the window.