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

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

    下载可运行包

    下载可运行包

  • 相关阅读:
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    PHP serialize() 函数
    PHP print_r() 函数
  • 原文地址:https://www.cnblogs.com/sanshi/p/1987551.html
Copyright © 2011-2022 走看看