forked from RasaHQ/rasa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathincluded_source.js
132 lines (113 loc) · 5.35 KB
/
included_source.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
This plugin gives us the ability to include source files
in a code-block in the docs, by using the following
syntax:
```python (docs/sources/path/to/file.py)
```
To make it work, you need to prefix the source file by `docs/sources/`.
It relies on `remark-source` and on a pre-build phase,
before docusaurus is started (or built). It allows us to support separate
versions of the docs (and of the program outputs).
*/
const path = require('path');
const fs = require('fs-extra');
const globby = require('globby');
const { readFile, outputFile } = fs;
const defaultOptions = {
docsDir: './docs',
relativeSourceDir: 'sources',
include: ['**.mdx', '**.md'],
pathPrefix: '../',
};
const _getIncludedSourceRe = (sourceDir) => `\`\`\`([a-z\-]+) \\(${sourceDir}/([^\\]\\s]+)\\)\n\`\`\``;
/**
This function is used copy the included sources
requested in the docs. It parses all the docs files,
finds the included sources and copy them under the `sourceDir`.
Options:
- docsDir: the directory containing the docs files
- relativeSourceDir: the directory that will contain the included sources
- include: list of patterns to look for doc files
- pathPrefix: a path prefix to use for reading the sources
*/
async function getIncludedSources(options) {
options = { ...defaultOptions, ...options };
const { docsDir, include, relativeSourceDir, pathPrefix } = options;
const cleanedSourceDir = path.join(docsDir.replace('./', ''), relativeSourceDir);
const includedSourceRe = _getIncludedSourceRe(cleanedSourceDir);
// first, gather all the docs files
const docsFiles = await globby(include, {
cwd: docsDir,
});
const seen = new Set();
// second, read every file source
let sourceFiles = await Promise.all(docsFiles.map(async (source) => {
const data = await readFile(`${docsDir}/${source}`);
const sourceFiles = [];
let group, sourceFile, content;
// third, find out if there is a source to be included
// there can be multiple sources in the same file
const re = new RegExp(includedSourceRe, 'gi');
while ((group = re.exec(data)) !== null) {
sourceFile = group[2];
if (seen.has(sourceFile)) {
continue;
}
seen.add(sourceFile);
// fourth, read the source file
content = await readFile(`${pathPrefix}${sourceFile}`);
sourceFiles.push([sourceFile, content]);
}
return sourceFiles;
}));
sourceFiles = sourceFiles.flat().filter(pair => pair.length > 0);
// finally, write all the source files in the source directory
return await Promise.all(sourceFiles.map(async ([sourceFile, content]) => {
return await outputFile(`${docsDir}/${relativeSourceDir}/${sourceFile}`, content);
}));
};
/**
This function is used to ensure that all the documentation files
which rely on the `remark-source` plugin to load source files into
the docs continue to work across documentation versions. There is no way for
`remark-source` to know about the file structure that we have, that's
why we need this extra function. The workflow is:
1. Doc files are put in a version folder upon release of a new version;
2. The files, previously on the `main` branch, used to point to source files
contained in `docs/source/...`;
3. Now that they are in a versioned folder, we need to them to point to source files
contained in `versioned_docs/version-xxx/sources/...`. This is what this function
does.
Options:
- docsDir: the directory containing the versionned docs files
- relativeSourceDir: the directory that will contain the included sources
- include: list of patterns to look for doc files
*/
async function updateVersionedSources(options) {
options = { ...defaultOptions, ...options };
const { docsDir, include, relativeSourceDir } = options;
const originalSourceDir = path.join(defaultOptions.docsDir.replace('./', ''), relativeSourceDir);
const newSourceDir = path.join(docsDir.replace('./', ''), relativeSourceDir);
const includedSourceRe = _getIncludedSourceRe(originalSourceDir);
// first, gather all the docs files
const docsFiles = await globby(include, {
cwd: docsDir,
});
const seen = new Set();
// second, read every doc file and compute their updated content
let newDocsFiles = await Promise.all(docsFiles.map(async (source) => {
const data = await readFile(`${docsDir}/${source}`);
// third, find out if there is a source to be included
// there can be multiple sources in the same file
const re = new RegExp(includedSourceRe, 'gi');
const updatedData = data.toString().replace(re, `\`\`\`$1 (${newSourceDir}/$2)\n\`\`\``);
return (updatedData != data) ? [`${docsDir}/${source}`, updatedData] : [];
}));
newDocsFiles = newDocsFiles.filter(pair => pair.length > 0);
// finally, update all the docs files with the path to the versioned source
return await Promise.all(newDocsFiles.map(async ([docsFile, updatedContent]) => {
return await outputFile(docsFile, updatedContent);
}));
}
module.exports = getIncludedSources;
module.exports.updateVersionedSources = updateVersionedSources;