mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-02 19:03:38 +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 !
|
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
|
||||||
|
|
||||||
> Blockquotes can also be nested...
|
> Blockquotes can also be nested...
|
||||||
|
|
|
@ -26,6 +26,12 @@ module.exports = async function load(siteDir) {
|
||||||
`export default ${JSON.stringify(docsData, null, 2)};`
|
`export default ${JSON.stringify(docsData, null, 2)};`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Create source to permalink mapping */
|
||||||
|
const sourceToLink = {};
|
||||||
|
Object.values(docsData).forEach(({source, permalink}) => {
|
||||||
|
sourceToLink[source] = permalink;
|
||||||
|
});
|
||||||
|
|
||||||
// pages
|
// pages
|
||||||
const pagesDir = path.resolve(siteDir, 'pages');
|
const pagesDir = path.resolve(siteDir, 'pages');
|
||||||
const pagesData = await loadPages(pagesDir);
|
const pagesData = await loadPages(pagesDir);
|
||||||
|
@ -41,6 +47,8 @@ module.exports = async function load(siteDir) {
|
||||||
const themePath = loadTheme(siteDir);
|
const themePath = loadTheme(siteDir);
|
||||||
|
|
||||||
const baseUrl = siteConfig.baseUrl || '/';
|
const baseUrl = siteConfig.baseUrl || '/';
|
||||||
|
const versionedDir = path.join(siteDir, 'versioned_docs');
|
||||||
|
const translatedDir = path.join(siteDir, 'translated_docs');
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
siteConfig,
|
siteConfig,
|
||||||
|
@ -52,7 +60,10 @@ module.exports = async function load(siteDir) {
|
||||||
pagesData,
|
pagesData,
|
||||||
outDir,
|
outDir,
|
||||||
themePath,
|
themePath,
|
||||||
baseUrl
|
baseUrl,
|
||||||
|
sourceToLink,
|
||||||
|
versionedDir,
|
||||||
|
translatedDir
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate React Router Config
|
// Generate React Router Config
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
import siteConfig from '@site/siteConfig';
|
|
||||||
import styles from './styles.css';
|
import styles from './styles.css';
|
||||||
|
|
||||||
/* eslint-disable react/prefer-stateless-function */
|
/* eslint-disable react/prefer-stateless-function */
|
||||||
|
|
|
@ -13,6 +13,9 @@ module.exports = function createBaseConfig(props, isServer) {
|
||||||
docsDir,
|
docsDir,
|
||||||
pagesDir,
|
pagesDir,
|
||||||
siteDir,
|
siteDir,
|
||||||
|
sourceToLink,
|
||||||
|
versionedDir,
|
||||||
|
translatedDir,
|
||||||
baseUrl
|
baseUrl
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -33,8 +36,8 @@ module.exports = function createBaseConfig(props, isServer) {
|
||||||
.set('symlinks', true)
|
.set('symlinks', true)
|
||||||
.alias.set('@theme', themePath)
|
.alias.set('@theme', themePath)
|
||||||
.set('@site', siteDir)
|
.set('@site', siteDir)
|
||||||
.set('@versioned_docs', path.resolve(siteDir, 'versioned_docs'))
|
.set('@versioned_docs', versionedDir)
|
||||||
.set('@translated_docs', path.resolve(siteDir, 'translated_docs'))
|
.set('@translated_docs', translatedDir)
|
||||||
.set('@docs', docsDir)
|
.set('@docs', docsDir)
|
||||||
.set('@pages', pagesDir)
|
.set('@pages', pagesDir)
|
||||||
.set('@build', outDir)
|
.set('@build', outDir)
|
||||||
|
@ -75,7 +78,7 @@ module.exports = function createBaseConfig(props, isServer) {
|
||||||
mdRule
|
mdRule
|
||||||
.use('markdown-loader')
|
.use('markdown-loader')
|
||||||
.loader(mdLoader)
|
.loader(mdLoader)
|
||||||
.options({siteConfig, siteDir, docsDir});
|
.options({siteConfig, versionedDir, translatedDir, docsDir, sourceToLink});
|
||||||
|
|
||||||
const cssRule = config.module.rule('css').test(/\.css$/);
|
const cssRule = config.module.rule('css').test(/\.css$/);
|
||||||
if (isProd) {
|
if (isProd) {
|
||||||
|
@ -110,12 +113,12 @@ module.exports = function createBaseConfig(props, isServer) {
|
||||||
warnings: false,
|
warnings: false,
|
||||||
compress: false,
|
compress: false,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
mangle: true,
|
mangle: true
|
||||||
},
|
},
|
||||||
sourceMap: true
|
sourceMap: true
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,13 +3,58 @@ const fm = require('front-matter');
|
||||||
|
|
||||||
module.exports = function(fileString) {
|
module.exports = function(fileString) {
|
||||||
const options = getOptions(this);
|
const options = getOptions(this);
|
||||||
const {siteConfig, siteDir, docsDir } = options;
|
const {
|
||||||
|
siteConfig,
|
||||||
|
versionedDir,
|
||||||
|
docsDir,
|
||||||
|
translatedDir,
|
||||||
|
sourceToLink
|
||||||
|
} = options;
|
||||||
|
|
||||||
/*
|
/* Extract content of markdown (without frontmatter) */
|
||||||
Process the markdown file content, including replacing all relative markdown links
|
const {body} = fm(fileString);
|
||||||
*/
|
|
||||||
const {body: content = ''} = 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 (
|
return (
|
||||||
`import React from 'react';\n` +
|
`import React from 'react';\n` +
|
||||||
`import Markdown from '@theme/Markdown'\n` +
|
`import Markdown from '@theme/Markdown'\n` +
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue