├── .babelrc
├── .editorconfig
├── .gitignore
├── .npmignore
├── .prettierrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── docs
├── index.html
└── index.js
├── less
└── highlight.less
├── package.json
├── src
├── Markdown.js
├── index.js
└── renderer.js
├── webpack.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "stage-0",
4 | "react",
5 | "es2015"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | end_of_line = lf
8 | indent_style = space
9 | indent_size = 2
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 | Ï
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | .vscode/
40 | lib/
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test/
2 | src/
3 | dev/
4 | dist/
5 | .vscode/
6 | examples/
7 | assets
8 | karma*
9 | .idea/
10 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "tabWidth": 2,
4 | "singleQuote": true
5 | }
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.2.0
2 |
3 | - Update dependencies
4 | - Breaking marked@0.6.2
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Simon Guo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-markdown-reader
2 |
3 | ## Install
4 |
5 | ```
6 | npm install html-loader --save-dev
7 | npm install markdown-loader --save-dev
8 | npm install react-markdown-reader --save-dev
9 | ```
10 |
11 | ## Usage
12 |
13 | `webpack.config.js`
14 |
15 | **webpack >= 2**
16 |
17 | ```js
18 | const markdownRenderer = require('react-markdown-reader').renderer;
19 |
20 | {
21 | test: /\.md$/,
22 | use: [{
23 | loader: 'html-loader'
24 | }, {
25 | loader: 'markdown-loader',
26 | options: {
27 | renderer: markdownRenderer(/**languages[string]**/)
28 | }
29 | }]
30 | }
31 | ```
32 |
33 | 注意: markdownRenderer 参数 languages,是为了按需加载,解决加载所有的语言包文件过大的问题。默认值:
34 |
35 | ```js
36 | ['javascript', 'bash', 'xml', 'css', 'markdown', 'less'];
37 | ```
38 |
39 | Exmaple
40 |
41 | ```js
42 | import { Markdown } from 'react-markdown-reader';
43 | import 'react-markdown-reader/less/highlight.less';
44 |
45 | {require('./README.md')};
46 | ```
47 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= htmlWebpackPlugin.options.title %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import Markdown from '../src/Markdown';
5 | import '../less/highlight.less';
6 |
7 | const App = () => {
8 | return {require('../README.md')};
9 | };
10 |
11 | ReactDOM.render(, document.getElementById('app'));
12 |
--------------------------------------------------------------------------------
/less/highlight.less:
--------------------------------------------------------------------------------
1 | /* Tomorrow Comment */
2 | .hljs-comment,
3 | .hljs-quote {
4 | color: #8e908c;
5 | }
6 |
7 | /* Tomorrow Red */
8 | .hljs-variable,
9 | .hljs-template-variable,
10 | .hljs-tag,
11 | .hljs-name,
12 | .hljs-selector-id,
13 | .hljs-selector-class,
14 | .hljs-regexp,
15 | .hljs-deletion {
16 | color: #c82829;
17 | }
18 |
19 | /* Tomorrow Orange */
20 | .hljs-number,
21 | .hljs-built_in,
22 | .hljs-builtin-name,
23 | .hljs-literal,
24 | .hljs-type,
25 | .hljs-params,
26 | .hljs-meta,
27 | .hljs-link {
28 | color: #f5871f;
29 | }
30 |
31 | /* Tomorrow Yellow */
32 | .hljs-attribute {
33 | color: #eab700;
34 | }
35 |
36 | /* Tomorrow Green */
37 | .hljs-string,
38 | .hljs-symbol,
39 | .hljs-bullet,
40 | .hljs-addition {
41 | color: #718c00;
42 | }
43 |
44 | /* Tomorrow Blue */
45 | .hljs-title,
46 | .hljs-section {
47 | color: #4271ae;
48 | }
49 |
50 | /* Tomorrow Purple */
51 | .hljs-keyword,
52 | .hljs-selector-tag {
53 | color: #8959a8;
54 | }
55 |
56 | .hljs {
57 | display: block;
58 | overflow-x: auto;
59 | background: white;
60 | color: #4d4d4c;
61 | padding: 0.5em;
62 | }
63 |
64 | .hljs-emphasis {
65 | font-style: italic;
66 | }
67 |
68 | .hljs-strong {
69 | font-weight: bold;
70 | }
71 |
72 |
73 |
74 | .markdown table {
75 | width: 100%;
76 | th {
77 | background: #f1f1f1;
78 | }
79 | td, th {
80 | border: 1px solid #eee;
81 | padding: 10px;
82 | }
83 | }
84 |
85 | pre {
86 | border: none;
87 | border-radius: 0;
88 | }
89 |
90 | code {
91 | border-radius: inherit;
92 | }
93 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-markdown-reader",
3 | "version": "1.2.0",
4 | "description": "markdown reader",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "dev": "NODE_ENV=development webpack-dev-server --inline --progress --colors --port 3100 --host 0.0.0.0 ",
8 | "build": "rm -rf lib && babel src --out-dir lib ",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/simonguo/react-markdown-reader.git"
14 | },
15 | "files": [
16 | "CHANGELOG.md",
17 | "lib"
18 | ],
19 | "keywords": [
20 | "react",
21 | "webpack",
22 | "mackdown"
23 | ],
24 | "author": "simonguo.2009@gmail.com",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/simonguo/react-markdown-reader/issues"
28 | },
29 | "homepage": "https://github.com/simonguo/react-markdown-reader#readme",
30 | "dependencies": {
31 | "highlight.js": "^9.4.0",
32 | "marked": "^0.6.2"
33 | },
34 | "peerDependencies": {
35 | "react": "^0.14.9 || >=15.3.0"
36 | },
37 | "devDependencies": {
38 | "babel-cli": "^6.26.0",
39 | "babel-core": "^6.7.6",
40 | "babel-eslint": "^6.1.2",
41 | "babel-loader": "^6.2.4",
42 | "babel-preset-es2015": "^6.6.0",
43 | "babel-preset-react": "^6.3.13",
44 | "babel-preset-stage-0": "^6.5.0",
45 | "compression-webpack-plugin": "^1.0.1",
46 | "css-loader": "^0.23.1",
47 | "extract-text-webpack-plugin": "^2.1.0",
48 | "html-loader": "^0.5.5",
49 | "html-webpack-plugin": "^2.22.0",
50 | "less": "^2.7.1",
51 | "less-loader": "^2.2.3",
52 | "markdown-loader": "^5.0.0",
53 | "react": "^16.4.2",
54 | "react-dom": "^16.4.2",
55 | "react-hot-loader": "^3.0.0-beta.6",
56 | "style-loader": "^0.13.1",
57 | "webpack": "^2.2.1",
58 | "webpack-dev-server": "^2.3.0"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Markdown.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class Markdown extends React.Component {
4 | constructor() {
5 | super();
6 | this.createMarkup = this.createMarkup.bind(this);
7 | }
8 | createMarkup() {
9 | return { __html: this.props.children };
10 | }
11 | render() {
12 | return (
13 |
17 | );
18 | }
19 | }
20 |
21 | export default Markdown;
22 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export Markdown from './Markdown';
2 | export renderer from './renderer';
3 |
--------------------------------------------------------------------------------
/src/renderer.js:
--------------------------------------------------------------------------------
1 | const marked = require('marked');
2 | const hl = require('highlight.js/lib/highlight');
3 | const defalutLanguages = ['javascript', 'bash', 'xml', 'css', 'markdown', 'less'];
4 |
5 | export default (languages = defalutLanguages) => {
6 | languages.forEach(langName => {
7 | let langModule = require(`highlight.js/lib/languages/${langName}`);
8 | hl.registerLanguage(langName, langModule);
9 | });
10 |
11 | const renderer = new marked.Renderer();
12 | const codeRenderer = function(code, lang) {
13 | lang = lang === 'js' ? 'javascript' : lang;
14 | if (lang === 'html') {
15 | lang = 'xml';
16 | }
17 |
18 | const hlCode = lang ? hl.highlight(lang, code).value : hl.highlightAuto(code).value;
19 | return ``;
21 | };
22 |
23 | renderer.code = codeRenderer;
24 |
25 | return renderer;
26 | };
27 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 | const HtmlwebpackPlugin = require('html-webpack-plugin');
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin');
5 | const CompressionPlugin = require('compression-webpack-plugin');
6 | const markdownRenderer = require('./lib/renderer')['default'];
7 | const { NODE_ENV } = process.env;
8 |
9 | const extractLess = new ExtractTextPlugin({
10 | filename: '[name].[contenthash].css',
11 | disable: NODE_ENV === 'development'
12 | });
13 |
14 | const docsPath = NODE_ENV === 'development' ? './assets' : './';
15 |
16 | const plugins = [
17 | new webpack.HotModuleReplacementPlugin(),
18 | new webpack.NamedModulesPlugin(),
19 | new webpack.DefinePlugin({
20 | 'process.env': {
21 | NODE_ENV: JSON.stringify(NODE_ENV)
22 | }
23 | }),
24 | extractLess,
25 | new HtmlwebpackPlugin({
26 | title: 'react code view',
27 | filename: 'index.html',
28 | template: 'docs/index.html',
29 | inject: true,
30 | hash: true,
31 | path: docsPath
32 | })
33 | ];
34 |
35 | if (process.env.NODE_ENV === 'production') {
36 | plugins.push(new webpack.optimize.UglifyJsPlugin());
37 | plugins.push(new webpack.BannerPlugin({ banner: `Last update: ${new Date().toString()}` }));
38 | plugins.push(
39 | new CompressionPlugin({
40 | asset: '[path].gz[query]',
41 | algorithm: 'gzip',
42 | test: /\.(js|html)$/,
43 | threshold: 10240,
44 | minRatio: 0.8
45 | })
46 | );
47 | }
48 |
49 | const common = {
50 | entry: path.resolve(__dirname, 'src/'),
51 | devServer: {
52 | hot: true,
53 | disableHostCheck: true,
54 | contentBase: path.resolve(__dirname, ''),
55 | publicPath: '/'
56 | },
57 | output: {
58 | path: path.resolve(__dirname, 'assets'),
59 | filename: 'bundle.js',
60 | publicPath: './'
61 | },
62 | plugins,
63 | module: {
64 | rules: [
65 | {
66 | test: /\.jsx?$/,
67 | use: ['babel-loader'],
68 | exclude: /node_modules/
69 | },
70 | {
71 | test: /\.less$/,
72 | loader: extractLess.extract({
73 | use: [
74 | {
75 | loader: 'css-loader'
76 | },
77 | {
78 | loader: 'less-loader'
79 | }
80 | ],
81 | // use style-loader in development
82 | fallback: 'style-loader'
83 | })
84 | },
85 | {
86 | test: /\.md$/,
87 | use: [
88 | {
89 | loader: 'html-loader'
90 | },
91 | {
92 | loader: 'markdown-loader',
93 | options: {
94 | renderer: markdownRenderer()
95 | }
96 | }
97 | ]
98 | }
99 | ]
100 | }
101 | };
102 |
103 | module.exports = () => {
104 | if (NODE_ENV === 'development') {
105 | return Object.assign({}, common, {
106 | entry: [
107 | 'react-hot-loader/patch',
108 | 'webpack-dev-server/client?http://127.0.0.1:3100',
109 | 'webpack/hot/only-dev-server',
110 | path.resolve(__dirname, 'docs/index')
111 | ],
112 | devtool: 'source-map'
113 | });
114 | }
115 |
116 | return Object.assign({}, common, {
117 | entry: [path.resolve(__dirname, 'docs/index')]
118 | });
119 | };
120 |
--------------------------------------------------------------------------------