编写一个markdown文本编辑器工具

1、UI组件/依赖库选择。

编辑器采用左右分割布局,左侧为Markdown编辑区,右侧为实时预览区,相关组件或依赖选择现成的开源库整合实现,减少开发成本。

1.1、左侧Markdown编辑区UI组件选择。

网上找了一下,仅发现RSyntaxTextArea https://github.com/bobbylight/rsyntaxtextarea这个组件比较适合。
RSyntaxTextArea的功能::

  • 现成的文本编辑界面
  • Markdown语法高亮显示
  • 可定制的编辑功能
  • 开源免费使用

1.2、webview组件选择

要创建markdown编辑,需要一个webview组件,在java里面可用的webview组件有:

  1. javafx.scene.web.WebView,开源免费,基于webkit内核
  2. jcef,开源免费,基于Chromium
  3. JxBrowser,商业收费,基于Chromium
    在考虑免费和整合方便上,选择了javafx.scene.web.WebView。

1.3、markdown转html开源库选择。

  1. CommonMark-java

    • 基于CommonMark规范实现
    • 轻量级,易于集成
    • 支持标准Markdown语法
  2. Flexmark-java

    • 功能丰富的Markdown处理器
    • 支持CommonMark和GitHub Flavored Markdown
    • 可扩展性强,支持自定义扩展
  3. Markdown4j

    • 简单易用的Markdown解析器
    • 基于JavaScript的markdown.js移植
    • 适合基本的Markdown转换需求
  4. Txtmark

    • 轻量级Markdown处理器
    • 性能较好
    • 支持基本Markdown语法

Flexmark-java支持最完整,选择了它。

2、核心技术实现

2.1、左侧Markdown编辑区实现

编辑区采用RSyntaxTextArea,初始化代码如下:

   // 初始化面板
   private void initPanel() {
        textArea = new RSyntaxTextArea();
        textArea.setCodeFoldingEnabled(true);
        textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_MARKDOWN);
        textArea.setAntiAliasingEnabled(true);
        textArea.setFont(Config.getFont());
        textArea.setLineWrap(Config.isIsLineWrap());
        textArea.addCaretListener(e -> {
            try
            {
                int pos = textArea.getCaretPosition();
                //获取行数
                int row = textArea.getLineOfOffset(pos) + 1;
                //获取列数
                int col = pos - textArea.getLineStartOffset(row - 1) + 1;
                rowValueLabel.setText(String.valueOf(row));
                columnValueLabel.setText(String.valueOf(col));
            }
            catch(Exception ex){
                log.log(Level.SEVERE, "   无法获得当前光标位置 ", ex);
            }
        });
        scrollPane = new RTextScrollPane(textArea);
        this.add(scrollPane, BorderLayout.CENTER);
    }

2.2、右侧webview预览实现

预览区采用javafx.scene.web.WebView,初始化代码如下:

private void initWebView(JFXPanel fxPanel){
        WebView webView = new WebView();

        webEngine = webView.getEngine();
        webEngine.setOnAlert((WebEvent<String> wEvent) -> {
            System.out.println("alert========: " + wEvent.getData());
        });
        webEngine.setOnError((WebErrorEvent wEvent) -> {
            System.out.println("error========: " + wEvent.getMessage());
        });

        String body = "";
        String markdown = textArea.getText();
        if (!StrUtil.isEmpty(markdown)){
            body = Markdown2Html.toHtml(markdown);
        }
        webEngine.loadContent(getHtml(body), "text/html");
        Scene scene = new Scene(new StackPane(webView));

        fxPanel.setScene(scene);
    }

2.3、markdown转html实现

左侧编辑区增加文本变动监听器,使用flexmark-java将Markdown文本转换为HTML,并通过WebView加载。关键步骤包括:

// 监听文本编辑,如果文本内容有更新,则将markdown转为html,并更新webview。
class MdDocumentListener implements DocumentListener {
    public void insertUpdate(DocumentEvent e) {
    }
    public void removeUpdate(DocumentEvent e) {
    }
    public void changedUpdate(DocumentEvent e) {
        String markdown = editor.getTextArea().getText();
        String html = Markdown2Html.toHtml(markdown);
        Platform.runLater(() -> {
            JSObject obj = (JSObject) webEngine.executeScript("window");
            obj.setMember("javaContent", html);
            webEngine.executeScript("addHtml(javaContent)");
        });
    }
}
public class Markdown2Html {
    private static Parser parser = null;
    private static HtmlRenderer renderer = null;
    public static String toHtml(String markdown) {
        MutableDataSet options = new MutableDataSet();
        options.set(Parser.EXTENSIONS, Arrays.asList(
                TablesExtension.create(),
                FootnoteExtension.create(),
                TaskListExtension.create()
        ));
        if (parser == null){
            parser = Parser.builder(options).build();
            renderer = HtmlRenderer.builder(options).build();
        }
        Node document = parser.parse(markdown);
        return renderer.render(document);
    }
}

3、运行效果

3.1、界面展示

启动应用后,界面呈现左右分割布局:左侧为支持语法高亮的文本编辑区,底部显示当前光标所在的行和列位置;右侧为实时渲染的预览区。
在这里插入图片描述
附件实现下载

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

penngo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值