From: Wouter Admiraal Date: Tue, 8 Jan 2019 10:01:45 +0000 (+0100) Subject: DOC-131 Improve @include handling X-Git-Tag: 7.6~132 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=505b1f5c8e6ee8f4f5376ffb7ad173dbd70c846b;p=sonarqube.git DOC-131 Improve @include handling --- diff --git a/server/sonar-docs/plugins/sonarsource-source-filesystem/index.js b/server/sonar-docs/plugins/sonarsource-source-filesystem/index.js index 4ed6bec103d..7bf46ef2567 100644 --- a/server/sonar-docs/plugins/sonarsource-source-filesystem/index.js +++ b/server/sonar-docs/plugins/sonarsource-source-filesystem/index.js @@ -20,20 +20,23 @@ const { createFilePath, createRemoteFileNode } = require('gatsby-source-filesystem'); const fs = require('fs-extra'); -function loadNodeContent(fileNode) { +function loadNodeContentSync(fileNode) { const content = fs.readFileSync(fileNode.absolutePath, 'utf-8'); - return new Promise((resolve, reject) => { - let newContent = cutSonarCloudContent(content); - newContent = removeRemainingContentTags(newContent); - resolve(newContent); - }); + let newContent = cutSonarCloudContent(content); + newContent = removeRemainingContentTags(newContent); + newContent = handleIncludes(newContent, fileNode); + return newContent; +} + +function loadNodeContent(fileNode) { + return Promise.resolve(loadNodeContentSync(fileNode)); } function removeRemainingContentTags(content) { const regexBase = ''; return content - .replace(new RegExp(`^${regexBase}(\n|\r|\r\n|$)`, 'gm'), '') // First, remove single-line ones, including ending carriage-returns. - .replace(new RegExp(`${regexBase}`, 'g'), ''); // Now remove all remaining ones. + .replace(new RegExp(`^${regexBase}(\n|\r|\r\n|$)`, 'gm'), '') + .replace(new RegExp(`${regexBase}`, 'g'), ''); } function cutSonarCloudContent(content) { @@ -52,6 +55,27 @@ function cutSonarCloudContent(content) { return newContent; } +function handleIncludes(content, fileNode) { + return content.replace(/@include (.*)/g, (_, path) => { + const relativePath = `${path}.md`; + const absolutePath = `${__dirname}/../../src/${relativePath}`; + + if (relativePath === fileNode.relativePath) { + throw new Error(`Error in ${fileNode.relativePath}: The file is trying to include itself.`); + } else if (!fs.existsSync(absolutePath)) { + throw new Error( + `Error in ${fileNode.relativePath}: Couldn't load "${relativePath}" for inclusion.` + ); + } else { + const fileContent = loadNodeContentSync({ absolutePath, relativePath }); + return fileContent + .replace(/^---[\w\W]+?---$/m, '') + .replace(/^#+ *(toc|table[ -]of[ -]contents?)$/gim, '') + .trim(); + } + }); +} + exports.createFilePath = createFilePath; exports.createRemoteFileNode = createRemoteFileNode; exports.loadNodeContent = loadNodeContent; diff --git a/server/sonar-docs/src/templates/page.js b/server/sonar-docs/src/templates/page.js index d627cd7a338..12d16defb24 100644 --- a/server/sonar-docs/src/templates/page.js +++ b/server/sonar-docs/src/templates/page.js @@ -46,13 +46,10 @@ export default class Page extends React.PureComponent { render() { const page = this.props.data.markdownRemark; - let htmlWithInclusions = page.html.replace(/

@include (.*)<\/p>/, (_, path) => { - const chunk = data.allMarkdownRemark.edges.find(edge => edge.node.fields.slug === path); - return chunk ? chunk.node.html : ''; - }); const realHeadingsList = removeExtraHeadings(page.html, page.headings); + let htmlWithInclusions = page.html; htmlWithInclusions = removeTableOfContents(htmlWithInclusions); htmlWithInclusions = createAnchorForHeadings(htmlWithInclusions, realHeadingsList); htmlWithInclusions = replaceDynamicLinks(htmlWithInclusions);