Pandoc's filters cho phép bạn vận hành trên đại diện nội bộ của Pandoc về tài liệu. Có thể có một chuỗi các bộ lọc thực hiện các phép biến đổi khác nhau. Tôi sẽ chia sẻ hai ví dụ minh họa về các bộ lọc sẽ giúp ích.
Markdown Mã Blocks
khối Mã trong Pandoc thường có nghĩa là để nhúng danh sách mã nguồn từ ngôn ngữ lập trình, nhưng ở đây chúng tôi đang cố gắng để giải nén cơ thể và giải thích nó như markdown. Thay vì sử dụng các lớp học từ tài liệu đầu vào của bạn như text
và quote
, hãy sử dụng lớp học chung as-markdown
. Pandoc sẽ tự động tạo các thẻ thích hợp.
Để đảm bảo khối mã mà không có lớp as-markdown
được giải thích như thường lệ, tôi bao gồm một khối haskell
mã. Dưới đây là việc thực hiện lọc:
#!/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
Chạy pandoc --filter markdown-code-block.hs index.md
sản xuất:
<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>
Hầu hết đó! Phần duy nhất không hoàn toàn đúng là thuộc tính HTML.
Thuộc tính HTML tùy chỉnh từ Siêu dữ liệu khối mã
Bộ lọc sau sẽ giúp bạn bắt đầu. Nó chuyển đổi các khối mã với lớp web-script
thành thẻ HTML <script>
khi định dạng đích là html
hoặc 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
Các data-id=test-123
trong khối cuối cùng của bạn sẽ đi qua trong cặp khóa-giá trị 's _namevals
với loại [(String, String)]
. Tất cả những gì bạn cần làm là refactor script
để hỗ trợ các thẻ tùy ý và cặp khóa-giá trị cho các thuộc tính HTML và chỉ định HTML nào sẽ tạo dựa trên các đầu vào đó. Để xem bản trình bày gốc của tài liệu đầu vào, hãy chạy 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()"]
Nếu bạn muốn chơi xung quanh với một trong các ví dụ này, chúng đều nằm trong kho lưu trữ pandoc-experiments
của tôi.
FWIW, tôi cũng nghĩ rằng điều này là (không may) không thể xảy ra với pandoc. – mjs