Skip to content

Commit f9e8caa

Browse files
committed
Documentation: Parsing markdown blocks (code blocks)
1 parent e03ce21 commit f9e8caa

File tree

11 files changed

+168
-54
lines changed

11 files changed

+168
-54
lines changed

docs-tool/bin/helpers/extend-webpack-config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ module.exports = function( webpackConfig, usersCwd ) {
2222

2323
// Adding the markdown loader and exclude if from the file loader
2424
webpackConfig.module.rules.forEach( rule => {
25-
if ( rule.loader === require.resolve('file-loader') ) {
25+
if ( rule.loader === require.resolve( 'file-loader' ) ) {
2626
rule.exclude.push( /\.md/ );
2727
}
2828
} );
2929
webpackConfig.module.rules.push( {
3030
test: /\.md/,
3131
use: require.resolve( 'raw-loader' ),
3232
} );
33-
}
33+
};

docs-tool/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
"private": true,
55
"dependencies": {
66
"lodash": "^4.17.4",
7+
"markdown-it": "^8.3.1",
78
"prismjs": "^1.6.0",
89
"react": "^15.6.1",
910
"react-dom": "^15.6.1",
10-
"react-markdown": "^2.5.0",
1111
"react-router-dom": "^4.1.1",
1212
"react-scripts": "1.0.10"
1313
},

docs-tool/src/Page.js

-39
This file was deleted.
File renamed without changes.

docs-tool/src/components/Page.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import React, { Component } from 'react';
2+
import { Link } from 'react-router-dom';
3+
import Prism from 'prismjs';
4+
5+
import { getNextStory, getPreviousStory } from 'glutenberg';
6+
import markdown from '../markdown';
7+
8+
class Tabs extends Component {
9+
constructor() {
10+
super( ...arguments );
11+
this.state = {
12+
activeTab: 0,
13+
};
14+
}
15+
16+
selectTab( index ) {
17+
return () => {
18+
this.setState( { activeTab: index } );
19+
};
20+
}
21+
22+
componentDidUpdate() {
23+
Prism.highlightAll();
24+
}
25+
26+
render() {
27+
const { tabs } = this.props;
28+
const activeTab = tabs[ this.state.activeTab ];
29+
30+
return (
31+
<div>
32+
<div>
33+
{ tabs.map( ( tab, index ) => (
34+
<button
35+
key={ index }
36+
onClick={ this.selectTab( index ) }
37+
className={ index === this.state.activeTab ? 'is-active' : '' }
38+
>
39+
{ tab.name }
40+
</button>
41+
) ) }
42+
{ activeTab && <div dangerouslySetInnerHTML={ { __html: activeTab.content } } /> }
43+
</div>
44+
</div>
45+
);
46+
}
47+
}
48+
49+
function MarkdownContent( { content } ) {
50+
const blocks = markdown( content );
51+
52+
return (
53+
<div>
54+
{ blocks.map( ( block, index ) => {
55+
if ( block.type === 'raw' ) {
56+
return <div key={ index } dangerouslySetInnerHTML={ { __html: block.content } } />;
57+
}
58+
if ( block.type === 'codetabs' ) {
59+
return <Tabs key={ index } tabs={ block.tabs } />;
60+
}
61+
62+
return null;
63+
} ) }
64+
</div>
65+
);
66+
}
67+
68+
class Page extends Component {
69+
componentDidMount() {
70+
Prism.highlightAll();
71+
}
72+
73+
render() {
74+
const { story } = this.props;
75+
const nextStory = getNextStory( story.id );
76+
const previousStory = getPreviousStory( story.id );
77+
78+
return (
79+
<div>
80+
{ !! story.Component && <story.Component /> }
81+
{ !! story.markdown && <MarkdownContent content={ story.markdown } /> }
82+
83+
<div className="navigation">
84+
{ !! previousStory && (
85+
<p className="nav-older">
86+
<Link to={ previousStory.path }>{ '←' } { previousStory.title }</Link>
87+
</p>
88+
) }
89+
{ !! nextStory && (
90+
<p className="nav-newer">
91+
<Link to={ nextStory.path }>{ nextStory.title } { '→' }</Link>
92+
</p>
93+
) }
94+
</div>
95+
</div>
96+
);
97+
}
98+
}
99+
100+
export default Page;
File renamed without changes.

