From 0faa1b731a9d4e4675b4f88d36f411f54f2a7580 Mon Sep 17 00:00:00 2001 From: Tan Wang Leng Date: Tue, 12 Jun 2018 15:14:18 +0800 Subject: [PATCH 1/2] Fix broken baseUrl references for inner websites The current working file path (ATTRIB_CWF) specifies the document that is including another file (this included file's path is specified with ATTRIB_INCLUDE_PATH). When resolving references inside the included file, it should be resolved with regards to the included file's directory, NOT the working file's directory. For example, if the current document is 'abc/index.md', and it includes another document 'book/some-file.md', then resolving references in 'some-file.md' should be done with the 'book/' directory. not the 'abc/' directory. Let's use ATTRIB_INCLUDE_PATH instead of ATTRIB_CWF so that the baseUrl is not resolved wrongly. --- lib/markbind/lib/parser.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/markbind/lib/parser.js b/lib/markbind/lib/parser.js index d472722851..c2fe6f7f2b 100644 --- a/lib/markbind/lib/parser.js +++ b/lib/markbind/lib/parser.js @@ -543,8 +543,8 @@ Parser.prototype._rebaseReference = function (node, foundBase) { }); // rebase current element - if (element.attribs[ATTRIB_CWF]) { - const filePath = element.attribs[ATTRIB_CWF]; + if (element.attribs[ATTRIB_INCLUDE_PATH]) { + const filePath = element.attribs[ATTRIB_INCLUDE_PATH]; let newBase = calculateNewBaseUrls(filePath, this.rootPath, this.baseUrlMap); if (newBase) { const { relative, parent } = newBase; @@ -552,10 +552,11 @@ Parser.prototype._rebaseReference = function (node, foundBase) { foundBase[parent] = relative; } - const bases = Object.keys(childrenBase); + const combinedBases = Object.assign({}, childrenBase, foundBase); + const bases = Object.keys(combinedBases); if (bases.length !== 0) { // need to rebase - newBase = childrenBase[bases[0]]; + newBase = combinedBases[bases[0]]; const { children } = element; if (children) { const currentBase = calculateNewBaseUrls(element.attribs[ATTRIB_CWF], this.rootPath, this.baseUrlMap); From e3c5d6d2ef340e40d1edec9916b0ef2824c16da0 Mon Sep 17 00:00:00 2001 From: Tan Wang Leng Date: Mon, 18 Jun 2018 14:51:33 +0800 Subject: [PATCH 2/2] Parser: Fix hostBaseUrl being replaced Parser#_rebaseReference() may be called multiple times. The file content may already have {{hostBaseUrl}} in it due to previous calls to Parser#_rebaseReference(). The variable {{hostBaseUrl}} is still not defined at this stage. Undefined variables are replaced by nunjucks with nothing, resulting in wrong paths. Let's prevent nunjucks from replacing {{hostBaseUrl}}, by declaring the variable to be itself, so that the value can be injected later when it actually exist. --- lib/markbind/lib/parser.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/markbind/lib/parser.js b/lib/markbind/lib/parser.js index c2fe6f7f2b..fecbd45d81 100644 --- a/lib/markbind/lib/parser.js +++ b/lib/markbind/lib/parser.js @@ -564,7 +564,12 @@ Parser.prototype._rebaseReference = function (node, foundBase) { if (currentBase.relative !== newBase) { cheerio.prototype.options.xmlMode = false; const newBaseUrl = `{{hostBaseUrl}}/${newBase}`; - const rendered = nunjucks.renderString(cheerio.html(children), { baseUrl: newBaseUrl }); + const rendered = nunjucks.renderString(cheerio.html(children), { + // This is to prevent the nunjuck call from converting {{hostBaseUrl}} to an empty string + // and let the hostBaseUrl value be injected later. + hostBaseUrl: '{{hostBaseUrl}}', + baseUrl: newBaseUrl, + }); element.children = cheerio.parseHTML(rendered, true); cheerio.prototype.options.xmlMode = true; }