jupyter-book / mystmd

Command line tools for working with MyST Markdown.
https://mystmd.org/guide
MIT License
219 stars 64 forks source link

Provide a `dedent` function for plugin development in `utils` or `ctx` #1655

Closed choldgraf closed 3 days ago

choldgraf commented 5 days ago

The MyST sandbox is also a useful way to generate MyST AST for your plugins. For example, with code like the following:

```{code} javascript
:filename: src/sandbox-demo.mjs
const myDirective = {
  name: "sandbox-demo",
  doc: "Demo of using the MyST sandbox to generate MyST AST.",
  run(data, vfile, ctx) {
    const ast = ctx.parseMyst(`:::{card} ${data.arg}\n${data.body}\n:::`);
    return ast.children[0];
  },
};

However it's easier to parse complex MyST strings as multi-line strings in JavaScript, like so:
:filename: src/sandbox-demo.mjs
const myDirective = {
  name: "sandbox-demo",
  doc: "Demo of using the MyST sandbox to generate MyST AST.",
  run(data, vfile, ctx) {
    const ast = ctx.parseMyst(`
    :::{card} ${data.arg}
    ${data.body}
    :::`);
    return ast.children[0];
  },
};

However, in this case you'll need to dedent the string manually to get the multi-line string to work. It would be helpful to have a utility function to do this so that users don't have to manually dedent their strings or install their own package.

For example:
:filename: src/sandbox-demo.mjs
const myDirective = {
  name: "sandbox-demo",
  doc: "Demo of using the MyST sandbox to generate MyST AST.",
  run(data, vfile, ctx) {
    const ast = ctx.dedent(ctx.parseMyst(`
    :::{card} ${data.arg}
    ${data.body}
    :::`));
    return ast.children[0];
  },
};


Alternatively, the parseMyst function could automatically try to dedent under the hood (perhaps with an option for dedent=false)
agoose77 commented 5 days ago

@choldgraf is there anything wrong with just

const myDirective = {
  name: "sandbox-demo",
  doc: "Demo of using the MyST sandbox to generate MyST AST.",
  run(data, vfile, ctx) {
    const ast = ctx.parseMyst(`
:::{card} ${data.arg}
${data.body}
:::
    `);
    return ast.children[0];
  },
};
choldgraf commented 5 days ago

Nothing wrong with it, it's just not the first thing most users would try, and it makes the code look kind of ugly. But yep that works for now

agoose77 commented 3 days ago

I'm going to close this for now. My rationale is that I don't think this would make reading simpler for the users that already lack the experience to manually dedent text strings, and I'm keen to keep the issue tracker down in anticipation of growth!

choldgraf commented 3 days ago

Sounds good - but let's mark it as wontfix rather than completed