docs-tool/src/config/index.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
import React from 'react';
21
import { find } from 'lodash';
3-
import ReactMarkdown from 'react-markdown';
42

53
const stories = [];
64

75
export function addStory( story ) {
8-
const { name, parents = [], markdown } = story;
6+
const { name, parents = [] } = story;
97
stories.push( {
108
path: '/' + parents.concat( name ).join( '/' ),
119
id: parents.concat( name ).join( '.' ),
1210
parent: parents.join( '.' ),
13-
Component: markdown ? () => <ReactMarkdown source={ markdown } /> : story.Component,
1411
...story,
1512
} );
1613
}

docs-tool/src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'prismjs/themes/prism.css';
55

66
import 'config';
77

8-
import App from './App';
8+
import App from './components/App';
99
import registerServiceWorker from './registerServiceWorker';
1010
import './styles/main.css';
1111

docs-tool/src/markdown/index.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import MarkdownIt from 'markdown-it';
2+
import { compact } from 'lodash';
3+
4+
const parser = new MarkdownIt();
5+
6+
const blockParsers = {
7+
raw( content ) {
8+
return {
9+
type: 'raw',
10+
content: parser.render( content ),
11+
};
12+
},
13+
14+
codetabs( content ) {
15+
const tabsRegex = /{%\s+([\w]+)\s+%}/gm;
16+
const splittedTabs = compact( content.trim().split( tabsRegex ) );
17+
const tabs = [];
18+
for ( let i = 0; i < splittedTabs.length; i = i + 2 ) {
19+
tabs.push( {
20+
name: splittedTabs[ i ],
21+
content: parser.render( splittedTabs[ i + 1 ] ),
22+
} );
23+
}
24+
25+
return {
26+
type: 'codetabs',
27+
tabs,
28+
};
29+
},
30+
};
31+
32+
function parse( markdown ) {
33+
const blocksRegex = /({%\s+[\w]+\s+%}(?:.|\n|\r)*?{%\s+end\s+%})/gm;
34+
const blockRegex = /{%\s+([\w]+)\s+%}((?:.|\n|\r)*?){%\s+end\s+%}/gm;
35+
const blocks = markdown.split( blocksRegex );
36+
return blocks
37+
.map( ( block ) => {
38+
const matches = blockRegex.exec( block );
39+
if ( ! matches ) {
40+
return { type: 'raw', content: block };
41+
}
42+
return { type: matches[ 1 ], content: matches[ 2 ] };
43+
} )
44+
.map( ( block ) => {
45+
const blockParser = blockParsers[ block.type ] || blockParsers.raw;
46+
47+
return blockParser( block.content );
48+
} );
49+
}
50+
51+
export default parse;

docs/blocks-basic.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Writing your first block
22

3+
{% codetabs %}
4+
{% ES5 %}
35
```js
4-
// block.js (ES5)
6+
// block.js
57
var el = wp.element.createElement;
68
var blockStyle = { backgroundColor: '#900', color: '#fff', padding: '20px' };
79

@@ -17,9 +19,9 @@ wp.blocks.registerBlockType( 'mytheme/block', {
1719
},
1820
} );
1921
```
20-
22+
{% ESnext %}
2123
```js
22-
// block.js (ESnext)
24+
// block.js
2325
const { registerBlockType } = wp.blocks;
2426
const blockStyle = { backgroundColor: '#900', color: '#fff', padding: '20px' };
2527

@@ -35,3 +37,4 @@ registerBlockType( 'mytheme/block', {
3537
},
3638
} );
3739
```
40+
{% end %}

docs/blocks-stylesheet.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Adding a stylesheet
22

3+
{% codetabs %}
4+
{% ES5 %}
35
```js
4-
// block.js (ES5)
6+
// block.js
57
var el = wp.element.createElement;
68

79
wp.blocks.registerBlockType( 'mytheme/block', {
@@ -16,9 +18,9 @@ wp.blocks.registerBlockType( 'mytheme/block', {
1618
},
1719
} );
1820
```
19-
21+
{% ESnext %}
2022
```js
21-
// block.js (ESnext)
23+
// block.js
2224
const { registerBlockType } = wp.blocks;
2325

2426
registerBlockType( 'mytheme/block', {
@@ -33,7 +35,7 @@ registerBlockType( 'mytheme/block', {
3335
},
3436
} );
3537
```
36-
38+
{% end %}
3739
```css
3840
/* style.css */
3941

0 commit comments

Comments
 (0)