git.iko.soy/typeable/pandoc
on master help sign in
Add section identifiers support for FB2 writer (#5315)

Closes #5229.

commitc75b558cbc2d21cdc4f5fa243b5f900ca7e83bbc authorJohn <46772462+KetzerX@users.noreply.github.com> dateFri 22 Feb 2019, 10:43 (8 years ago) parent69d433d
4 files changed+63−70
src/Text/Pandoc/Writers/FB2.hs+28−35 test/fb2/basic.fb2+3−3 test/fb2/titles.fb2+1−1 test/writer.fb2+31−31
src/Text/Pandoc/Writers/FB2.hs+28−35
@@ -52,13 +52,15 @@ import Network.HTTP (urlEncode)
5252import Text.XML.Light
5353import qualified Text.XML.Light as X
5454import qualified Text.XML.Light.Cursor as XC
55+import qualified Text.XML.Light.Input as XI
5556
5657import Text.Pandoc.Class (PandocMonad, report)
5758import qualified Text.Pandoc.Class as P
5859import Text.Pandoc.Definition
5960import Text.Pandoc.Logging
6061import Text.Pandoc.Options (HTMLMathMethod (..), WriterOptions (..), def)
61−import Text.Pandoc.Shared (capitalize, isHeaderBlock, isURI, orderedListMarkers)
62+import Text.Pandoc.Shared (capitalize, isURI, orderedListMarkers, hierarchicalize)
63+import qualified Text.Pandoc.Shared as Shared (Element(Blk, Sec))
6264
6365-- | Data to be written at the end of the document:
6466-- (foot)notes, URLs, references, images.
@@ -177,20 +179,28 @@ docdate meta' = do
177179-- representation.
178180renderSections :: PandocMonad m => Int -> [Block] -> FBM m [Content]
179181renderSections level blocks = do
180− let secs = splitSections level blocks
181− mapM (renderSection level) secs
182−
183−renderSection :: PandocMonad m => Int -> ([Inline], [Block]) -> FBM m Content
184−renderSection level (ttl, body) = do
185− title <- if null ttl
182+ let elements = hierarchicalize blocks
183+ let isSection Shared.Sec{} = True
184+ isSection _ = False
185+ let (initialBlocks, secs) = break isSection elements
186+ let elements' = if null initialBlocks
187+ then secs
188+ else Shared.Sec 1 [] nullAttr mempty initialBlocks : secs
189+ cMapM (renderSection level) elements'
190+
191+
192+
193+renderSection :: PandocMonad m => Int -> Shared.Element -> FBM m [Content]
194+renderSection _ (Shared.Blk block) = blockToXml block
195+renderSection lvl (Shared.Sec _ _num (id',_,_) title elements) = do
196+ content <- cMapM (renderSection (lvl + 1)) elements
197+ title' <- if null title
186198 then return []
187− else list . el "title" <$> formatTitle ttl
188− content <- if hasSubsections body
189− then renderSections (level + 1) body
190− else cMapM blockToXml body
191− return $ el "section" (title ++ content)
192− where
193− hasSubsections = any isHeaderBlock
199+ else list . el "title" <$> formatTitle title
200+ let sectionContent = if null id'
201+ then el "section" (title' ++ content)
202+ else el "section" ([uattr "id" id'], (title' ++ content))
203+ return $ [sectionContent]
194204
195205-- | Only <p> and <empty-line> are allowed within <title> in FB2.
196206formatTitle :: PandocMonad m => [Inline] -> FBM m [Content]
@@ -206,24 +216,6 @@ isLineBreak :: Inline -> Bool
206216isLineBreak LineBreak = True
207217isLineBreak _ = False
208218
209−-- | Divide the stream of block elements into sections: [(title, blocks)].
210−splitSections :: Int -> [Block] -> [([Inline], [Block])]
211−splitSections level blocks = reverse $ revSplit (reverse blocks)
212− where
213− revSplit [] = []
214− revSplit rblocks =
215− let (lastsec, before) = break sameLevel rblocks
216− (header, prevblocks) =
217− case before of
218− (Header n _ title:prevblocks') ->
219− if n == level
220− then (title, prevblocks')
221− else ([], before)
222− _ -> ([], before)
223− in (header, reverse lastsec) : revSplit prevblocks
224− sameLevel (Header n _ _) = n == level
225− sameLevel _ = False
226−
227219-- | Make another FictionBook body with footnotes.
228220renderFootnotes :: PandocMonad m => FBM m [Content]
229221renderFootnotes = do
@@ -325,9 +317,10 @@ blockToXml (Para [Image atr alt (src,'f':'i':'g':':':tit)]) =
325317blockToXml (Para ss) = (list . el "p") <$> cMapM toXml ss
326318blockToXml (CodeBlock _ s) = return . spaceBeforeAfter .
327319 map (el "p" . el "code") . lines $ s
328−blockToXml b@(RawBlock _ _) = do
329− report $ BlockNotRendered b
330− return []
320+blockToXml (RawBlock f str) = do
321+ if f == Format "fb2"
322+ then return $ XI.parseXML str
323+ else return []
331324blockToXml (Div _ bs) = cMapM blockToXml bs
332325blockToXml (BlockQuote bs) = (list . el "cite") <$> cMapM blockToXml bs
333326blockToXml (LineBlock lns) =
test/fb2/basic.fb2+3−3
@@ -12,15 +12,15 @@
1212<title>
1313<p />
1414</title>
15−<section>
15+<section id="top-level-title">
1616<title>
1717<p>Top-level title</p>
1818</title>
19−<section>
19+<section id="section">
2020<title>
2121<p>Section</p>
2222</title>
23−<section>
23+<section id="subsection">
2424<title>
2525<p>Subsection</p>
2626</title>
test/fb2/titles.fb2+1−1
@@ -1,3 +1,3 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<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>
2+<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>
33
test/writer.fb2+31−31
@@ -26,25 +26,25 @@
2626John Gruber’s markdown test suite.</p>
2727<empty-line />
2828</section>
29−<section>
29+<section id="headers">
3030<title>
3131<p>Headers</p>
3232</title>
33−<section>
33+<section id="level-2-with-an-embedded-link">
3434<title>
3535<p>Level 2 with an <a l:href="/url">embedded link</a>
3636</p>
3737</title>
38−<section>
38+<section id="level-3-with-emphasis">
3939<title>
4040<p>Level 3 with <emphasis>emphasis</emphasis>
4141</p>
4242</title>
43−<section>
43+<section id="level-4">
4444<title>
4545<p>Level 4</p>
4646</title>
47−<section>
47+<section id="level-5">
4848<title>
4949<p>Level 5</p>
5050</title>
@@ -53,23 +53,23 @@ John Gruber’s markdown test suite.</p>
5353</section>
5454</section>
5555</section>
56−<section>
56+<section id="level-1">
5757<title>
5858<p>Level 1</p>
5959</title>
60−<section>
60+<section id="level-2-with-emphasis">
6161<title>
6262<p>Level 2 with <emphasis>emphasis</emphasis>
6363</p>
6464</title>
65−<section>
65+<section id="level-3">
6666<title>
6767<p>Level 3</p>
6868</title>
6969<p>with no blank line</p>
7070</section>
7171</section>
72−<section>
72+<section id="level-2">
7373<title>
7474<p>Level 2</p>
7575</title>
@@ -77,7 +77,7 @@ John Gruber’s markdown test suite.</p>
7777<empty-line />
7878</section>
7979</section>
80−<section>
80+<section id="paragraphs">
8181<title>
8282<p>Paragraphs</p>
8383</title>
@@ -93,7 +93,7 @@ list item.</p>
9393here.</p>
9494<empty-line />
9595</section>
96−<section>
96+<section id="block-quotes">
9797<title>
9898<p>Block Quotes</p>
9999</title>
@@ -131,7 +131,7 @@ It is pretty short.</p>
131131<p>And a following paragraph.</p>
132132<empty-line />
133133</section>
134−<section>
134+<section id="code-blocks">
135135<title>
136136<p>Code Blocks</p>
137137</title>
@@ -176,11 +176,11 @@ It is pretty short.</p>
176176<empty-line />
177177<empty-line />
178178</section>
179−<section>
179+<section id="lists">
180180<title>
181181<p>Lists</p>
182182</title>
183−<section>
183+<section id="unordered">
184184<title>
185185<p>Unordered</p>
186186</title>
@@ -218,7 +218,7 @@ It is pretty short.</p>
218218<p>• Minus 3</p>
219219<empty-line />
220220</section>
221−<section>
221+<section id="ordered">
222222<title>
223223<p>Ordered</p>
224224</title>
@@ -255,7 +255,7 @@ back.</p>
255255<p>3. Item 3.</p>
256256<empty-line />
257257</section>
258−<section>
258+<section id="nested">
259259<title>
260260<p>Nested</p>
261261</title>
@@ -280,7 +280,7 @@ back.</p>
280280<p>3. Third</p>
281281<empty-line />
282282</section>
283−<section>
283+<section id="tabs-and-spaces">
284284<title>
285285<p>Tabs and spaces</p>
286286</title>
@@ -297,7 +297,7 @@ indented with tabs</p>
297297indented with spaces</p>
298298<empty-line />
299299</section>
300−<section>
300+<section id="fancy-list-markers">
301301<title>
302302<p>Fancy list markers</p>
303303</title>
@@ -326,7 +326,7 @@ starting with 4</p>
326326<empty-line />
327327</section>
328328</section>
329−<section>
329+<section id="definition-lists">
330330<title>
331331<p>Definition Lists</p>
332332</title>
@@ -440,7 +440,7 @@ crisp, pleasant to taste</p>
440440<p>1. sublist</p>
441441<p>2. sublist</p>
442442</section>
443−<section>
443+<section id="html-blocks">
444444<title>
445445<p>HTML Blocks</p>
446446</title>
@@ -484,7 +484,7 @@ crisp, pleasant to taste</p>
484484<p>Hr’s:</p>
485485<empty-line />
486486</section>
487−<section>
487+<section id="inline-markup">
488488<title>
489489<p>Inline Markup</p>
490490</title>
@@ -521,7 +521,7 @@ crisp, pleasant to taste</p>
521521because of the unescaped spaces: a^b c^d, a~b c~d.</p>
522522<empty-line />
523523</section>
524−<section>
524+<section id="smart-quotes-ellipses-dashes">
525525<title>
526526<p>Smart quotes, ellipses, dashes</p>
527527</title>
@@ -537,7 +537,7 @@ So is ‘pine.’</p>
537537<p>Ellipses…and…and….</p>
538538<empty-line />
539539</section>
540−<section>
540+<section id="latex">
541541<title>
542542<p>LaTeX</p>
543543</title>
@@ -564,7 +564,7 @@ So is ‘pine.’</p>
564564<p>Here’s a LaTeX table:</p>
565565<empty-line />
566566</section>
567−<section>
567+<section id="special-characters">
568568<title>
569569<p>Special Characters</p>
570570</title>
@@ -597,11 +597,11 @@ So is ‘pine.’</p>
597597<p>Minus: -</p>
598598<empty-line />
599599</section>
600−<section>
600+<section id="links">
601601<title>
602602<p>Links</p>
603603</title>
604−<section>
604+<section id="explicit">
605605<title>
606606<p>Explicit</p>
607607</title>
@@ -627,7 +627,7 @@ So is ‘pine.’</p>
627627<p>
628628<a l:href="">Empty</a>.</p>
629629</section>
630−<section>
630+<section id="reference">
631631<title>
632632<p>Reference</p>
633633</title>
@@ -647,7 +647,7 @@ So is ‘pine.’</p>
647647<p>Foo <a l:href="/url/">bar</a>.</p>
648648<p>Foo <a l:href="/url/">biz</a>.</p>
649649</section>
650−<section>
650+<section id="with-ampersands">
651651<title>
652652<p>With ampersands</p>
653653</title>
@@ -656,7 +656,7 @@ So is ‘pine.’</p>
656656<p>Here’s an <a l:href="/script?foo=1&amp;bar=2">inline link</a>.</p>
657657<p>Here’s an <a l:href="/script?foo=1&amp;bar=2">inline link in pointy braces</a>.</p>
658658</section>
659−<section>
659+<section id="autolinks">
660660<title>
661661<p>Autolinks</p>
662662</title>
@@ -682,7 +682,7 @@ So is ‘pine.’</p>
682682<empty-line />
683683</section>
684684</section>
685−<section>
685+<section id="images">
686686<title>
687687<p>Images</p>
688688</title>
@@ -691,7 +691,7 @@ So is ‘pine.’</p>
691691<p>Here is a movie <image l:href="#image2" l:type="inlineImageType" alt="movie" /> icon.</p>
692692<empty-line />
693693</section>
694−<section>
694+<section id="footnotes">
695695<title>
696696<p>Footnotes</p>
697697</title>