mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-12 00:27:21 +02:00
fix(content-blog): generate feed by reading build output (#6454)
This commit is contained in:
parent
ebd5340205
commit
76a8d5f38a
28 changed files with 364 additions and 249 deletions
|
@ -1,133 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {mdxToHtml} from '../mdxUtils';
|
||||
|
||||
describe('mdxToHtml', () => {
|
||||
test('work with simple markdown', () => {
|
||||
const mdxString = `
|
||||
# title
|
||||
|
||||
title text **bold**
|
||||
|
||||
## subtitle
|
||||
|
||||
subtitle text *italic*
|
||||
|
||||
> Quote
|
||||
|
||||
`;
|
||||
|
||||
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
||||
`"<h1>title</h1><p>title text <strong>bold</strong></p><h2>subtitle</h2><p>subtitle text <em>italic</em></p><blockquote><p>Quote</p></blockquote>"`,
|
||||
);
|
||||
});
|
||||
|
||||
test('work with MDX imports', () => {
|
||||
const mdxString = `
|
||||
# title
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
text
|
||||
|
||||
`;
|
||||
|
||||
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
||||
`"<h1>title</h1><p>text</p>"`,
|
||||
);
|
||||
});
|
||||
|
||||
test('work with MDX exports', () => {
|
||||
const mdxString = `
|
||||
# title
|
||||
|
||||
export const someExport = 42
|
||||
|
||||
export const MyLocalComponent = () => "result"
|
||||
|
||||
export const toc = [
|
||||
{id: "title",label: "title"}
|
||||
]
|
||||
|
||||
text
|
||||
|
||||
|
||||
`;
|
||||
|
||||
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
||||
`"<h1>title</h1><p>text</p>"`,
|
||||
);
|
||||
});
|
||||
|
||||
test('work with MDX Tabs', () => {
|
||||
const mdxString = `
|
||||
# title
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="apple" label="Apple">
|
||||
This is an apple 🍎
|
||||
</TabItem>
|
||||
<TabItem value="orange" label="Orange">
|
||||
This is an orange 🍊
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
text
|
||||
|
||||
|
||||
`;
|
||||
|
||||
// TODO this is not an ideal behavior!
|
||||
// There is a warning "Component TabItem was not imported, exported, or provided by MDXProvider as global scope"
|
||||
// Theme + MDX config should provide a list of React components to put in MDX scope
|
||||
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
||||
`"<h1>title</h1><div><div value=\\"apple\\" label=\\"Apple\\">This is an apple 🍎</div><div value=\\"orange\\" label=\\"Orange\\">This is an orange 🍊</div></div><p>text</p>"`,
|
||||
);
|
||||
});
|
||||
|
||||
test('work with MDX Tabs with ```mdx-code-block', () => {
|
||||
const mdxString = `
|
||||
# title
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
\`\`\`mdx-code-block
|
||||
<Tabs>
|
||||
<TabItem value="apple" label="Apple">
|
||||
This is an apple 🍎
|
||||
</TabItem>
|
||||
<TabItem value="orange" label="Orange">
|
||||
This is an orange 🍊
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
\`\`\`
|
||||
|
||||
text
|
||||
|
||||
`;
|
||||
|
||||
// TODO bad behavior!
|
||||
// ```mdx-code-block should be unwrapped and inner MDX content should be evaluated
|
||||
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(`
|
||||
"<h1>title</h1><pre><code class=\\"language-mdx-code-block\\"><Tabs>
|
||||
<TabItem value="apple" label="Apple">
|
||||
This is an apple 🍎
|
||||
</TabItem>
|
||||
<TabItem value="orange" label="Orange">
|
||||
This is an orange 🍊
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</code></pre><p>text</p>"
|
||||
`);
|
||||
});
|
||||
});
|
|
@ -23,7 +23,6 @@ import {simpleHash, docuHash} from './hashUtils';
|
|||
import {DEFAULT_PLUGIN_ID} from './constants';
|
||||
|
||||
export * from './constants';
|
||||
export * from './mdxUtils';
|
||||
export * from './urlUtils';
|
||||
export * from './tags';
|
||||
export * from './markdownParser';
|
||||
|
@ -210,6 +209,39 @@ export function getPluginI18nPath({
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permalink The URL that the HTML file corresponds to, without base URL
|
||||
* @param outDir Full path to the output directory
|
||||
* @param trailingSlash The site config option. If provided, only one path will be read.
|
||||
* @returns This returns a buffer, which you have to decode string yourself if
|
||||
* needed. (Not always necessary since the output isn't for human consumption
|
||||
* anyways, and most HTML manipulation libs accept buffers)
|
||||
*/
|
||||
export async function readOutputHTMLFile(
|
||||
permalink: string,
|
||||
outDir: string,
|
||||
trailingSlash: boolean | undefined,
|
||||
): Promise<Buffer> {
|
||||
const withTrailingSlashPath = path.join(outDir, permalink, 'index.html');
|
||||
const withoutTrailingSlashPath = path.join(outDir, `${permalink}.html`);
|
||||
if (trailingSlash) {
|
||||
return fs.readFile(withTrailingSlashPath);
|
||||
} else if (trailingSlash === false) {
|
||||
return fs.readFile(withoutTrailingSlashPath);
|
||||
} else {
|
||||
const HTMLPath = await findAsyncSequential(
|
||||
[withTrailingSlashPath, withoutTrailingSlashPath],
|
||||
fs.pathExists,
|
||||
);
|
||||
if (!HTMLPath) {
|
||||
throw new Error(
|
||||
`Expected output HTML file to be found at ${withTrailingSlashPath}`,
|
||||
);
|
||||
}
|
||||
return fs.readFile(HTMLPath);
|
||||
}
|
||||
}
|
||||
|
||||
export async function mapAsyncSequential<T, R>(
|
||||
array: T[],
|
||||
action: (t: T) => Promise<R>,
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import MDX from '@mdx-js/runtime';
|
||||
import removeImports from 'remark-mdx-remove-imports';
|
||||
import removeExports from 'remark-mdx-remove-exports';
|
||||
|
||||
/**
|
||||
* Transform mdx text to plain html text
|
||||
* Initially created to convert MDX blog posts to HTML for the RSS feed
|
||||
* without import/export nodes
|
||||
*
|
||||
* TODO not ideal implementation, won't work well with MDX elements!
|
||||
* TODO theme+global site config should be able to declare MDX comps in scope for rendering the RSS feeds
|
||||
* see also https://github.com/facebook/docusaurus/issues/4625
|
||||
*/
|
||||
export function mdxToHtml(
|
||||
mdxStr: string,
|
||||
// TODO allow providing components/scope here, see https://github.com/mdx-js/mdx/tree/v1.6.13/packages/runtime
|
||||
): string {
|
||||
return ReactDOMServer.renderToString(
|
||||
React.createElement(MDX, {remarkPlugins: [removeImports, removeExports]}, [
|
||||
mdxStr,
|
||||
]),
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue