使用flexmark将Markdown转为HTML
0
最近将网站后台文章编辑器改为Markdown。
直接写Markdown感觉比使用富文本编辑器更好,主要是富文本编辑会多出非常多的标签,编辑不受控制。
使用Markdown转换HTML就比较令人满意了。
但是这里又有一个问题了,就是外链没有加上rel="nofollow"
,我们需要自己实现这个功能,代码如下:
package com.acgist.utils;
import com.vladsch.flexmark.ast.AutoLink;
import com.vladsch.flexmark.ast.Link;
import com.vladsch.flexmark.html.AttributeProvider;
import com.vladsch.flexmark.html.AttributeProviderFactory;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.html.IndependentAttributeProviderFactory;
import com.vladsch.flexmark.html.renderer.AttributablePart;
import com.vladsch.flexmark.html.renderer.LinkResolverContext;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.profiles.pegdown.Extensions;
import com.vladsch.flexmark.profiles.pegdown.PegdownOptionsAdapter;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.data.DataHolder;
import com.vladsch.flexmark.util.data.MutableDataHolder;
import com.vladsch.flexmark.util.html.Attributes;
/**
* Markdown工具
*
* @author acgist
*/
public class MarkdownUtils {
/**
* 本站域名
*/
private static final String SITE_HOST = "acgist.com";
static class LinkRefExtension implements HtmlRenderer.HtmlRendererExtension {
@Override
public void rendererOptions(MutableDataHolder holder) {
}
@Override
public void extend(HtmlRenderer.Builder rendererBuilder, String rendererType) {
rendererBuilder.attributeProviderFactory(LinkRefAttributeProvider.Factory());
}
static LinkRefExtension create() {
return new LinkRefExtension();
}
}
static class LinkRefAttributeProvider implements AttributeProvider {
@Override
public void setAttributes(Node node, AttributablePart part, Attributes attributes) {
if ((node instanceof Link || node instanceof AutoLink) && part == AttributablePart.LINK) {
// 如果非本站地址添加:ref="nofollow"
final var href = attributes.get("href");
if(href != null && href.getValue() != null && !href.getValue().contains(SITE_HOST)) {
attributes.replaceValue("rel", "nofollow");
}
}
}
static AttributeProviderFactory Factory() {
return new IndependentAttributeProviderFactory() {
@Override
public AttributeProvider apply(LinkResolverContext context) {
return new LinkRefAttributeProvider();
}
};
}
}
/**
* <p>Markdown转HTML</p>
* <p>去掉链接自动转换</p>
*/
public static final String toHTML(String markdown) {
final DataHolder holder = PegdownOptionsAdapter.flexmarkOptions(true, Extensions.ALL ^ Extensions.AUTOLINKS, LinkRefExtension.create());
final Parser parser = Parser.builder(holder).build();
final Node document = parser.parse(markdown);
final HtmlRenderer renderer = HtmlRenderer.builder(holder).build();
return renderer.render(document);
}
}
两个静态类实现了扩展,向a
标签里面添加了ref
属性。
Extensions.ALL ^ Extensions.AUTOLINKS
这段代码是去掉自动转换链接的扩展。