const { parseAttributes, renderAttributes } = require('../../helpers/utils'); /** * Search the renderedContent looking for code examples that have a path (and optionally a region) attribute. * When they are found replace their content with the appropriate doc-region parsed previously from an example file. */ module.exports = function renderExamples(getExampleRegion, log, createDocMessage) { return { $runAfter: ['docs-rendered'], $runBefore: ['writing-files'], ignoreBrokenExamples: false, $process: function(docs) { const titleVsHeaderErrors = []; docs.forEach(doc => { if (doc.renderedContent) { // We match either `code-example` or `code-pane` elements that have a path attribute doc.renderedContent = doc.renderedContent.replace( /<(code-example|code-pane)([^>]*)>[^<]*<\/([^>]+)>/g, (original, openingTag, attributes, closingTag) => { const attrMap = parseAttributes(attributes); if (attrMap.hasOwnProperty('title')) { titleVsHeaderErrors.push(createDocMessage( `Using the "title" attribute for specifying a ${openingTag} header is no longer supported. ` + `Use the "header" attribute instead.\n<${openingTag}${attributes}>`, doc)); return; } if (attrMap.path) { try { if (closingTag !== openingTag) { // The markdown renderer will wrap what it thinks is a paragraph in `

` and `

` tags. // If you do not leave a blank line between a paragraph of text and a `` then // the markdown renderer may add a paragraph marker "in-between" the opening and closing // tags of the code-example. For example: // // ``` // Some paragraph // // // // ``` // // will be rendered as: // // ``` //

Some paragraph // //

//
// ``` throw new Error( 'Badly formed example: ' + original + ' - closing tag does not match opening tag.\n' + ' - Perhaps you forgot to put a blank line before the example?'); } // We found a path attribute so look up the example and rebuild the HTML const exampleContent = getExampleRegion(doc, attrMap.path, attrMap.region); return `<${openingTag}${renderAttributes(attrMap)}>\n${exampleContent}\n`; } catch(e) { log.warn(createDocMessage(e.message, doc)); if (!this.ignoreBrokenExamples) { throw e; } } } // No path attribute so just ignore this one return original; }); } }); if (titleVsHeaderErrors.length) { titleVsHeaderErrors.forEach(err => log.error(err)); throw new Error('Some code snippets use the `title` attribute instead of `header`.'); } } }; };