Java集成editor.md开发markdonw程序

前言

本篇主要是使用Java语言结合开源editor.md进行开发markdown论坛功能,具体请看下图,如果不是你想要的,那可以看我另外一篇使用commonmark-java解析成html文档的文章

详细功能:
markdown界面很简洁,也就是这样,下图是你想要的吗?

详细功能图

原材料准备

editor.md

是国人开发的开源在线Markdown编辑器,单纯基于前端JavaScript,无需后台代码加持,适用于任何语言,我这里使用examples示例来进行改造,很久没更新了.....
首页地址:http://pandao.github.io/editor.md/

Java集成editor.md开发markdonw程序_第1张图片
目录结构

项目搭建,资源准备

注意:这个步骤过程有点繁琐,尤其是一些资源文件的访问,所以可以根据自己的情况进行调整,但一定要看到第10步对应的界面,资源准备才算完成

  • 名词:下述所有的“外层”表示源码包的第一层目录
  1. 新建SpringBoot项目,这里不做赘述,不会的朋友请看超简单SpringBoot搭建
  2. 然后将外层examples文件夹中的css、js资源,拷贝到resources下的static中
  3. 将外层examples文件夹中的simple.html示例文件拷贝到工程的templates下面,如下图
资源准备
  1. 编辑simple.html文件,将如下图的资源文件路径根据你的项目进行调整
Java集成editor.md开发markdonw程序_第2张图片
css资源
Java集成editor.md开发markdonw程序_第3张图片
js资源
  1. 上图中的editormd.css和editormd.min.js需要从外层文件中拷贝进来,拷贝进来后如下图


    Java集成editor.md开发markdonw程序_第4张图片
    准备editormd.css和editormd.min.js
  2. 拷贝外层的lib目录


    Java集成editor.md开发markdonw程序_第5张图片
    lib目录加载
  3. 拷贝外层的fonts目录,并且将外层文件夹images中的loading.gif拷贝到我们项目的images中


    fonts目录,loading.gif文件
  4. 最终 调整后的simple.html文件内容为


    Java集成editor.md开发markdonw程序_第6张图片
    最终路径与内容对比
  5. 加入Controller类,以便于做后续操作


    Java集成editor.md开发markdonw程序_第7张图片
    image.png
  6. 启动服务器,要求能够访问simple.html,并且样式能够正常加载没有错误,如下图


    看到该图后才可进行下一步

开始开发,前方高能

开发主要分为3个层面

  1. 简单的后台提交内容示例。
  2. 前台接收markdown内容页面显示时进行转换加载。
  3. 复杂的服务器端开发(带文件上传)

1、后台内容提交页面

该页面即simple.html页面,核心的加载的JS在代码在页面底部,如下:

 var testEditor;

    $(function() {
        testEditor = editormd("test-editormd", {
            width   : "90%",
            height  : 640,
            syncScrolling : "single",
            path    : "lib/"
        });

    });
开发提交功能

开始进入简单功能的开发,其JS的写法,也可以看examples中其他页面,对应不同的功能,有不同的JS,或者直接跟我进入开发,保证不带沟里

  • simple界面中,加入form表单,修改JS,简单的提交客户端完成,内容如下:
simple界面中的form

    
    
testEditor中JS的变化
            /**下述为新增,上面一行记得加逗号结束*/
            /*指定需要显示的功能按钮*/
            toolbarIcons : function() {
                return ["undo", "redo", "|","bold", "italic","ucwords","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","table","datetime","hr",  "||",  "watch", "fullscreen", "preview", "releaseIcon", "index"]
            },

            /*自定义功能按钮,下面我自定义了2个,一个是发布,一个是返回首页*/
            toolbarIconTexts : {
                releaseIcon : "发布",
                index : "返回首页",
            },

            /*给自定义按钮指定回调函数*/
            toolbarHandlers:{
                releaseIcon : function(cm, icon, cursor, selection) {
                        contentCommit();//提交表单代码在下面
                        console.log("日志输出 testIcon =>", this, cm, icon, cursor, selection);
                },
                index : function(){
                    window.location.href = '返回首页的路径.html';
                },
            }

