首页 > 解决方案 > 如何处理 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

解决方案


您可能将位置数据视为元数据,但使用块处理器处理它意味着它不是元数据;块在 Asciidoctor 的 AST 中占据一个位置,并预计在输出中占据一个位置;应该在那个位置渲染一些东西。

标题的特殊之处在于它们既定义了节/文档标题的文本,又定义了标题和节的子元素的容器。如果你使用块处理器,它必须跟在标题后面,或者它没有包含在带有标题和其他子元素的容器中。将元素结构从[location ...]块导航到标题部分将比仅使用parent.

如果位置数据是真正的元数据,因为您不希望在[location ...]存在的地方呈现任何内容,您可能会考虑将您的逻辑实现为预处理器,它可以从源代码行中的注释中读取位置信息。

使用预处理器方法解析注释的一个优点是,任何使用您的 Asciidoctor 源的人都会看到相同的渲染(除了 CSS),无论他们是否安装/激活了您的扩展。


推荐阅读