Add collapsible spoiler blocks to Markdown

pull/8085/head
Mhfd 5 days ago
parent 8a979690a7
commit 1426e6589c

@ -224,6 +224,7 @@ import mermaid from 'mermaid'
// Helpers
import katexHelper from './common/katex'
import spoiler from './markdown/spoiler'
import tabsetHelper from './markdown/tabset'
import cmFold from './common/cmFold'
@ -264,6 +265,7 @@ const md = new MarkdownIt({
.use(mdAttrs, {
allowedAttributes: ['id', 'class', 'target']
})
.use(spoiler)
.use(mdDecorate)
.use(underline)
.use(mdEmoji)

@ -0,0 +1,12 @@
const container = require('markdown-it-container')
module.exports = md => md.use(container, 'spoiler', {
validate: params => /^spoiler(?:\s+.*)?$/.test(params.trim()),
render(tokens, idx) {
if (tokens[idx].nesting === 1) {
const title = tokens[idx].info.trim().slice('spoiler'.length).trim() || 'Spoiler'
return `<details class="spoiler"><summary>${md.utils.escapeHtml(title)}</summary>\n`
}
return '</details>\n'
}
})

@ -2,6 +2,7 @@ const md = require('markdown-it')
const mdAttrs = require('markdown-it-attrs')
const mdDecorate = require('markdown-it-decorate')
const _ = require('lodash')
const spoiler = require('./spoiler')
const underline = require('./underline')
const quoteStyles = {
@ -43,6 +44,7 @@ module.exports = {
mkdown.use(mdAttrs, {
allowedAttributes: ['id', 'class', 'target']
})
mkdown.use(spoiler)
mkdown.use(mdDecorate)
for (let child of this.children) {

@ -0,0 +1,12 @@
const container = require('markdown-it-container')
module.exports = md => md.use(container, 'spoiler', {
validate: params => /^spoiler(?:\s+.*)?$/.test(params.trim()),
render(tokens, idx) {
if (tokens[idx].nesting === 1) {
const title = tokens[idx].info.trim().slice('spoiler'.length).trim() || 'Spoiler'
return `<details class="spoiler"><summary>${md.utils.escapeHtml(title)}</summary>\n`
}
return '</details>\n'
}
})

@ -0,0 +1,38 @@
const renderer = require('../../../modules/rendering/markdown-core/renderer')
const render = input => renderer.render.call({
input,
children: [],
config: {
allowHTML: true,
linebreaks: true,
linkify: true,
typographer: false,
quotes: 'English',
underline: false
}
})
describe('markdown-core spoiler container', () => {
it('renders a closed details element with a default title', async () => {
const output = await render('::: spoiler\nHidden **content**.\n:::')
expect(output).toContain('<details class="spoiler"><summary>Spoiler</summary>')
expect(output).toContain('<p>Hidden <strong>content</strong>.</p>')
expect(output).toContain('</details>')
})
it('supports a custom escaped title', async () => {
const output = await render('::: spoiler Reveal <script>alert(1)</script>\nSecret\n:::')
expect(output).toContain('<summary>Reveal &lt;script&gt;alert(1)&lt;/script&gt;</summary>')
expect(output).not.toContain('<summary>Reveal <script>')
})
it('leaves other containers unchanged', async () => {
const output = await render('::: note\nVisible\n:::')
expect(output).toContain('::: note')
expect(output).not.toContain('<details')
})
})

@ -13485,6 +13485,11 @@ markdown-it-attrs@3.0.3:
resolved "https://registry.yarnpkg.com/markdown-it-attrs/-/markdown-it-attrs-3.0.3.tgz#92acdb16fe551cb056c5eb9848413443cafb5231"
integrity sha512-cLnICU2t61skNCr4Wih/sdza+UbQcqJGZwvqAypnbWA284nzDm+Gpc90iaRk/JjsIy4emag5v3s0rXFhFBWhCA==
markdown-it-container@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-3.0.0.tgz#1d19b06040a020f9a827577bb7dbf67aa5de9a5b"
integrity sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==
markdown-it-decorate@1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/markdown-it-decorate/-/markdown-it-decorate-1.2.2.tgz#f1e11d11d837ae78906198f8a2c974f0e646acb7"

Loading…
Cancel
Save