mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-05 13:17:23 +02:00
* Fix bug Code block tabs broke the referenced links - The reason is that the previous Codeblock implementation separates the tabs, the markdown before tabs, and the markdown after tabs into separate Remarkable component, thus they don't share information regarding the reference link - To solve this, change the Doc implementation so that one Doc have only one Remarkable component by transforming the codeblock into html string and add it as part of the markdown, letting the Remarkable take care of the html string - However, this approach made us need to ensure that there is no newline in the codetab, otherwise, the formatting inside the code will be broken. Thus, I replace every newline inside the code tag with a br tag Fix #1215 * Fix prettier
143 lines
3.9 KiB
JavaScript
143 lines
3.9 KiB
JavaScript
/**
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const React = require('react');
|
|
const {renderToStaticMarkup} = require('react-dom/server');
|
|
const MarkdownBlock = require('./MarkdownBlock.js');
|
|
const CodeTabsMarkdownBlock = require('./CodeTabsMarkdownBlock.js');
|
|
|
|
const translate = require('../server/translate.js').translate;
|
|
|
|
const editThisDoc = translate(
|
|
'Edit this Doc|recruitment message asking to edit the doc source',
|
|
);
|
|
const translateThisDoc = translate(
|
|
'Translate this Doc|recruitment message asking to translate the docs',
|
|
);
|
|
|
|
const splitTabsToTitleAndContent = content => {
|
|
const titles = content.match(/<!--(.*?)-->/gms);
|
|
const tabs = content.split(/<!--.*?-->/gms);
|
|
if (!titles || !tabs || !titles.length || !tabs.length) {
|
|
return [];
|
|
}
|
|
tabs.shift();
|
|
return titles.map((title, idx) => ({
|
|
title: title.substring(4, title.length - 3).trim(),
|
|
content: tabs[idx],
|
|
}));
|
|
};
|
|
|
|
const cleanTheCodeTag = content => {
|
|
const contents = content.split(/(<pre>)(.*?)(<\/pre>)/gms);
|
|
let inCodeBlock = false;
|
|
const cleanContents = contents.map(c => {
|
|
if (c === '<pre>') {
|
|
inCodeBlock = true;
|
|
return c;
|
|
}
|
|
if (c === '</pre>') {
|
|
inCodeBlock = false;
|
|
return c;
|
|
}
|
|
if (inCodeBlock) {
|
|
return c.replace(/\n/g, '<br />');
|
|
}
|
|
return c;
|
|
});
|
|
return cleanContents.join('');
|
|
};
|
|
|
|
// inner doc component for article itself
|
|
class Doc extends React.Component {
|
|
renderContent() {
|
|
const {content} = this.props;
|
|
let inCodeTabs = false;
|
|
const contents = content.split(
|
|
/(<!--DOCUSAURUS_CODE_TABS-->\n)(.*?)(\n<!--END_DOCUSAURUS_CODE_TABS-->)/gms,
|
|
);
|
|
|
|
const renderResult = contents.map(c => {
|
|
if (c === '<!--DOCUSAURUS_CODE_TABS-->\n') {
|
|
inCodeTabs = true;
|
|
return '';
|
|
}
|
|
if (c === '\n<!--END_DOCUSAURUS_CODE_TABS-->') {
|
|
inCodeTabs = false;
|
|
return '';
|
|
}
|
|
if (inCodeTabs) {
|
|
const codeTabsMarkdownBlock = renderToStaticMarkup(
|
|
<CodeTabsMarkdownBlock>
|
|
{splitTabsToTitleAndContent(c)}
|
|
</CodeTabsMarkdownBlock>,
|
|
);
|
|
return cleanTheCodeTag(codeTabsMarkdownBlock);
|
|
}
|
|
return c;
|
|
});
|
|
|
|
return renderResult.join('');
|
|
}
|
|
|
|
render() {
|
|
let docSource = this.props.source;
|
|
|
|
if (this.props.version && this.props.version !== 'next') {
|
|
// If versioning is enabled and the current version is not next, we need to trim out "version-*" from the source if we want a valid edit link.
|
|
docSource = docSource.match(new RegExp(/version-.*?\/(.*\.md)/, 'i'))[1];
|
|
}
|
|
|
|
const editUrl =
|
|
this.props.metadata.custom_edit_url ||
|
|
(this.props.config.editUrl && this.props.config.editUrl + docSource);
|
|
let editLink = editUrl && (
|
|
<a
|
|
className="edit-page-link button"
|
|
href={editUrl}
|
|
target="_blank"
|
|
rel="noreferrer noopener">
|
|
{editThisDoc}
|
|
</a>
|
|
);
|
|
|
|
// If internationalization is enabled, show Recruiting link instead of Edit Link.
|
|
if (
|
|
this.props.language &&
|
|
this.props.language !== 'en' &&
|
|
this.props.config.translationRecruitingLink
|
|
) {
|
|
editLink = (
|
|
<a
|
|
className="edit-page-link button"
|
|
href={`${this.props.config.translationRecruitingLink}/${
|
|
this.props.language
|
|
}`}
|
|
target="_blank"
|
|
rel="noreferrer noopener">
|
|
{translateThisDoc}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="post">
|
|
<header className="postHeader">
|
|
{editLink}
|
|
{!this.props.hideTitle && (
|
|
<h1 className="postHeaderTitle">{this.props.title}</h1>
|
|
)}
|
|
</header>
|
|
<article>
|
|
<MarkdownBlock>{this.renderContent()}</MarkdownBlock>
|
|
</article>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = Doc;
|