markdown文件转html代码,Markdown转HTML之Node篇

[toc]

前言

然后好巧不巧又看到了一个Node上的相关模块,看起来渲染效果比我那个好多了。联想到hexo这款静态博客生成工具,就思量着也大致的做一下。

环境及编码

接下来简单的模拟一下相关的实现。代码比较凌乱,思维比较混乱,还望海涵(虽然主要是作为我自己的笔记,但如果对你有些许帮助,那就不枉我码了这么多字咯)。

搭建环境

所依赖的第三方模块有如下几个:

express: 开启本地服务, 预览生成效果。

Markdown-it: 渲染md文件为HTML内容。

rd: 一个读取文件夹内容的好帮手。

commander: 制作命令行工具的一大利器。

下面简要对这几个模块进行阐述,以及相关的使用技巧。

express

express不仅作为对connect的高层封装,更包含了一些额外的处理。所以我们可以方便的进行路由控制,这对于本次的工具而言,是个不错的选择。

// 初始化服务器

var app = express();

var router = express.Router();

app.use('/assets', server_static(path.resolve(dir, 'assets')));

app.use(router);

// 渲染文章

router.get('/posts/*', function(req, res, next){

var name = stripExtname(req.params[0]);

// 渲染req.params[0]对应的文章,然后展示给前台

res.end(html);

});

// res.end(req.params[0]);

});

// 渲染列表

router.get('/', function(req, res, next){

// 读取源文件目录, 渲染出列表内容。

res.end('list of articles.');

});

app.listen(8080);

markdown-it

相对于Python中的那些第三方库,我倒是觉得Node中与其也没甚么两样。使用起来同样很简单。

第一步,引入依赖

let markdowner = require('markdown-it');

第二步, 配置构造器

var md = new markdowner({

html: true,

prefix: 'code-',

});

第三步, 调用渲染方法,获取渲染后内容

var html = md.render(sourcedata||'');

如此,便是markdown-it的基础内容了,待会将在代码中更加详细的运用。

commander

用过Python的argparser的估计都知道,很方便的一个处理命令行参数的第三方库。不过Node中的commander用起来更方便。

第一步, 安装模块

npm install commander --save

第二步,编码

/**

* 一个命令行工具库。

*/

let commander = require('commander');

// help 命令

commander.command('help')

.description('显示工具如何使用的帮助信息')

.action(function(){

commander.outputHelp();

});

// create 命令

commander.command('create [dirname]')

.description('创建一个空的博客')

.action(function(dirname){

console.log(dirname+' 创建完成。')

});

// preview 命令

commander.command('preview [dirname]')

.description('预览获取到的Markdown文件夹内容')

.action(function(dirname){

console.log(' preview of %s', dirname);

});

// .action(require('./cmd_preview'));

// build 命令

commander.command('build [dirname]')

.description('根据给定的文件夹路径生成HTML内容.')

.option('-o OR --output ', '导出生成的HTML存放的路径')

.action(function(dirname){

console.log('build based on %s', dirname);

});

// .action(require('./cmd_build'));

// 解析相关命令

commander.parse(process.argv);

第三步, 查看效果

90c341e1133e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

**commander**运行效果

如果想更加方便一点,直接使用命令来操作。使用

npm link

当然了,还需要设置一下对应的package.json文件内容。这里不过多叙述了。

rd

我这里的需求是读取_posts文件夹下的Markdown源文件,所以只需要readFile方法即可。

具体代码如下:

rd.readFile(sourcedir, function(err, files){

if(err){

console.log('读取文件夹内容失败!');

return;

}

// 遍历文件夹列表,对每一个文件执行渲染操作。

files.forEach(function(file){

// 做自己的逻辑处理即可。

});

});

核心编码

下面正式开始今天的主题,做一个带预览功能的Markdown文件转HTML页面的工具。

cmd_preview模块

/**

* 关于预览实现相关的代码。

*/

let express = require('express');

let path = require('path');

let markdowner = require('markdown-it');

let fs = require('fs');

let rd = require('rd');

var md = new markdowner({

html: true,

langPrefix: 'code-',

});

module.exports = function(dir) {

dir = dir || '.';

// 初始化服务器

var app = express();

var router = express.Router();

app.use(router);

// 渲染文章

router.get('/posts/*', function(req, res, next){

var name = stripExtname(req.params[0]);

var file = path.resolve(dir, '_posts', name+'.md');

console.log('---dir--', dir);

console.log('---name--', name);

console.log('---file--', file);

fs.readFile(file, function(err, content){

if(err){

console.log('读取文件失败!');

res.end(JSON.stringify(err)+"\n");

return next(err);

}

res.writeHead(200, {"Content-Type": "text/html;charset=UTF-8"});

var html = markdownTOHTML(content.toString());

console.log('读取文件成功, 解析后的内容为:\n', html);

res.end(html);

});

// res.end(req.params[0]);

});

// 渲染列表

router.get('/', function(req, res, next){

var sourcefolder = path.resolve(dir, '_posts');

rd.readFile(sourcefolder, function(err, files){

if(err){

console.log('读取文件夹内文件失败!');

return next(err);

}

res.writeHead(200, {"Content-Type": "text/html;charset=UTF-8"});

var html = "

Markdown 转 HTML 实时预览



";

files.forEach(function(filepath){

html += ""+get_file_name(filepath)+"
";

});

html += "";

res.end(html);

});

// res.end('list of articles.');

});

app.listen(8080);

};

