我目前正在Swift中开发一个CommonMark框架。我没有自己编写解析器,而是决定使用Github的cmark分支,即CommonMark的C参考实现。
通过查看使用cmark的其他库和阅读cmark源代码,我找到了使用cmark所需的大部分知识。我不太清楚的一件事是如何为表、删除线、自动链接和标签过滤启用gfm扩展。从我找到的文档来看,这一点并不明显。
经过反复试验和阅读cmark源代码后,我发现有必要首先调用:
core_extensions_ensure_registered()
然后你需要使用以下方法将扩展附加到你的解析器:
cmark_parser_attach_syntax_extension(parser, extension)
为此,您需要使用流接口,而不是简单的cmark_parse_document接口。
如何在Swift中做到这一点的例子:
core_extensions_ensure_registered()
guard let parser = cmark_parser_new(options.rawValue) else {
return
}
defer {
cmark_parser_free(parser)
}
if let tableExtension = cmark_find_syntax_extension("table") {
cmark_parser_attach_syntax_extension(parser, tableExtension)
}
if let autolinkExtension = cmark_find_syntax_extension("autolink") {
cmark_parser_attach_syntax_extension(parser, autolinkExtension)
}
if let extension = cmark_find_syntax_extension("strikethrough") {
cmark_parser_attach_syntax_extension(parser, extension)
}
cmark_parser_feed(parser, text, text.utf8.count)
guard let cmarkNode = cmark_parser_finish(parser) else {
return
}
下面是一个在启用标签过滤扩展的情况下将cmark节点呈现为HTML的示例。这假设您已经在某个时刻调用了core_extensions_ensure_registered()。
var extensions: UnsafeMutablePointer<cmark_llist>? = nil
if let tagfilter = cmark_find_syntax_extension("tagfilter") {
extensions = cmark_llist_append(cmark_get_default_mem_allocator(), nil, tagfilter)
}
guard let buffer = cmark_render_html(cmarkNode, options.rawValue, extensions) else {
return
}
defer {
free(buffer)
}
guard let html = String(validatingUTF8: buffer) else {
return
}
// use the filtered html
我仍然在做我的CommonMark库的第一个版本,但是我有一个Swift兼容的框架可以直接使用cmark-gfm。它与Carthage, CocoaPods和Swift Package Manager一起工作。可以在https://github.com/KristopherGBaker/libcmark_gfm上找到它。
Carthage
github "KristopherGBaker/libcmark_gfm" ~> 0.28.0
CocoaPods
pod 'libcmark_gfm'
网友评论