feat(content-blog): add full blog post html into RSS/Atom feeds (#4330)

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
moonrailgun 2021-10-08 18:59:02 +08:00 committed by GitHub
parent 198590446a
commit 6ed698976d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 377 additions and 18 deletions

View file

@ -0,0 +1,133 @@
/**
* 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\\">&lt;Tabs&gt;
&lt;TabItem value=&quot;apple&quot; label=&quot;Apple&quot;&gt;
This is an apple 🍎
&lt;/TabItem&gt;
&lt;TabItem value=&quot;orange&quot; label=&quot;Orange&quot;&gt;
This is an orange 🍊
&lt;/TabItem&gt;
&lt;/Tabs&gt;
</code></pre><p>text</p>"
`);
});
});

View file

@ -0,0 +1,12 @@
/**
* 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.
*/
// Dependencies with missing typedefs
declare module '@mdx-js/runtime';
declare module 'remark-mdx-remove-imports';
declare module 'remark-mdx-remove-exports';

View file

@ -25,6 +25,7 @@ import {posixPath as posixPathImport} from './posixPath';
import {simpleHash, docuHash} from './hashUtils';
import {normalizeUrl} from './normalizeUrl';
export * from './mdxUtils';
export * from './normalizeUrl';
export * from './tags';

View file

@ -0,0 +1,32 @@
/**
* 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,
]),
);
}