nhn / tui.editor

🍞📝 Markdown WYSIWYG Editor. GFM Standard + Chart & UML Extensible.
http://ui.toast.com/tui-editor
MIT License
17.23k stars 1.76k forks source link

Is there some guide to extend Markdown syntax? #1009

Open taurenshaman opened 4 years ago

taurenshaman commented 4 years ago

Version

v2.1.0

Development Environment

OS: Windows 10 Browser: Opera 68.0.3618.125

Scenario/Background

Roam Research is becomming popular this days. If someone shared some content copied from Roam, I must try my best to display it correctly. e.g. highlight text using ^^. image

Current Behavior

There is no easy guide to extend markdown syntax. Ont only Highlight text.

Expected Behavior

Some advanced interface/API of the editor or ToastMark?

{
el: document.querySelector('#' + elementId),
previewStyle: 'vertical',
initialEditType: 'markdown',
toolbarItems: [],
syntax: [
{
name: 'highlight',
isInline: true,
/** 1. simple replace: highlight, strike, underline **/
rangeRegex: /^\^\^.*\^\^$/,
contentRegex: /\^\^([\^\^]*)\^\^/g,
symbol: '^^',
/** 2. using call back for advanced syntax: [[]], (()), {{}} **/
autoSuggestion: function (text){ /** a call back **/}
}
]
}

Try

I tried to give a fork to the copy of strike, But I don't know how to import the api of changeSyntax. Code: https://codepen.io/taurenshaman/pen/wvKbXJM
And also, I got nothing about how to convert markdown syntax to html element, e.g. strike, bold, ... Maybe it's in \Github\tui.editor\apps\editor\src\js\convertor.js?

andy0130tw commented 4 years ago

Maybe a little off-topic here, but it would be great if some APIs can be added to ToastMark to define tokens in some easy way. Not only it would be a neat feature that the reference implementation is not expected to cover, but also make it extendable without knowing all the parsing details.

There is a project, markdown-it, that has done this job very well. As ToastMark has essentially optimized everything to be an editor's backend, extensibility may be a concern. For example, block tokens' start rules and handlers can be merged into individual classes. Then we can define (at a high-level view):

const AtxHeading = BlockRule.define({
  isLeaf: true,
  startByCharacter: '#',
  // inlineParser: SomeDefaultInlineParser,
  /* omitting to use default */
})
const FencedCodeBlock = BlockRule.define({
  isLeaf: true,
  inlineParser: HighlightParserAsync,  // or VerbatimParser if highlighting is not interested
})
const BlockquoteBlock = BlockRule.define({
  isLeaf: false,
  startByCharacter: '>',
})

const Document = BlockRule.define({
  isLeaf: false,
})

/* then combine it to  */
const parser = new Parser('...' /* input */, {
  topLevelRule: Document,
  subRules: [ AtxHeading, FencedCodeBlock, BlockquoteBlock, /* ... */],
  defaultInlineParser: SomeDefaultInlineParser,
})

I am trying to convince myself that this can always be done, though. If you have any plans on this idea, I am willing to help!