From 3263d0d7c4052307ce38f342800197dec5a3fba0 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 29 Oct 2017 21:46:44 +0300 Subject: Write FB2 lists without nesting blocks inside

(#4004) According to FB2 XML schema cannot be placed inside

. Linux FBReader can't display such paragraphs, e.g. any "loose" lists produced by pandoc prior to this commit. Besides that, FB2 writer placed

inside

when writing nested lists, this commit fixes the bug. Also this commit removes leading non-breaking space from ordered lists for consistency with bullet lists. Definition lists are not affected at all. --- src/Text/Pandoc/Writers/FB2.hs | 48 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Text/Pandoc/Writers/FB2.hs b/src/Text/Pandoc/Writers/FB2.hs index b7dc43685..6d61ea62c 100644 --- a/src/Text/Pandoc/Writers/FB2.hs +++ b/src/Text/Pandoc/Writers/FB2.hs @@ -338,13 +338,13 @@ blockToXml (LineBlock lns) = blockToXml (OrderedList a bss) = do state <- get let pmrk = parentListMarker state - let markers = map ((pmrk ++ " ") ++) $ orderedListMarkers a + let markers = map (pmrk ++) $ orderedListMarkers a let mkitem mrk bs = do - modify (\s -> s { parentListMarker = mrk }) - itemtext <- cMapM blockToXml . paraToPlain $ bs + modify (\s -> s { parentListMarker = mrk ++ " "}) + item <- cMapM blockToXml $ plainToPara $ indentBlocks (mrk ++ " ") bs modify (\s -> s { parentListMarker = pmrk }) -- old parent marker - return . el "p" $ [ txt mrk, txt " " ] ++ itemtext - zipWithM mkitem markers bss + return item + concat <$> (zipWithM mkitem markers bss) blockToXml (BulletList bss) = do state <- get let level = parentBulletLevel state @@ -354,10 +354,10 @@ blockToXml (BulletList bss) = do let mrk = prefix ++ bullets !! (level `mod` length bullets) let mkitem bs = do modify (\s -> s { parentBulletLevel = level+1 }) - itemtext <- cMapM blockToXml . paraToPlain $ bs + item <- cMapM blockToXml $ plainToPara $ indentBlocks (mrk ++ " ") bs modify (\s -> s { parentBulletLevel = level }) -- restore bullet level - return $ el "p" $ txt (mrk ++ " ") : itemtext - mapM mkitem bss + return item + cMapM mkitem bss blockToXml (DefinitionList defs) = cMapM mkdef defs where @@ -408,19 +408,24 @@ blockToXml Null = return [] paraToPlain :: [Block] -> [Block] paraToPlain [] = [] paraToPlain (Para inlines : rest) = - let p = Plain (inlines ++ [LineBreak]) - in p : paraToPlain rest + Plain (inlines) : Plain ([LineBreak]) : paraToPlain rest paraToPlain (p:rest) = p : paraToPlain rest +-- Replace plain text with paragraphs and add line break after paragraphs. +-- It is used to convert plain text from tight list items to paragraphs. +plainToPara :: [Block] -> [Block] +plainToPara [] = [] +plainToPara (Plain inlines : rest) = + Para (inlines) : plainToPara rest +plainToPara (Para inlines : rest) = + Para (inlines) : Plain [LineBreak] : plainToPara rest +plainToPara (p:rest) = p : plainToPara rest + -- Simulate increased indentation level. Will not really work -- for multi-line paragraphs. -indent :: Block -> Block -indent = indentBlock +indentPrefix :: String -> Block -> Block +indentPrefix spacer = indentBlock where - -- indentation space - spacer :: String - spacer = replicate 4 ' ' - -- indentBlock (Plain ins) = Plain (Str spacer:ins) indentBlock (Para ins) = Para (Str spacer:ins) indentBlock (CodeBlock a s) = @@ -434,6 +439,17 @@ indent = indentBlock indentLines ins = let lns = split isLineBreak ins :: [[Inline]] in intercalate [LineBreak] $ map (Str spacer:) lns +indent :: Block -> Block +indent = indentPrefix spacer + where + -- indentation space + spacer :: String + spacer = replicate 4 ' ' + +indentBlocks :: String -> [Block] -> [Block] +indentBlocks _ [] = [] +indentBlocks prefix (x:xs) = indentPrefix prefix x : map (indentPrefix $ replicate (length prefix) ' ') xs + -- | Convert a Pandoc's Inline element to FictionBook XML representation. toXml :: PandocMonad m => Inline -> FBM m [Content] toXml (Str s) = return [txt s] -- cgit v1.2.3