写在前面

主要技术点:使用 thymeleaf+flexmark 渲染模板渲染 markdown 文件 ,highlight 渲染代码高亮 thymeleaf 模板负责渲染页面 flexmark 是 java 语言编写,负责将数据库中的 markdown 语法文本转为 html 文本 highlight 负责渲染 code 部分的代码,是一款 js+css 库

步骤

首先定义一个 controller 和 requstmapping

package com.kikt.web.ctl.blog;

import com.kikt.service.markdown.MarkdownService;
import com.sun.org.apache.xpath.internal.operations.Mod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;

/**
 * Created by cai on 2017/8/25.
 */
@Controller
@RequestMapping("/md")
public class MarkdownCtl {

    @Autowired
    private MarkdownService service;

    @RequestMapping(value = "/parse", method = RequestMethod.POST)
    public String parseMarkDown(Model model, @RequestParam("md") String markdownText) {
        model.addAttribute("md", service.parseMarkdownString(markdownText));
        return "test";
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model) {
        model.addAttribute("inputName", "md");
        return "markdown";
    }

}

在 static/templates 下定义一个文件,markdown.html

这样当访问 http://localhost:8080/md/index的时候,就会跳转到index页面中

<!DOCTYPE html>
<html
  xmlns:th="http://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
>
  <head>
    <meta charset="UTF-8" />
    <script type="text/javascript" th:src="@{/js/jquery-3.2.1.min.js}"></script>
    <script type="text/javascript">
      $(document).ready({});
    </script>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <form method="post" action="./parse">
      <div>
        <textarea
          th:name="${inputName}"
          title="md"
          th:width="200px"
          th:height="300px"
        />
        <button type="submit">提交</button>
      </div>
    </form>
  </body>
</html>

其中很简单,就定义了一个表单,表单中有一个输入框和一个提交按钮,这里模拟的是一个 post 提交表单的过程,提交的 url 为/parse 也就是/md/parse,对应的就是指向 test.html

<!DOCTYPE html>
<html
  xmlns:th="http://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta charset="UTF-8" />
    <link rel="stylesheet" th:href="@{/highlight/styles/default.css}" />
    <script th:src="@{/highlight/highlight.pack.js}"></script>
    <link rel="stylesheet" type="text/css" th:href="@{/css/markdown.css}" />
    <script type="text/javascript" th:src="@{/js/jquery-3.2.1.min.js}"></script>
    <script th:inline="javascript" type="text/javascript">
      $(document).ready(function () {
          var a = [[${md}]]
          $("#div").html(a)
          $('pre code').each(function(i, block) {
              hljs.highlightBlock(block);
          });
      })
    </script>
    <title>Title</title>
  </head>
  <body>
    <div id="div"></div>
  </body>
</html>

再来看下 js 中的代码是在后台定义的 attr,名字为 md,来源是 service service 的代码如下:

package com.kikt.service.markdown

import com.kikt.ext.logger
import com.vladsch.flexmark.html.HtmlRenderer
import com.vladsch.flexmark.parser.Parser
import com.vladsch.flexmark.util.options.MutableDataSet
import org.springframework.stereotype.Service

/**
 * Created by cai on 2017/8/25.
 */
@Service
open class MarkdownService {

    fun parseMarkdownString(markdown: String): String {
        val options = MutableDataSet()
        val parser = Parser.builder(options).build()
        val renderer = HtmlRenderer.builder(options).build()
        val document = parser.parse(markdown)
        val html = renderer.render(document)
        logger.info("parse html = $html")
        return html
    }

}

就是定义一个了第三方的 markdown 解析器,传入前端页面,再由前端页面通过 js 进行渲染 markdown.css 是我自己定义的一些渲染规则

blockquote {
  font: 18px normal helvetica, sans-serif;
  margin-top: 10px;
  margin-bottom: 10px;
  margin-left: 10px;
  padding-left: 8px;
  border-left: 9px solid #ccc;
}

pre {
  font: 14px normal helvetica, sans-serif;
  background-color: #efefef;
  color: #333333;
  margin-left: 5px;
  padding: 10px;
  margin-right: 30px;
}

a {
  font: 16px normal helvetica, sans-serif;
}

blockquote p {
  font-size: 18px;
  margin-left: 0px;
}

p {
  font-size: 14px;
  margin-left: 10px;
}

p code {
  background-color: #ededef;
}

第三方库来源及用途

thymeleaf 模板 用于渲染 java 中的视图层 flexmark-java java 中的库,用于转化 markdown 语法到 html 语法 spring boot java 的轻应用构建框架 highlightjs 高亮 pre 中的 code 语法 jquery 前端都知道的 js 框架

截图


屏幕快照 2017-08-27 下午3.58.02.png

屏幕快照 2017-08-27 下午3.58.09.png

后记

也没什么创新可言,主要就是做一个小技术点的总结

其实更节省资源的做法是将 markdown 从文本到 html 的语法全部交给前端解决,后端只负责储存,这样将解析的过程交给每个浏览器去解决是个更好的解决思路,这样的好处就是不论什么浏览器都可以正常的渲染出 markdown