UNPKG

docutils-ts

Version:

Port of the Python Docutils library to TypeScript

103 lines (102 loc) 4.11 kB
import * as nodes from '../nodes.js'; import * as utils from '../utils.js'; import Transform from '../transform.js'; class Decorations extends Transform { apply() { const headerNodes = this.generateHeader(); if (headerNodes && headerNodes.length) { const decoration = this.document.getDecoration(); const header = decoration.getHeader(); header.add(headerNodes); } const footerNodes = this.generateFooter(); if (footerNodes && footerNodes.length) { const decoration = this.document.getDecoration(); const footer = decoration.getFooter(); if (typeof footer === 'undefined') { throw new Error('unexpected undefined footer'); } footer.add(footerNodes); } } generateHeader() { return undefined; } generateFooter() { // @@@ Text is hard-coded for now. // Should be made dynamic (language-dependent). // @@@ Use timestamp from the `SOURCE_DATE_EPOCH`_ environment variable // for the datestamp? // See https://sourceforge.net/p/docutils/patches/132/ // and https://reproducible-builds.org/specs/source-date-epoch/ const settings = this.document.settings; let core = settings; if (core.generator || core.datestamp || core.sourceLink || core.sourceUrl) { const text = []; if ((core.sourceLink && settings._source) || core.sourceUrl) { const source = core.sourceUrl || utils.relativePath(settings._destination, settings._source); text.push(new nodes.reference('', 'View document source', [], { refuri: source }), new nodes.Text('.\n')); } if (core.datestamp) { const datestamp = 'fixme'; // get time text.push(new nodes.Text(`Generated on: ${datestamp}\n`)); } if (core.generator) { text.push(new nodes.Text('Generated by '), new nodes.reference('', 'Docutils', [], { refuri: 'http://docutils.sourceforge.net/', }), new nodes.Text(' from '), new nodes.reference('', 'reStructuredText', [], { refuri: 'http://docutils.sourceforge.net/rst.html' }), new nodes.Text(' source.\n')); } return [new nodes.paragraph('', '', text)]; } return undefined; } } Decorations.defaultPriority = 820; /** * Place any system messages generated after parsing into a dedicated section * of the document. */ class Messages extends Transform { apply() { const unfiltered = this.document.transformMessages; if (unfiltered == null) { throw new Error('need transformmessages'); } const threshold = this.document.reporter.reportLevel; const messages = unfiltered.filter((msg) => msg.attributes.level >= threshold && msg.parent == null); if (messages.length) { const section = new nodes.section('', [], { classes: 'system-messages' }); // @@@ get this from the language module? section.add([new nodes.title('', 'Docutils System Messages'), ...messages]); const m = this.document.transformMessages; m.splice(0, m.length); this.document.append(section); } } } Messages.defaultPriority = 860; /** * Remove system messages below verbosity threshold. */ class FilterMessages extends Transform { apply() { this.document.traverse({ condition: nodes.system_message }).forEach((node, i) => { if (node.attributes.level < this.document.reporter.reportLevel) { //node.parent!.children.pop(i); } }); } } FilterMessages.defaultPriority = 870; /** * Append all post-parse system messages to the end of the document. * Used for testing purposes. * @todo unimplemented */ class TestMessages extends Transform { apply() { } } TestMessages.defaultPriority = 880; export { Decorations, Messages, FilterMessages, TestMessages, };