Java实现富文本转markdown

 更新时间:2023年12月08日 09:06:46   作者:路口lyne  
这篇文章主要为大家详细介绍了如何通过Java实现富文本转markdown功能,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下

实现富文本即html语法转md,要求是尽可能展示效果一样,可以有少许误差,另外只实现了html中的body转md,其他标签如head等未实现。

大致思路是:通过jsoup工具获取html节点,再穷举替换。前提是熟悉html以及md语法

依赖如下:

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.16.1</version>
        </dependency>

代码如下:

import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
 
import java.util.ArrayList;
import java.util.List;
 
public class Html2MarkdownUtil {
 
    public static void main(String[] args) {
        String html = "<p style=\"padding: 0; margin: 10px 0; line-height: 1.5; font-size: 16px;\"><b style=\"padding: 0; margin: 0;\">Hello<font color=\"#c24f4a\" style=\"padding: 0; margin: 0;\">world</font></b></p>";
        System.out.println(parseHtml2Markdown(html));
    }
 
    /**
     * 解析html2md
     *
     * @param html html
     * @return {@link String}
     */
    public static String parseHtml2Markdown(String html) {
        Document doc = Jsoup.parse(html);
        StringBuilder sb = new StringBuilder();
        for (Element element : doc.body().children()) {
            HtmlElement htmlElement = new HtmlElement(element);
            sb.append(htmlElement.getMarkdownText());
        }
        return sb.toString();
    }
 
    /**
     * 标记文本
     *
     * @param element 要素
     * @return {@link String}
     */
    public static String toMarkdownText(Element element) {
        StringBuilder sb = new StringBuilder();
        String tagName = element.tagName().toLowerCase();
        String text = element.ownText();
        switch (tagName) {
            case "h1":
                sb.append("# ").append(text);
                break;
            case "h2":
                sb.append("## ").append(text);
                break;
            case "h3":
                sb.append("### ").append(text);
                break;
            case "h4":
                sb.append("#### ").append(text);
                break;
            case "h5":
                sb.append("##### ").append(text);
                break;
            case "h6":
                sb.append("###### ").append(text);
                break;
            case "p":
            case "font":
            case "b":
            case "span":
                sb.append(text);
                break;
            case "ul":
                for (Element child : element.children()) {
                    sb.append("* ").append(child.text().trim()).append("\n");
                }
                break;
            case "ol":
                int index = 1;
                for (Element child : element.children()) {
                    sb.append(index).append(". ").append(child.text().trim()).append("\n");
                    index++;
                }
                break;
            case "a":
                sb.append("[").append(text).append("](").append(element.attr("href")).append(")");
                break;
            case "strong":
                sb.append("**").append(text).append("**");
                break;
            case "em":
                sb.append("_").append(text).append("_");
                break;
            case "blockquote":
                sb.append("> ").append(text);
                break;
            case "img":
                sb.append("![");
                if (element.hasAttr("alt")) {
                    sb.append(element.attr("alt"));
                }
                sb.append("](").append(element.attr("src")).append(")");
                break;
            default:
                break;
        }
        return sb.toString();
    }
 
    @Data
    public static class HtmlElement {
 
        private Element element;
        private String tagName;
        private String ownText;
        private boolean isNewline;
        private List<HtmlElement> children;
 
        public HtmlElement(Element element) {
            this.element = element;
            this.tagName = element.tagName().toLowerCase();
            this.ownText = element.ownText();
            this.isNewline = isNewline();
            if (!StringUtils.equalsAny(this.tagName, "ul", "ol")) {
                Elements children = element.children();
                if (children.size() > 0) {
                    this.children = new ArrayList<>();
                    for (Element child : children) {
                        this.children.add(new HtmlElement(child));
                    }
                }
            }
        }
 
        public boolean isNewline() {
            return StringUtils.equalsAny(tagName, "h1", "h2", "h3", "h4", "h5", "h6", "p", "ul", "ol", "blockquote");
        }
 
        public String getMarkdownText() {
            StringBuilder sb = new StringBuilder();
            sb.append(toMarkdownText(element));
            if (children != null && children.size() > 0) {
                for (HtmlElement child : children) {
                    sb.append(child.getMarkdownText());
                }
            }
            if (isNewline) {
                sb.append("\n");
            }
            return sb.toString();
        }
    }
}

到此这篇关于Java实现富文本转markdown的文章就介绍到这了,更多相关Java富文本转markdown内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java基础详解之数据类型知识点总结

    java基础详解之数据类型知识点总结

    这篇文章主要介绍了java基础详解之数据类型知识点总结,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有很大的帮助,需要的朋友可以参考下
    2021-04-04
  • Maven dependencyManagement元素标签的具体使用

    Maven dependencyManagement元素标签的具体使用

    在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器,本文主要介绍了Maven dependencyManagement元素标签的具体使用,感兴趣的可以了解一下
    2024-03-03
  • Java基础教程之字符流文件读写

    Java基础教程之字符流文件读写

    这篇文章主要给大家介绍了关于Java基础教程之字符流文件读写的相关资料,,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • Spring Data JPA中的动态查询实例

    Spring Data JPA中的动态查询实例

    本篇文章主要介绍了详解Spring Data JPA中的动态查询。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • JPA之EntityManager踩坑及解决:更改PersistenceContext

    JPA之EntityManager踩坑及解决:更改PersistenceContext

    这篇文章主要介绍了JPA之EntityManager踩坑及解决:更改PersistenceContext方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java TreeSet实现学生按年龄大小和姓名排序的方法示例

    Java TreeSet实现学生按年龄大小和姓名排序的方法示例

    这篇文章主要介绍了Java TreeSet实现学生按年龄大小和姓名排序的方法,涉及java类型转换、遍历、比较等相关操作技巧,需要的朋友可以参考下
    2017-09-09
  • 基于springboot2集成jpa,创建dao的案例

    基于springboot2集成jpa,创建dao的案例

    这篇文章主要介绍了基于springboot2集成jpa,创建dao的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 浅谈springcloud gateway 连接保活问题

    浅谈springcloud gateway 连接保活问题

    这篇文章主要介绍了springcloud gateway 连接保活问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java内存模型及其作用详解

    Java内存模型及其作用详解

    在现代计算机系统中,尤其是多处理器架构下,每个处理器都有自己的高速缓存,而主内存(RAM)是所有处理器共享的数据存储区域,这篇文章主要介绍了深入理解Java内存模型及其作用,需要的朋友可以参考下
    2024-04-04
  • SpringBoot集成jersey打包jar找不到class的处理方法

    SpringBoot集成jersey打包jar找不到class的处理方法

    这篇文章主要介绍了SpringBoot集成jersey打包jar找不到class的处理方法,文中通过代码示例介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-03-03

最新评论