使用Pandoc格式化div

时间:2018-08-04 21:13:45

标签: html5 markdown pandoc

我正在使用Pandoc将Pandoc Markdown文档转换为HTML5文档。在md输入中,我使用special Pandoc syntax编写自定义div,例如:

::: Resources
A nice document
Informative website
:::

结果HTML是这样的:

<div class="Resources">
    <p>A nice document Informative website</p>
</div>

我希望输出改为这样:

<div class="Resources">
    <div>A nice document</div>      
    <div>Informative website</div>
</div>

即。我希望两个资源位于两个不同的容器中。我没有找到任何解决方案(pandoc filters可以,但我不太了解如何编写它们)。

非常感谢您提供任何帮助。干杯。

1 个答案:

答案 0 :(得分:1)

如果主要目标是拥有单独的 Resource 块,我建议在div内使用list

::: Resources
- A nice document
- Informative website
:::

这将给

<div class="Resources">
<ul>
<li>A nice document</li>
<li>Informative website</li>
</ul>
</div>

这还不是您想要的,但是可以让我们半途而废。它已经将所有资源标记为单独的块。这简化了我们通过过滤进一步优化文档结构的任务。以下使用pandoc的Lua过滤器功能;将代码放入文件中,然后通过--lua-filter命令行参数将其传递给pandoc。

local list_to_resources = {
  BulletList = function (el)
    local resources = {}
    local resource_attr = pandoc.Attr('', {'Resource'}, {})
    for i, item in ipairs(el.content) do
      resources[i] = pandoc.Div(item, resource_attr)
    end
    return resources
  end
}

function Div (el)
  -- return div unaltered unless it is of class "Resources"
  if not el.classes:includes'Resources' then
    return nil
  end
  return pandoc.walk_block(el, list_to_resources)
end

使用此过滤器调用pandoc将产生所需的输出:

<div class="Resources">
<div class="Resource">
A nice document
</div>
<div class="Resource">
Informative website
</div>
</div>

为了完整起见,我还将在字面意义上为问题添加解决方案。但是,出于各种原因,我不建议您使用它:

  1. 这远不如“降价促销”。在Markdown中,仅使用换行符来分隔项目并不常见,这违背了其具有可读性好而又不出意外的哲学。
  2. 必要的代码更加复杂易碎。
  3. 您将无法向资源 div添加其他信息,因为该信息将始终由过滤器处理。在以前的解决方案中,只有项目符号列表才具有特殊含义。

话虽如此,下面是代码:

-- table to collect elements in a line
local elements_in_line = {}

-- produce a span from the collected elements
local function line_as_span()
  local span = pandoc.Span(elements_in_line)
  elements_in_line = {}
  return span
end

local lines_to_blocks = {
  Inline = function (el)
    print(el.t)
    if el.t == 'SoftBreak' then
      return line_as_span()
    end
    table.insert(elements_in_line, el)
    return {}
  end,

  Para = function (el)
    local resources = {}
    local content = el.content
    -- last line is not followed by SoftBreak, add it here
    table.insert(content, line_as_span())
    local attr = pandoc.Attr('', {'Resource'})
    for i, line in ipairs(content) do
      resources[i] = pandoc.Div(pandoc.Plain(line.content), attr)
    end
    return resources
  end
}

function Div (el)
  -- return div unaltered unless it is of class "Resources"
  if not el.classes:includes'Resources' then
    return nil
  end
  return pandoc.walk_block(el, lines_to_blocks)
end