road_to_bookdown

road_to_bookdown

陳鍾誠老師的一個專案,目前性質看起來和 gitbook 有點類似,正在觀望他的發展。因為這個教學專案還滿仔細的,所以有空的時候會來複習一下

[TOC]

  • 01-showdown

  • 02-staticServer

  • 03-showdownServer

  • 04-routeServer

  • 05-purecss

  • 06-handlebarsTemplate

  • 07-templateServer

  • 08-bookdown001modulized

  • 09-katexMathRender

  • 10-editServer

01-showdown

/**********markdown2html.js***********/
// 載入套件
var fs        = require('fs');
var showdown  = require('showdown');
var converter = new showdown.Converter();

showdown.setFlavor('github');
converter.setOption('tables', true);

var md        = fs.readFileSync("markdown.md", "utf8");
var html      = converter.makeHtml(md);
fs.writeFileSync("markdown.html", html);

/**********markdown2html.js***********/

02-staticServer

/**********staticServer.js***********/

// 載入套件
var koa = require('koa');
var serve = require('koa-static');
var path = require('path'); // 把字串用斜線接起來
var app = koa(); // 建立一個叫 koa() 的物件

app.use(serve(path.join(__dirname, ''))); // 公開當前目錄
app.listen(3000);
console.log('listening on port 3000');

/**********staticServer.js***********/

03-showdownServer

  • 顧名思義,能看 markdown、又有靜態伺服器

/*************showdownServer.js*************/

var fs = require('mz/fs');
var showdown  = require('showdown');
var koa = require('koa');
var serve = require('koa-static');
var path = require('path');

var app = koa();
var converter = new showdown.Converter();
converter.setOption('tables', true);

function *view(next) {
    yield next;
    if (this.path.startsWith("/view/")) { // convert *.md to html
      var tpath = this.path.replace("/view/", "/user/"); // 用view看user
        var fullpath = path.join(__dirname, tpath);
        var fstat = yield fs.stat(fullpath);
        if (fstat.isFile()) {
            if (this.path.endsWith(".md")) {
                this.type = "html";
                var md = yield fs.readFile(fullpath, "utf8"); // 讀檔案
                this.body = converter.makeHtml(md); // 轉成 html        
            } else {
                this.type = path.extname(this.path);
                this.body = fs.createReadStream(fullpath);
            }
        }
    }
}

var rootpath = path.join(__dirname, '');
console.log("rootpath=%s", rootpath);
app.use(serve(rootpath)); // 靜態伺服器

app.use(view);

if (!module.parent) app.listen(3000);
console.log('listening on port 3000');

/*************showdownServer.js*************/

04-routeServer

  • 看不懂

/************routeServer.js*************/

var fs = require('mz/fs');
var showdown = require('showdown');
var koa = require('koa');
var serve = require('koa-static');
var route = require('koa-route');
var path = require('path');

function *view(book, file) { // view(mdFile):convert *.md to html
    var fullpath = path.join(__dirname, "/user/"+book+"/"+file);
    var fstat = yield fs.stat(fullpath);
    if (fstat.isFile()) {
        if (this.path.endsWith(".md")) {
            this.type = "html";
            var md = yield fs.readFile(fullpath, "utf8");
            this.body = converter.makeHtml(md);
        } else {
            this.type = path.extname(this.path);
            this.body = fs.createReadStream(fullpath);
        }
    }
}

var app = koa();
var converter = new showdown.Converter();
converter.setOption('tables', true);

app.use(serve(path.join(__dirname, '')));

app.use(route.get('/view/:book/:file', view)); // 引入 route
// :book, :file 是參數,丟給 view

if (!module.parent) app.listen(3000);
console.log('listening on port 3000');

/************routeServer.js*************/

05-purecss

  • 簡單提到 ccckmit.gitbooks.io/javascript-web/content/,但有些內容已經不合時宜,像是 jQurey

  • 雅虎出了 purecss

  • 聽說引用這段 css,就可以使用它的語法

<link rel="stylesheet" href="https://unpkg.com/purecss@0.6.0/build/pure-min.css">

06-handlebarsTemplate

  • 樣板引擎

  • 因為 Swig 樣板引擎不維護了,所以老師想換一個

  • 結果找到這個:鬍子 http://handlebarsjs.com/

  • 用處: 套樣本。例如

<!------- 樣本範例 ------->

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>

<!------- 樣本範例 ------->
  • 範例程式

/************ helloHandlebars.js ************/

var Handlebars = require("Handlebars");
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
             "{{kids.length}} kids:</p>" +
             "<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
var template = Handlebars.compile(source);

