mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-06 21:03:47 +02:00
feat: replace relative markdown link to corrrect url
This commit is contained in:
parent
4d10c3b8f3
commit
760b9172b0
5 changed files with 85 additions and 13 deletions
|
@ -3,6 +3,20 @@ id: hello
|
|||
title: Hello, World !
|
||||
---
|
||||
|
||||
## Relative links
|
||||
|
||||
Replace this
|
||||
[highlight](highlight.md) [docusaurus](docusaurus.md)
|
||||
|
||||
Can't replace this
|
||||
[file](file.md)
|
||||
|
||||
Do not replace below
|
||||
|
||||
```
|
||||
[highlight](highlight.md) [docusaurus](docusaurus.md)
|
||||
```
|
||||
|
||||
## Blockquotes
|
||||
|
||||
> Blockquotes can also be nested...
|
||||
|
|
|
@ -26,6 +26,12 @@ module.exports = async function load(siteDir) {
|
|||
`export default ${JSON.stringify(docsData, null, 2)};`
|
||||
);
|
||||
|
||||
/* Create source to permalink mapping */
|
||||
const sourceToLink = {};
|
||||
Object.values(docsData).forEach(({source, permalink}) => {
|
||||
sourceToLink[source] = permalink;
|
||||
});
|
||||
|
||||
// pages
|
||||
const pagesDir = path.resolve(siteDir, 'pages');
|
||||
const pagesData = await loadPages(pagesDir);
|
||||
|
@ -41,6 +47,8 @@ module.exports = async function load(siteDir) {
|
|||
const themePath = loadTheme(siteDir);
|
||||
|
||||
const baseUrl = siteConfig.baseUrl || '/';
|
||||
const versionedDir = path.join(siteDir, 'versioned_docs');
|
||||
const translatedDir = path.join(siteDir, 'translated_docs');
|
||||
|
||||
const props = {
|
||||
siteConfig,
|
||||
|
@ -52,7 +60,10 @@ module.exports = async function load(siteDir) {
|
|||
pagesData,
|
||||
outDir,
|
||||
themePath,
|
||||
baseUrl
|
||||
baseUrl,
|
||||
sourceToLink,
|
||||
versionedDir,
|
||||
translatedDir
|
||||
};
|
||||
|
||||
// Generate React Router Config
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import siteConfig from '@site/siteConfig';
|
||||
import styles from './styles.css';
|
||||
|
||||
/* eslint-disable react/prefer-stateless-function */
|
||||
|
|
|
@ -13,6 +13,9 @@ module.exports = function createBaseConfig(props, isServer) {
|
|||
docsDir,
|
||||
pagesDir,
|
||||
siteDir,
|
||||
sourceToLink,
|
||||
versionedDir,
|
||||
translatedDir,
|
||||
baseUrl
|
||||
} = props;
|
||||
|
||||
|
@ -33,8 +36,8 @@ module.exports = function createBaseConfig(props, isServer) {
|
|||
.set('symlinks', true)
|
||||
.alias.set('@theme', themePath)
|
||||
.set('@site', siteDir)
|
||||
.set('@versioned_docs', path.resolve(siteDir, 'versioned_docs'))
|
||||
.set('@translated_docs', path.resolve(siteDir, 'translated_docs'))
|
||||
.set('@versioned_docs', versionedDir)
|
||||
.set('@translated_docs', translatedDir)
|
||||
.set('@docs', docsDir)
|
||||
.set('@pages', pagesDir)
|
||||
.set('@build', outDir)
|
||||
|
@ -75,7 +78,7 @@ module.exports = function createBaseConfig(props, isServer) {
|
|||
mdRule
|
||||
.use('markdown-loader')
|
||||
.loader(mdLoader)
|
||||
.options({siteConfig, siteDir, docsDir});
|
||||
.options({siteConfig, versionedDir, translatedDir, docsDir, sourceToLink});
|
||||
|
||||
const cssRule = config.module.rule('css').test(/\.css$/);
|
||||
if (isProd) {
|
||||
|
@ -110,12 +113,12 @@ module.exports = function createBaseConfig(props, isServer) {
|
|||
warnings: false,
|
||||
compress: false,
|
||||
ecma: 6,
|
||||
mangle: true,
|
||||
mangle: true
|
||||
},
|
||||
sourceMap: true
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
return config;
|
||||
};
|
||||
|
|
|
@ -3,13 +3,58 @@ const fm = require('front-matter');
|
|||
|
||||
module.exports = function(fileString) {
|
||||
const options = getOptions(this);
|
||||
const {siteConfig, siteDir, docsDir } = options;
|
||||
const {
|
||||
siteConfig,
|
||||
versionedDir,
|
||||
docsDir,
|
||||
translatedDir,
|
||||
sourceToLink
|
||||
} = options;
|
||||
|
||||
/*
|
||||
Process the markdown file content, including replacing all relative markdown links
|
||||
*/
|
||||
const {body: content = ''} = fm(fileString);
|
||||
|
||||
/* Extract content of markdown (without frontmatter) */
|
||||
const {body} = fm(fileString);
|
||||
|
||||
/* Determine whether this file is in @docs, @versioned_docs or @translated_docs */
|
||||
let dirAlias;
|
||||
if (this.resourcePath.startsWith(translatedDir)) {
|
||||
dirAlias = '@translated_docs';
|
||||
} else if (this.resourcePath.startsWith(versionedDir)) {
|
||||
dirAlias = '@versioned_docs';
|
||||
} else if (this.resourcePath.startsWith(docsDir)) {
|
||||
dirAlias = '@docs';
|
||||
}
|
||||
|
||||
/* Replace internal markdown linking (except in fenced blocks) */
|
||||
let content = body;
|
||||
if (dirAlias) {
|
||||
let fencedBlock = false;
|
||||
const lines = body.split('\n').map(line => {
|
||||
if (line.trim().startsWith('```')) {
|
||||
fencedBlock = !fencedBlock;
|
||||
}
|
||||
if (fencedBlock) return line;
|
||||
|
||||
let modifiedLine = line;
|
||||
const mdLinks = [];
|
||||
const mdRegex = /(?:\]\()(?:\.\/)?([^'")\]\s>]+\.md)/g;
|
||||
let match = mdRegex.exec(content);
|
||||
while (match !== null) {
|
||||
mdLinks.push(match[1]);
|
||||
match = mdRegex.exec(content);
|
||||
}
|
||||
mdLinks.forEach(mdLink => {
|
||||
const source = `${dirAlias}/${mdLink}`;
|
||||
const permalink = sourceToLink[source];
|
||||
if (permalink) {
|
||||
modifiedLine = modifiedLine.replace(mdLink, permalink);
|
||||
}
|
||||
});
|
||||
return modifiedLine;
|
||||
});
|
||||
content = lines.join('\n');
|
||||
}
|
||||
|
||||
/* Return a React component */
|
||||
return (
|
||||
`import React from 'react';\n` +
|
||||
`import Markdown from '@theme/Markdown'\n` +
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue