Markdown Renderer
Inkdrop's markdown rendering system is built on top of remark, a markdown processor powered by plugins part of the unified collective. You can access a global instance of this class using the code provided below.
const { markdownRenderer } = require('inkdrop')
Compatibility note: Inkdrop (>=5.6.0) uses unified@10, remark@14, remark-rehype@10.
remarkPlugins
An array of custom Remark plugins.
See also: math plugin
Here is a plugin that adds your custom Remark plugin:
Example plugin
const { markdownRenderer } = require('inkdrop')
module.exports = {
activate() {
if (markdownRenderer) {
markdownRenderer.remarkPlugins.push(YOUR_PLUGIN)
}
},
deactivate() {
if (markdownRenderer) {
markdownRenderer.remarkPlugins = markdownRenderer.remarkPlugins.filter(
plugin => YOUR_PLUGIN !== plugin
)
}
}
}
rehypePlugins
The Markdown notes are converted from Markdown to HTML. The HTML data is then processed with Rehype. You can extend the process by adding your custom Rehype plugins.
Here is a plugin that adds your custom Rehype plugin:
Example plugin
const { markdownRenderer } = require('inkdrop')
module.exports = {
activate() {
if (markdownRenderer) {
markdownRenderer.rehypePlugins.push(YOUR_PLUGIN)
}
},
deactivate() {
if (markdownRenderer) {
markdownRenderer.rehypePlugins = markdownRenderer.remarkPlugins.filter(
plugin => YOUR_PLUGIN !== plugin
)
}
}
}
remarkReactComponents
This property is an object that maps HTML element names to React components.
You can override default elements (such as a
, p
, etc.) by passing your custom components.
Check out rehype-react for more details.
- Example plugin: toc
Do not use remarkReactComponents
to override the click events of a
HTML elements.
Instead, use the events
property.
If you want to override the rendering of a
HTML elements with a custom component, you can do it as shown:
Override Anchor Element
class Anchor extends React.Component {
render() {
// ...
}
}
markdownRenderer.remarkReactComponents.a = Anchor
remarkCodeComponents
Allows you to render code blocks with custom React components. You can define a component for a specific language as demonstrated:
- Example plugin: mermaid
JavaScript Code Block
const JSCodeBlock = props => {
const { lang, title, lineAt } = props
const code = props.children[0]
return (
<pre>
{/* Custom JS block */}
</pre>
)
}
markdownRenderer.remarkCodeComponents['javascript'] = JSCodeBlock
events
The events
property allows you to listen to events emitted by the renderer.
An event handler can be an async
function.
Here is a list of events that you can listen to:
- Name
a:click
- Type
- Description
Emitted when
a
link is clicked. Returnstrue
if the event is handled.- Name
event
- Type
- React.MouseEvent<HTMLAnchorElement, MouseEvent>
- Description
Mouse event
- Name
checkbox:change
- Type
- Description
Emitted when
checkbox
is clicked. Returnstrue
if the event is handled.- Name
event
- Type
- React.ChangeEvent<HTMLInputElement>
- Description
Change event
- Name
detail
- Type
- { checked: boolean numLine: number }
- Description
checked
indicates whether the checkbox is checked or not.numLine
is the line number of the checkbox.
Listening to the renderer events
useEffect(() => {
const app = getApp()
const disposables = [
events.on('checkbox:change', (_e, { checked, numLine }) => {
console.log(`checkbox ${checked ? 'checked' : 'unchecked'} at line ${numLine}`)
}),
events.on('a:click', e => {
const target = e.target as HTMLAnchorElement
const { href } = target
console.log(`clicked link: ${href}`)
// Should return true if the event is handled
return true
})
]
return () => {
disposables.forEach(d => d())
}
}, [])