md2site v0.4.0 - support async markdown loading

This commit is contained in:
dntzhang 2017-03-14 11:00:28 +08:00
parent ebb4b90280
commit da0a4c4093
6 changed files with 422 additions and 365 deletions

View File

@ -1,6 +1,6 @@
{
"name": "md2site",
"version": "0.3.7",
"version": "0.4.0",
"description": "Transform Markdown to Website base on Omi Framework.",
"main": "bin/md2site",
"engines": {

View File

@ -1,164 +1,175 @@
var del = require('del'),
gulp = require('gulp'),
csso = require('gulp-csso'),
webpack = require('webpack-stream'),
runSequence = require('run-sequence'),
htmlreplace = require('gulp-html-replace'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
header = require('gulp-header'),
browserSync = require('browser-sync').create(),
config = require('./project.js'),
urlPrefix = require('gulp-html-url-prefix');
var assets = [],
cdn = config.cdn,
ENV = process.env.npm_lifecycle_event;
gulp.task('clean', function(callback) {
del.sync([ENV+'/**/**']);
callback();
});
var webpackConfig = require('./webpack.config.js');
var isDist = ENV ==='dist';
gulp.task('webpack', function() {
return gulp.src('src/js/index.js')
.pipe(webpack(webpackConfig, null, function(err, stats) {
/* Use stats to do more things if needed */
console.log(stats.toJson().assets);
assets = stats.toJson().assets;
//https://www.npmjs.com/package/gulp-html-replace
//require("fs").writeFileSync("stats.json",JSON.stringify(stats.toJson()));
})).pipe(gulp.dest(ENV+'/js/'));
});
gulp.task('copyCSS', function() {
if(isDist){
return gulp.src(['src/**/*.css','!src/component/**/*.css'])
.pipe(csso()).pipe(rev())
.pipe(gulp.dest(ENV))
.pipe(rev.manifest()) //- 生成一个rev-manifest.json
.pipe(gulp.dest('./rev'));
}else{
return gulp.src('src/**/*.css')
.pipe(gulp.dest(ENV))
}
});
gulp.task('rev', function() {
return gulp.src(['./rev/*.json', ENV+'/*.html']) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
.pipe(revCollector()) //- 执行文件内css名的替换
.pipe(gulp.dest(ENV)); //- 替换后的文件输出的目录
});
gulp.task('copyHTML', function() {
return gulp.src('src/*.html').pipe(gulp.dest(ENV));
});
gulp.task('copyAsset', function() {
return gulp.src('src/asset/*.**').pipe(gulp.dest(ENV+'/asset'));
});
gulp.task('copyCommon', function() {
return gulp.src(['src/common/**']).pipe(gulp.dest(ENV+'/common'));
});
gulp.task('copyComponent', function() {
return gulp.src(['src/component/**','!src/component/**/*.js','!src/component/**/*.html','!src/component/**/*.css']).pipe(gulp.dest(ENV+'/component'));
});
gulp.task('fixEvn', function() {
return gulp.src(['src/component/**','!src/component/**/*.js']).pipe(gulp.dest(ENV+'/component'));
});
//https://segmentfault.com/q/1010000005760064/a-1020000005760268
gulp.task('replace', function() {
var vdName = assets[assets.length-1].name;
var omiName = '';
assets.forEach(function(item){
if(item.chunkNames[0]==='omi'){
omiName = item.name;
}
});
assets.forEach(function(item){
console.log(ENV+'/'+item.chunkNames[0]+ '.html')
gulp.src(ENV+'/'+item.chunkNames[0]+ '.html')
.pipe(htmlreplace({
'omijs':(isDist?(cdn+ 'js/'+ omiName):''),
'vjs': (isDist?(cdn+ 'js/'+ vdName):('js/'+ vdName)),
'js': (isDist?(cdn+ 'js/'+ item.name):('js/'+ item.name))
}))
.pipe(gulp.dest(ENV));
if(item.chunkNames[0]!=='omi'&&item.chunkNames[0]!=='vendor') {
gulp.src(ENV + '/js/' + item.name)
.pipe(header('window.Root ={}; Root.isDev = ' + (isDist ? 'false' : 'true') + ';'))
.pipe(gulp.dest(ENV + '/js'))
}
});
});
gulp.task('cdnReplace', function() {
return gulp.src('./dist/*.html')
.pipe(urlPrefix({
prefix: cdn
}))
.pipe(gulp.dest('./dist'));
});
gulp.task('browser-sync',function(){
browserSync.init({
server:{
baseDir:'./'+ENV+'/'
}
});
if(!isDist) {
gulp.watch(ENV + '/**').on('change', browserSync.reload);
gulp.watch(['src/docs/**/*.**','src/component/**/*.**','src/component/*.**', 'src/js/*.js', 'common/*.js'], function () {
runSequence(
'webpack',
'replace');
});
gulp.watch(['src/css/**'], function () {
runSequence(
'copyCSS');
});
}
});
if(isDist){
gulp.task('default', function(done) {
runSequence(
'clean',
'webpack',
'copyCSS',
'copyAsset',
'copyHTML',
'copyCommon',
'copyComponent',
'rev',
'cdnReplace',
'replace',
'browser-sync',
done);
});
}else{
gulp.task('default', function(done) {
runSequence(
'clean',
'webpack',
'copyCSS',
'copyAsset',
'copyHTML',
'copyCommon',
'copyComponent',
'replace',
'browser-sync',
done);
});
}
var del = require('del'),
gulp = require('gulp'),
csso = require('gulp-csso'),
webpack = require('webpack-stream'),
runSequence = require('run-sequence'),
htmlreplace = require('gulp-html-replace'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
header = require('gulp-header'),
browserSync = require('browser-sync').create(),
config = require('./project.js'),
urlPrefix = require('gulp-html-url-prefix');
var assets = [],
cdn = config.cdn,
ENV = process.env.npm_lifecycle_event;
gulp.task('clean', function(callback) {
del.sync([ENV+'/**/**']);
callback();
});
var webpackConfig = require('./webpack.config.js');
var isDist = ENV ==='dist';
gulp.task('webpack', function() {
return gulp.src('src/js/index.js')
.pipe(webpack(webpackConfig, null, function(err, stats) {
/* Use stats to do more things if needed */
console.log(stats.toJson().assets);
assets = stats.toJson().assets;
//https://www.npmjs.com/package/gulp-html-replace
//require("fs").writeFileSync("stats.json",JSON.stringify(stats.toJson()));
})).pipe(gulp.dest(ENV+'/js/'));
});
gulp.task('copyCSS', function() {
if(isDist){
return gulp.src(['src/**/*.css','!src/component/**/*.css'])
.pipe(csso()).pipe(rev())
.pipe(gulp.dest(ENV))
.pipe(rev.manifest()) //- 生成一个rev-manifest.json
.pipe(gulp.dest('./rev'));
}else{
return gulp.src('src/**/*.css')
.pipe(gulp.dest(ENV))
}
});
gulp.task('rev', function() {
return gulp.src(['./rev/*.json', ENV+'/*.html']) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
.pipe(revCollector()) //- 执行文件内css名的替换
.pipe(gulp.dest(ENV)); //- 替换后的文件输出的目录
});
gulp.task('copyHTML', function() {
return gulp.src('src/*.html').pipe(gulp.dest(ENV));
});
gulp.task('copyAsset', function() {
return gulp.src('src/asset/*.**').pipe(gulp.dest(ENV+'/asset'));
});
gulp.task('copyCommon', function() {
return gulp.src(['src/common/**']).pipe(gulp.dest(ENV+'/common'));
});
gulp.task('copyDocs', function(callback) {
if(config.async) {
return gulp.src(['src/docs/**']).pipe(gulp.dest(ENV + '/docs'));
}else{
callback();
}
});
gulp.task('copyComponent', function() {
return gulp.src(['src/component/**','!src/component/**/*.js','!src/component/**/*.html','!src/component/**/*.css']).pipe(gulp.dest(ENV+'/component'));
});
gulp.task('fixEvn', function() {
return gulp.src(['src/component/**','!src/component/**/*.js']).pipe(gulp.dest(ENV+'/component'));
});
//https://segmentfault.com/q/1010000005760064/a-1020000005760268
gulp.task('replace', function() {
var vdName = assets[assets.length-1].name;
var omiName = '';
assets.forEach(function(item){
if(item.chunkNames[0]==='omi'){
omiName = item.name;
}
});
assets.forEach(function(item){
console.log(ENV+'/'+item.chunkNames[0]+ '.html')
gulp.src(ENV+'/'+item.chunkNames[0]+ '.html')
.pipe(htmlreplace({
'omijs':(isDist?(cdn+ 'js/'+ omiName):''),
'vjs': (isDist?(cdn+ 'js/'+ vdName):('js/'+ vdName)),
'js': (isDist?(cdn+ 'js/'+ item.name):('js/'+ item.name))
}))
.pipe(gulp.dest(ENV));
if(item.chunkNames[0]!=='omi'&&item.chunkNames[0]!=='vendor') {
gulp.src(ENV + '/js/' + item.name)
.pipe(header('window.Root ={}; Root.isDev = ' + (isDist ? 'false' : 'true') + ';'))
.pipe(gulp.dest(ENV + '/js'))
}
});
});
gulp.task('cdnReplace', function() {
return gulp.src('./dist/*.html')
.pipe(urlPrefix({
prefix: cdn
}))
.pipe(gulp.dest('./dist'));
});
gulp.task('browser-sync',function(){
browserSync.init({
server:{
baseDir:'./'+ENV+'/'
}
});
if(!isDist) {
gulp.watch(ENV + '/**').on('change', browserSync.reload);
gulp.watch(['src/docs/**/*.**','src/component/**/*.**','src/component/*.**', 'src/js/*.js', 'common/*.js'], function () {
runSequence(
'webpack',
'replace');
});
gulp.watch(['src/css/**'], function () {
runSequence(
'copyCSS');
});
}
});
if(isDist){
gulp.task('default', function(done) {
runSequence(
'clean',
'webpack',
'copyCSS',
'copyAsset',
'copyHTML',
'copyCommon',
'copyComponent',
'copyDocs',
'rev',
'cdnReplace',
'replace',
'browser-sync',
done);
});
}else{
gulp.task('default', function(done) {
runSequence(
'clean',
'webpack',
'copyCSS',
'copyAsset',
'copyHTML',
'copyCommon',
'copyComponent',
'copyDocs',
'replace',
'browser-sync',
done);
});
}

View File

@ -1,7 +1,9 @@
module.exports = {
/*
your cdn address , such as:
cdn : '//s.url.cn/'
*/
cdn : ''
module.exports = {
/*
your cdn address , such as:
cdn : '//s.url.cn/'
*/
cdn : '',
//whether or not to load markdown async
async: true
}

View File

@ -1,85 +1,115 @@
import Omi from 'omi';
import config from '../../docs/config.js';
import highlightLines from './highlight-lines.js';
const tpl = require('./index.html');
const css = require('./index.css');
class Content extends Omi.Component {
constructor(data) {
data = Object.assign({
lan:'cn',
name: 'installation'
},data);
super(data);
this.md = new Remarkable({html:true});
}
getMarkDown(name,lan) {
return require("md-text!../../docs/" + lan + "/" + name + ".md");
}
installed(){
this.initCodeStyle();
}
afterUpdate(){
this.initCodeStyle();
}
initCodeStyle() {
let codes = Omi.$$("code");
let codeHlNumArr = [];
codes.forEach(code => {
hljs.highlightBlock(code);
let arr = code.className.match(/{\S*}/);
let hllNums = null;
if (arr) {
let numArr = arr[0].replace(/[{|}]/g, '').split(',');
hllNums = this._arrToNumber(numArr);
}
codeHlNumArr.push(hllNums);
})
highlightLines();
codes.forEach((code, index) => {
this._hll(code, codeHlNumArr[index])
})
}
_arrToNumber (numArr){
let arr = [];
numArr.forEach(item=>{
if(item.indexOf('-')!==-1){
const tempArr = item.split('-');
const begin = Number(tempArr[0]);
const end = Number(tempArr[1]);
for(let i=begin;i<end+1;i++){
arr.push(i);
}
}else{
arr.push(Number(item));
}
})
return arr;
}
_hll(code, hllNums){
let spans = Omi.$$('.line',code);
hllNums&&hllNums.forEach(num =>{
spans[num]&&spans[num].classList.add('highlight');
})
}
render () {
this.data.html = this.md.render(this.getMarkDown(this.data.name, this.data.lan));
return tpl;
}
style () {
return css;
}
}
import Omi from 'omi';
import config from '../../docs/config.js';
import highlightLines from './highlight-lines.js';
import proj_config from '../../../project.js';
const tpl = require('./index.html');
const css = require('./index.css');
class Content extends Omi.Component {
constructor(data) {
data = Object.assign({
lan:'cn',
name: 'installation'
},data);
super(data);
this.md = new Remarkable({html:true});
}
asyncUpdate() {
this.loadMarkdown("../../docs/" + this.data.lan + "/" + this.data.name + ".md",(md)=>{
this.data.html = this.md.render(md);
this.update();
})
}
installed(){
this.initCodeStyle();
}
install(){
if(proj_config.async) {
this.asyncUpdate();
}
}
afterUpdate(){
this.initCodeStyle();
}
getMarkDown(name,lan){
return require("../../docs/" + lan + "/" + name + ".md");
}
loadMarkdown(url,callback) {
var xobj = new XMLHttpRequest();
//xobj.overrideMimeType("application/json");
xobj.open('GET', url, true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
initCodeStyle() {
let codes = Omi.$$("code");
let codeHlNumArr = [];
codes.forEach(code => {
hljs.highlightBlock(code);
let arr = code.className.match(/{\S*}/);
let hllNums = null;
if (arr) {
let numArr = arr[0].replace(/[{|}]/g, '').split(',');
hllNums = this._arrToNumber(numArr);
}
codeHlNumArr.push(hllNums);
})
highlightLines();
codes.forEach((code, index) => {
this._hll(code, codeHlNumArr[index])
})
}
_arrToNumber (numArr){
let arr = [];
numArr.forEach(item=>{
if(item.indexOf('-')!==-1){
const tempArr = item.split('-');
const begin = Number(tempArr[0]);
const end = Number(tempArr[1]);
for(let i=begin;i<end+1;i++){
arr.push(i);
}
}else{
arr.push(Number(item));
}
})
return arr;
}
_hll(code, hllNums){
let spans = Omi.$$('.line',code);
hllNums&&hllNums.forEach(num =>{
spans[num]&&spans[num].classList.add('highlight');
})
}
render () {
if(!proj_config.async) {
this.data.html = this.md.render(this.getMarkDown(this.data.name, this.data.lan));
}
return tpl;
}
style () {
return css;
}
}
export default Content;

View File

@ -1,45 +1,50 @@
import Omi from 'omi';
const tpl = require('./index.html');
const css = require('./index.css');
class List extends Omi.Component {
constructor(data) {
super(data);
Omi.mixIndexToArray(this.data.list);
this.data.currentIndex = 0;
var self = this;
this.data.isCurrent = function () {
return (this.index === self.data.currentIndex) && self.data.active;
}
}
goto(name, index) {
Omi.get('content').data.name = name;
Omi.get('content').update();
this.data.currentIndex = index;
this.parent.children.forEach((child,index) => {
child.data.active = false;
if (child.id === this.id) {
Omi.get('pager').activeIndex = index;
child.data.active = true;
}
child.update();
});
Omi.get('pager').currentIndex = index;
Omi.get('pager').update();
document.body.scrollTop = 0;
}
render() {
return tpl;
}
style() {
return css;
}
}
export default List;
import Omi from 'omi';
import proj_config from '../../../project.js';
const tpl = require('./index.html');
const css = require('./index.css');
class List extends Omi.Component {
constructor(data) {
super(data);
Omi.mixIndexToArray(this.data.list);
this.data.currentIndex = 0;
var self = this;
this.data.isCurrent = function () {
return (this.index === self.data.currentIndex) && self.data.active;
}
}
goto(name, index) {
Omi.get('content').data.name = name;
if(proj_config.async) {
Omi.get('content').asyncUpdate();
}else{
Omi.get('content').update();
}
this.data.currentIndex = index;
this.parent.children.forEach((child,index) => {
child.data.active = false;
if (child.id === this.id) {
Omi.get('pager').activeIndex = index;
child.data.active = true;
}
child.update();
});
Omi.get('pager').currentIndex = index;
Omi.get('pager').update();
document.body.scrollTop = 0;
}
render() {
return tpl;
}
style() {
return css;
}
}
export default List;

View File

@ -1,66 +1,75 @@
var path = require('path');
var webpack = require('webpack');
/**
* Env
* Get npm lifecycle event to identify the environment
*/
var ENV = process.env.npm_lifecycle_event;
var config = {
entry: {
'docs-cn': './src/js/docs_main_cn.js',
'docs-en': './src/js/docs_main_en.js'
},
//dist命令使用下面的config
//output: {
// filename: '[name].[chunkhash:8].js'
//},
//dev使用下面的
output: {
filename: '[name].js'
},
//watch: true,
module: {
loaders: [
{
loader: 'babel-loader',
test: /\.js$/,
query: {
presets: ['es2015',"stage-0"],
},
exclude:/node_modules/
},
{ test: /\.html$/, loader: "string" },
{ test: /\.css$/, loader: "string" }
]
},
plugins: [
// Avoid publishing files when compilation fails
new webpack.NoErrorsPlugin()
],
stats: {
// Nice colored output
colors: true
}
// Create Sourcemaps for the bundle
//devtool: 'source-map'
};
if(ENV === 'dist'){
config.plugins.push(new webpack.optimize.UglifyJsPlugin());
config.entry ={
'docs-cn': './src/js/docs_main_cn.js',
'docs-en': './src/js/docs_main_en.js',
omi : ['omi'],
vendor : ['./src/common/class_list.js']
}
config.plugins[1] = new webpack.optimize.CommonsChunkPlugin({name:['omi','vendor'],minChunks:Infinity});
config.output.filename = '[name].[chunkhash:8].js';
}else{
config.entry.vendor = ['omi','./src/common/class_list.js'];
config.output.filename = '[name].js';
config.plugins[1] = new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.js")
}
var path = require('path');
var webpack = require('webpack');
var proj_config = require('./project.js');
/**
* Env
* Get npm lifecycle event to identify the environment
*/
var ENV = process.env.npm_lifecycle_event;
var config = {
entry: {
'docs-cn': './src/js/docs_main_cn.js',
'docs-en': './src/js/docs_main_en.js'
},
//dist命令使用下面的config
//output: {
// filename: '[name].[chunkhash:8].js'
//},
//dev使用下面的
output: {
filename: '[name].js'
},
//watch: true,
module: {
loaders: [
{
loader: 'babel-loader',
test: /\.js$/,
query: {
presets: ['es2015',"stage-0"],
},
exclude:/node_modules/
},
{ test: /\.html$/, loader: "string" },
{ test: /\.css$/, loader: "string" },
{
test: /\.md$/,
loader: "md-text"
}
]
},
plugins: [
// Avoid publishing files when compilation fails
new webpack.NoErrorsPlugin()
],
stats: {
// Nice colored output
colors: true
}
// Create Sourcemaps for the bundle
//devtool: 'source-map'
};
if(proj_config.async) {
config.module.loaders[3].exclude = /\.md$/;
}
if(ENV === 'dist'){
config.plugins.push(new webpack.optimize.UglifyJsPlugin());
config.entry ={
'docs-cn': './src/js/docs_main_cn.js',
'docs-en': './src/js/docs_main_en.js',
omi : ['omi'],
vendor : ['./src/common/class_list.js']
}
config.plugins[1] = new webpack.optimize.CommonsChunkPlugin({name:['omi','vendor'],minChunks:Infinity});
config.output.filename = '[name].[chunkhash:8].js';
}else{
config.entry.vendor = ['omi','./src/common/class_list.js'];
config.output.filename = '[name].js';
config.plugins[1] = new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.js")
}
module.exports = config;