tutorial. 组合tree:subtree与transclude[grove-0002]
subtree命令把一段内容声明为独立的树;transclude命令把那棵树的正文嵌入当前位置。它们保留来源与结构,不是复制粘贴HTML。
定义一段可复用内容[#16]
下面定义一个有稳定ID的subtree:
@subtree[#:id "tree-example"]{
@title{从文本到内容树}
@taxon["definition"]
@paragraph{普通文本先被解析为内容节点,再由页面分析器链接成森林。}
@itemize{
@item{源码:作者编写的 .plant 文件。}
@item{内容树:命令和文本的结构化结果。}
@item{输出:renderer 生成的 HTML 或其他 artifact。}
}
}
@transclude["tree-example"]definition. 从文本到内容树[tree-example]
普通文本先被解析为内容节点,再由页面分析器链接成森林。
- 源码:作者编写的.plant文件。
- 内容树:命令和文本的结构化结果。
- 输出:renderer生成的HTML或其他artifact。
#:id让这个subtree在移动和编辑后仍可被引用。title是subtree必需的直接子节点;它成为这棵树的标题。正文里的paragraph和itemize会一起保留;普通文本与根文档一样按空行自动解码为段落。
上面的定义留在原始页面里;真正的嵌入由transclude命令完成。它按ID查询分析后的森林,并把目标正文放在这里。该subtree同时有独立路由,所以内容仍可直接访问。
嵌入不改变来源[#17]
这是第二次嵌入同一个subtree:
从文本到内容树[tree-example]
普通文本先被解析为内容节点,再由页面分析器链接成森林。
- 源码:作者编写的.plant文件。
- 内容树:命令和文本的结构化结果。
- 输出:renderer生成的HTML或其他artifact。
首页也使用相同方式嵌入了一份页面源码的形状。链接、标题和来源仍属于定义subtree;renderer会为重复嵌入调整HTML锚点,避免重复ID。源文件变化也会使依赖它的页面重新构建。
remark. 为什么显式命名[#18]
普通subtree不必填写#:id:分析器会分配unstable-N形式的临时ID,让它也可以独立打开。这个编号随全站内容的增删与排列可能变化,不应用作长期引用。需要从别处transclude、链接或长期分享时,再指定稳定名字。
Flora为需要长期引用的文章采用短ASCII地址。教程文章使用grove-NNNN、math-NNNN和lp-NNNN前缀;数字部分按base36地址约定分配,不表达阅读顺序。页面地址同时也是对应的源文件名。普通小节继续使用Grove自动分配的临时ID;具名subtree则使用能提示内容的短名称,例如source-shape和tree-example。
共享的Scheme定义放在文档顶层,再把它们的值交给subtree正文;定义的位置不改变生成内容的tree归属。
文档结构统一由tree的嵌套表达。局部组织也使用subtree;需要跨页面引用时,为它指定稳定的ID。标题是tree的属性,显示层级由嵌套深度决定。
用taxon和tag描述页面[#19]
页面元数据也属于可查询的内容。taxon说明这棵tree的种类,例如教程、定义、示例或说明;tag则适合标注主题:
@taxon["tutorial"]
@tag["composition"]{Composition} Flora的taxon只写一个小写英文名称,例如definition,同时用于分类查询与显示。样式将首字母大写,渲染层添加末尾句点。分类置于标题前,也放入目录;同一棵tree被嵌入时保留自己的分类,独立打开时则在主标题上方显示。上面的“从文本到内容树”因此显示为“Definition. 从文本到内容树”。这里不添加章节编号,分类说明的是内容种类而不是阅读顺序。
不必为每棵tree分类:只有种类明确、对阅读有帮助时才添加taxon。它仍是可查询的内容事实;文字外观由项目样式决定。
remark. 每棵tree都有自己的属性[#21]
根文章与subtree使用相同的frontmatter规则。summary、published、updated属于各自的tree;tag和taxon保留为可查询的内容节点。子tree的内容与引用归它自己所有。
@subtree[#:id "named-lemma" #:open? #f]{
@title{一条引理}
@summary{可复用的局部结论。}
@taxon["lemma"]
这是第一段。
这是第二段。
}
@link["named-lemma"]{引用引理}
@transclude["named-lemma"]#:open? #f让展示默认折叠,不改变tree身份。目录按实际展示的嵌套顺序生成;相同tree展示多次时,各次展示拥有不同的局部锚点。