asciidoctor - 如何处理 asciidoctor 中标题的元数据?
问题描述
我正在使用 asciidoctor 为我家乡即将举行的活动生成一个静态站点,并且我们为外地客人提供了酒店和名胜古迹的列表。每个地点在地图上都有一个位置、一个类型(酒店、餐厅等)以及他们是否是活动的赞助商。
我已经阅读了有关块处理器的文档,这似乎是最好的方法,但我不知道如何用可以以这种方式处理的元数据来标记标题。
目前,我们对文档中的每个位置都有这样的描述
== Locations
[[Fancy_Hotel]]
=== Fancy Hotel
[location, 55, 73, hotel, sponsor]
A nice hotel in the middle of town
[[Chain_Restaurant]]
=== Chain Breakfast Restaurant
[location, 98, 16, restaurant]
A good place for food
我在构建页面时读取了元数据,然后使用导航到相应条目的可点击链接填充地图。以下代码有效,但如果可能的话,我想将元数据移动到标题上方,所以我不会如此积极地依赖父级。
require 'asciidoctor'
require 'asciidoctor/extensions'
$Locations = Array.new
def make_map_svg locs
# Do some magic here
locs.each {|a| puts a}
end
class LocationBlock < Asciidoctor::Extensions::BlockProcessor
use_dsl
named :location
on_context :paragraph
name_positional_attributes ['x', 'y', 'type', 'sponsor']
def process parent, reader, attrs
x = ((attrs.delete 'x') || 0).to_i
y = ((attrs.delete 'y') || 0).to_i
type = attrs.delete 'type'
sponsor = (attrs.delete 'sponsor') == 'sponsor'
$Locations.push({
x:x,
y:y,
type:type,
sponsor:sponsor,
title:parent.title,
parent.id
})
create_paragraph parent, reader.lines, attrs, {}
end
end
Asciidoctor::Extensions.register do
block LocationBlock
end
Asciidoctor.convert_file "./Locations.adoc"
make_map_svg $Locations
make_map_svg 函数工作正常,问题是弄清楚如何使元数据条目不那么骇人听闻。
解决方案
您可能将位置数据视为元数据,但使用块处理器处理它意味着它不是元数据;块在 Asciidoctor 的 AST 中占据一个位置,并预计在输出中占据一个位置;应该在那个位置渲染一些东西。
标题的特殊之处在于它们既定义了节/文档标题的文本,又定义了标题和节的子元素的容器。如果你使用块处理器,它必须跟在标题后面,或者它没有包含在带有标题和其他子元素的容器中。将元素结构从[location ...]
块导航到标题部分将比仅使用parent
.
如果位置数据是真正的元数据,因为您不希望在[location ...]
存在的地方呈现任何内容,您可能会考虑将您的逻辑实现为预处理器,它可以从源代码行中的注释中读取位置信息。
使用预处理器方法解析注释的一个优点是,任何使用您的 Asciidoctor 源的人都会看到相同的渲染(除了 CSS),无论他们是否安装/激活了您的扩展。