function stripExtname(name) {

var i = 0-path.extname(name).length;

if(i==0) i=name.length;

return name.slice(0, i);

}

function get_file_name(fullname){

var ls = fullname.toString().split('\\');

var filename = ls[ls.length-1].split('.');

// console.log('ls--', ls);

// console.log('filename--', filename);

return filename[0];

}

function markdownTOHTML(content) {

return md.render(content||'');

}

cmd_build模块

/**

* 实现Markdown文件到HTML文件的转换。

*/

let markdowner = require('markdown-it');

let rd = require('rd');

let path = require('path');

let fs = require('fs');

var md = new markdowner({

html: true,

langPrefix: 'code-',

})

module.exports = function(dir) {

dir = dir || '.';

console.log('当前文件路径为:', dir);

// 读取出给定目录下的所有的文件

// 将所有Markdown文件依次转成HTML页面,并进行保存操作。

get_files_by_dir(dir);

}

function get_files_by_dir(dir) {

// 计算出源文件的路径

var sourcedir = path.resolve(dir, '_posts');

var publicdir = path.resolve(dir, 'public');

rd.readFile(sourcedir, function(err, files){

if(err){

console.log('读取文件夹内容失败!');

return;

}

// 遍历文件夹列表,对每一个文件执行渲染操作。

files.forEach(function(file){

var html = md2html(file);

var filename = get_filename_by_path(file);

var output = path.resolve(publicdir, filename+'.html');

console.log('保存路径为:', output);

save_html_content(html, output);

console.log('%s.html 生成成功!', filename);

});

});

}

function md2html(filepath){

var content = fs.readFileSync(filepath);

var html = md.render(content.toString()||'');

return "

"+get_filename_by_path(filepath)+""+html+"";

}

function save_html_content(content, outpath){

fs.writeFile(outpath, content, function(err){

if(err){

console.log('save_html_content: 保存文件内容失败!');

return;

}

console.log('save_html_content: %s 保存成功!', outpath);

});

}

function get_filename_by_path(filepath){

var paths = filepath.toString().split('\\');

return paths[paths.length-1].split('.')[0];

}

打造命令行工具

还是用刚才的hello.js,现在稍微修改一下action里面的内容,对应我们刚才做的那两个小模块,做下修改即可。完整代码如下:

/**

* 一个命令行工具库。

*/

let commander = require('commander');

// help 命令

commander.command('help')

.description('显示工具如何使用的帮助信息')

.action(function(){

commander.outputHelp();

});

// create 命令

commander.command('create [dirname]')

.description('创建一个空的博客')

.action(function(dirname){

console.log(dirname+' 创建完成。')

});

// preview 命令

commander.command('preview [dirname]')

.description('预览获取到的Markdown文件夹内容')

// .action(function(dirname){

// console.log(' preview of %s', dirname);

// });

.action(require('./cmd_preview'));

// build 命令

commander.command('build [dirname]')

.description('根据给定的文件夹路径生成HTML内容.')

.option('-o OR --output ', '导出生成的HTML存放的路径')

// .action(function(dirname){

// console.log('build based on %s', dirname);

// });

.action(require('./cmd_build'));

// 解析相关命令

commander.parse(process.argv);

写点xx.md

巧妇难为无米之炊, 现在先在hello.js的同级目录下建个文件夹_posts,里面写点xx.md文件,然后建一个public文件夹保存生成的HTML文件。比如我的目录结构是这样的。

E:\Code\Nodejs\learn\libs-learn\commander-related>tree /f .

卷 文档 的文件夹 PATH 列表

卷序列号为 0000-4823

E:\CODE\NODEJS\LEARN\LIBS-LEARN\COMMANDER-RELATED

│ cmd_build.js

│ cmd_preview.js

│ hello.js

├─public

└─_posts

helloworld.md

second.md

演示

首先是预览实现,在命令行里输入以下命令:

node hello.js preview . # .代表当前目录

结果如下:

90c341e1133e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

**preview**效果图

然后是针对每一篇文章生成效果的演示。

90c341e1133e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

每一篇文章的预览效果

最后就是看下build功能的实现。

现在在命令行里面输入以下命令:

node hello.js build . # .代表当前目录

然后看下效果。

90c341e1133e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

**build** 功能实现

总结

大致来说功能就算是完成了,但是目前这样子是没法直接应用的。很多东西都需要润色,比如:

模板化HTML页面处理。

命令行选项的link实现。

通过监测文件内容变化实现实时预览。

就先到这里吧,今天又发现了两个不错的网址,然后还是先去学一波,补充补充知识吧。很多时候,不是能力不够,而是见识不足。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值