【问题标题】:Is Pandoc capable of injecting arbitrary HTML attributes to any elements?Pandoc 是否能够将任意 HTML 属性注入任何元素?
【发布时间】:2013-11-25 18:37:17
【问题描述】:

因此代码块可以使用fenced_code_blocks 扩展来定义 HTML 属性:

~~~~ {#mycode .haskell .numberLines startFrom="100"}
qsort []     = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
               qsort (filter (>= x) xs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

是否可以以某种方式将上述语法用于常规文本块?例如,我想转换以下 Markdown 文本:

# My header

~~~ {.text}
This is regular text. This is regular text.
~~~

~~~ {.quote}
> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
~~~

~~~ {data-id=test-123}
+   Red
+   Green
+   Blue
~~~

变成这样:

<h1 id="my-header">My header</h1>
<p class="text">This is regular text. This is regular text.</p>
<blockquote class="quote">
<p>This is the first level of quoting.</p>
<blockquote>
<p>This is nested blockquote.</p>
</blockquote>
<p>Back to the first level.</p>
</blockquote>
<ul data-id="test-123">
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul>

如果 Pandoc 本身没有这样的支持,是否有可能在 Lua 中创建一个这样的自定义编写器?

编辑:查看sample.lua 自定义编写器,有人知道第35 行的“属性表”是什么吗?以及如何将这些属性传递给特定的 Pandoc 元素?此外,我在上面寻找的功能与 header_extension 扩展非常相似,除了它适用于所有元素,而不仅仅是标题。

【问题讨论】:

  • FWIW,我也认为使用 pandoc (不幸)这是不可能的。
  • 不是 all 元素,而是标题、代码块、图像、链接、div、spans.... 即使是 div 和 spans pandoc 也有原生的 markdown 语法,见:pandoc.org/MANUAL.html#divs-and-spans

标签: html markdown pandoc


【解决方案1】:

这在kramdown中是非常可行的,它将转换以下输入

# My header

This is regular text. This is regular text.
{: .text}

> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
{: .quote}

+   Red
+   Green
+   Blue
{: data-id="test-123"}

<h1 id="my-header">My header</h1>

<p class="text">This is regular text. This is regular text.</p>

<blockquote class="quote">
  <p>This is the first level of quoting.</p>

  <blockquote>
    <p>This is nested blockquote.</p>
  </blockquote>

  <p>Back to the first level.</p>
</blockquote>

<ul data-id="test-123">
  <li>Red</li>
  <li>Green</li>
  <li>Blue</li>
</ul>

详情请参阅attribute list definition section of the syntax

【讨论】:

    【解决方案2】:

    Pandoc's filters 让您可以对文档的 Pandoc 内部表示进行操作。可以有一系列过滤器来进行不同的转换。我将分享两个应该有所帮助的过滤器示例。

    Markdown 代码块

    Pandoc 中的代码块通常用于嵌入来自编程语言的源代码列表,但在这里我们试图提取主体并将其解释为降价。与其使用输入文档中的类,如textquote,不如使用通用的as-markdown 类。 Pandoc 会自动生成合适的标签。

    # My header
    
    ~~~ {.as-markdown}
    This is regular text. This is regular text.
    ~~~
    
    ~~~ {.as-markdown}
    > This is the first level of quoting.
    >
    > > This is nested blockquote.
    >
    > Back to the first level.
    ~~~
    
    ~~~ {.as-markdown data-id=test-123}
    +   Red
    +   Green
    +   Blue
    ~~~
    
    ~~~ haskell
    main :: IO ()
    ~~~
    

    为了确保没有as-markdown 类的代码块能像往常一样被解释,我包含了一个haskell 代码块。这是过滤器的实现:

    #!/usr/bin/env runhaskell
    import Text.Pandoc.Definition       (Pandoc(..), Block(..), Format(..))
    import Text.Pandoc.Error            (handleError)
    import Text.Pandoc.JSON             (toJSONFilter)
    import Text.Pandoc.Options          (def)
    import Text.Pandoc.Readers.Markdown (readMarkdown)
    
    asMarkdown :: String -> [Block]
    asMarkdown contents =
      case handleError $ readMarkdown def contents of
        Pandoc _ blocks -> blocks
    
    -- | Unwrap each CodeBlock with the "as-markdown" class, interpreting
    -- its contents as Markdown.
    markdownCodeBlock :: Maybe Format -> Block -> IO [Block]
    markdownCodeBlock _ cb@(CodeBlock (_id, classes, _namevals) contents) =
      if "as-markdown" `elem` classes then
        return $ asMarkdown contents
      else
        return [cb]
    markdownCodeBlock _ x = return [x]
    
    main :: IO ()
    main = toJSONFilter markdownCodeBlock
    

    运行pandoc --filter markdown-code-block.hs index.md 产生:

    <h1 id="my-header">My header</h1>
    <p>This is regular text. This is regular text.</p>
    <blockquote>
    <p>This is the first level of quoting.</p>
    <blockquote>
    <p>This is nested blockquote.</p>
    </blockquote>
    <p>Back to the first level.</p>
    </blockquote>
    <ul>
    <li>Red</li>
    <li>Green</li>
    <li>Blue</li>
    </ul>
    <div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">main ::</span> <span class="dt">IO</span> ()</code></pre></div>
    

    快到了!唯一不完全正确的部分是 HTML 属性。

    来自代码块元数据的自定义 HTML 属性

    以下过滤器应该可以帮助您入门。当目标格式为htmlhtml5 时,它将带有web-script 类的代码块转换为HTML &lt;script&gt; 标签。

    #!/usr/bin/env runhaskell
    import Text.Pandoc.Builder
    import Text.Pandoc.JSON
    
    webFormats :: [String]
    webFormats =
      [ "html"
      , "html5"
      ]
    
    script :: String -> Block
    script src = Para $ toList $ rawInline "html" ("<script type='application/javascript'>" <> src <> "</script>")
    
    injectScript :: Maybe Format -> Block -> IO Block
    injectScript (Just (Format format)) cb@(CodeBlock (_id, classes, _namevals) contents) =
      if "web-script" `elem` classes then
        if format `elem` webFormats then
          return $ script contents
        else
          return Null
      else
        return cb
    injectScript _ x = return x
    
    main :: IO ()
    main = toJSONFilter injectScript
    

    最后一个块中的data-id=test-123 将出现在_namevals 的键值对中,类型为[(String, String)]。您需要做的就是重构 script 以支持 HTML 属性的任意标签和键值对,并根据这些输入指定要生成的 HTML。要查看输入文档的本机表示,请运行 pandoc -t native index.md

    [Header 1 ("my-header",[],[]) [Str "My",Space,Str "header"]
    ,CodeBlock ("",["as-markdown"],[]) "This is regular text. This is regular text."
    ,CodeBlock ("",["as-markdown"],[]) "> This is the first level of quoting.\n>\n> > This is nested blockquote.\n>\n> Back to the first level."
    ,CodeBlock ("",["as-markdown"],[("data-id","test-123")]) "+   Red\n+   Green\n+   Blue"
    ,Para [Str "To",Space,Str "ensure",Space,Str "regular",Space,Str "code",Space,Str "blocks",Space,Str "work",Space,Str "as",Space,Str "usual."]
    ,CodeBlock ("",["haskell"],[]) "main :: IO ()"]
    

    如果您想尝试这些示例中的任何一个,它们都在我的 pandoc-experiments 存储库中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多