另外需要提供提交JS的代码

    /*提交表单的js*/
    function contentCommit(){
        mdEditorForm.method = "post";
        mdEditorForm.action = "contentCommit";//提交至服务器的路径
        mdEditorForm.submit();
    }
  • 修改Controller,加入接收提交内容的方法,并且提供一个简单的view界面,用于预览,如下


    服务器端代码

上图代码如下:

@Controller
@RequestMapping
public class MarkdownController {

    @RequestMapping("simple")
    public ModelAndView simple(){
        //这里的文件名将直接定位到templates下面的文件
        ModelAndView modelAndView = new ModelAndView("simple");
        System.out.println("进入内容编写页面");
        return modelAndView;
    }

    @RequestMapping("contentCommit")
    public ModelAndView contentCommit(String content){
        System.out.println("提交的内容为:" + content);
        ModelAndView modelAndView = new ModelAndView("view");
        //将内容发送至前台预览
        modelAndView.addObject("viewContent" , content);
        System.out.println("跳转至内容显示页面");
        return modelAndView;
    }

}
Java集成editor.md开发markdonw程序_第8张图片
修改后的markdown页面
  • 启动服务器,并且点击提交,你会发现内容正确到达客户端。

简单的提交完成,接下来,开发预览界面


2. 前台加载markdown语法,并且解析

  1. 拷贝examples中的html-preview-markdown-to-html.html页面,改名为view.html界面,将其中依赖的静态资源文件全部调整正确, 并且访问不报错误,所以你需要将不存在的文件有序的拷贝进来

    • 新依赖外层css中的editormd.preview.css文件
    • 新依赖外层的editormd.js,或直接将内容改为editormd.min.js,两者效果一样
    • 新依赖examples中的test.md文件,jquery.min.js所依赖,可以修改jquery文件,移除掉
  2. 更改完成后的内容页面如下,控制台不能够报错

Java集成editor.md开发markdonw程序_第9张图片
预览界面的内容

预览界面重要代码如下

Java集成editor.md开发markdonw程序_第10张图片
预览JS图
  1. 前台页面textarea id="append-test"中的内容全部清除,将上图JS中的test.md改为内容请求地址,后台提供一个rest内容获取接口
     /**
     * 读取所保存的markdown数据
     * @return
     */
    @RequestMapping("getContent")
    @ResponseBody
    public String getContent(){
        return "### 这是markdown格式的内容,暂时固定写死,应从数据库读取上个接口保存的内容";
    }
Java集成editor.md开发markdonw程序_第11张图片
更改后的JS代码
Java集成editor.md开发markdonw程序_第12张图片
点击发布后,出现的预览界面

到此为止,简单的markdonw集成进来了,其中的按钮以及js用法,还需要结合其他的页面进行进一步探讨,整体流程效果图如下:

整体流程效果图

3. 剪切板文件上传代码加入

  1. 很多时候我们上传文件不会手动去写markdown的文件语法,也不会去点击markdown提供的文件上传按钮,更多的是通过Ctrl+C、Ctrl+V来读取剪贴板实现上传,类似于、csdn等博客都有实现该功能。但在如下代码中,剪切板的读取存在浏览器兼容的问题,经测试,目前只能读取QQ等应用Ctrl+Alt+A截图的图片,无法读取在桌面右键->复制的图片,望各位悉知,效果图如下
