Skip to content

CodiMD Document Extensions - request for comments #1023

Open
@ccoenen

Description

@ccoenen

(very loosely related to #787, as this is very very focused on how document rendering itself can be extended)

Right now, a lot of rendering is extended in public/js/extra.js. Among other things, it handles highlighters, mermaid, video plugins and so on. For the following, I'll use mermaid as an example, because I'm familar with how it works.

I would love if we came up with a common interface for things like that. This way we could get much of the code out of extra.js, and we might end up with more extensions along the way!

Basically, Mermaid is applied in three steps.

  • In highlightRender(), we're looking for a magic word like "mermaid", then a <div> with its raw content is returned.

    codimd/public/js/extra.js

    Lines 931 to 932 in 152dfc2

    } else if (lang === 'mermaid') {
    return `<div class="mermaid raw">${code}</div>`
  • In finishView(view), all those divs are then looked up and processed.

    codimd/public/js/extra.js

    Lines 374 to 394 in 152dfc2

    const mermaids = view.find('div.mermaid.raw').removeClass('raw')
    mermaids.each((key, value) => {
    try {
    var $value = $(value)
    const $ele = $(value).closest('pre')
    window.mermaid.mermaidAPI.parse($value.text())
    $ele.addClass('mermaid')
    $ele.html($value.text())
    window.mermaid.init(undefined, $ele)
    } catch (err) {
    var errormessage = err
    if (err.str) {
    errormessage = err.str
    }
    $value.unwrap()
    $value.parent().append('<div class="alert alert-warning">' + errormessage + '</div>')
    console.warn(errormessage)
    }
    })
  • In case of mermaid, the bulk of processing comes from an external library (line 380, I believe), but this wouldn't have to be the case.

So basically, I propose a plugin or extension system that would take those commonalities so we could easily write more such additions, and also that could perhaps be lazy-loaded. Or they could even be distributed in a different way (think: their own NPM modules)

// example Document Extension
{
  keyword: 'mermaid',
  highlightRender: (code) => {
    // returns a html element for later processing
    return htmlElement;
  },
  finishView: (view) => {
    // modifies element in place
  }
}

perhaps we could even get away from that extra step and just pass an object reference right into finishView or something.

  • Name: Is "Document Extensions" the right name?
  • User expectation: how do we deal with different CodiMD instances offering different functionalities?
  • Do we need anything more than what's proposed? Does ony one of you know other extensions that would need different things?

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionExchange of some opinions neededhelp wantedWe want you to help us with this!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions