markdown_header_and_footer.js
/** @module */
import { wrapTokens } from '../helpers/wrap_tokens'
import marpitPlugin from '../plugin'
/**
* Marpit header and footer plugin.
*
* At each slide, add header and footer that are provided by directives.
*
* @function headerAndFooter
* @param {MarkdownIt} md markdown-it instance.
*/
function _headerAndFooter(md) {
md.core.ruler.after(
'marpit_directives_apply',
'marpit_header_and_footer',
(state) => {
if (state.inlineMode) return
const parsedInlines = new Map()
const getParsed = (markdown) => {
let parsed = parsedInlines.get(markdown)
if (!parsed) {
parsed = md.parseInline(markdown, state.env)
delete parsed.map
parsedInlines.set(markdown, parsed)
}
return parsed
}
const createMarginalTokens = (tag, markdown) =>
wrapTokens(
state.Token,
`marpit_${tag}`,
{ tag, close: { block: true } },
getParsed(markdown),
)
let current
const newTokens = []
for (const token of state.tokens) {
if (token.type === 'marpit_slide_open') {
current = token
newTokens.push(token)
if (current.meta && current.meta.marpitHeader)
newTokens.push(
...createMarginalTokens('header', current.meta.marpitHeader),
)
} else if (token.type === 'marpit_slide_close') {
if (current.meta && current.meta.marpitFooter)
newTokens.push(
...createMarginalTokens('footer', current.meta.marpitFooter),
)
newTokens.push(token)
} else {
newTokens.push(token)
}
}
state.tokens = newTokens
},
)
}
export const headerAndFooter = marpitPlugin(_headerAndFooter)
export default headerAndFooter