@@ -2,44 +2,11 @@ import React from 'react';
22import PropTypes from 'prop-types' ;
33import clsx from 'clsx' ;
44import { useSelector } from 'react-redux' ;
5- import marked from 'marked/lib/marked' ;
65import { withStyles } from '@material-ui/core/styles' ;
76import textToHash from 'docs/src/modules/utils/textToHash' ;
7+ import { render as renderMarkdown } from 'docs/src/modules/utils/parseMarkdown' ;
88import prism from 'docs/src/modules/components/prism' ;
99
10- // Monkey patch to preserve non-breaking spaces
11- // https://github.com/chjj/marked/blob/6b0416d10910702f73da9cb6bb3d4c8dcb7dead7/lib/marked.js#L142-L150
12- marked . Lexer . prototype . lex = function lex ( src ) {
13- src = src
14- . replace ( / \r \n | \r / g, '\n' )
15- . replace ( / \t / g, ' ' )
16- . replace ( / \u2424 / g, '\n' ) ;
17-
18- return this . token ( src , true ) ;
19- } ;
20-
21- const renderer = new marked . Renderer ( ) ;
22- renderer . heading = ( text , level ) => {
23- // Small title. No need for an anchor.
24- // It's reducing the risk of duplicated id and it's fewer elements in the DOM.
25- if ( level >= 4 ) {
26- return `<h${ level } >${ text } </h${ level } >` ;
27- }
28-
29- // eslint-disable-next-line no-underscore-dangle
30- const hash = textToHash ( text , global . __MARKED_UNIQUE__ ) ;
31-
32- return [
33- `<h${ level } >` ,
34- `<a class="anchor-link" id="${ hash } "></a>` ,
35- text ,
36- `<a class="anchor-link-style" aria-hidden="true" aria-label="anchor" href="#${ hash } ">` ,
37- '<svg><use xlink:href="#anchor-link-icon" /></svg>' ,
38- '</a>' ,
39- `</h${ level } >` ,
40- ] . join ( '' ) ;
41- } ;
42-
4310const externs = [
4411 'https://material.io/' ,
4512 'https://getbootstrap.com/' ,
@@ -50,70 +17,6 @@ const externs = [
5017 'https://ui-kit.co/' ,
5118] ;
5219
53- renderer . link = ( href , title , text ) => {
54- let more = '' ;
55-
56- if ( externs . some ( ( domain ) => href . indexOf ( domain ) !== - 1 ) ) {
57- more = ' target="_blank" rel="noopener nofollow"' ;
58- }
59-
60- // eslint-disable-next-line no-underscore-dangle
61- const userLanguage = global . __MARKED_USER_LANGUAGE__ ;
62- let finalHref = href ;
63-
64- if ( userLanguage !== 'en' && finalHref . indexOf ( '/' ) === 0 && finalHref !== '/size-snapshot' ) {
65- finalHref = `/${ userLanguage } ${ finalHref } ` ;
66- }
67-
68- return `<a href="${ finalHref } "${ more } >${ text } </a>` ;
69- } ;
70-
71- const markedOptions = {
72- gfm : true ,
73- tables : true ,
74- breaks : false ,
75- pedantic : false ,
76- sanitize : false ,
77- smartLists : true ,
78- smartypants : false ,
79- highlight ( code , language ) {
80- let prismLanguage ;
81- switch ( language ) {
82- case 'ts' :
83- prismLanguage = prism . languages . tsx ;
84- break ;
85-
86- case 'js' :
87- case 'sh' :
88- prismLanguage = prism . languages . jsx ;
89- break ;
90-
91- case 'diff' :
92- prismLanguage = { ...prism . languages . diff } ;
93- // original `/^[-<].*$/m` matches lines starting with `<` which matches
94- // <SomeComponent />
95- // we will only use `-` as the deleted marker
96- prismLanguage . deleted = / ^ [ - ] .* $ / m;
97- break ;
98-
99- default :
100- prismLanguage = prism . languages [ language ] ;
101- break ;
102- }
103-
104- if ( ! prismLanguage ) {
105- if ( language ) {
106- throw new Error ( `unsupported language: "${ language } ", "${ code } "` ) ;
107- } else {
108- prismLanguage = prism . languages . jsx ;
109- }
110- }
111-
112- return prism . highlight ( code , prismLanguage ) ;
113- } ,
114- renderer,
115- } ;
116-
11720const styles = ( theme ) => ( {
11821 root : {
11922 ...theme . typography . body1 ,
@@ -301,14 +204,90 @@ function MarkdownElement(props) {
301204
302205 const userLanguage = useSelector ( ( state ) => state . options . userLanguage ) ;
303206
304- // eslint-disable-next-line no-underscore-dangle
305- global . __MARKED_USER_LANGUAGE__ = userLanguage ;
207+ const renderedMarkdown = React . useMemo ( ( ) => {
208+ return renderMarkdown ( text , {
209+ highlight ( code , language ) {
210+ let prismLanguage ;
211+ switch ( language ) {
212+ case 'ts' :
213+ prismLanguage = prism . languages . tsx ;
214+ break ;
215+
216+ case 'js' :
217+ case 'sh' :
218+ prismLanguage = prism . languages . jsx ;
219+ break ;
220+
221+ case 'diff' :
222+ prismLanguage = { ...prism . languages . diff } ;
223+ // original `/^[-<].*$/m` matches lines starting with `<` which matches
224+ // <SomeComponent />
225+ // we will only use `-` as the deleted marker
226+ prismLanguage . deleted = / ^ [ - ] .* $ / m;
227+ break ;
228+
229+ default :
230+ prismLanguage = prism . languages [ language ] ;
231+ break ;
232+ }
233+
234+ if ( ! prismLanguage ) {
235+ if ( language ) {
236+ throw new Error ( `unsupported language: "${ language } ", "${ code } "` ) ;
237+ } else {
238+ prismLanguage = prism . languages . jsx ;
239+ }
240+ }
241+
242+ return prism . highlight ( code , prismLanguage ) ;
243+ } ,
244+ heading : ( headingText , level ) => {
245+ // Small title. No need for an anchor.
246+ // It's reducing the risk of duplicated id and it's fewer elements in the DOM.
247+ if ( level >= 4 ) {
248+ return `<h${ level } >${ headingText } </h${ level } >` ;
249+ }
250+
251+ // eslint-disable-next-line no-underscore-dangle
252+ const hash = textToHash ( headingText , global . __MARKED_UNIQUE__ ) ;
253+
254+ return [
255+ `<h${ level } >` ,
256+ `<a class="anchor-link" id="${ hash } "></a>` ,
257+ headingText ,
258+ `<a class="anchor-link-style" aria-hidden="true" aria-label="anchor" href="#${ hash } ">` ,
259+ '<svg><use xlink:href="#anchor-link-icon" /></svg>' ,
260+ '</a>' ,
261+ `</h${ level } >` ,
262+ ] . join ( '' ) ;
263+ } ,
264+ link : ( href , title , linkText ) => {
265+ let more = '' ;
266+
267+ if ( externs . some ( ( domain ) => href . indexOf ( domain ) !== - 1 ) ) {
268+ more = ' target="_blank" rel="noopener nofollow"' ;
269+ }
270+
271+ let finalHref = href ;
272+
273+ if (
274+ userLanguage !== 'en' &&
275+ finalHref . indexOf ( '/' ) === 0 &&
276+ finalHref !== '/size-snapshot'
277+ ) {
278+ finalHref = `/${ userLanguage } ${ finalHref } ` ;
279+ }
280+
281+ return `<a href="${ finalHref } "${ more } >${ linkText } </a>` ;
282+ } ,
283+ } ) ;
284+ } , [ text , userLanguage ] ) ;
306285
307286 /* eslint-disable react/no-danger */
308287 return (
309288 < div
310289 className = { clsx ( classes . root , 'markdown-body' , className ) }
311- dangerouslySetInnerHTML = { { __html : marked ( text , markedOptions ) } }
290+ dangerouslySetInnerHTML = { { __html : renderedMarkdown } }
312291 { ...other }
313292 />
314293 ) ;
0 commit comments