Pandoc's filters позволяет управлять внутренним представлением документа Pandoc. Возможно иметь цепочку фильтров, которые выполняют разные преобразования. Я расскажу о двух иллюстративных примерах фильтров, которые должны помочь.
Markdown Код Блоки
Блоки код в Pandoc, как правило, предназначены для встраивания исходного кода списков из языков программирования, но здесь мы пытаемся извлечь тело и интерпретировать его как уценку. Вместо использования классов из вашего входного документа, например text
и quote
, давайте использовать общий класс as-markdown
. Pandoc автоматически создаст соответствующие теги.
Чтобы блоки кода без 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 _ [email protected](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 атрибуты из кода блока метаданных
Следующий фильтр должен помочь вам начать работу. Он преобразует кодовые блоки с классом web-script
в тег HTML <script>
, когда целевой формат равен html
или html5
.
#!/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)) [email protected](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
«s с типом [(String, String)]
. Все, что вам нужно сделать, это refactor 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
хранилища.
FWIW, я также считаю, что это (к сожалению) невозможно с pandoc. – mjs