import liquid from './liquid.js' import cheerio from 'cheerio' import { encode } from 'html-entities' import stripHtmlComments from 'strip-html-comments' import createProcessor from './create-processor.js' // used below to remove extra newlines in TOC lists const endLine = '</a>\r?\n' const blankLine = '\\s*?[\r\n]*' const startNextLine = '[^\\S\r\n]*?[-\\*] <a' const blankLineInList = new RegExp(`(${endLine})${blankLine}(${startNextLine})`, 'mg') // used below to remove unwanted newlines from inline tags in tables const inlineTags = ['a', 'code', 'em'] const inlineTagString = `(?:${inlineTags.join('|')})` const inlineTagRegex = new RegExp(`\n?(</?${inlineTagString}>?)\n?`, 'gm') // parse multiple times because some templates contain more templates. :] async function renderContent(template = '', context = {}, options = {}) { // If called with a falsy template, it can't ever become something // when rendered. We can exit early to save some pointless work. if (!template) return template try { // remove any newlines that precede html comments, then remove the comments if (template) { template = stripHtmlComments(template.replace(/\n<!--/g, '<!--')) } template = await liquid.parseAndRender(template, context) // this workaround loses syntax highlighting but correctly handles tags like <em> and entities like < template = template.replace( /``` ?shell\r?\n\s*?(\S[\s\S]*?)\r?\n.*?```/gm, '<pre><code class="hljs language-shell">$1</code></pre>' ) // clean up empty lines in TOC lists left by unrendered list items (due to productVersions) // for example, remove the blank line here: // - <a>foo</a> // // - <a>bar</a> if (template.includes('</a>')) { template = template.replace(blankLineInList, '$1$2') } // this removes any extra newlines left by (now resolved) liquid // statements so that extra space doesn't mess with list numbering template = template.replace(/(\r?\n){3}/g, '\n\n') const processor = createProcessor(context) const vFile = await processor.process(template) let html = vFile.toString() // Remove unwanted newlines (which appear as spaces) from inline tags inside tables if (html.includes('<table>')) html = removeNewlinesFromInlineTags(html) if (options.textOnly) { html = cheerio.load(html).text().trim() } if (options.cheerioObject) { return cheerio.load(html, { xmlMode: true }) } if (options.encodeEntities) html = encode(html) return html.trim() } catch (error) { if (options.filename) { console.error(`renderContent failed on file: ${options.filename}`) } throw error } } function removeNewlinesFromInlineTags(html) { const $ = cheerio.load(html) // see https://cheerio.js.org/#html-htmlstring- $(inlineTags.join(',')) .parents('td') .get() .map((tag) => $(tag).html($(tag).html().replace(inlineTagRegex, '$1'))) return $('body').html() } renderContent.liquid = liquid export default renderContent