micromark / micromark-extension-directive

micromark extension to support generic directives (`:cite[smith04]`)
https://unifiedjs.com
MIT License
29 stars 16 forks source link

Rendering failure? #15

Closed Ahacad closed 2 years ago

Ahacad commented 2 years ago

Initial checklist

Affected packages and versions

2.0.1

Link to runnable example

No response

Steps to reproduce

  1. init a new npm repo
  2. install dependencies: micromark and micromark-extension-directive
  3. create a JavaScript file say index.js, put the example code from README here:
    
    import fs from 'node:fs'
    import {micromark} from 'micromark'
    import {directive, directiveHtml} from 'micromark-extension-directive'

const output = micromark(fs.readFileSync('example.md'), { extensions: [directive()], htmlExtensions: [directiveHtml({abbr})] })

console.log(output)

function abbr(d) { if (d.type !== 'textDirective') return false

this.tag('<abbr')

if (d.attributes && 'title' in d.attributes) { this.tag(' title="' + this.encode(d.attributes.title) + '"') }

this.tag('>') this.raw(d.label || '') this.tag('') }

4. inside `example.md`, input all the text from the SYNTAX section in README
5. run `node index.js` and get output in the console

### Expected behavior

Directives in blocks and containers should get rendered, but the output is an empty string.

### Actual behavior

Below is the actual output:

Directives in text can form with a single colon, such as . Their syntax is :name[label]{attributes}.

Leafs (block without content) can form by using two colons:

Their syntax is ::name[label]{attributes} on its own line.

Containers (blocks with content) can form by using three colons:

The name part is required. The first character must be a letter, other characters can be alphanumerical, -, and _. - or _ cannot end a name.

The [label] part is optional (:x and :x[] are equivalent)†. When used, it can include text constructs such as emphasis and so on: x[a *b* c].

The {attributes} part is optional (:x and :x{} are equivalent)†. When used, it is handled like HTML attributes, such as that {a}, {a=""}, , {a=''} but also {a=b}, {a="b"}, and {a='b'} are equivalent. Shortcuts are available for id= ({#readme} for {id=readme}) and class ({.big} for {class=big}). When multiple ids are found, the last is used; when multiple classes are found, they are combined: {.red class=green .blue} is equivalent to {.red .green .blue} and {class="red green blue"}.

† there is one case where a name must be followed by an empty label or empty attributes: a text directive that only has a name, cannot be followed by a colon. So, :red: doesn’t work. Use either :red[] or :red{} instead. The reason for this is to allow GitHub emoji (gemoji) and directives to coexist.

Containers can be nested by using more colons outside:

The closing fence must include the same or more colons as the opening. If no closing is found, the container runs to the end of its parent container (block quote, list item, document, or other container).



You can see containers and blocks are omitted, by my memory they should have got rendered.

### Runtime

Node v14

### Package manager

npm v7

### OS

Linux

### Build and bundle tools

_No response_
wooorm commented 2 years ago

Hey!

I think the idea here is that unknown directives are ignored by default. As they could be turned into anything: dangerous html, youtube videos, embed of other stuff, math, you name it. Just rendering something is probably not the best outcome.

So, the example JS code works with the example MD code, but not with the syntax explanation. That requires more code.

Does that make sense?

Ahacad commented 2 years ago

Oh, I am clear about it now. So it requires similar code like:

function abbr(d) {
  if (d.type !== 'textDirective') return false

  this.tag('<abbr')

  if (d.attributes && 'title' in d.attributes) {
    this.tag(' title="' + this.encode(d.attributes.title) + '"')
  }

  this.tag('>')
  this.raw(d.label || '')
  this.tag('</abbr>')
}

to render the containers and blocks right?

wooorm commented 2 years ago

Yes, you need to write your own handlers to deal with containers in the way you want!

wooorm commented 2 years ago

closing as it’s more a question that doesn’t need any code changes!

github-actions[bot] commented 2 years ago

Hi! This was closed. Team: If this was fixed, please add phase/solved. Otherwise, please add one of the no/* labels.