facebook / fbmarkdown
Hack 的 Markdown 解析器和渲染器
Requires
- hhvm: ^4.128
- hhvm/type-assert: ^3.1|^4.0
Requires (Dev)
- facebook/fbexpect: ^2.1.0
- hhvm/hacktest: ^2.0
- hhvm/hhast: ^4.0
- hhvm/hhvm-autoload: ^2.0|^3.0
README
FBMarkdown 是一个可扩展的 GitHub Flavored Markdown 解析器和渲染器,使用 Hack 编写。
它用于渲染 Hack 和 HHVM 文档。
为什么还需要另一个 Markdown 库?
对于 docs.hhvm.com,我们希望
- 拥有 GitHub Flavored Markdown 的熟悉度
- 支持自定义扩展
最初,Ruby GFM 管道是最合适的选择;随着时间的推移,我们开始希望
- 使向 docs.hhvm.com 贡献变得更简单、更快
- 移除 Ruby 依赖,以便在其他 Hack 项目中渲染 Markdown
- 在渲染前生成和修改 AST
- 支持多种渲染
FBMarkdown 的存在就是为了实现所有这些目标。
要求
- HHVM 3.24 或更高版本。
- hhvm-autoload
安装 FBMarkdown
hhvm composer.phar require facebook/fbmarkdown
使用 FBMarkdown
use namespace Facebook\Markdown; function render(string $markdown): string { $ast = Markdown\parse(new Markdown\ParserContext(), $markdown); $html = (new Markdown\HTMLRenderer( new Markdown\RenderContext() ))->render($ast); return $html; }
FBMarkdown 目前支持三种类型的 Markdown 源,计划扩展:受信任的、赞助的以及用户生成的内容。
-
受信任内容模式:启用嵌入式 HTML,并启用所有 URI 方案,并将它们解析为链接。此外,所有图片都按正常方式处理。
-
赞助模式:启用 HTML 渲染,但仅限于允许的标签(由
TagFilterExtension
定义,基于 GFM 规范)。此外,URI 限制为http
、https
、irc
和mailto
方案,并为所有链接添加rel="nofollow ugc"
。 -
用户生成内容:禁用所有 HTML,包括链接和图片(无论方案如何)。如果重新启用链接,则所有链接将添加
rel="nofollow ugc"
。
要更改这些默认设置
- 您可以通过调用解析器函数
setAllowedURISchemes()
来更改允许的 URI 方案的键集。 - 您可以通过调用解析器函数
enableHTML_UNSAFE()
来启用嵌入式 HTML。**注意**:为了与 GitHub Flavored Markdown 完全兼容,必须启用嵌入式 HTML。 - 您可以通过调用渲染器函数
disableImageFiltering()
来禁用图片过滤。 - 您可以通过调用渲染器函数
addNoFollowUGCAllLinks()
来为所有链接添加rel="nofollow ugc"
。
如果您正在重复使用上下文以渲染多个独立的片段,则需要调用上下文的 resetFileData()
。
FBMarkdown 的工作方式
解析
Facebook\Markdown\UnparsedBlocks
命名空间中的类将 Markdown 文本转换为表示文档块结构的节点树,但块的内部内容未解析。- 块(内联)的内容使用
Facebook\Markdown\Inlines
命名空间中的类进行解析。 - 最后,使用
Facebook\Markdown\Blocks
命名空间中的类来表示完全解析的AST - 块和内联。
渲染
递归遍历AST,为每个笔记输出内容,例如HTML渲染器产生字符串。
扩展FBMarkdown
扩展FBMarkdown主要有两种方式:扩展解析器和转换AST。
扩展解析器
内联
扩展Facebook\Markdown\Inlines\Inline
或其子类,并将类名传递给$render_ctx->getInlineContext()->prependInlineTypes(...)
。
然后有几种渲染方法
- 实例化子类,并将其支持添加到自定义渲染器
- 实例化子类,并使其实现
Facebook\Markdown\RenderableAsHTML
接口 - 如果可以替换为多个现有的内联元素,返回一个
Facebook\Markdown\Inlines\InlineSequence
,那么您就不需要扩展渲染器。
块
需要实现Facebook\Markdown\UnparsedBlocks\BlockProducer
接口,并将类名传递给$render_ctx->getBlockContext()->prependBlockTypes(...)
。
然后有几种渲染方法
- 创建
Block
的子类,并将其支持添加到自定义渲染器 - 创建
Block
的子类,并使其实现Facebook\Markdown\RenderableAsHTML
接口 - 如果它可以替换为多个现有的块,返回一个
Facebook\Markdown\Blocks\BlockSequence
- 如果它可以替换为内联元素的段落,返回一个
Facebook\Markdown\Blocks\InlineSequenceBlock
转换AST
扩展Facebook\Markdown\RenderFilter
,并将其传递给$render_ctx->appendFilters(...)
。
示例
Hack和HHVM文档使用了这些方法中的大部分;见
许可证
FBMarkdown采用MIT许可证。
FBMarkdown可能包含第三方软件;有关详细信息,请参阅third_party_notices.txt。