fix: support relative markdown linking (#1138)

* fix: relative markdown reference linking

* prioritize relative linking resolve
This commit is contained in:
Endilie Yacop Sucipto 2018-12-04 12:26:43 +08:00 committed by GitHub
parent c4a9b31984
commit 9360739cba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 80 deletions

View file

@ -6,6 +6,7 @@
*/ */
const CWD = process.cwd(); const CWD = process.cwd();
const {join} = require('path'); const {join} = require('path');
const {resolve} = require('url');
const fs = require('fs-extra'); const fs = require('fs-extra');
const React = require('react'); const React = require('react');
const loadConfig = require('./config'); const loadConfig = require('./config');
@ -50,67 +51,47 @@ function getFile(metadata) {
} }
function mdToHtmlify(oldContent, mdToHtml, metadata) { function mdToHtmlify(oldContent, mdToHtml, metadata) {
let content = oldContent; /* Store broken links */
const mdLinks = [];
const mdReferences = [];
const mdBrokenLinks = []; const mdBrokenLinks = [];
// find any inline-style links to markdown files let content = oldContent;
const linkRegex = /(?:\]\()(?:\.\/)?([^'")\]\s>]+\.md)/g; /* Replace internal markdown linking (except in fenced blocks) */
let linkMatch = linkRegex.exec(content); let fencedBlock = false;
while (linkMatch !== null) { const lines = content.split('\n').map(line => {
mdLinks.push(linkMatch[1]); if (line.trim().startsWith('```')) {
linkMatch = linkRegex.exec(content); fencedBlock = !fencedBlock;
}
// find any reference-style links to markdown files
const refRegex = /(?:\]:)(?:\s)?(?:\.\/|\.\.\/)?([^'")\]\s>]+\.md)/g;
let refMatch = refRegex.exec(content);
while (refMatch !== null) {
mdReferences.push(refMatch[1]);
refMatch = refRegex.exec(content);
}
// replace markdown links to their website html links
new Set(mdLinks).forEach(mdLink => {
let htmlLink = mdToHtml[mdLink];
if (htmlLink) {
htmlLink = getPath(htmlLink, siteConfig.cleanUrl);
htmlLink = htmlLink.replace('/en/', `/${metadata.language}/`);
htmlLink = htmlLink.replace(
'/VERSION/',
metadata.version && metadata.version !== env.versioning.latestVersion
? `/${metadata.version}/`
: '/',
);
content = content.replace(
new RegExp(`\\]\\((\\./)?${mdLink}`, 'g'),
`](${htmlLink}`,
);
} else {
mdBrokenLinks.push(mdLink);
} }
}); if (fencedBlock) return line;
// replace markdown refernces to their website html links let modifiedLine = line;
new Set(mdReferences).forEach(refLink => { /* Replace inline-style links or reference-style links e.g:
let htmlLink = mdToHtml[refLink]; This is [Document 1](doc1.md) -> we replace this doc1.md with correct link
if (htmlLink) { [doc1]: doc1.md -> we replace this doc1.md with correct link
htmlLink = getPath(htmlLink, siteConfig.cleanUrl); */
htmlLink = htmlLink.replace('/en/', `/${metadata.language}/`); const mdRegex = /(?:(?:\]\()|(?:\]:\s?))(?!https)([^'")\]\s>]+\.md)/g;
htmlLink = htmlLink.replace( let mdMatch = mdRegex.exec(modifiedLine);
'/VERSION/', while (mdMatch !== null) {
metadata.version && metadata.version !== env.versioning.latestVersion /* Replace it to correct html link */
? `/${metadata.version}/` let htmlLink =
: '/', mdToHtml[resolve(metadata.source, mdMatch[1])] || mdToHtml[mdMatch[1]];
); if (htmlLink) {
content = content.replace( htmlLink = getPath(htmlLink, siteConfig.cleanUrl);
new RegExp(`\\]:(?:\\s)?(\\./|\\.\\./)?${refLink}`, 'g'), htmlLink = htmlLink.replace('/en/', `/${metadata.language}/`);
`]: ${htmlLink}`, htmlLink = htmlLink.replace(
); '/VERSION/',
} else { metadata.version && metadata.version !== env.versioning.latestVersion
mdBrokenLinks.push(refLink); ? `/${metadata.version}/`
: '/',
);
modifiedLine = modifiedLine.replace(mdMatch[1], htmlLink);
} else {
mdBrokenLinks.push(mdMatch[1]);
}
mdMatch = mdRegex.exec(modifiedLine);
} }
return modifiedLine;
}); });
content = lines.join('\n');
if (mdBrokenLinks.length) { if (mdBrokenLinks.length) {
console.log( console.log(

View file

@ -8,6 +8,7 @@
const fm = require('front-matter'); const fm = require('front-matter');
const {getOptions} = require('loader-utils'); const {getOptions} = require('loader-utils');
const path = require('path'); const path = require('path');
const {resolve} = require('url');
const Remarkable = require('remarkable'); const Remarkable = require('remarkable');
const hljs = require('highlight.js'); const hljs = require('highlight.js');
const chalk = require('chalk'); const chalk = require('chalk');
@ -58,37 +59,25 @@ module.exports = function(fileString) {
if (fencedBlock) return line; if (fencedBlock) return line;
let modifiedLine = line; let modifiedLine = line;
const inlineLinks = []; /* Replace inline-style links or reference-style links e.g:
const refLinks = []; This is [Document 1](doc1.md) -> we replace this doc1.md with correct link
/* Replace inline-style links e.g:
This is [Document 1](doc1.md) -> we replace this doc1.md with correct link
*/
const inlineRegex = /(?:\]\()(?:\.\/)?([^'")\]\s>]+\.md)/g;
let inlineMatch = inlineRegex.exec(content);
while (inlineMatch !== null) {
inlineLinks.push(inlineMatch[1]);
inlineMatch = inlineRegex.exec(content);
}
/* Replace reference-style links e.g:
This is [Document 1][doc1].
[doc1]: doc1.md -> we replace this doc1.md with correct link [doc1]: doc1.md -> we replace this doc1.md with correct link
*/ */
const refRegex = /(?:\]:)(?:\s)?(?:\.\/|\.\.\/)?([^'")\]\s>]+\.md)/g; const mdRegex = /(?:(?:\]\()|(?:\]:\s?))(?!https)([^'")\]\s>]+\.md)/g;
let refMatch = refRegex.exec(content); let mdMatch = mdRegex.exec(modifiedLine);
while (refMatch !== null) { while (mdMatch !== null) {
refLinks.push(refMatch[1]); /* Replace it to correct html link */
refMatch = refRegex.exec(content); const mdLink = mdMatch[1];
}
[...refLinks, ...inlineLinks].forEach(mdLink => {
const targetSource = `${sourceDir}/${mdLink}`; const targetSource = `${sourceDir}/${mdLink}`;
const {permalink} = sourceToMetadata[targetSource] || {}; const {permalink} =
sourceToMetadata[resolve(thisSource, mdLink)] ||
sourceToMetadata[targetSource] ||
{};
if (permalink) { if (permalink) {
modifiedLine = modifiedLine.replace(mdLink, permalink); modifiedLine = modifiedLine.replace(mdLink, permalink);
} }
}); mdMatch = mdRegex.exec(modifiedLine);
}
return modifiedLine; return modifiedLine;
}); });
content = lines.join('\n'); content = lines.join('\n');