Change commonmark to flexmark.

pull/235/head
ruibaby 2019-06-27 23:29:54 +08:00
parent 1a3fb94151
commit ab069efefd
6 changed files with 96 additions and 133 deletions

View File

@ -55,13 +55,6 @@ dependencies {
implementation 'com.qiniu:qiniu-java-sdk:7.2.18' implementation 'com.qiniu:qiniu-java-sdk:7.2.18'
implementation 'com.aliyun.oss:aliyun-sdk-oss:3.4.2' implementation 'com.aliyun.oss:aliyun-sdk-oss:3.4.2'
implementation 'net.coobird:thumbnailator:0.4.8' implementation 'net.coobird:thumbnailator:0.4.8'
implementation 'com.atlassian.commonmark:commonmark:0.12.1'
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.12.1'
implementation 'com.atlassian.commonmark:commonmark-ext-yaml-front-matter:0.12.1'
implementation 'com.atlassian.commonmark:commonmark-ext-autolink:0.12.1'
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:0.12.1'
implementation 'com.atlassian.commonmark:commonmark-ext-heading-anchor:0.12.1'
implementation 'com.atlassian.commonmark:commonmark-ext-ins:0.12.1'
implementation 'io.springfox:springfox-swagger2:2.9.2' implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2' implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'org.apache.commons:commons-lang3:3.8.1' implementation 'org.apache.commons:commons-lang3:3.8.1'
@ -69,6 +62,20 @@ dependencies {
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.2' implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.2'
implementation 'org.eclipse.jgit:org.eclipse.jgit:5.3.0.201903130848-r' implementation 'org.eclipse.jgit:org.eclipse.jgit:5.3.0.201903130848-r'
implementation 'com.vladsch.flexmark:flexmark:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-attributes:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-autolink:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-emoji:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-escaped-character:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-ins:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-media-tags:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-tables:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-toc:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-ext-yaml-front-matter:0.42.12'
implementation 'com.vladsch.flexmark:flexmark-html-parser:0.42.12'
runtimeOnly 'com.h2database:h2' runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java' runtimeOnly 'mysql:mysql-connector-java'

View File

@ -5,7 +5,6 @@ import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import run.halo.app.model.enums.PostCreateFrom; import run.halo.app.model.enums.PostCreateFrom;
import run.halo.app.model.enums.PostStatus; import run.halo.app.model.enums.PostStatus;
import run.halo.app.utils.MarkdownUtils;
import javax.persistence.*; import javax.persistence.*;
import java.util.Date; import java.util.Date;
@ -54,7 +53,7 @@ public class BasePost extends BaseEntity {
/** /**
* Rendered content. * Rendered content.
* *
* @see MarkdownUtils#renderMarkdown(String) * @see run.halo.app.utils.MarkdownUtils#renderHtml(String)
*/ */
@Column(name = "format_content", columnDefinition = "text not null") @Column(name = "format_content", columnDefinition = "text not null")
private String formatContent; private String formatContent;

View File

@ -212,7 +212,7 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
Assert.notNull(post, "Post must not be null"); Assert.notNull(post, "Post must not be null");
// Render content // Render content
post.setFormatContent(MarkdownUtils.renderMarkdown(post.getOriginalContent())); post.setFormatContent(MarkdownUtils.renderHtml(post.getOriginalContent()));
// Create or update post // Create or update post
if (ServiceUtils.isEmptyId(post.getId())) { if (ServiceUtils.isEmptyId(post.getId())) {
@ -275,7 +275,7 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
// Set summary // Set summary
if (StringUtils.isBlank(basePostSimpleDTO.getSummary())) { if (StringUtils.isBlank(basePostSimpleDTO.getSummary())) {
basePostSimpleDTO.setSummary(convertToSummary(post.getOriginalContent())); // TODO build post summary
} }
return basePostSimpleDTO; return basePostSimpleDTO;
@ -348,14 +348,11 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
@NonNull @NonNull
protected String convertToSummary(@Nullable String markdownContent) { protected String convertToSummary(@Nullable String markdownContent) {
// Render text content
String textContent = MarkdownUtils.renderText(markdownContent);
// Get summary length // Get summary length
Integer summaryLength = optionService.getByPropertyOrDefault(PostProperties.SUMMARY_LENGTH, Integer.class, 150); Integer summaryLength = optionService.getByPropertyOrDefault(PostProperties.SUMMARY_LENGTH, Integer.class, 150);
// Set summary // TODO build summary.
return StringUtils.substring(textContent, 0, summaryLength); return "";
} }
} }

View File

@ -280,7 +280,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
Assert.notNull(markdown, "Markdown document must not be null"); Assert.notNull(markdown, "Markdown document must not be null");
// Render markdown to html document. // Render markdown to html document.
String content = MarkdownUtils.renderMarkdown(markdown); String content = MarkdownUtils.renderHtml(markdown);
// Gets frontMatter // Gets frontMatter
Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown); Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown);
@ -462,8 +462,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
PostListVO postListVO = new PostListVO().convertFrom(post); PostListVO postListVO = new PostListVO().convertFrom(post);
if (StringUtils.isBlank(postListVO.getSummary())) { if (StringUtils.isBlank(postListVO.getSummary())) {
// Set summary // TODO Set summary
postListVO.setSummary(convertToSummary(post.getOriginalContent()));
} }
Optional.ofNullable(tagListMap.get(post.getId())).orElseGet(LinkedList::new); Optional.ofNullable(tagListMap.get(post.getId())).orElseGet(LinkedList::new);

View File

@ -102,11 +102,12 @@ public class SheetServiceImpl extends BasePostServiceImpl<Sheet> implements Shee
Assert.notNull(markdown, "Markdown document must not be null"); Assert.notNull(markdown, "Markdown document must not be null");
// Render markdown to html document. // Render markdown to html document.
String content = MarkdownUtils.renderMarkdown(markdown); String content = MarkdownUtils.renderHtml(markdown);
// Gets frontMatter // Gets frontMatter
Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown); Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown);
// TODO
return null; return null;
} }

