jupyter-book / myst-spec

MyST is designed to create publication-quality, computational documents written entirely in Markdown.
https://mystmd.org/spec
MIT License
14 stars 6 forks source link

Introduce leaf directives #57

Open chrisjsewell opened 1 year ago

chrisjsewell commented 1 year ago

background

Restructured text allow for the syntax:

.. note:: This is a short note

It is a nice, terse, one-line syntax for an admonition.

This comes at a price though; the parsing of a directive's "structure" is dependent on the type of directive. Because the body content can possibly be on the first line, this does not work:

.. note:: I want a bespoke title

    Then some content

It is simply treated as a note with two body paragraphs This means you then have to then use a different directive 😒:

.. admonition:: I want a bespoke title
    :class: note

    Then some content

https://github.com/executablebooks/MyST-Parse currently follows this logic with colon_fence, e.g.

:::{note} This is a body paragraph
this is a continuation of the same paragraph
:::

However, https://myst-tools.org/docs/mystjs/admonitions#admonition-titles does not

:::{note} This is the title
This is the body paragraph
:::

proposal

I propose "disambiguating" this difference, by introducing a "leaf div" to compliment the block "div"

::{note} This is a leaf div. It is interpreted as a single body paragraph,
that can continue on to multiple lines if really necessary

:::{note} this is a block div title
This is a block div content
:::

In https://github.com/executablebooks/mdit-py-plugins/pull/72, I have sketched out what this would look like for a markdown-it plugin

Note with block attributes, you could also provide options to leaf divs, e.g. this

{#name .class key=value}
::{note} A note

would be equivalent to

:::{note}
:name: name
:class: class
:key: value

A note
:::
chrisjsewell commented 1 year ago

thoughts @rowanc1 ?

rowanc1 commented 1 year ago

Intriguing, is that leaf div syntax used elsewhere?

I will get the proposal @mmcky and I are stewing on posted tomorrow. I think it complements this well, although it is smaller in scope -- only about the block title changes.

chrisjsewell commented 1 year ago

is that leaf div syntax used elsewhere?

Relatively similar: https://talk.commonmark.org/t/generic-directives-plugins-syntax/444 https://github.com/remarkjs/remark-directive

and then I also opened https://github.com/jgm/djot/issues/215

rowanc1 commented 1 year ago

I really like this for things like iframes, and fenced directives that @mmcky has introduced which don't have body content and should be a single line but end up being two.

chrisjsewell commented 1 year ago

which don't have body content and should be a single line but end up being two.

A trick thing here though is: do you interpret the content of a leaf div, as its body, or its argument? or have some way of discriminating the two?

For example, for admonitions we definitely want the content to be the body, but for other things like images you would want it to be the argument:

.. note:: The body that can have *nested syntax*

.. image:: path/to/image.png

you might even what these as separate (leaf) syntaxes, something like:

::{note} The body that can have *nested syntax*

..{image} path/to/image.png

So :: and .. (or some other character?) is similar to the discrimination between ::: and ```

chrisjsewell commented 1 year ago

Here I guess you would call ..{image} path/to/image.png a "leaf fence", i.e. the content is not interpreted as MyST

chrisjsewell commented 1 year ago

Just to be clear:

and, well, if you just wanted {"name": "name", "argument": None, "body": None}, I guess you could use either in principal (but ..{name} would be recommended)

chrisjsewell commented 1 year ago

what do you think of that ☝️ @rowanc1 @mmcky

mmcky commented 1 year ago

Oh this is interesting for gated directives like {exercise-start} and {exercise-end}. I will think about these syntax ideas as for the gated directive case you want to add options but there may be a more compact way.

For example in the exercise case the pattern is often:

```{exercise-start}
:label: ex1
<some code>


So `config/options/meta` is more important in this case than `content` 🤔 

https://ebp-sphinx-exercise.readthedocs.io/en/latest/syntax.html#alternative-gated-syntax
chrisjsewell commented 1 year ago

so then your example above would potentially go to:

{label=ex1}
..{exercise-start}

```{code-cell} python
<some code>

..{exercise-end}

chrisjsewell commented 1 year ago

what do you think of that ☝️ @rowanc1 @mmcky

gentle nudge @rowanc1 😉

rowanc1 commented 1 year ago

Leaf directives are a cool idea, and allow for really terse syntax, which I think is awesome. I also really like the idea that they have almost the same syntax as a colon directive.

I think that we probably don't need a difference between parsing an argument vs parsing markdown, and we just do it in the same way that we don't have syntax differences between :::{figure} img.png and :::{admonition} _title_. This logic already has a precedence for living in the parser, not the syntax.

I like saying to a user, "want to do this on one line":

:::{note}
Hello note!
:::

"remove a colon, and put it on one line!" 💥

::{note} Hello note!
chrisjsewell commented 1 year ago

I think that we probably don't need a difference between parsing an argument vs parsing markdown...

This is not the difference, though, it's the difference between using the argument vs the body

Lets say you had a directive that could look like this:

:::{name} argument
body
:::

what does this represent?

::{name} text
tavin commented 1 year ago

Say I switch to the div extension from colon_fence. What might be the meaning (rendering) of the following?

:::
*Hello*
:::
chrisjsewell commented 1 year ago

Say I switch to the div extension from colon_fence. What might be the meaning (rendering) of the following?

<div>
<p><em>Hello</em></p>
</div>

(similar to https://djot.net/playground/?text=%3A%3A%3A%0A*Hello*%0A%3A%3A%3A&mode=html&sourcepos=false)

chrisjsewell commented 1 year ago

You'll find this is what https://myst-parser.readthedocs.io/en/stable/live-preview.html already does now (since v0.19) with colon_fence

image

The potential difference for div would be how it treats directives with a first line, and allowing that first line to be part of the body

image
tavin commented 1 year ago

In addition to taking arguments (titles) from the remainder of the line, I would like to propose that "block attributes" be interpreted inside the braces of the directive as well:

:::{note#id.class} Title
chrisjsewell commented 1 year ago

In addition to taking arguments (titles) from the remainder of the line, I would like to propose that "block attributes" be interpreted inside the braces of the directive as well:

Off hand, I don't feel this would not be viable / a good idea

  1. the directive name can contain things like spaces and other punctuation, so identifying where any attributes begin is tricky
  2. it somewhat breaks the principle of uniformity; that block attributes are always above any syntax block (and are cumulative)