var data = { "name": "Alan", "hometown": "Somewhere, TX",
             "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
var result = template(data);
console.log("result=%s", result);

// Would render:
// <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
// <ul>
//   <li>Jimmy is 12</li>
//   <li>Sally is 4</li>
// </ul>

/************ helloHandlebars.js ************/
  • 確認樣本引擎正不正確的測試程式

/**************bookHandlebars.js*************/

var fs = require("fs");
var handlebars = require("handlebars");
var showdown  = require('showdown');
var converter = new showdown.Converter();

var md = fs.readFileSync("user/markdown/markdown.md", "utf8");
var viewHtml   = fs.readFileSync("view.html", "utf8");
var viewRender = handlebars.compile(viewHtml);

var bookJson = fs.readFileSync("user/markdown/book.json", "utf8");//讀取
var book = JSON.parse(bookJson); // 轉成一個物件,被用在側邊欄
book.html = converter.makeHtml(md); // 轉成 html

var html = viewRender(book);  
fs.writeFileSync("user/markdown/markdown.html", html); // 套樣板

/**************bookHandlebars.js*************/

07-templateServer

  • 套樣板

  • 靜止伺服器

/************** templateServer.js ****************/

var fs = require('mz/fs');
var showdown = require('showdown');
var handlebars = require('handlebars');
var koa = require('koa');
var serve = require('koa-static');
var route = require('koa-route');
var path = require('path');

var render = { 
  view:handlebars.compile(fs.readFileSync("view.html", "utf8")),
}

function *view(book, file) { // view(mdFile):convert *.md to html
  var bookPath = path.join(__dirname, "/user/"+book);
    var filePath = path.join(__dirname, "/user/"+book+"/"+file);
    var fstat = yield fs.stat(filePath);
    if (fstat.isFile()) {
        if (this.path.endsWith(".md")) {
            this.type = "html";
            var md = yield fs.readFile(filePath, "utf8");
            var bookJson = yield fs.readFile(bookPath+"/book.json", "utf8");
            var book = JSON.parse(bookJson);  // 建立 book 物件
            book.html = converter.makeHtml(md); // 轉換成 html
            var page = render.view(book); // 拿去套樣板
            console.log("page=", page);
            this.body = page;
        } else {
            this.type = path.extname(this.path);
            this.body = fs.createReadStream(filePath);
        }
    }
}
/*
var md = fs.readFileSync("user/markdown/markdown.md", "utf8");
var viewHtml   = fs.readFileSync("view.html", "utf8");
var viewRender = handlebars.compile(viewHtml);
var bookJson = fs.readFileSync("user/markdown/book.json", "utf8");
var book = JSON.parse(bookJson);
book.html = converter.makeHtml(md);
var html = viewRender(book);
fs.writeFileSync("user/markdown/markdown.html", html);
*/
var app = koa();
var converter = new showdown.Converter();
converter.setOption('tables', true);

app.use(serve(path.join(__dirname, '')));

app.use(route.get('/view/:book/:file', view));


if (!module.parent) app.listen(3000);
console.log('listening on port 3000');


/************** templateServer.js ****************/

08-bookdown001modulized

  • 想讓這個專案真的能發布到 github 等地方

  • 因此加入 package.json。一定需要這個東西,才能發布到 npm

  • server.js 好像沒什麼變,只是模組化程度更高了一點

  • 好像只是在說有成功上傳的 npm 的樣子 ...

{
  "name": "bookdown",
  "version": "0.0.1",
  "description": "Book Editing System for Markdown",
  "main": "server.js",
  "dependencies": {
    "handlebars": "^4.0.6",
    "koa": "^1.2.4",
    "koa-route": "^2.4.2",
    "koa-static": "^2.0.0",
    "mz": "^2.6.0",
    "showdown": "^1.5.1"
  },
  "devDependencies": {},
  "scripts": {},
  "bin": {},
  "keywords": [],
  "homepage": "https://github.com/ccckmit/bookdown",
  "repository": {
    "type": "git",
    "url": "http://github.com/ccckmit/bookdown.git"
  },
  "author": {
    "name": "Chung-Chen Chen",
    "email": "ccckmit@gmail.com",
    "url": "http://ccc.nqu.edu.tw"
  },
  "license": "MIT"
}
/************** server.js *****************/

var fs = require('mz/fs');
var showdown = require('showdown');
var handlebars = require('handlebars');
var koa = require('koa');
var serve = require('koa-static');
var route = require('koa-route');
var path = require('path');

var userPath = path.join(__dirname, 'user');

var render = { 
  view:handlebars.compile(fs.readFileSync("render/view.html", "utf8")),
}

function *view(book, file) { // view(mdFile):convert *.md to html
  var bookPath = path.join(userPath, "/book/"+book);
    var filePath = path.join(userPath, "/book/"+book+"/"+file);
    var fstat = yield fs.stat(filePath);
    if (fstat.isFile()) {
        if (this.path.endsWith(".md")) {
            this.type = "html";
            var md = yield fs.readFile(filePath, "utf8");
            var bookJson = yield fs.readFile(bookPath+"/book.json", "utf8");
            var book = JSON.parse(bookJson);
            book.html = converter.makeHtml(md);
            var page = render.view(book);
            this.body = page;
        } else {
            this.type = path.extname(this.path);
            this.body = fs.createReadStream(filePath);
        }
    }
}

var app = koa();
var converter = new showdown.Converter();
converter.setOption('tables', true);

app.use(serve(path.join(__dirname, 'web')));
app.use(serve(userPath));

app.use(route.get('/', function*() { this.redirect('/view/markdown/README.md') }));
app.use(route.get('/view/:book/:file', view));


if (!module.parent) app.listen(3000);
console.log('listening on port 3000');

/************** server.js *****************/

09-katexMathRender

  • 渲染數學式

10-editServer

  • cmd 提示少安裝套件

  • npm install co-body --save

  • MangoDB 用的 port 27017

  • http 預設 80

Last updated