View File

@ -1,147 +1,107 @@
package run.halo.app.utils; package run.halo.app.utils;
import com.vladsch.flexmark.convert.html.FlexmarkHtmlParser;
import com.vladsch.flexmark.ext.attributes.AttributesExtension;
import com.vladsch.flexmark.ext.autolink.AutolinkExtension;
import com.vladsch.flexmark.ext.emoji.EmojiExtension;
import com.vladsch.flexmark.ext.emoji.EmojiImageType;
import com.vladsch.flexmark.ext.emoji.EmojiShortcutType;
import com.vladsch.flexmark.ext.escaped.character.EscapedCharacterExtension;
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension;
import com.vladsch.flexmark.ext.ins.InsExtension;
import com.vladsch.flexmark.ext.media.tags.MediaTagsExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.ext.toc.TocExtension;
import com.vladsch.flexmark.ext.yaml.front.matter.AbstractYamlFrontMatterVisitor;
import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.options.DataHolder;
import com.vladsch.flexmark.util.options.MutableDataSet;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.commonmark.Extension;
import org.commonmark.ext.autolink.AutolinkExtension;
import org.commonmark.ext.front.matter.YamlFrontMatterExtension;
import org.commonmark.ext.front.matter.YamlFrontMatterVisitor;
import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
import org.commonmark.ext.ins.InsExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.renderer.text.TextContentRenderer;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import run.halo.app.model.support.HaloConst; import run.halo.app.model.support.HaloConst;
import java.util.Collections; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* Markdown utils * Markdown utils.
* *
* @author ryanwang * @author ryanwang
* @date : 2018/11/14 * @date : 2019/06/27
*/ */
public class MarkdownUtils { public class MarkdownUtils {
private static final DataHolder OPTIONS = new MutableDataSet()
.set(Parser.EXTENSIONS, Arrays.asList(
AttributesExtension.create(),
AutolinkExtension.create(),
EmojiExtension.create(),
EscapedCharacterExtension.create(),
StrikethroughExtension.create(),
TaskListExtension.create(),
InsExtension.create(),
MediaTagsExtension.create(),
TablesExtension.create(),
TocExtension.create(),
YamlFrontMatterExtension.create())
)
.set(TablesExtension.WITH_CAPTION, false)
.set(TablesExtension.COLUMN_SPANS, false)
.set(TablesExtension.MIN_HEADER_ROWS, 1)
.set(TablesExtension.MAX_HEADER_ROWS, 1)
.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
.set(EmojiExtension.USE_SHORTCUT_TYPE, EmojiShortcutType.GITHUB)
.set(EmojiExtension.USE_IMAGE_TYPE, EmojiImageType.IMAGE_ONLY);
/** private static final Parser PARSER = Parser.builder(OPTIONS).build();
* commonmark-java extension for autolinking
*/
private static final Set<Extension> EXTENSIONS_AUTO_LINK = Collections.singleton(AutolinkExtension.create());
/** private static final HtmlRenderer RENDERER = HtmlRenderer.builder(OPTIONS).build();
* commonmark-java extension for strikethrough
*/
private static final Set<Extension> EXTENSIONS_STRIKETHROUGH = Collections.singleton(StrikethroughExtension.create());
/**
* commonmark-java extension for tables
*/
private static final Set<Extension> EXTENSIONS_TABLES = Collections.singleton(TablesExtension.create());
/**
* commonmark-java extension for adding id attributes to h tags
*/
private static final Set<Extension> EXTENSIONS_HEADING_ANCHOR = Collections.singleton(HeadingAnchorExtension.create());
/**
* commonmark-java extension for &lt;ins&gt; (underline)
*/
private static final Set<Extension> EXTENSIONS_INS = Collections.singleton(InsExtension.create());
/**
* commonmark-java extension for YAML front matter
*/
private static final Set<Extension> EXTENSIONS_YAML_FRONT_MATTER = Collections.singleton(YamlFrontMatterExtension.create());
/**
* Parse Markdown content
*/
private static final Parser PARSER = Parser.builder()
.extensions(EXTENSIONS_AUTO_LINK)
.extensions(EXTENSIONS_STRIKETHROUGH)
.extensions(EXTENSIONS_TABLES)
.extensions(EXTENSIONS_HEADING_ANCHOR)
.extensions(EXTENSIONS_INS)
.extensions(EXTENSIONS_YAML_FRONT_MATTER)
.build();
/**
* Render HTML content
*/
private static final HtmlRenderer RENDERER = HtmlRenderer.builder()
.extensions(EXTENSIONS_AUTO_LINK)
.extensions(EXTENSIONS_STRIKETHROUGH)
.extensions(EXTENSIONS_TABLES)
.extensions(EXTENSIONS_HEADING_ANCHOR)
.extensions(EXTENSIONS_INS)
.extensions(EXTENSIONS_YAML_FRONT_MATTER)
.build();
/**
* Render text content
*/
private static final TextContentRenderer TEXT_CONTENT_RENDERER = TextContentRenderer.builder()
.extensions(EXTENSIONS_AUTO_LINK)
.extensions(EXTENSIONS_STRIKETHROUGH)
.extensions(EXTENSIONS_TABLES)
.extensions(EXTENSIONS_HEADING_ANCHOR)
.extensions(EXTENSIONS_INS)
.extensions(EXTENSIONS_YAML_FRONT_MATTER)
.build();
/** /**
* Render Markdown content * Render Markdown content
* *
* @param content content * @param content content
* @return String * @return String
* @see <a href="https://github.com/otale/tale/blob/master/src/main/java/com/tale/utils/TaleUtils.java">TaleUtils.java</a>
*/ */
public static String renderMarkdown(String content) { public static String renderHtml(String markdown) {
if (StringUtils.isBlank(markdown)) {
return "";
}
Node document = PARSER.parse(markdown);
String renderedContent = RENDERER.render(document);
final Node document = PARSER.parse(content); // Render netease music short url.
String renderContent = RENDERER.render(document); if (markdown.contains(HaloConst.NETEASE_MUSIC_PREFIX)) {
renderedContent = markdown.replaceAll(HaloConst.NETEASE_MUSIC_REG_PATTERN, HaloConst.NETEASE_MUSIC_IFRAME);
// render netease music short url
if (content.contains(HaloConst.NETEASE_MUSIC_PREFIX)) {
renderContent = content.replaceAll(HaloConst.NETEASE_MUSIC_REG_PATTERN, HaloConst.NETEASE_MUSIC_IFRAME);
} }
// render bilibili video short url // Render bilibili video short url.
if (content.contains(HaloConst.BILIBILI_VIDEO_PREFIX)) { if (markdown.contains(HaloConst.BILIBILI_VIDEO_PREFIX)) {
renderContent = content.replaceAll(HaloConst.BILIBILI_VIDEO_REG_PATTERN, HaloConst.BILIBILI_VIDEO_IFRAME); renderedContent = markdown.replaceAll(HaloConst.BILIBILI_VIDEO_REG_PATTERN, HaloConst.BILIBILI_VIDEO_IFRAME);
} }
// render youtube video short url // Render youtube video short url.
if (content.contains(HaloConst.YOUTUBE_VIDEO_PREFIX)) { if (markdown.contains(HaloConst.YOUTUBE_VIDEO_PREFIX)) {
renderContent = content.replaceAll(HaloConst.YOUTUBE_VIDEO_REG_PATTERN, HaloConst.YOUTUBE_VIDEO_IFRAME); renderedContent = markdown.replaceAll(HaloConst.YOUTUBE_VIDEO_REG_PATTERN, HaloConst.YOUTUBE_VIDEO_IFRAME);
} }
return renderContent; return renderedContent;
} }
/** /**
* Render text content. * Render html document to markdown document.
* *
* @param markdownContent markdown content * @param html html document
* @return text content or empty string if markdown content is blank * @return markdown document
*/ */
@NonNull public static String renderMarkdown(String html) {
public static String renderText(@Nullable String markdownContent) { return FlexmarkHtmlParser.parse(html);
if (StringUtils.isBlank(markdownContent)) {
return "";
}
return TEXT_CONTENT_RENDERER.render(PARSER.parse(markdownContent));
} }
/** /**
@ -150,10 +110,10 @@ public class MarkdownUtils {
* @param content content * @param content content
* @return Map * @return Map
*/ */
public static Map<String, List<String>> getFrontMatter(String content) { public static Map<String, List<String>> getFrontMatter(String markdown) {
final YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); AbstractYamlFrontMatterVisitor visitor = new AbstractYamlFrontMatterVisitor();
final Node document = PARSER.parse(content); Node document = PARSER.parse(markdown);
document.accept(visitor); visitor.visit(document);
return visitor.getData(); return visitor.getData();
} }
} }