zoukankan      html  css  js  c++  java
  • [原创]使用 NodeJS, MarkdownJS, PrettifyJS 打造个人博客写作平台 打包下载

    引言

    上一篇文章我们介绍了使用 NodeJS, MarkdownJS, PrettifyJS 打造个人博客写作平台的整体思路, 也顺利解决了把 PrettifyJS 转换为 NodeJS 模块的麻烦。这篇文章我们会分析 NodeJS 相关代码,并给出可运行的压缩包下载。

    在继续本文之前,先来回答上篇评论中网友的疑问,这么做的好处有哪些? 如果我们有 Showdown 这样的在线转换 Markdown 语法的工具,这篇文章的意义在哪里?

    • 首先我希望使用记事本写文章,这样方便快捷。然后本机能够直接生成 HTML,这样我既可以直接放在我的个人主页,也可以粘贴到博客中。
    • 其次技术文章中,需要粘贴很多源代码,有 CSS, HTML, JavaScript 或者 Asp.NET, C# 的源代码,我希望这些源代码能自动着色,这样文章看起来更生动。 由于 Markdown 语法不支持为 <pre> 标签设置 class 属性,所以只能使用 Google 的 PrettifyJS,但是一般博客提供商是不会让你引入外部 JavaScript 的, 但大部分可以修改 CSS,这就需要在转换过程中直接生成着色后的 HTML,而这是 Showdown 不可能支持的。

    实现

    首先来看看发布的压缩包的目录结构:

    root
            lib
                    nodejs
                            node
    .exe
                    markdown
                            markdown
    .js
                            prettify
    -nodejs.js
                            build
    .js (所以的代码都在这里)
                           
    template.html (使用 prettify 在浏览器解析的页面模板)
                           
    template-prettify-inline.html (不包含 prettify JavaScript 文件的页面模板)
            nodejs_markdownjs
                    intro
    .md (我们写的文章)
                    build
    .bat (执行这个文件会把当前目录下的所有 .md 文件转化为 .html 文件)

    我们来看下 build.js 的内容:

    var fs = require('fs'),
            markdown
    = require("./markdown"),
            path
    = require('path'),
            prettify
    = require('./prettify-nodejs');


    // 可以传递第三个参数,如果为true则使用prettify的内联方式,不用加载JS
    // 比如:..\lib\nodejs\node ../lib/markdown/build.js true
    var prettifyInline = false;
    if(process.argv.length >= 3) {
            prettifyInline
    = process.argv[2] === 'true' ? true : false;
    }      

    // 当前目录下的所有文件
    var files = fs.readdirSync('./'),
            i
    = 0, count = files.length,
            file
    , dotLastIndex, fileName, fileType;

    // 对所有以 .md 为后缀的文件,进行转换
    for(; i < count; i++) {
            file
    = files[i];
            dotLastIndex
    = file.lastIndexOf('.');
           
    if(dotLastIndex >= 0) {
                    fileType
    = file.substr(dotLastIndex + 1);
                   
    if(fileType === 'md') {
                            fileName
    = file.substr(0, dotLastIndex);
                            buildFile
    (file, fileName);
                   
    }
           
    }
    }

    // 获取模板文件内容
    function getTemplate() {
           
    var markdownPath = path.dirname(process.argv[1]);
           
    if(prettifyInline) {
                    markdownPath
    = markdownPath + '/template-prettify-inline.html';
           
    } else {
                    markdownPath
    = markdownPath + '/template.html';
           
    }
           
    return fs.readFileSync(markdownPath, 'utf8');
    }

    // 转换 markdown 文件为html文件
    function buildFile(file, fileName){
            console
    .log('Build file: ' + file);
           
    var fileContent, h1Regex, title = '';
            fileContent
    = fs.readFileSync(file, 'utf8');
            fileContent
    = markdown.toHTML(fileContent);

           
    // 从 html 中提取 h1 标签内的内容,作为网页的标题
            h1Regex
    = /<h1>([\w\W]*?)<\/h1>/.exec(fileContent);
           
    if(h1Regex && h1Regex.length === 2) {
                    title
    = h1Regex[1];
           
    }

           
    // 转化为 prettify 需要的格式
            fileContent
    = fileContent.replace(/<pre><code>([\w\W]*?)<\/code><\/pre>/g, function(str, p1) {
                   
    if(prettifyInline) {
                           
    // prettify 对单引号的处理有问题,这是权宜之策
                            p1
    = p1.replace(/&#39;/g, "'");
                           
    // 如果是内联的 prettify,需要预先生成代码的 html 格式
                            p1
    = prettify.prettyPrintOne(p1);
                   
    }
                   
    return '<pre class="prettyprint">' + p1 + '</pre>';
           
    });

           
    // 替换模板内容
            fileContent
    = getTemplate().replace('${title}', title).replace('${body}', fileContent);

            fs
    .writeFileSync(fileName + '.html', fileContent);
    }

    console
    .log('Done!');

    如果你用过 nodejs,上面的代码很好理解了,大致分为如下几个步骤:

    • 读取 build.bat 同级目录下的所有以 .md 为后缀的文件。
    • 对每个 .md 文件,调用 MarkdownJS 模块,转化为 HTML 源代码。
    • 提取 HTML 源代码中的 <h1> 标签作为页面的标题;对所有的 <pre><code>...</code></pre> 调用 PrettifyJS 模块,直接生成着色后的 HTML 代码。
    • 保存生成的 HTML 文件。

    使用方法

    下载 Markdown 写作平台,解压缩到任意文件夹,然后和 lib 同级目录创建一个文件夹 HelloWorld,里面新建两个文件:

    build.bat

    ..\lib\nodejs\node ../lib/markdown/build.js true

    intro.md

    ## 段落一

    下面是出自 [MDC Developer Center][1] 的一段 JavaScript 代码:


            s_obj
    = new String(s_prim = s_also_prim = "foo");
            s_obj
    .length;       // 3
            s_prim
    .length;      // 3
            s_also_prim
    .length; // 3
           
    'foo'.length;       // 3
           
    "foo".length;       // 3


    [1]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String

    运行 build.bat,会在当前目录下生成 intro.html 文件,打开:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
           
    <title></title>
           
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
           
    <style>
           
    .markdown-post h1
           
    {
                    font
    -weight: bold;
                    font
    -size: 2.2em;
                    margin
    : 25px 0px 15px;
           
    }
           
    .markdown-post h2
           
    {
                    font
    -size: 2em;
                    font
    -weight: bold;
                    margin
    : 25px 0 15px;
           
    }
           
    .markdown-post h3
           
    {
                    font
    -weight: bold;
                    font
    -size: 1.2em;
                    margin
    : 10px 0px 5px;
           
    }
           
    ...
           
    </style>
    </head>
    <body>
    <div class="markdown-post">
    <h2>段落一</h2>

    <p>下面是出自 <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String">MDC Developer Center</a> 的一段 JavaScript 代码:</p>

    <pre class="prettyprint">
           
    <span class="pln">s_obj </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span>
            ...
    </pre>
    </div>
    </body>
    </html>

    需要注意的是:这个生成的 HTML 文件不包含任何 JavaScript 文件,但是代码都已经被着色了,实际的效果如下:

    HelloWorld intro.html

    如何把生成的 HTML 添加为博客园随笔

    首先我们需要在博客园的后台管理中,进入“设置”标签,添加自定义的 CSS(这个 CSS 也就是生成的 intro.html 头部的CSS):

    Add Global CSS to cnblogs

    在添加随笔时,打开 HTML 视图,把生成 HTML 的 <body> 部分的全部内容拷贝进去就可以了:

    Add article to cnblogs

    如果你想看具体的示例,这篇文章和上篇文章就是最好的范例了。

    下载可运行包

    下载可运行包

  • 相关阅读:
    sb#run():
    aop编程,自定义注解参数和方法范围
    vue 工程化
    mybatis SqlSession
    java传时间
    树的同构
    串的模式匹配
    堆栈模拟队列
    银行业务队列简单模拟
    一元多项式的乘法与加法运算
  • 原文地址:https://www.cnblogs.com/sanshi/p/1987551.html
Copyright © 2011-2022 走看看