aa.gif
  1. 编写JS代码


    Java集成editor.md开发markdonw程序_第13张图片
    JS剪切板读取
        //读取剪切板
        $("#test-editormd").on('paste', function (ev) {
            var topicCode = $("#topicCode").val();
            //详细可查看clipboardData属性的使用方式
            var data = (ev.clipboardData || ev.originalEvent.clipboardData);
            var items1 = data.items;
            console.log(items1);//输出 DataTransferItem对象
            var imageFile;
            for(var index in items1){
                var item = items1[index];
                //如果kind是file,可以用getAsFile()方法获取到文件
                if (item.kind === 'file') {
                    imageFile = item.getAsFile();
                    console.log('获取到剪贴板的文件' + item.kind);
                    break;
                }else if(item.kind === 'string'){
                    console.log('获取到剪贴板的字符串' + item.kind);
                }
            }

            //执行上传
            uploadTrigger(imageFile,topicCode);
        });

上图中uploadTrigger(imageFile,topicCode) 函数为文件上传的js代码,如下:

Java集成editor.md开发markdonw程序_第14张图片
文件上传代码片段
    //执行上传
    function uploadTrigger(imageFile,topicCode){
        //topicCode为文章代码,需要在关联图片,从而实现预览时准确加载到图片
        var url = "uploadMdFile.json?topicCode="+topicCode;
        var formdata = new FormData();
        formdata.append("file", imageFile);

            $.ajax({
                url: url,
                type: "post",
                data: formdata,
                //关闭序列化
                processData: false,
                contentType: false,
                success: function (data) {
                    //data为后台返回的retMap数据
                    if(data.retCode == "success"){
                        //向markdown区域插入该格式的值,从而实现图片在右侧显示
                        testEditor.insertValue("\n![" + data.file + "](" + data.rootPath + ")");
                    } else {
                        console.log(data.msg);
                    }
                },
                error : function(data){
                }
            });
    }
  1. 页面JS完成后,需要实现后台服务端接收并存储图片,代码片段如下,图片我这里没有存储在数据库中,而是直接写在了本地服务器能够访问的地方,可根据实际情况进行改变目录或者上传至OSS存储服务器
Java集成editor.md开发markdonw程序_第15张图片
image.png
    /**
     * 上传文件
     * @return
     */
    @RequestMapping("uploadMdFile.json")
    @ResponseBody
    public Map getContent(HttpServletRequest request,@RequestParam(value = "file",required=false) MultipartFile file,String topicCode){
        Map resultMap = new HashMap<>();
        if(topicCode != null && !"".equals(topicCode)){
            //该CODE用于对应图片存储,实际项目中需要存储该文章与图片的关系,我这不做处理
            System.out.println("主题CODE->" + topicCode);
        }
        try {
            // 检测是不是存在上传文件
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if(isMultipart){
                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                Map multipartFileMap = multipartRequest.getFileMap();
                for (Map.Entry entryFile : multipartFileMap.entrySet()) {
                    MultipartFile value = entryFile.getValue();
                    //读取输入流
                    InputStream is = value.getInputStream();
                    //获取文件名
                    String fileName = value.getOriginalFilename();
                    //声明byte缓冲数组
                    byte[] b = new byte[(int) value.getSize()];
                    is.read(b);
                    //将文件名上传的name作为返回的key,默认为file
                    resultMap.put(entryFile.getKey() , fileName);
                    //返回接口调用状态码
                    resultMap.put("retCode" , "success");
                    //返回图片访问路径,此处可以改为OSS分布式存储,根据项目具体情况调整
                    resultMap.put("rootPath" , "http://localhost:8080/"+fileName);
                    //上传到文件服务器路径,此处我直接上传到项目部署编译路径,需要调整
                    OutputStream os = new FileOutputStream(new File("F:\\work\\testjava\\md\\target\\classes\\static" , fileName));
                    os.write(b);
                    os.flush();
                }
            }
        }catch (Exception e){
        }
        return resultMap;
    }

上述代码中 F:\\work\\testjava\\md\\target\\classes\\static 指的是我的代码编译目录,该目录下的文件可以通过:http://localhost:8080/xxx 进行访问,请根据自身情况进行调整

先暂时更新到这里,具体的功能基本已经实现,若需要读取桌面文件,则可能需要实现文本框也支持图片流,可以采用H5的FileReader实现,后续再更....

你可能感兴趣的:(Java集成editor.md开发markdonw程序)