2013-11-25 1 views
8

Так блоки кода можно определить HTML атрибуты, используя fenced_code_blocks расширение:Является ли Pandoc способным вводить произвольные атрибуты 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, за исключением того, что она будет работать для всех элементов, а не только для заголовков.

+0

FWIW, я также считаю, что это (к сожалению) невозможно с pandoc. – mjs

ответ

2

Это очень выполнимо в 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 для деталей.

+0

Принимая это как правильный ответ из-за того, что Pandoc не в состоянии это сделать. Спасибо за предоставление альтернативы! – mart1n

0

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 хранилища.

 Смежные вопросы

  • Нет связанных вопросов^_^