UNPKG

@arothuis/markdown-it-biblatex

Version:

A markdown-it plug-in for rendering citations and a bibliography inside markdown

140 lines (109 loc) 3.64 kB
function parser(context) { const { suppressAuthorMark, authorOnlyMark, compositeMark, infixMark, bibliographyMark, alwaysReloadFiles, } = context.options; const marks = [suppressAuthorMark, authorOnlyMark, compositeMark] .map((mark) => mark.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) .join('|'); const validCitation = new RegExp(`(?<=^\\[)((${marks})?@)(.+?)[^](?=])`); function reference(state) { const { pos, posMax, src } = state; if (state.env.bib === undefined) { if (alwaysReloadFiles === true) { const { bibData, citeproc } = context.loadFiles(context.options); context.bibData = bibData; context.citeproc = citeproc; } state.env.bib = { refs: [], }; } if (pos + 4 > posMax) { return false; } const match = src.slice(pos).match(validCitation); if (match === null) { return false; } if (match[0].slice(0, suppressAuthorMark.length) === suppressAuthorMark) { return processReference(state, match[0], 'suppress-author'); } if (match[0].slice(0, authorOnlyMark.length) === authorOnlyMark) { return processReference(state, match[0], 'author-only'); } if (match[0].slice(0, compositeMark.length) === compositeMark) { return processReference(state, match[0], 'composite'); } return processReference(state, match[0]); } function processReference(state, ref, mode) { let infix = null; const citationItems = ref.split(';').map((rawItem) => { const item = rawItem.trim(); const label = item.split('{')[0].split('#')[0].split('@')[1]; const findLocator = item.match(/(?<=#)(.+?)(?=({|$))/) || []; const findAffixes = item.match(/(?<={)(.+?)(?=})/g) || []; let prefix = findAffixes[0]; if (mode === 'composite') { if (infix === null) { const [foundInfix] = findAffixes.filter((i) => i[0] === infixMark); infix = (foundInfix || '').slice(1); } [prefix] = findAffixes.filter((i) => i[0] !== infixMark[0]); } return { label, id: context.bibData.ids[label], number: state.env.bib.refs.length, prefix, locator: findLocator[0], }; }); const token = state.push('biblatex_reference', '', 0); token.meta = { ref: `[${ref}]`, citation: { citationItems, properties: { noteIndex: 0, mode, infix, }, }, }; state.env.bib.refs.push(token.meta); state.pos += ref.length + 2; return true; } function bibliography(state, startLine) { const start = state.bMarks[startLine] + state.tShift[startLine]; const foundMark = state.src.slice(start, start + bibliographyMark.length) === bibliographyMark; if (!foundMark) { return false; } state.push('biblatex_bibliography_open', '', 0); state.push('biblatex_bibliography_contents', '', 1); state.push('biblatex_bibliography_close', '', 0); state.line += 1; return true; } function appendBibliography(state) { state.tokens.push(new state.Token('biblatex_bibliography_open', '', 0)); state.tokens.push(new state.Token('biblatex_bibliography_contents', '', 1)); state.tokens.push(new state.Token('biblatex_bibliography_close', '', 0)); return true; } return { reference, bibliography, appendBibliography, }; } module.exports = { parser, };