feat: add GitHub-style alerts plugin with customizable titles and integrated rendering

pull/7766/head
Akibur Rahman 3 months ago
parent 1c7b34462c
commit f81ed87b89

@ -212,6 +212,7 @@ import mdFootnote from 'markdown-it-footnote'
import mdImsize from 'markdown-it-imsize'
import katex from 'katex'
import underline from '../../libs/markdown-it-underline'
import githubAlerts from '../../libs/markdown-it-github-alerts'
import 'katex/dist/contrib/mhchem'
import twemoji from 'twemoji'
import plantuml from './markdown/plantuml'
@ -266,6 +267,7 @@ const md = new MarkdownIt({
})
.use(mdDecorate)
.use(underline)
.use(githubAlerts, { customTitle: true })
.use(mdEmoji)
.use(mdTaskLists, { label: false, labelAfter: false })
.use(mdExpandTabs)
@ -308,9 +310,21 @@ function injectLineNumbers (tokens, idx, options, env, slf) {
}
return slf.renderToken(tokens, idx, options, env, slf)
}
// Store the existing blockquote renderer (which now includes GitHub alerts)
const existingBlockquoteRender = md.renderer.rules.blockquote_open
// Create a combined renderer for blockquotes that handles both line numbers and GitHub alerts
md.renderer.rules.blockquote_open = function(tokens, idx, opts, env, slf) {
// First apply line number injection
injectLineNumbers(tokens, idx, opts, env, slf)
// Then apply the GitHub alerts rendering (if any)
return existingBlockquoteRender(tokens, idx, opts, env, slf)
}
// Apply line number injection to other elements
md.renderer.rules.paragraph_open = injectLineNumbers
md.renderer.rules.heading_open = injectLineNumbers
md.renderer.rules.blockquote_open = injectLineNumbers
cmFold.register('markdown')
// ========================================

@ -0,0 +1,74 @@
// ------------------------------------
// Markdown - GitHub-style Alerts (Client-side)
// ------------------------------------
function githubAlertsPlugin(md, options = {}) {
const alertTypes = {
'note': { class: 'is-info' },
'info': { class: 'is-info' },
'tip': { class: 'is-success' },
'warning': { class: 'is-warning' },
'important': { class: 'is-info' },
'caution': { class: 'is-danger' }
}
// Store original renderer - will handle line number injection if it exists
const defaultRender = md.renderer.rules.blockquote_open || function(tokens, idx, options, env, slf) {
return slf.renderToken(tokens, idx, options)
}
// Override blockquote_open renderer to handle both alerts and line numbers
md.renderer.rules.blockquote_open = function(tokens, idx, opts, env, slf) {
const nextToken = tokens[idx + 1]
// Check if the next token is a paragraph containing inline content
if (nextToken && nextToken.type === 'paragraph_open') {
const inlineToken = tokens[idx + 2] // The inline token after paragraph_open
if (inlineToken && inlineToken.type === 'inline' && inlineToken.children) {
const firstChild = inlineToken.children[0]
if (firstChild && firstChild.type === 'text') {
const content = firstChild.content
const alertMatch = content.match(/^\[!(NOTE|INFO|TIP|WARNING|IMPORTANT|CAUTION)\](?:\s+(.+?))?$/i)
if (alertMatch) {
const alertType = alertMatch[1].toLowerCase()
const customTitle = alertMatch[2] ? alertMatch[2].trim() : null
const alertConfig = alertTypes[alertType]
if (alertConfig) {
// Add CSS class to blockquote
tokens[idx].attrJoin('class', alertConfig.class)
// Handle custom title or remove alert tag
if (customTitle && options.customTitle !== false) {
// Replace with bold custom title
firstChild.content = `**${customTitle}**`
} else if (customTitle && options.customTitle === false) {
// Custom titles disabled but title provided - remove the entire alert line
firstChild.content = ''
} else {
// No custom title - remove the alert tag
firstChild.content = ''
}
// If we emptied the first text node, remove it
if (firstChild.content === '') {
inlineToken.children.shift()
// Also remove the following softbreak if it exists
if (inlineToken.children[0] && inlineToken.children[0].type === 'softbreak') {
inlineToken.children.shift()
}
}
}
}
}
}
}
return defaultRender(tokens, idx, opts, env, slf)
}
}
module.exports = githubAlertsPlugin
Loading…
Cancel
Save