@patternfly/documentation-framework 1.0.0
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/CHANGELOG.md +3964 -0
- package/README.md +92 -0
- package/app.js +118 -0
- package/assets/android-chrome-36x36.png +0 -0
- package/assets/android-chrome-48x48.png +0 -0
- package/assets/android-chrome-96x96.png +0 -0
- package/assets/favicon-16x16.png +0 -0
- package/assets/favicon-32x32.png +0 -0
- package/assets/favicon-48x48.png +0 -0
- package/assets/favicon.ico +0 -0
- package/assets/manifest.json +29 -0
- package/components/autoLinkHeader/autoLinkHeader.css +22 -0
- package/components/autoLinkHeader/autoLinkHeader.js +41 -0
- package/components/cssVariables/cssSearch.js +32 -0
- package/components/cssVariables/cssVariables.css +15 -0
- package/components/cssVariables/cssVariables.js +233 -0
- package/components/example/example.css +106 -0
- package/components/example/example.js +196 -0
- package/components/example/exampleToolbar.js +208 -0
- package/components/example/missing-thumbnail.jpg +0 -0
- package/components/footer/RHLogo.png +0 -0
- package/components/footer/footer.css +114 -0
- package/components/footer/footer.js +262 -0
- package/components/gdprBanner/gdprBanner.css +14 -0
- package/components/gdprBanner/gdprBanner.js +31 -0
- package/components/index.js +12 -0
- package/components/inlineAlert/inlineAlert.js +19 -0
- package/components/link/link.js +68 -0
- package/components/propsTable/propTypeWithLinks.js +33 -0
- package/components/propsTable/propsTable.js +82 -0
- package/components/sideNav/sideNav.css +17 -0
- package/components/sideNav/sideNav.js +95 -0
- package/components/tableOfContents/tableOfContents.css +77 -0
- package/components/tableOfContents/tableOfContents.js +89 -0
- package/components/topNav/topNav.css +30 -0
- package/components/topNav/topNav.js +24 -0
- package/global.css +7 -0
- package/helpers/asyncComponentFactory.js +41 -0
- package/helpers/capitalize.js +7 -0
- package/helpers/codeTitleTransformer.js +40 -0
- package/helpers/codesandbox.js +204 -0
- package/helpers/copy.js +19 -0
- package/helpers/createHandlebars.js +26 -0
- package/helpers/d3-timer.js +7 -0
- package/helpers/extractExampleHelpers.js +24 -0
- package/helpers/fonts.js +164 -0
- package/helpers/getId.js +6 -0
- package/helpers/getTitle.js +5 -0
- package/helpers/index.js +9 -0
- package/helpers/liveCodeTypes.js +4 -0
- package/helpers/slugger.js +35 -0
- package/helpers/trackEvent.js +17 -0
- package/helpers/xterm-addon-fit.js +3 -0
- package/helpers/xterm.js +8 -0
- package/images/patternfly-logo.svg +14 -0
- package/images/patternfly-orb.svg +28 -0
- package/layouts/index.js +1 -0
- package/layouts/logo.svg +33 -0
- package/layouts/sideNavLayout/sideNavLayout.css +104 -0
- package/layouts/sideNavLayout/sideNavLayout.js +237 -0
- package/package.json +87 -0
- package/pages/404/404.css +16 -0
- package/pages/404/404.svg +26 -0
- package/pages/404/chart.svg +24 -0
- package/pages/404/components.svg +1 -0
- package/pages/404/guidelines.svg +1 -0
- package/pages/404/index.js +136 -0
- package/pages/404/patternfly-flat.svg +1 -0
- package/pages/global-css-variables.md +108 -0
- package/pages/img/component-variable-mapping.png +0 -0
- package/pages/red-hat-font.md +40 -0
- package/routes-client.js +1 -0
- package/routes-generated.js +1 -0
- package/routes.js +155 -0
- package/scripts/cli/build.js +95 -0
- package/scripts/cli/buildClient.js +23 -0
- package/scripts/cli/buildServer.js +24 -0
- package/scripts/cli/cli.js +63 -0
- package/scripts/cli/generate.js +23 -0
- package/scripts/cli/helpers.js +9 -0
- package/scripts/cli/init.js +68 -0
- package/scripts/cli/serve.js +13 -0
- package/scripts/cli/start.js +32 -0
- package/scripts/md/anchor-header.js +69 -0
- package/scripts/md/auto-link-url.js +33 -0
- package/scripts/md/example-captions.js +67 -0
- package/scripts/md/jsxAttributes.js +20 -0
- package/scripts/md/mdx-ast-to-mdx-hast.js +210 -0
- package/scripts/md/mdx-hast-to-jsx.js +233 -0
- package/scripts/md/parseMD.js +308 -0
- package/scripts/md/remove-comments.js +21 -0
- package/scripts/md/styled-tags.js +87 -0
- package/scripts/md/typecheck.js +133 -0
- package/scripts/tsDocgen.js +155 -0
- package/scripts/webpack/getHtmlWebpackPlugins.js +78 -0
- package/scripts/webpack/prerender.js +59 -0
- package/scripts/webpack/webpack.base.config.js +159 -0
- package/scripts/webpack/webpack.client.config.js +146 -0
- package/scripts/webpack/webpack.server.config.js +55 -0
- package/scripts/writeScreenshots.js +66 -0
- package/templates/design-guidelines.js +13 -0
- package/templates/html.ejs +52 -0
- package/templates/mdx.css +308 -0
- package/templates/mdx.js +185 -0
- package/templates/patternfly-docs/content/extensions/extension/design-guidelines/design-guidelines.md +25 -0
- package/templates/patternfly-docs/content/extensions/extension/design-guidelines/img/card-elements.png +0 -0
- package/templates/patternfly-docs/content/extensions/extension/examples/Basic.jsx +4 -0
- package/templates/patternfly-docs/content/extensions/extension/examples/basic.md +25 -0
- package/templates/patternfly-docs/pages/index.js +27 -0
- package/templates/patternfly-docs/patternfly-docs.config.js +6 -0
- package/templates/patternfly-docs/patternfly-docs.css.js +8 -0
- package/templates/patternfly-docs/patternfly-docs.routes.js +12 -0
- package/templates/patternfly-docs/patternfly-docs.source.js +24 -0
- package/templates/sitemap.ejs +10 -0
- package/versions.json +870 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: Red Hat font
|
|
3
|
+
section: developer-resources
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
PR - [https://github.com/patternfly/patternfly/pull/4476](https://github.com/patternfly/patternfly/pull/4476)
|
|
7
|
+
|
|
8
|
+
Available in [v4.161.0](https://github.com/patternfly/patternfly/releases/tag/prerelease-v4.161.0)
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
PatternFly has created opt-ins for `v4.0.2` of the [RedHatFont](https://github.com/RedHatOfficial/RedHatFont/). This is an update from `v2.x`. There are many new features in this update, including:
|
|
13
|
+
|
|
14
|
+
- Variable fonts
|
|
15
|
+
- New weights in Red Hat Display and Red Hat Text
|
|
16
|
+
- Tabular figures (monospaced numbers) in Red Hat Display and Red Hat Text
|
|
17
|
+
- Red Hat Mono typeface
|
|
18
|
+
- Dropping support for IE11 (dropped the `.woff` format)
|
|
19
|
+
|
|
20
|
+
### Available Opt-ins
|
|
21
|
+
|
|
22
|
+
#### `.pf-m-redhat-updated-font`
|
|
23
|
+
|
|
24
|
+
Updates the Red Hat Text and Red Hat Display font stacks to `v4.0.2`. This should be a safe, seamless opt-in, with small improvements to glyph shape, kerning, metadata across the entire family of fonts. Potential concerns may be that this will remove support for IE11 by removing the `.woff` format support, and small layout shifts as result of the small improvements.
|
|
25
|
+
|
|
26
|
+
#### `.pf-m-redhatmono-font`
|
|
27
|
+
|
|
28
|
+
Updates the monospaced font stack to use the Red Hat Mono font. This opt-in can be combined with `.pf-m-redhat-updated-font`.
|
|
29
|
+
|
|
30
|
+
#### `.pf-m-redhatVF-font`
|
|
31
|
+
|
|
32
|
+
Updates the Red Hat Text, Red Hat Display, and Red Hat Mono font stacks to use the variable font files.
|
|
33
|
+
|
|
34
|
+
#### `.pf-m-tabular-nums`
|
|
35
|
+
|
|
36
|
+
This is a global class that can be applied to any element to enable monospaced numbers on that element and its children.
|
|
37
|
+
|
|
38
|
+
### Using opt-in classes
|
|
39
|
+
|
|
40
|
+
To opt-in to any of the new fonts (`.pf-m-redhat-updated-font`, `.pf-m-redhatmono-font`, and `.pf-m-redhatVF-font`), add the opt-in class to the `<body>` tag of your application. To opt-in to monospaced numbers globally across your application, apply `.pf-m-tabular-nums` to any element that wraps your entire application (eg, `<body>`, `<div id="root">`, `<div class="pf-c-page">`, etc). To opt-in to monospaced numbers on a particular element and its children, add the class to that element itself.
|
package/routes-client.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require(require('path').join(process.cwd(), 'patternfly-docs/patternfly-docs.routes'));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require(require('path').join(process.cwd(), 'patternfly-docs/generated'));
|
package/routes.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// This module is shared between NodeJS and babelled ES5
|
|
2
|
+
const { makeSlug, slugger } = require('@patternfly/documentation-framework/helpers/slugger');
|
|
3
|
+
const { asyncComponentFactory } = require('@patternfly/documentation-framework/helpers/asyncComponentFactory');
|
|
4
|
+
const clientRoutes = require('./routes-client'); // Webpack replaces this import: patternfly-docs.routes.js
|
|
5
|
+
const generatedRoutes = require('./routes-generated'); // Webpack replaces this import: patternfly-docs/generated/index.js
|
|
6
|
+
|
|
7
|
+
const routes = {
|
|
8
|
+
...clientRoutes,
|
|
9
|
+
...generatedRoutes
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
for (let route in routes) {
|
|
13
|
+
const pageData = routes[route];
|
|
14
|
+
if (pageData.SyncComponent) {
|
|
15
|
+
pageData.Component = pageData.SyncComponent;
|
|
16
|
+
}
|
|
17
|
+
else if (pageData.Component) {
|
|
18
|
+
pageData.Component = asyncComponentFactory(route, pageData);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Save a copy of all routes for path matching on first load
|
|
23
|
+
const allRoutes = Object.assign({}, routes);
|
|
24
|
+
|
|
25
|
+
// Group routes by section, id
|
|
26
|
+
const isNull = o => o === null || o === undefined;
|
|
27
|
+
|
|
28
|
+
const groupedRoutes = Object.entries(routes)
|
|
29
|
+
.filter(([_slug, { id, section }]) => !isNull(id) && !isNull(section))
|
|
30
|
+
.reduce((accum, [slug, pageData]) => {
|
|
31
|
+
const { section, id, title, source, katacodaLayout, hideNavItem } = pageData;
|
|
32
|
+
accum[section] = accum[section] || {};
|
|
33
|
+
accum[section][id] = accum[section][id] || {
|
|
34
|
+
id,
|
|
35
|
+
section,
|
|
36
|
+
title,
|
|
37
|
+
slug: makeSlug(source, section, id, true),
|
|
38
|
+
sources: [],
|
|
39
|
+
katacodaLayout,
|
|
40
|
+
hideNavItem
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
pageData.slug = slug;
|
|
44
|
+
accum[section][id].sources.push(pageData);
|
|
45
|
+
|
|
46
|
+
return accum;
|
|
47
|
+
}, {});
|
|
48
|
+
|
|
49
|
+
const sourceOrder = {
|
|
50
|
+
react: 1,
|
|
51
|
+
'react-composable': 1.1,
|
|
52
|
+
'react-legacy': 1.2,
|
|
53
|
+
'react-demos': 2,
|
|
54
|
+
html: 3,
|
|
55
|
+
'html-demos': 4,
|
|
56
|
+
'design-guidelines': 99,
|
|
57
|
+
'accessibility': 100
|
|
58
|
+
};
|
|
59
|
+
const defaultOrder = 50;
|
|
60
|
+
|
|
61
|
+
const sortSources = ({ source: s1 }, { source: s2 }) => {
|
|
62
|
+
const s1Index = sourceOrder[s1] || defaultOrder;
|
|
63
|
+
const s2Index = sourceOrder[s2] || defaultOrder;
|
|
64
|
+
if (s1Index === defaultOrder && s2Index === defaultOrder) {
|
|
65
|
+
return s1.localeCompare(s2);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return s1Index > s2Index ? 1 : -1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const getDefaultDesignGuidelines = ({ id, section, slug, title }) => {
|
|
72
|
+
const Component = () => require('@patternfly/documentation-framework/templates/design-guidelines').DesignGuidelineTemplate
|
|
73
|
+
const pageData = {
|
|
74
|
+
id,
|
|
75
|
+
section,
|
|
76
|
+
slug: `${slug}/design-guidelines`,
|
|
77
|
+
source: 'design-guidelines',
|
|
78
|
+
title,
|
|
79
|
+
Component
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
Component.getPageData = () => pageData;
|
|
83
|
+
|
|
84
|
+
return pageData;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Object.entries(groupedRoutes)
|
|
88
|
+
.forEach(([_section, ids]) => {
|
|
89
|
+
Object.values(ids).forEach(pageData => {
|
|
90
|
+
const { slug, section } = pageData;
|
|
91
|
+
// Remove source routes for `app.js`
|
|
92
|
+
pageData.sources.forEach(({ slug }) => {
|
|
93
|
+
delete routes[slug];
|
|
94
|
+
});
|
|
95
|
+
// Add design guidelines if doesn't exist
|
|
96
|
+
if (
|
|
97
|
+
['components', 'charts', 'layouts', 'demos'].includes(section) &&
|
|
98
|
+
!pageData.sources.map(({ source }) => source).includes('design-guidelines') &&
|
|
99
|
+
process.env.hasDesignGuidelines
|
|
100
|
+
) {
|
|
101
|
+
pageData.sources.push(getDefaultDesignGuidelines(pageData));
|
|
102
|
+
}
|
|
103
|
+
// Sort sources for tabs
|
|
104
|
+
pageData.sources = pageData.sources.sort(sortSources);
|
|
105
|
+
// Add grouped route
|
|
106
|
+
routes[slug] = pageData;
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
function getAsyncComponent(url) {
|
|
111
|
+
if (!url && typeof window !== 'undefined') {
|
|
112
|
+
url = window.location.pathname.replace(/\/$/, '') || '/';
|
|
113
|
+
}
|
|
114
|
+
// Normalize path for matching
|
|
115
|
+
url = url.replace(process.env.pathPrefix, '');
|
|
116
|
+
let res;
|
|
117
|
+
|
|
118
|
+
if (allRoutes[url]) {
|
|
119
|
+
res = allRoutes[url].Component;
|
|
120
|
+
}
|
|
121
|
+
else if (routes[url]) {
|
|
122
|
+
res = routes[url].sources[0].Component;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (res && res.preload) {
|
|
126
|
+
return res;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const fullscreenRoutes = Object.entries(allRoutes)
|
|
133
|
+
.filter(([, { examples, fullscreenExamples }]) => examples || fullscreenExamples)
|
|
134
|
+
.reduce((acc, val) => {
|
|
135
|
+
const [path, { Component, examples = [], fullscreenExamples = [] }] = val;
|
|
136
|
+
examples
|
|
137
|
+
.concat(fullscreenExamples)
|
|
138
|
+
.forEach(title => {
|
|
139
|
+
const slug = `${path}/${slugger(title)}`;
|
|
140
|
+
acc[slug] = {
|
|
141
|
+
title,
|
|
142
|
+
Component,
|
|
143
|
+
isFullscreen: true,
|
|
144
|
+
isFullscreenOnly: fullscreenExamples.includes(title)
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
return acc;
|
|
148
|
+
}, {});
|
|
149
|
+
|
|
150
|
+
module.exports = {
|
|
151
|
+
routes,
|
|
152
|
+
groupedRoutes,
|
|
153
|
+
fullscreenRoutes,
|
|
154
|
+
getAsyncComponent
|
|
155
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { fork } = require('child_process');
|
|
3
|
+
const webpack = require('webpack');
|
|
4
|
+
const { generate } = require('./generate');
|
|
5
|
+
const { getConfig } = require('./helpers');
|
|
6
|
+
|
|
7
|
+
async function buildWebpack(webpackConfig) {
|
|
8
|
+
let compiler;
|
|
9
|
+
try {
|
|
10
|
+
compiler = webpack(webpackConfig);
|
|
11
|
+
} catch (err) {
|
|
12
|
+
if (err.name === "WebpackOptionsValidationError") {
|
|
13
|
+
console.error(err.message);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return new Promise((res, rej) =>
|
|
21
|
+
compiler.run((err, stats) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
console.error(err.stack || err);
|
|
24
|
+
if (err.details) {
|
|
25
|
+
console.error(err.details);
|
|
26
|
+
}
|
|
27
|
+
rej();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const info = stats.toJson();
|
|
31
|
+
|
|
32
|
+
if (stats.hasErrors()) {
|
|
33
|
+
console.error(info.errors);
|
|
34
|
+
rej();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (stats.hasWarnings()) {
|
|
38
|
+
console.warn(info.warnings.join('\n'));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
res();
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function execFile(file, args) {
|
|
47
|
+
const start = new Date();
|
|
48
|
+
return new Promise((res, rej) => {
|
|
49
|
+
const child = fork(path.join(__dirname, file), args);
|
|
50
|
+
function errorHandler(err) {
|
|
51
|
+
console.error(err);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
};
|
|
54
|
+
function successHandler(code) {
|
|
55
|
+
if (code === 0) {
|
|
56
|
+
const duration = new Date() - start;
|
|
57
|
+
console.log('%s took %ss', file, duration / 1000);
|
|
58
|
+
res();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
process.exit(code);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
child.on('error', errorHandler);
|
|
65
|
+
child.on('exit', successHandler);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function build(cmd, options) {
|
|
70
|
+
generate(options);
|
|
71
|
+
const toBuild = cmd === 'all'
|
|
72
|
+
? ['server', 'client']
|
|
73
|
+
: cmd;
|
|
74
|
+
const config = getConfig(options);
|
|
75
|
+
config.analyze = options.analyze;
|
|
76
|
+
config.output = options.output;
|
|
77
|
+
|
|
78
|
+
// These get passed to `fork`ed builds
|
|
79
|
+
process.env.pathPrefix = config.pathPrefix;
|
|
80
|
+
process.env.hasDesignGuidelines = config.hasDesignGuidelines;
|
|
81
|
+
// console.log('build', cmd, options.parent.cssconfig);
|
|
82
|
+
if (toBuild.includes('server')) {
|
|
83
|
+
// Need to fork since first webpack build puts pressure on GC
|
|
84
|
+
// Otherwise CircleCI will fail with 4GB RAM
|
|
85
|
+
await execFile('buildServer.js', [JSON.stringify(config)]);
|
|
86
|
+
}
|
|
87
|
+
if (toBuild.includes('client')) {
|
|
88
|
+
await execFile('buildClient.js', [JSON.stringify(config)]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = {
|
|
93
|
+
build,
|
|
94
|
+
buildWebpack
|
|
95
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { buildWebpack } = require('./build');
|
|
2
|
+
const clientConfig = require('../webpack/webpack.client.config');
|
|
3
|
+
|
|
4
|
+
const options = JSON.parse(process.argv[2]);
|
|
5
|
+
|
|
6
|
+
async function buildClient() {
|
|
7
|
+
console.log('load client webpack config');
|
|
8
|
+
|
|
9
|
+
const webpackArgv = {
|
|
10
|
+
mode: 'production',
|
|
11
|
+
...options
|
|
12
|
+
};
|
|
13
|
+
const webpackClientConfig = await clientConfig(options.analyze && 'analyze', webpackArgv);
|
|
14
|
+
console.log('build client');
|
|
15
|
+
await buildWebpack(webpackClientConfig);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
buildClient()
|
|
19
|
+
.catch(err => {
|
|
20
|
+
console.error(err);
|
|
21
|
+
process.exit(3);
|
|
22
|
+
})
|
|
23
|
+
.then(() => process.exit(0));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const { buildWebpack } = require('./build');
|
|
2
|
+
const serverConfig = require('../webpack/webpack.server.config');
|
|
3
|
+
|
|
4
|
+
const options = JSON.parse(process.argv[2]);
|
|
5
|
+
|
|
6
|
+
async function buildServer() {
|
|
7
|
+
console.log('load server webpack config');
|
|
8
|
+
|
|
9
|
+
const webpackArgv = {
|
|
10
|
+
mode: 'production',
|
|
11
|
+
...options
|
|
12
|
+
};
|
|
13
|
+
const webpackServerConfig = await serverConfig(null, webpackArgv);
|
|
14
|
+
console.log('build server');
|
|
15
|
+
await buildWebpack(webpackServerConfig);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
buildServer()
|
|
19
|
+
.catch(err => {
|
|
20
|
+
console.error(err);
|
|
21
|
+
process.exit(2);
|
|
22
|
+
})
|
|
23
|
+
.then(() => process.exit(0));
|
|
24
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const program = require('commander');
|
|
3
|
+
|
|
4
|
+
program
|
|
5
|
+
.option('-c, --config <path>', 'set config path', 'patternfly-docs/patternfly-docs.config.js')
|
|
6
|
+
.option('-css, --cssconfig <path>', 'set css import file path', 'patternfly-docs/patternfly-docs.css.js')
|
|
7
|
+
.option('-s, --source <path>', 'set source generation file path', 'patternfly-docs/patternfly-docs.source.js');
|
|
8
|
+
|
|
9
|
+
program
|
|
10
|
+
.command('generate')
|
|
11
|
+
.description('generates source files')
|
|
12
|
+
.action(options => {
|
|
13
|
+
const { generate } = require('./generate');
|
|
14
|
+
generate(options);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.command('start')
|
|
19
|
+
.description('generates source files and runs webpack-dev-server')
|
|
20
|
+
.action(options => {
|
|
21
|
+
const { start } = require('./start');
|
|
22
|
+
start(options);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.command('build <server|client|all>')
|
|
27
|
+
.option('-a, --analyze', 'use webpack-bundle-analyzer', false)
|
|
28
|
+
.option('-o, --output <folder>', 'output folder', 'public')
|
|
29
|
+
.description('generates source files and runs webpack')
|
|
30
|
+
.action((cmd, options) => {
|
|
31
|
+
const { build } = require('./build');
|
|
32
|
+
build(cmd, options);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
program
|
|
36
|
+
.command('serve <folder>')
|
|
37
|
+
.option('-p, --port <port>', 'port to serve on', 5000)
|
|
38
|
+
.description('serves a directory on a port')
|
|
39
|
+
.action((cmd, options) => {
|
|
40
|
+
const { serve } = require('./serve');
|
|
41
|
+
serve(cmd, options);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command('screenshots')
|
|
46
|
+
.option('-u, --urlPrefix <prefix>', 'where fullscreen pages are hosted', 'http://localhost:5000/v4')
|
|
47
|
+
.description('updates screenshots for generated components')
|
|
48
|
+
.action(options => {
|
|
49
|
+
const { writeScreenshots } = require('../writeScreenshots');
|
|
50
|
+
writeScreenshots(options);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
program
|
|
54
|
+
.command('init')
|
|
55
|
+
.option('-n, --name <extension>', 'name of the extension', 'extension')
|
|
56
|
+
.option('-s, --scripts', 'Adds script targets to package.json', false)
|
|
57
|
+
.description('Initialize patternfly-docs')
|
|
58
|
+
.action(options => {
|
|
59
|
+
const { init } = require('./init');
|
|
60
|
+
init(options);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { sourceMD, sourceProps, writeIndex } = require('../md/parseMD');
|
|
3
|
+
|
|
4
|
+
function getSource(options) {
|
|
5
|
+
return require(path.join(process.cwd(), options.parent.source));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function generate(options) {
|
|
9
|
+
const start = new Date();
|
|
10
|
+
console.log('write source files to patternfly-docs/generated');
|
|
11
|
+
const sourceMDWithOptions = (glob, source, ignore) => sourceMD(glob, source, ignore, options._name);
|
|
12
|
+
getSource(options)(sourceMDWithOptions, sourceProps);
|
|
13
|
+
const exitCode = writeIndex();
|
|
14
|
+
if (exitCode !== 0) {
|
|
15
|
+
process.exit(exitCode);
|
|
16
|
+
}
|
|
17
|
+
const duration = new Date() - start;
|
|
18
|
+
console.log('generating took %ss', duration / 1000);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
generate
|
|
23
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const fse = require("fs-extra");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
function init({ name, scripts }) {
|
|
6
|
+
const srcDir = path.join(__dirname, "../../templates/patternfly-docs");
|
|
7
|
+
const destDir = path.join(process.cwd(), "/patternfly-docs");
|
|
8
|
+
|
|
9
|
+
console.log(`Scaffolding patternfly-docs at ${destDir}`);
|
|
10
|
+
|
|
11
|
+
// To copy a folder or file
|
|
12
|
+
fse.copy(srcDir, destDir, function (err) {
|
|
13
|
+
if (err) {
|
|
14
|
+
console.error(err);
|
|
15
|
+
} else {
|
|
16
|
+
const nameLowerCaseHyphenated = name.toLowerCase().split(" ").join("-");
|
|
17
|
+
fs.renameSync(
|
|
18
|
+
path.join(destDir, "/content/extensions/extension"),
|
|
19
|
+
path.join(destDir, `/content/extensions/${nameLowerCaseHyphenated}`)
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
if (scripts) {
|
|
23
|
+
console.log(`Adding script targets to package.json`);
|
|
24
|
+
const packageJson = require(path.join(process.cwd(), "/package.json"));
|
|
25
|
+
if (!packageJson) {
|
|
26
|
+
console.error(`No package.json found at ${process.cwd()}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (!packageJson.scripts) {
|
|
30
|
+
packageJson.scripts = {};
|
|
31
|
+
}
|
|
32
|
+
packageJson.scripts = {
|
|
33
|
+
...packageJson.scripts,
|
|
34
|
+
"docs:develop": "pf-docs-framework start",
|
|
35
|
+
"docs:build": "pf-docs-framework build all --output public",
|
|
36
|
+
"docs:serve": "pf-docs-framework serve public --port 5000",
|
|
37
|
+
"docs:screenshots":
|
|
38
|
+
"pf-docs-framework screenshots --urlPrefix http://localhost:5000",
|
|
39
|
+
};
|
|
40
|
+
// console.log(packageJson);
|
|
41
|
+
const jsonString = JSON.stringify(packageJson, null, 2);
|
|
42
|
+
fs.writeFile("./package.json", jsonString, (err) => {
|
|
43
|
+
if (err) {
|
|
44
|
+
console.log("Error writing to package.json", err);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const filesToReplaceId = [
|
|
50
|
+
path.join(destDir, `/content/extensions/${nameLowerCaseHyphenated}/design-guidelines/design-guidelines.md`),
|
|
51
|
+
path.join(destDir, `/content/extensions/${nameLowerCaseHyphenated}/examples/basic.md`)
|
|
52
|
+
];
|
|
53
|
+
filesToReplaceId.forEach(path => {
|
|
54
|
+
fs.readFile(path, "utf-8", function (err, data) {
|
|
55
|
+
if (err) throw err;
|
|
56
|
+
var newValue = data.replace(/id: My extension/, `id: ${name}`);
|
|
57
|
+
fs.writeFile(path, newValue, "utf-8", function (err, data) {
|
|
58
|
+
if (err) throw err;
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
init,
|
|
68
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
|
|
3
|
+
function serve(serveDir, { port }) {
|
|
4
|
+
const app = express();
|
|
5
|
+
|
|
6
|
+
app.use(express.static(serveDir));
|
|
7
|
+
|
|
8
|
+
app.listen(port, () => console.log(`Serving ${serveDir} at http://localhost:${port}`));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
serve
|
|
13
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const WebpackDevServer = require('webpack-dev-server');
|
|
2
|
+
const webpack = require('webpack');
|
|
3
|
+
const clientConfig = require('../webpack/webpack.client.config');
|
|
4
|
+
const { generate } = require('./generate');
|
|
5
|
+
const { getConfig } = require('./helpers');
|
|
6
|
+
const { watchMD } = require('../md/parseMD');
|
|
7
|
+
|
|
8
|
+
function startWebpackDevServer(webpackConfig) {
|
|
9
|
+
webpackConfig.devServer.filename = webpackConfig.output.filename;
|
|
10
|
+
webpackConfig.devServer.publicPath = webpackConfig.output.publicPath;
|
|
11
|
+
const { port } = webpackConfig.devServer;
|
|
12
|
+
const compiler = webpack(webpackConfig);
|
|
13
|
+
const server = new WebpackDevServer(compiler, webpackConfig.devServer);
|
|
14
|
+
|
|
15
|
+
server.listen(port, 'localhost', err => {
|
|
16
|
+
if (err) {
|
|
17
|
+
console.log(err);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function start(options) {
|
|
23
|
+
generate(options, true);
|
|
24
|
+
const webpackClientConfig = await clientConfig(null, { mode: 'development', ...getConfig(options) });
|
|
25
|
+
console.log('start webpack-dev-server');
|
|
26
|
+
watchMD();
|
|
27
|
+
startWebpackDevServer(webpackClientConfig);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
start
|
|
32
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const visit = require('unist-util-visit');
|
|
2
|
+
const toText = require('hast-util-to-text')
|
|
3
|
+
const { slugger } = require('../../helpers/slugger');
|
|
4
|
+
const { liveCodeTypes } = require('../../helpers/liveCodeTypes');
|
|
5
|
+
|
|
6
|
+
// This transforms headers in markdown to AutoLinkHeader JSX components
|
|
7
|
+
function anchorHeader(tocCallback) {
|
|
8
|
+
return tree => {
|
|
9
|
+
const ids = {};
|
|
10
|
+
const toc = [];
|
|
11
|
+
const addTOCItem = (tocItem, level) => {
|
|
12
|
+
if (level === 'h2') {
|
|
13
|
+
toc.push(tocItem);
|
|
14
|
+
}
|
|
15
|
+
else if (level === 'h3') {
|
|
16
|
+
// Only need to support up to h3s, so this array structure works fine
|
|
17
|
+
const lastTOC = toc[toc.length - 1];
|
|
18
|
+
if (Array.isArray(lastTOC)) {
|
|
19
|
+
lastTOC.push(tocItem);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
toc.push([tocItem]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
visit(tree, 'element', node => {
|
|
27
|
+
if (node.tagName.match(/h\d/)) {
|
|
28
|
+
// Add a unique id for auto link headers
|
|
29
|
+
const text = toText(node);
|
|
30
|
+
node.properties.id = node.properties.id || slugger(text);
|
|
31
|
+
const idNum = ids[node.properties.id];
|
|
32
|
+
const tocItem = { text };
|
|
33
|
+
if (idNum !== undefined) {
|
|
34
|
+
ids[node.properties.id] += 1;
|
|
35
|
+
node.properties.id += `-${idNum}`;
|
|
36
|
+
// Only add id if its not === `slugger(text)` to save some bandwidth
|
|
37
|
+
tocItem.id = node.properties.id;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
ids[node.properties.id] = 0;
|
|
41
|
+
}
|
|
42
|
+
// Add to TOC for indexing
|
|
43
|
+
addTOCItem(tocItem, node.tagName);
|
|
44
|
+
|
|
45
|
+
node.properties.size = node.tagName;
|
|
46
|
+
node.properties.className = node.properties.className || '';
|
|
47
|
+
node.properties.className += node.properties.className ? ' ' : '';
|
|
48
|
+
node.properties.className += `ws-title ws-${node.tagName}`;
|
|
49
|
+
node.tagName = 'AutoLinkHeader';
|
|
50
|
+
}
|
|
51
|
+
else if (
|
|
52
|
+
node.tagName === 'Example'
|
|
53
|
+
&& liveCodeTypes.includes(node.properties.lang)
|
|
54
|
+
&& !node.properties.noLive
|
|
55
|
+
) {
|
|
56
|
+
addTOCItem(
|
|
57
|
+
{
|
|
58
|
+
text: node.title
|
|
59
|
+
},
|
|
60
|
+
'h3'
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
tocCallback(toc);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = anchorHeader;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// https://github.com/remarkjs/remark/tree/main/packages/remark-parse#processoruseparse-options
|
|
2
|
+
// https://github.com/remarkjs/remark/blob/main/packages/remark-parse/lib/tokenize/auto-link.js
|
|
3
|
+
const decode = require('parse-entities');
|
|
4
|
+
|
|
5
|
+
// Support `<https://google.com>`
|
|
6
|
+
// This is removed in MDX 2: https://github.com/mdx-js/mdx/issues/1049
|
|
7
|
+
function plugin({ beginMarker = '<http', endMarker = '>' } = {}) {
|
|
8
|
+
const Parser = this.Parser;
|
|
9
|
+
const tokenizers = Parser.prototype.inlineTokenizers;
|
|
10
|
+
const methods = Parser.prototype.inlineMethods;
|
|
11
|
+
|
|
12
|
+
tokenizers.autoLinkUrl = function autoLinkUrl(eat, value) {
|
|
13
|
+
if (!value.startsWith(beginMarker)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const endIndex = value.indexOf(endMarker);
|
|
17
|
+
if (endIndex >= 1) {
|
|
18
|
+
const link = value.substr(1, endIndex);
|
|
19
|
+
return eat(value.substr(0, endIndex))({
|
|
20
|
+
type: 'link',
|
|
21
|
+
title: null,
|
|
22
|
+
url: decode(link, { nonTerminated: false })
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
tokenizers.autoLinkUrl.locator = (value, fromIndex) => value.indexOf(beginMarker, fromIndex);
|
|
28
|
+
|
|
29
|
+
// Put before existing `autoLink` which will be deleted in remark-mdx
|
|
30
|
+
methods.splice(methods.indexOf('autoLink'), 0, 'autoLinkUrl')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = plugin;
|