@bbc/morty-docs 1.12.2 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/build/generate-indexes.js +7 -12
- package/build/generate-transform-input.js +47 -12
- package/build/helpers/filter-dirs-in-dir.js +4 -7
- package/build/helpers/filter-files-in-dir.js +0 -4
- package/build/helpers/get-directory-paths.js +0 -4
- package/build/helpers/get-header-paths.js +0 -1
- package/build/helpers/sort-array-by-date.js +0 -2
- package/build/index.js +0 -2
- package/build/markdown-to-html-parser.js +6 -11
- package/build/page-renderers/Components/Footer.js +0 -4
- package/build/page-renderers/Components/Header.js +0 -5
- package/build/page-renderers/Components/IndexListItem.js +0 -7
- package/build/page-renderers/Components/PrettyDate.js +0 -8
- package/build/page-renderers/Components/Reset.js +0 -3
- package/build/page-renderers/Components/Title.js +0 -3
- package/build/page-renderers/Components/icons/IconFileLines.js +0 -2
- package/build/page-renderers/Components/icons/IconFolderOpen.js +0 -2
- package/build/page-renderers/IndexPage.js +0 -11
- package/build/page-renderers/MortyPage.js +0 -8
- package/build/transform-content.js +0 -9
- package/build/transform.js +0 -6
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -88,6 +88,14 @@ through because it is not markdown or asciidoc e.g. images
|
|
|
88
88
|
|
|
89
89
|
## Things to Consider
|
|
90
90
|
|
|
91
|
+
### Index file generation
|
|
92
|
+
|
|
93
|
+
Morty will automatically generate an `index.html` file for any directory that
|
|
94
|
+
contains markdown or asciidoc files (or has descendants that contain these
|
|
95
|
+
files). This file contains links to any documentation files or subdirectories
|
|
96
|
+
the directory contains. The generation will be skipped for any directory that
|
|
97
|
+
already contains an `index.md`, `index.asciidoc`, `index.adoc` or `index.asc` file.
|
|
98
|
+
|
|
91
99
|
### File & Directory Ordering
|
|
92
100
|
|
|
93
101
|
These are sorted lexically (0-9 < a-z>).
|
|
@@ -189,4 +197,4 @@ We would expect code quality to be at least as good if not better than
|
|
|
189
197
|
the code quality of the project at the time you make your contribution.
|
|
190
198
|
After all, we all hope to leave things better than we find them!
|
|
191
199
|
|
|
192
|
-
© BBC
|
|
200
|
+
© BBC 2024
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
|
|
3
2
|
const renderIndexPage = require('./page-renderers/IndexPage');
|
|
4
|
-
|
|
5
3
|
const getDirectories = require('./helpers/get-directory-paths');
|
|
6
|
-
|
|
7
4
|
const filterFilesInDirectory = require('./helpers/filter-files-in-dir');
|
|
8
|
-
|
|
9
5
|
const filterDirectoriesInDirectory = require('./helpers/filter-dirs-in-dir');
|
|
10
|
-
|
|
11
6
|
const generateIndex = (directory, filePaths, subDirPaths, options) => {
|
|
12
7
|
const subDirLinks = subDirPaths.filter(dirPath => !dirPath.includes('/')).map(dirPath => ({
|
|
13
8
|
link: `${dirPath}/index.html`,
|
|
@@ -24,22 +19,23 @@ const generateIndex = (directory, filePaths, subDirPaths, options) => {
|
|
|
24
19
|
});
|
|
25
20
|
return renderIndexPage([...subDirLinks, ...fileLinks], options, directory);
|
|
26
21
|
};
|
|
27
|
-
|
|
28
22
|
const generateIndexes = (files, options = {
|
|
29
23
|
contentTitle: ''
|
|
30
24
|
}) => {
|
|
31
25
|
const supportedFilePaths = files.map(file => file.relativePath).filter(relativePath => path.extname(relativePath) === '.html' || path.extname(relativePath) === '.pdf');
|
|
32
|
-
const directories = getDirectories(supportedFilePaths);
|
|
26
|
+
const directories = getDirectories(supportedFilePaths);
|
|
27
|
+
// If we have not got a 'root' folder, then add one.
|
|
33
28
|
// TODO: Refactor this so it is not needed (maybe?)
|
|
34
|
-
|
|
35
29
|
if (!directories.includes('')) {
|
|
36
30
|
directories.push('');
|
|
37
31
|
}
|
|
38
|
-
|
|
39
|
-
const indexes = directories.map(directory => {
|
|
32
|
+
const indexes = directories.flatMap(directory => {
|
|
40
33
|
const filesInDir = filterFilesInDirectory(supportedFilePaths, directory);
|
|
41
34
|
const subDirsInDir = filterDirectoriesInDirectory(directories, directory);
|
|
42
|
-
const indexPath = directory
|
|
35
|
+
const indexPath = path.join(directory, 'index.html');
|
|
36
|
+
if (filesInDir.includes(indexPath)) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
43
39
|
return {
|
|
44
40
|
relativePath: indexPath,
|
|
45
41
|
raw: Buffer.from(generateIndex(directory, filesInDir, subDirsInDir, options))
|
|
@@ -47,5 +43,4 @@ const generateIndexes = (files, options = {
|
|
|
47
43
|
});
|
|
48
44
|
return indexes;
|
|
49
45
|
};
|
|
50
|
-
|
|
51
46
|
module.exports = generateIndexes;
|
|
@@ -1,19 +1,54 @@
|
|
|
1
|
-
const readdir = require('recursive-readdir');
|
|
2
|
-
|
|
3
1
|
const fs = require('fs');
|
|
4
|
-
|
|
5
2
|
const path = require('path');
|
|
6
|
-
|
|
7
3
|
const generateTransformInput = dir => {
|
|
8
4
|
dir = path.format(path.parse(dir));
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
raw: fs.readFileSync(file)
|
|
14
|
-
};
|
|
15
|
-
});
|
|
5
|
+
let list = [];
|
|
6
|
+
const files = fs.readdirSync(dir, {
|
|
7
|
+
recursive: true,
|
|
8
|
+
withFileTypes: true
|
|
16
9
|
});
|
|
17
|
-
|
|
10
|
+
// recursive option available from node 18+
|
|
11
|
+
// when options.withFileTypes set to true, the returned array will contain <fs.Dirent> objects.
|
|
12
|
+
for (const dirent of files) {
|
|
13
|
+
// Node API for Dirent is unstable
|
|
14
|
+
const dirPath = dirent.path || dirent.parentPath; // path is DEPRECATED! But parentPath does not work in 18.17
|
|
18
15
|
|
|
16
|
+
const fullPath = path.join(dirPath, dirent.name);
|
|
17
|
+
// console.log('fullPath = ', fullPath)
|
|
18
|
+
|
|
19
|
+
if (dirent.isDirectory()) {
|
|
20
|
+
console.log('directory... continue');
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (dirent.isFile()) {
|
|
24
|
+
list.push(makeInputObject(fullPath, dir));
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (dirent.isSymbolicLink) {
|
|
28
|
+
if (fs.existsSync(fullPath)) {
|
|
29
|
+
// fs.exists() is deprecated, but fs.existsSync() is not.
|
|
30
|
+
const stats = fs.statSync(fullPath);
|
|
31
|
+
console.log('Good symlink');
|
|
32
|
+
if (stats.isFile()) {
|
|
33
|
+
// get file details
|
|
34
|
+
list.push(makeInputObject(fullPath, dir)); // symlinks become copies
|
|
35
|
+
} else {
|
|
36
|
+
// recursive call to get all files in the symlinked directory
|
|
37
|
+
const newlist = generateTransformInput(fullPath);
|
|
38
|
+
list = list.concat(newlist);
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
console.log(`Broken symlink at: ${fullPath}`);
|
|
42
|
+
}
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return list;
|
|
47
|
+
};
|
|
48
|
+
const makeInputObject = (fullPath, rootPath) => {
|
|
49
|
+
return {
|
|
50
|
+
relativePath: fullPath.replace(`${rootPath}/`, ''),
|
|
51
|
+
raw: fs.readFileSync(fullPath, 'utf-8')
|
|
52
|
+
};
|
|
53
|
+
};
|
|
19
54
|
module.exports = generateTransformInput;
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
const {
|
|
2
2
|
sortArrayByDate
|
|
3
3
|
} = require('./sort-array-by-date');
|
|
4
|
-
|
|
5
4
|
const filterDirs = (directoryPaths, directory) => {
|
|
6
5
|
const directoryArray = [];
|
|
7
6
|
const nestedDirFolders = directoryPaths.filter(directoryPath => directoryPath.includes(directory) && !directoryPath.startsWith(directory) && directoryPath !== directory);
|
|
8
|
-
if (nestedDirFolders.length) directoryArray.push(nestedDirFolders);
|
|
7
|
+
if (nestedDirFolders.length) directoryArray.push(nestedDirFolders);
|
|
8
|
+
// if directory path includes the config folder then return the full directory path
|
|
9
9
|
|
|
10
10
|
const rootDirFolders = directoryPaths.filter(directoryPath => directoryPath.startsWith(directory) && directoryPath !== directory);
|
|
11
11
|
const rootDir = rootDirFolders.map(directoryPath => directoryPath.startsWith(`${directory}/`) && directory !== '' ? directoryPath.replace(`${directory}/`, '') : directoryPath);
|
|
12
|
-
if (rootDir.length) directoryArray.push(rootDir);
|
|
12
|
+
if (rootDir.length) directoryArray.push(rootDir);
|
|
13
|
+
// if directory path starts with the config folder then remove the directory from the path
|
|
13
14
|
// sort array here
|
|
14
|
-
|
|
15
15
|
let sortedDirectoryArray = directoryArray;
|
|
16
|
-
|
|
17
16
|
if (sortedDirectoryArray.length) {
|
|
18
17
|
sortedDirectoryArray.map(arr => sortArrayByDate(arr));
|
|
19
18
|
}
|
|
20
|
-
|
|
21
19
|
return sortedDirectoryArray.flat();
|
|
22
20
|
};
|
|
23
|
-
|
|
24
21
|
module.exports = filterDirs;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
const {
|
|
2
2
|
sortArrayByDate
|
|
3
3
|
} = require('./sort-array-by-date');
|
|
4
|
-
|
|
5
4
|
const directoryDepth = path => path.split('/').length;
|
|
6
|
-
|
|
7
5
|
const isInRootDirectory = filePath => directoryDepth(filePath) === 1;
|
|
8
|
-
|
|
9
6
|
const isIn = directory => filePath => filePath.startsWith(directory) && directoryDepth(filePath) - 1 === directoryDepth(directory);
|
|
10
|
-
|
|
11
7
|
module.exports = (filePaths, directory) => {
|
|
12
8
|
const isInSpecifiedDirectory = directory ? isIn(directory) : isInRootDirectory;
|
|
13
9
|
return sortArrayByDate(filePaths.filter(isInSpecifiedDirectory));
|
|
@@ -4,7 +4,6 @@ const getDirectoryPaths = filePaths => {
|
|
|
4
4
|
if (!path.includes('/')) return ''; // if file is not in the directory, return '', as this is the root
|
|
5
5
|
|
|
6
6
|
const splitPaths = path.split('/'); // => [ 'SomeOtherDir', 'AnotherDir', 'AnotherNestedDir', 'File1.html' ]
|
|
7
|
-
|
|
8
7
|
splitPaths.pop(); // remove file.html
|
|
9
8
|
|
|
10
9
|
const allDirs = splitPaths.map((splitPath, index) => {
|
|
@@ -15,14 +14,11 @@ const getDirectoryPaths = filePaths => {
|
|
|
15
14
|
});
|
|
16
15
|
return [...new Set(dirPaths.flat())];
|
|
17
16
|
};
|
|
18
|
-
|
|
19
17
|
const joinPathParts = (pathsArray, end) => {
|
|
20
18
|
if (end === 0) {
|
|
21
19
|
return pathsArray[0];
|
|
22
20
|
}
|
|
23
|
-
|
|
24
21
|
end++;
|
|
25
22
|
return pathsArray.slice(0, end).join('/');
|
|
26
23
|
};
|
|
27
|
-
|
|
28
24
|
module.exports = getDirectoryPaths;
|
|
@@ -3,11 +3,9 @@ const dateRegex = /\d{4}-\d{2}-\d{2}/; // i.e. 2019-10-29
|
|
|
3
3
|
function sortByDate(a, b) {
|
|
4
4
|
return a.match(dateRegex) && b.match(dateRegex) ? b.localeCompare(a) : a.localeCompare(b);
|
|
5
5
|
}
|
|
6
|
-
|
|
7
6
|
const sortArrayByDate = arr => {
|
|
8
7
|
return arr.sort(sortByDate);
|
|
9
8
|
};
|
|
10
|
-
|
|
11
9
|
module.exports = {
|
|
12
10
|
sortArrayByDate
|
|
13
11
|
};
|
package/build/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
const showdown = require('showdown');
|
|
2
|
-
// to convert links within a file from *.md to *.html
|
|
3
|
-
|
|
1
|
+
const showdown = require('showdown');
|
|
4
2
|
|
|
3
|
+
// there may be an option to enable this, but since we haven't found it here is a reg-ex
|
|
4
|
+
// to convert links within a file from *.md to *.html
|
|
5
5
|
const convertMdLinksToHtmlLinks = {
|
|
6
6
|
type: 'output',
|
|
7
7
|
regex: /<a href="([^:\n]*?).md">/g,
|
|
8
8
|
// exclude colon, so external links aren't converted
|
|
9
9
|
replace: '<a href="$1.html">'
|
|
10
|
-
};
|
|
10
|
+
};
|
|
11
11
|
|
|
12
|
+
// Replace hash links with .html e.g. page.md#Title becomes page.html#Title.
|
|
12
13
|
const convertMdHashLinksToHtmlLinks = {
|
|
13
14
|
type: 'output',
|
|
14
15
|
regex: /<a href="([^:\n]*?).md#(.*?)">/g,
|
|
@@ -17,7 +18,7 @@ const convertMdHashLinksToHtmlLinks = {
|
|
|
17
18
|
};
|
|
18
19
|
const headingExtension = {
|
|
19
20
|
type: 'output',
|
|
20
|
-
regex: /<(h[123456]) id="(
|
|
21
|
+
regex: /<(h[123456]) id="([^"]+)">(.*)<\/\1>/g,
|
|
21
22
|
replace: '<$1 id="$2"><a href="#$2">$3</a></$1>'
|
|
22
23
|
};
|
|
23
24
|
const classMap = {
|
|
@@ -29,17 +30,13 @@ const bindings = Object.keys(classMap).map(key => ({
|
|
|
29
30
|
regex: new RegExp(`<${key}(.*)>`, 'g'),
|
|
30
31
|
replace: `<${key} class="${classMap[key]}" $1>`
|
|
31
32
|
}));
|
|
32
|
-
|
|
33
33
|
const normaliseBasePath = basePath => {
|
|
34
34
|
const pathElements = (basePath || '').split('/').filter(entry => Boolean(entry));
|
|
35
|
-
|
|
36
35
|
if (pathElements.length === 0) {
|
|
37
36
|
return '';
|
|
38
37
|
}
|
|
39
|
-
|
|
40
38
|
return '/' + pathElements.join('/');
|
|
41
39
|
};
|
|
42
|
-
|
|
43
40
|
const createParser = options => {
|
|
44
41
|
const basePath = normaliseBasePath(options.basePath);
|
|
45
42
|
const addBasePathToRootLinks = {
|
|
@@ -54,10 +51,8 @@ const createParser = options => {
|
|
|
54
51
|
parser.setFlavor('github');
|
|
55
52
|
return parser;
|
|
56
53
|
};
|
|
57
|
-
|
|
58
54
|
const parseToHTML = (markdown, options = {}) => {
|
|
59
55
|
const parser = createParser(options);
|
|
60
56
|
return parser.makeHtml(markdown);
|
|
61
57
|
};
|
|
62
|
-
|
|
63
58
|
module.exports = parseToHTML;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const {
|
|
4
3
|
prettyDate
|
|
5
4
|
} = require('./PrettyDate');
|
|
6
|
-
|
|
7
5
|
const Styles = {
|
|
8
6
|
footer: {
|
|
9
7
|
bottom: '0',
|
|
@@ -20,7 +18,6 @@ const Styles = {
|
|
|
20
18
|
color: '#337ab7'
|
|
21
19
|
}
|
|
22
20
|
};
|
|
23
|
-
|
|
24
21
|
const Footer = () => {
|
|
25
22
|
return React.createElement("footer", {
|
|
26
23
|
style: Styles.footer
|
|
@@ -29,5 +26,4 @@ const Footer = () => {
|
|
|
29
26
|
style: Styles.footerLink
|
|
30
27
|
}, "Morty-Docs on github"), React.createElement("br", null), "Page generated on ", prettyDate(new Date()));
|
|
31
28
|
};
|
|
32
|
-
|
|
33
29
|
module.exports = Footer;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const getHeaderPaths = require('../../helpers/get-header-paths');
|
|
4
|
-
|
|
5
3
|
const Styles = {
|
|
6
4
|
navbar: {
|
|
7
5
|
border: 'none',
|
|
@@ -28,7 +26,6 @@ const Styles = {
|
|
|
28
26
|
color: '#ebebeb'
|
|
29
27
|
}
|
|
30
28
|
};
|
|
31
|
-
|
|
32
29
|
const HeaderLinks = ({
|
|
33
30
|
paths
|
|
34
31
|
}) => paths.map(({
|
|
@@ -45,7 +42,6 @@ const HeaderLinks = ({
|
|
|
45
42
|
href: path
|
|
46
43
|
}, text));
|
|
47
44
|
});
|
|
48
|
-
|
|
49
45
|
const Header = ({
|
|
50
46
|
relPath,
|
|
51
47
|
basePath
|
|
@@ -60,5 +56,4 @@ const Header = ({
|
|
|
60
56
|
paths: getHeaderPaths(basePath, relPath)
|
|
61
57
|
}))));
|
|
62
58
|
};
|
|
63
|
-
|
|
64
59
|
module.exports = Header;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const IconFileLines = require('./icons/IconFileLines');
|
|
4
|
-
|
|
5
3
|
const IconFolderOpen = require('./icons/IconFolderOpen');
|
|
6
|
-
|
|
7
4
|
const Styles = {
|
|
8
5
|
indexListItem: {
|
|
9
6
|
fontSize: '1.5rem',
|
|
@@ -28,7 +25,6 @@ const Styles = {
|
|
|
28
25
|
width: '1em'
|
|
29
26
|
}
|
|
30
27
|
};
|
|
31
|
-
|
|
32
28
|
const Icon = ({
|
|
33
29
|
iconName
|
|
34
30
|
}) => {
|
|
@@ -37,12 +33,10 @@ const Icon = ({
|
|
|
37
33
|
style: Styles.icon
|
|
38
34
|
});
|
|
39
35
|
}
|
|
40
|
-
|
|
41
36
|
return React.createElement(IconFileLines, {
|
|
42
37
|
style: Styles.icon
|
|
43
38
|
});
|
|
44
39
|
};
|
|
45
|
-
|
|
46
40
|
const IndexListItem = ({
|
|
47
41
|
link,
|
|
48
42
|
text,
|
|
@@ -61,5 +55,4 @@ const IndexListItem = ({
|
|
|
61
55
|
style: Styles.linkText
|
|
62
56
|
}, text)));
|
|
63
57
|
};
|
|
64
|
-
|
|
65
58
|
module.exports = IndexListItem;
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const nth = function (d) {
|
|
4
3
|
if (d > 3 && d < 21) return 'th';
|
|
5
|
-
|
|
6
4
|
switch (d % 10) {
|
|
7
5
|
case 1:
|
|
8
6
|
return 'st';
|
|
9
|
-
|
|
10
7
|
case 2:
|
|
11
8
|
return 'nd';
|
|
12
|
-
|
|
13
9
|
case 3:
|
|
14
10
|
return 'rd';
|
|
15
|
-
|
|
16
11
|
default:
|
|
17
12
|
return 'th';
|
|
18
13
|
}
|
|
19
14
|
};
|
|
20
|
-
|
|
21
15
|
const month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
22
|
-
|
|
23
16
|
const prettyDate = dateObj => {
|
|
24
17
|
const day = dateObj.getDate();
|
|
25
18
|
const year = dateObj.getFullYear();
|
|
26
19
|
return React.createElement(React.Fragment, null, day, React.createElement("sup", null, nth(day)), " ", month[dateObj.getMonth()], " ", year);
|
|
27
20
|
};
|
|
28
|
-
|
|
29
21
|
module.exports = {
|
|
30
22
|
prettyDate
|
|
31
23
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const resetStyles = `/* http://meyerweb.com/eric/tools/css/reset/
|
|
4
3
|
v2.0 | 20110126
|
|
5
4
|
License: none (public domain)
|
|
@@ -54,11 +53,9 @@ sup {
|
|
|
54
53
|
padding-right: 0.2rem;
|
|
55
54
|
}
|
|
56
55
|
`;
|
|
57
|
-
|
|
58
56
|
const Reset = () => React.createElement("style", {
|
|
59
57
|
dangerouslySetInnerHTML: {
|
|
60
58
|
__html: resetStyles
|
|
61
59
|
}
|
|
62
60
|
});
|
|
63
|
-
|
|
64
61
|
module.exports = Reset;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const Styles = {
|
|
4
3
|
heading: {
|
|
5
4
|
fontSize: '2rem',
|
|
6
5
|
fontWeight: '500'
|
|
7
6
|
}
|
|
8
7
|
};
|
|
9
|
-
|
|
10
8
|
const Title = ({
|
|
11
9
|
contentTitle
|
|
12
10
|
}) => {
|
|
@@ -22,5 +20,4 @@ const Title = ({
|
|
|
22
20
|
}, contentTitle));
|
|
23
21
|
} else return null;
|
|
24
22
|
};
|
|
25
|
-
|
|
26
23
|
module.exports = Title;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const IconFileLines = ({
|
|
4
3
|
style
|
|
5
4
|
}) => React.createElement("svg", {
|
|
@@ -10,5 +9,4 @@ const IconFileLines = ({
|
|
|
10
9
|
}, '<!--! Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. -->', React.createElement("path", {
|
|
11
10
|
d: "M256 0v128h128L256 0zM224 128L224 0H48C21.49 0 0 21.49 0 48v416C0 490.5 21.49 512 48 512h288c26.51 0 48-21.49 48-48V160h-127.1C238.3 160 224 145.7 224 128zM272 416h-160C103.2 416 96 408.8 96 400C96 391.2 103.2 384 112 384h160c8.836 0 16 7.162 16 16C288 408.8 280.8 416 272 416zM272 352h-160C103.2 352 96 344.8 96 336C96 327.2 103.2 320 112 320h160c8.836 0 16 7.162 16 16C288 344.8 280.8 352 272 352zM288 272C288 280.8 280.8 288 272 288h-160C103.2 288 96 280.8 96 272C96 263.2 103.2 256 112 256h160C280.8 256 288 263.2 288 272z"
|
|
12
11
|
}));
|
|
13
|
-
|
|
14
12
|
module.exports = IconFileLines;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const IconFolderOpen = ({
|
|
4
3
|
style
|
|
5
4
|
}) => React.createElement("svg", {
|
|
@@ -10,5 +9,4 @@ const IconFolderOpen = ({
|
|
|
10
9
|
}, '<!--! Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. -->', React.createElement("path", {
|
|
11
10
|
d: "M147.8 192H480V144C480 117.5 458.5 96 432 96h-160l-64-64h-160C21.49 32 0 53.49 0 80v328.4l90.54-181.1C101.4 205.6 123.4 192 147.8 192zM543.1 224H147.8C135.7 224 124.6 230.8 119.2 241.7L0 480h447.1c12.12 0 23.2-6.852 28.62-17.69l96-192C583.2 249 567.7 224 543.1 224z"
|
|
12
11
|
}));
|
|
13
|
-
|
|
14
12
|
module.exports = IconFolderOpen;
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
-
|
|
3
2
|
const React = require('react');
|
|
4
|
-
|
|
5
3
|
const ReactDOMServer = require('react-dom/server');
|
|
6
|
-
|
|
7
4
|
const Header = require('./Components/Header');
|
|
8
|
-
|
|
9
5
|
const Title = require('./Components/Title');
|
|
10
|
-
|
|
11
6
|
const Footer = require('./Components/Footer');
|
|
12
|
-
|
|
13
7
|
const IndexListItem = require('./Components/IndexListItem');
|
|
14
|
-
|
|
15
8
|
const Reset = require('./Components/Reset');
|
|
16
|
-
|
|
17
9
|
const Styles = {
|
|
18
10
|
headingContainer: {
|
|
19
11
|
padding: '40px 15px',
|
|
@@ -49,7 +41,6 @@ const Styles = {
|
|
|
49
41
|
margin: 'auto'
|
|
50
42
|
}
|
|
51
43
|
};
|
|
52
|
-
|
|
53
44
|
const IndexPage = ({
|
|
54
45
|
listItems,
|
|
55
46
|
options,
|
|
@@ -85,11 +76,9 @@ const IndexPage = ({
|
|
|
85
76
|
key: index
|
|
86
77
|
}, item))))())))), React.createElement(Footer, null)));
|
|
87
78
|
};
|
|
88
|
-
|
|
89
79
|
const renderIndexPage = (listItems, options, htmlFilePaths) => ReactDOMServer.renderToString(React.createElement(IndexPage, {
|
|
90
80
|
listItems: listItems,
|
|
91
81
|
options: options,
|
|
92
82
|
relPath: htmlFilePaths
|
|
93
83
|
}));
|
|
94
|
-
|
|
95
84
|
module.exports = renderIndexPage;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
|
-
|
|
3
2
|
const ReactDOMServer = require('react-dom/server');
|
|
4
|
-
|
|
5
3
|
const Header = require('./Components/Header');
|
|
6
|
-
|
|
7
4
|
const Footer = require('./Components/Footer');
|
|
8
|
-
|
|
9
5
|
const Reset = require('./Components/Reset');
|
|
10
|
-
|
|
11
6
|
const Styles = {
|
|
12
7
|
wrapper: {
|
|
13
8
|
minHeight: '75vh',
|
|
@@ -174,7 +169,6 @@ const contentStyles = `
|
|
|
174
169
|
}
|
|
175
170
|
|
|
176
171
|
`;
|
|
177
|
-
|
|
178
172
|
const MortyPage = ({
|
|
179
173
|
relPath,
|
|
180
174
|
body,
|
|
@@ -209,11 +203,9 @@ const MortyPage = ({
|
|
|
209
203
|
}
|
|
210
204
|
})), React.createElement(Footer, null)));
|
|
211
205
|
};
|
|
212
|
-
|
|
213
206
|
const renderMortyPage = (relPath, htmlBody, options) => ReactDOMServer.renderToString(React.createElement(MortyPage, {
|
|
214
207
|
relPath: relPath,
|
|
215
208
|
body: htmlBody,
|
|
216
209
|
options: options
|
|
217
210
|
}));
|
|
218
|
-
|
|
219
211
|
module.exports = renderMortyPage;
|
|
@@ -1,28 +1,20 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
|
|
3
2
|
const asciidoctor = require('asciidoctor')();
|
|
4
|
-
|
|
5
3
|
const renderMortyPage = require('./page-renderers/MortyPage');
|
|
6
|
-
|
|
7
4
|
const parseToHtml = require('./markdown-to-html-parser');
|
|
8
|
-
|
|
9
5
|
const changeExtension = relPath => relPath.replace(/\.[^.]*$/, '.html'); // \.[^.]*$ selects everything from end of string to first '.' character including the '.'
|
|
10
6
|
|
|
11
|
-
|
|
12
7
|
const convertToHtml = ({
|
|
13
8
|
relativePath,
|
|
14
9
|
raw
|
|
15
10
|
}, options) => {
|
|
16
11
|
const textString = raw.toString();
|
|
17
12
|
const ext = path.extname(relativePath);
|
|
18
|
-
|
|
19
13
|
if (ext === '.asciidoc' || ext === '.adoc' || ext === '.asc') {
|
|
20
14
|
return asciidoctor.convert(textString);
|
|
21
15
|
}
|
|
22
|
-
|
|
23
16
|
return parseToHtml(textString, options);
|
|
24
17
|
};
|
|
25
|
-
|
|
26
18
|
const transformContent = (inputObj, options) => {
|
|
27
19
|
const inputRelPath = inputObj.relativePath;
|
|
28
20
|
const html = convertToHtml(inputObj, options);
|
|
@@ -31,5 +23,4 @@ const transformContent = (inputObj, options) => {
|
|
|
31
23
|
raw: renderMortyPage(inputRelPath, html, options)
|
|
32
24
|
};
|
|
33
25
|
};
|
|
34
|
-
|
|
35
26
|
module.exports = transformContent;
|
package/build/transform.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
|
|
3
2
|
const transformContent = require('./transform-content');
|
|
4
|
-
|
|
5
3
|
const generateIndexes = require('./generate-indexes');
|
|
6
|
-
|
|
7
4
|
const validate = inputObjs => {
|
|
8
5
|
if (!Array.isArray(inputObjs)) throw new Error('First arg to transform() must be an array');
|
|
9
6
|
inputObjs.map(inputObj => {
|
|
@@ -11,12 +8,10 @@ const validate = inputObjs => {
|
|
|
11
8
|
if (typeof inputObj.relativePath === 'undefined') throw new Error('All objects in input array must have a .relativePath property');
|
|
12
9
|
});
|
|
13
10
|
};
|
|
14
|
-
|
|
15
11
|
const transform = (inputObjs, options) => {
|
|
16
12
|
validate(inputObjs);
|
|
17
13
|
const contentObjs = inputObjs.map(inputObj => {
|
|
18
14
|
const ext = path.extname(inputObj.relativePath);
|
|
19
|
-
|
|
20
15
|
if (ext === '.md' || ext === '.asciidoc' || ext === '.adoc' || ext === '.asc') {
|
|
21
16
|
return transformContent(inputObj, options);
|
|
22
17
|
} else {
|
|
@@ -26,5 +21,4 @@ const transform = (inputObjs, options) => {
|
|
|
26
21
|
const indexObjs = generateIndexes(contentObjs, options);
|
|
27
22
|
return [...contentObjs, ...indexObjs];
|
|
28
23
|
};
|
|
29
|
-
|
|
30
24
|
module.exports = transform;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbc/morty-docs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "To generate a static website from markdown documentation, to allow users to consume content in an easily accessible format",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"markdown"
|
|
32
32
|
],
|
|
33
33
|
"engines": {
|
|
34
|
-
"node": ">=
|
|
34
|
+
"node": ">=18.x",
|
|
35
|
+
"npm": ">=8.x"
|
|
35
36
|
},
|
|
36
37
|
"author": "BBC",
|
|
37
38
|
"license": "Apache-2.0",
|
|
@@ -55,7 +56,7 @@
|
|
|
55
56
|
"@babel/preset-react": "^7.0.0",
|
|
56
57
|
"babel-eslint": "^10.0.3",
|
|
57
58
|
"http-server": "^14.1.1",
|
|
58
|
-
"jest": "^
|
|
59
|
+
"jest": "^29.7.0",
|
|
59
60
|
"jest-serializer-html": "^7.0.0",
|
|
60
61
|
"standard": "^12.0.1"
|
|
61
62
|
},
|