Skip to content

Commit

Permalink
fix: support relative markdown linking (#1138)
Browse files Browse the repository at this point in the history
* fix: relative markdown reference linking

* prioritize relative linking resolve
  • Loading branch information
endiliey authored Dec 4, 2018
1 parent c4a9b31 commit 9360739
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 81 deletions.
93 changes: 37 additions & 56 deletions v1/lib/server/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
const CWD = process.cwd();
const {join} = require('path');
const {resolve} = require('url');
const fs = require('fs-extra');
const React = require('react');
const loadConfig = require('./config');
Expand Down Expand Up @@ -50,67 +51,47 @@ function getFile(metadata) {
}

function mdToHtmlify(oldContent, mdToHtml, metadata) {
let content = oldContent;
const mdLinks = [];
const mdReferences = [];
/* Store broken links */
const mdBrokenLinks = [];

// find any inline-style links to markdown files
const linkRegex = /(?:\]\()(?:\.\/)?([^'")\]\s>]+\.md)/g;
let linkMatch = linkRegex.exec(content);
while (linkMatch !== null) {
mdLinks.push(linkMatch[1]);
linkMatch = linkRegex.exec(content);
}
// 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);
let content = oldContent;
/* Replace internal markdown linking (except in fenced blocks) */
let fencedBlock = false;
const lines = content.split('\n').map(line => {
if (line.trim().startsWith('```')) {
fencedBlock = !fencedBlock;
}
});

// replace markdown refernces to their website html links
new Set(mdReferences).forEach(refLink => {
let htmlLink = mdToHtml[refLink];
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(`\\]:(?:\\s)?(\\./|\\.\\./)?${refLink}`, 'g'),
`]: ${htmlLink}`,
);
} else {
mdBrokenLinks.push(refLink);
if (fencedBlock) return line;

let modifiedLine = line;
/* Replace inline-style links or reference-style links e.g:
This is [Document 1](doc1.md) -> we replace this doc1.md with correct link
[doc1]: doc1.md -> we replace this doc1.md with correct link
*/
const mdRegex = /(?:(?:\]\()|(?:\]:\s?))(?!https)([^'")\]\s>]+\.md)/g;
let mdMatch = mdRegex.exec(modifiedLine);
while (mdMatch !== null) {
/* Replace it to correct html link */
let htmlLink =
mdToHtml[resolve(metadata.source, mdMatch[1])] || mdToHtml[mdMatch[1]];
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}/`
: '/',
);
modifiedLine = modifiedLine.replace(mdMatch[1], htmlLink);
} else {
mdBrokenLinks.push(mdMatch[1]);
}
mdMatch = mdRegex.exec(modifiedLine);
}
return modifiedLine;
});
content = lines.join('\n');

if (mdBrokenLinks.length) {
console.log(
Expand Down
39 changes: 14 additions & 25 deletions v2/lib/webpack/loaders/markdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const fm = require('front-matter');
const {getOptions} = require('loader-utils');
const path = require('path');
const {resolve} = require('url');
const Remarkable = require('remarkable');
const hljs = require('highlight.js');
const chalk = require('chalk');
Expand Down Expand Up @@ -58,37 +59,25 @@ module.exports = function(fileString) {
if (fencedBlock) return line;

let modifiedLine = line;
const inlineLinks = [];
const refLinks = [];

/* 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].
/* Replace inline-style links or reference-style links e.g:
This is [Document 1](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;
let refMatch = refRegex.exec(content);
while (refMatch !== null) {
refLinks.push(refMatch[1]);
refMatch = refRegex.exec(content);
}

[...refLinks, ...inlineLinks].forEach(mdLink => {
const mdRegex = /(?:(?:\]\()|(?:\]:\s?))(?!https)([^'")\]\s>]+\.md)/g;
let mdMatch = mdRegex.exec(modifiedLine);
while (mdMatch !== null) {
/* Replace it to correct html link */
const mdLink = mdMatch[1];
const targetSource = `${sourceDir}/${mdLink}`;
const {permalink} = sourceToMetadata[targetSource] || {};
const {permalink} =
sourceToMetadata[resolve(thisSource, mdLink)] ||
sourceToMetadata[targetSource] ||
{};
if (permalink) {
modifiedLine = modifiedLine.replace(mdLink, permalink);
}
});
mdMatch = mdRegex.exec(modifiedLine);
}
return modifiedLine;
});
content = lines.join('\n');
Expand Down

0 comments on commit 9360739

Please sign in to comment.