mirror of
https://github.com/jgm/pandoc.git
synced 2026-08-28 17:20:47 +08:00
@@ -52,13 +52,15 @@ import Network.HTTP (urlEncode)
|
||||
import Text.XML.Light
|
||||
import qualified Text.XML.Light as X
|
||||
import qualified Text.XML.Light.Cursor as XC
|
||||
import qualified Text.XML.Light.Input as XI
|
||||
|
||||
import Text.Pandoc.Class (PandocMonad, report)
|
||||
import qualified Text.Pandoc.Class as P
|
||||
import Text.Pandoc.Definition
|
||||
import Text.Pandoc.Logging
|
||||
import Text.Pandoc.Options (HTMLMathMethod (..), WriterOptions (..), def)
|
||||
import Text.Pandoc.Shared (capitalize, isHeaderBlock, isURI, orderedListMarkers)
|
||||
import Text.Pandoc.Shared (capitalize, isURI, orderedListMarkers, hierarchicalize)
|
||||
import qualified Text.Pandoc.Shared as Shared (Element(Blk, Sec))
|
||||
|
||||
-- | Data to be written at the end of the document:
|
||||
-- (foot)notes, URLs, references, images.
|
||||
@@ -177,20 +179,28 @@ docdate meta' = do
|
||||
-- representation.
|
||||
renderSections :: PandocMonad m => Int -> [Block] -> FBM m [Content]
|
||||
renderSections level blocks = do
|
||||
let secs = splitSections level blocks
|
||||
mapM (renderSection level) secs
|
||||
let elements = hierarchicalize blocks
|
||||
let isSection Shared.Sec{} = True
|
||||
isSection _ = False
|
||||
let (initialBlocks, secs) = break isSection elements
|
||||
let elements' = if null initialBlocks
|
||||
then secs
|
||||
else Shared.Sec 1 [] nullAttr mempty initialBlocks : secs
|
||||
cMapM (renderSection level) elements'
|
||||
|
||||
renderSection :: PandocMonad m => Int -> ([Inline], [Block]) -> FBM m Content
|
||||
renderSection level (ttl, body) = do
|
||||
title <- if null ttl
|
||||
|
||||
|
||||
renderSection :: PandocMonad m => Int -> Shared.Element -> FBM m [Content]
|
||||
renderSection _ (Shared.Blk block) = blockToXml block
|
||||
renderSection lvl (Shared.Sec _ _num (id',_,_) title elements) = do
|
||||
content <- cMapM (renderSection (lvl + 1)) elements
|
||||
title' <- if null title
|
||||
then return []
|
||||
else list . el "title" <$> formatTitle ttl
|
||||
content <- if hasSubsections body
|
||||
then renderSections (level + 1) body
|
||||
else cMapM blockToXml body
|
||||
return $ el "section" (title ++ content)
|
||||
where
|
||||
hasSubsections = any isHeaderBlock
|
||||
else list . el "title" <$> formatTitle title
|
||||
let sectionContent = if null id'
|
||||
then el "section" (title' ++ content)
|
||||
else el "section" ([uattr "id" id'], (title' ++ content))
|
||||
return $ [sectionContent]
|
||||
|
||||
-- | Only <p> and <empty-line> are allowed within <title> in FB2.
|
||||
formatTitle :: PandocMonad m => [Inline] -> FBM m [Content]
|
||||
@@ -206,24 +216,6 @@ isLineBreak :: Inline -> Bool
|
||||
isLineBreak LineBreak = True
|
||||
isLineBreak _ = False
|
||||
|
||||
-- | Divide the stream of block elements into sections: [(title, blocks)].
|
||||
splitSections :: Int -> [Block] -> [([Inline], [Block])]
|
||||
splitSections level blocks = reverse $ revSplit (reverse blocks)
|
||||
where
|
||||
revSplit [] = []
|
||||
revSplit rblocks =
|
||||
let (lastsec, before) = break sameLevel rblocks
|
||||
(header, prevblocks) =
|
||||
case before of
|
||||
(Header n _ title:prevblocks') ->
|
||||
if n == level
|
||||
then (title, prevblocks')
|
||||
else ([], before)
|
||||
_ -> ([], before)
|
||||
in (header, reverse lastsec) : revSplit prevblocks
|
||||
sameLevel (Header n _ _) = n == level
|
||||
sameLevel _ = False
|
||||
|
||||
-- | Make another FictionBook body with footnotes.
|
||||
renderFootnotes :: PandocMonad m => FBM m [Content]
|
||||
renderFootnotes = do
|
||||
@@ -325,9 +317,10 @@ blockToXml (Para [Image atr alt (src,'f':'i':'g':':':tit)]) =
|
||||
blockToXml (Para ss) = (list . el "p") <$> cMapM toXml ss
|
||||
blockToXml (CodeBlock _ s) = return . spaceBeforeAfter .
|
||||
map (el "p" . el "code") . lines $ s
|
||||
blockToXml b@(RawBlock _ _) = do
|
||||
report $ BlockNotRendered b
|
||||
return []
|
||||
blockToXml (RawBlock f str) = do
|
||||
if f == Format "fb2"
|
||||
then return $ XI.parseXML str
|
||||
else return []
|
||||
blockToXml (Div _ bs) = cMapM blockToXml bs
|
||||
blockToXml (BlockQuote bs) = (list . el "cite") <$> cMapM blockToXml bs
|
||||
blockToXml (LineBlock lns) =
|
||||
|
||||
+3
-3
@@ -12,15 +12,15 @@
|
||||
<title>
|
||||
<p />
|
||||
</title>
|
||||
<section>
|
||||
<section id="top-level-title">
|
||||
<title>
|
||||
<p>Top-level title</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="section">
|
||||
<title>
|
||||
<p>Section</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="subsection">
|
||||
<title>
|
||||
<p>Subsection</p>
|
||||
</title>
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>unrecognised</genre></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p /></title><section><title><p>Simple title</p></title><p>This example tests FictionBook titles.</p></section><section><title><p><emphasis>Emphasized</emphasis> <strong>Strong</strong> Title</p></title></section></body></FictionBook>
|
||||
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>unrecognised</genre></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p /></title><section id="simple-title"><title><p>Simple title</p></title><p>This example tests FictionBook titles.</p></section><section id="emphasized-strong-title"><title><p><emphasis>Emphasized</emphasis> <strong>Strong</strong> Title</p></title></section></body></FictionBook>
|
||||
|
||||
|
||||
+31
-31
@@ -26,25 +26,25 @@
|
||||
John Gruber’s markdown test suite.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="headers">
|
||||
<title>
|
||||
<p>Headers</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="level-2-with-an-embedded-link">
|
||||
<title>
|
||||
<p>Level 2 with an <a l:href="/url">embedded link</a>
|
||||
</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="level-3-with-emphasis">
|
||||
<title>
|
||||
<p>Level 3 with <emphasis>emphasis</emphasis>
|
||||
</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="level-4">
|
||||
<title>
|
||||
<p>Level 4</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="level-5">
|
||||
<title>
|
||||
<p>Level 5</p>
|
||||
</title>
|
||||
@@ -53,23 +53,23 @@ John Gruber’s markdown test suite.</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section id="level-1">
|
||||
<title>
|
||||
<p>Level 1</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="level-2-with-emphasis">
|
||||
<title>
|
||||
<p>Level 2 with <emphasis>emphasis</emphasis>
|
||||
</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="level-3">
|
||||
<title>
|
||||
<p>Level 3</p>
|
||||
</title>
|
||||
<p>with no blank line</p>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section id="level-2">
|
||||
<title>
|
||||
<p>Level 2</p>
|
||||
</title>
|
||||
@@ -77,7 +77,7 @@ John Gruber’s markdown test suite.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section id="paragraphs">
|
||||
<title>
|
||||
<p>Paragraphs</p>
|
||||
</title>
|
||||
@@ -93,7 +93,7 @@ list item.</p>
|
||||
here.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="block-quotes">
|
||||
<title>
|
||||
<p>Block Quotes</p>
|
||||
</title>
|
||||
@@ -131,7 +131,7 @@ It is pretty short.</p>
|
||||
<p>And a following paragraph.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="code-blocks">
|
||||
<title>
|
||||
<p>Code Blocks</p>
|
||||
</title>
|
||||
@@ -176,11 +176,11 @@ It is pretty short.</p>
|
||||
<empty-line />
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="lists">
|
||||
<title>
|
||||
<p>Lists</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="unordered">
|
||||
<title>
|
||||
<p>Unordered</p>
|
||||
</title>
|
||||
@@ -218,7 +218,7 @@ It is pretty short.</p>
|
||||
<p>• Minus 3</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="ordered">
|
||||
<title>
|
||||
<p>Ordered</p>
|
||||
</title>
|
||||
@@ -255,7 +255,7 @@ back.</p>
|
||||
<p>3. Item 3.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="nested">
|
||||
<title>
|
||||
<p>Nested</p>
|
||||
</title>
|
||||
@@ -280,7 +280,7 @@ back.</p>
|
||||
<p>3. Third</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="tabs-and-spaces">
|
||||
<title>
|
||||
<p>Tabs and spaces</p>
|
||||
</title>
|
||||
@@ -297,7 +297,7 @@ indented with tabs</p>
|
||||
indented with spaces</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="fancy-list-markers">
|
||||
<title>
|
||||
<p>Fancy list markers</p>
|
||||
</title>
|
||||
@@ -326,7 +326,7 @@ starting with 4</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section id="definition-lists">
|
||||
<title>
|
||||
<p>Definition Lists</p>
|
||||
</title>
|
||||
@@ -440,7 +440,7 @@ crisp, pleasant to taste</p>
|
||||
<p>1. sublist</p>
|
||||
<p>2. sublist</p>
|
||||
</section>
|
||||
<section>
|
||||
<section id="html-blocks">
|
||||
<title>
|
||||
<p>HTML Blocks</p>
|
||||
</title>
|
||||
@@ -484,7 +484,7 @@ crisp, pleasant to taste</p>
|
||||
<p>Hr’s:</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="inline-markup">
|
||||
<title>
|
||||
<p>Inline Markup</p>
|
||||
</title>
|
||||
@@ -521,7 +521,7 @@ crisp, pleasant to taste</p>
|
||||
because of the unescaped spaces: a^b c^d, a~b c~d.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="smart-quotes-ellipses-dashes">
|
||||
<title>
|
||||
<p>Smart quotes, ellipses, dashes</p>
|
||||
</title>
|
||||
@@ -537,7 +537,7 @@ So is ‘pine.’</p>
|
||||
<p>Ellipses…and…and….</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="latex">
|
||||
<title>
|
||||
<p>LaTeX</p>
|
||||
</title>
|
||||
@@ -564,7 +564,7 @@ So is ‘pine.’</p>
|
||||
<p>Here’s a LaTeX table:</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="special-characters">
|
||||
<title>
|
||||
<p>Special Characters</p>
|
||||
</title>
|
||||
@@ -597,11 +597,11 @@ So is ‘pine.’</p>
|
||||
<p>Minus: -</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="links">
|
||||
<title>
|
||||
<p>Links</p>
|
||||
</title>
|
||||
<section>
|
||||
<section id="explicit">
|
||||
<title>
|
||||
<p>Explicit</p>
|
||||
</title>
|
||||
@@ -627,7 +627,7 @@ So is ‘pine.’</p>
|
||||
<p>
|
||||
<a l:href="">Empty</a>.</p>
|
||||
</section>
|
||||
<section>
|
||||
<section id="reference">
|
||||
<title>
|
||||
<p>Reference</p>
|
||||
</title>
|
||||
@@ -647,7 +647,7 @@ So is ‘pine.’</p>
|
||||
<p>Foo <a l:href="/url/">bar</a>.</p>
|
||||
<p>Foo <a l:href="/url/">biz</a>.</p>
|
||||
</section>
|
||||
<section>
|
||||
<section id="with-ampersands">
|
||||
<title>
|
||||
<p>With ampersands</p>
|
||||
</title>
|
||||
@@ -656,7 +656,7 @@ So is ‘pine.’</p>
|
||||
<p>Here’s an <a l:href="/script?foo=1&bar=2">inline link</a>.</p>
|
||||
<p>Here’s an <a l:href="/script?foo=1&bar=2">inline link in pointy braces</a>.</p>
|
||||
</section>
|
||||
<section>
|
||||
<section id="autolinks">
|
||||
<title>
|
||||
<p>Autolinks</p>
|
||||
</title>
|
||||
@@ -682,7 +682,7 @@ So is ‘pine.’</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section id="images">
|
||||
<title>
|
||||
<p>Images</p>
|
||||
</title>
|
||||
@@ -691,7 +691,7 @@ So is ‘pine.’</p>
|
||||
<p>Here is a movie <image l:href="#image2" l:type="inlineImageType" alt="movie" /> icon.</p>
|
||||
<empty-line />
|
||||
</section>
|
||||
<section>
|
||||
<section id="footnotes">
|
||||
<title>
|
||||
<p>Footnotes</p>
|
||||
</title>
|
||||
|
||||
Reference in New Issue
Block a user