@@ -21,7 +21,7 @@ module Text.Pandoc.Writers.FB2 (writeFB2) where
21import Prelude
21import Prelude
22import Control.Monad (zipWithM)
22import Control.Monad (zipWithM)
23import Control.Monad.Except (catchError)
23import Control.Monad.Except (catchError)
24−import Control.Monad.State.Strict (StateT, evalStateT, get, lift, liftM, modify)
24+import Control.Monad.State.Strict (StateT, evalStateT, get, gets, lift, liftM, modify)
25import Data.ByteString.Base64 (encode)
25import Data.ByteString.Base64 (encode)
26import qualified Data.ByteString.Char8 as B8
26import qualified Data.ByteString.Char8 as B8
27import Data.Char (isAscii, isControl, isSpace, toLower)
27import Data.Char (isAscii, isControl, isSpace, toLower)
@@ -104,7 +104,7 @@ description meta' = do
104 let as = authors meta'
104 let as = authors meta'
105 dd <- docdate meta'
105 dd <- docdate meta'
106 annotation <- case lookupMeta "abstract" meta' of
106 annotation <- case lookupMeta "abstract" meta' of
107− Just (MetaBlocks bs) -> (list . el "annotation") <$> cMapM blockToXml (map unPlain bs)
107+ Just (MetaBlocks bs) -> list . el "annotation" <$> cMapM blockToXml (map unPlain bs)
108 _ -> pure mempty
108 _ -> pure mempty
109 let lang = case lookupMeta "lang" meta' of
109 let lang = case lookupMeta "lang" meta' of
110 Just (MetaInlines [Str s]) -> [el "lang" $ iso639 s]
110 Just (MetaInlines [Str s]) -> [el "lang" $ iso639 s]
@@ -182,8 +182,8 @@ renderSection lvl (Shared.Sec _ _num (id',_,_) title elements) = do
182 else list . el "title" <$> formatTitle title
182 else list . el "title" <$> formatTitle title
183 let sectionContent = if null id'
183 let sectionContent = if null id'
184 then el "section" (title' ++ content)
184 then el "section" (title' ++ content)
185− else el "section" ([uattr "id" id'], (title' ++ content))
185+ else el "section" ([uattr "id" id'], title' ++ content)
186− return $ [sectionContent]
186+ return [sectionContent]
188-- | Only <p> and <empty-line> are allowed within <title> in FB2.
188-- | Only <p> and <empty-line> are allowed within <title> in FB2.
189formatTitle :: PandocMonad m => [Inline] -> FBM m [Content]
189formatTitle :: PandocMonad m => [Inline] -> FBM m [Content]
@@ -290,6 +290,15 @@ isMimeType s =
290footnoteID :: Int -> String
290footnoteID :: Int -> String
291footnoteID i = "n" ++ show i
291footnoteID i = "n" ++ show i
293+mkitem :: PandocMonad m => String -> [Block] -> FBM m [Content]
295+ pmrk <- gets parentListMarker
296+ let nmrk = pmrk ++ mrk ++ " "
297+ modify (\s -> s { parentListMarker = nmrk})
298+ item <- cMapM blockToXml $ plainToPara $ indentBlocks nmrk bs
299+ modify (\s -> s { parentListMarker = pmrk }) -- old parent marker
293-- | Convert a block-level Pandoc's element to FictionBook XML representation.
302-- | Convert a block-level Pandoc's element to FictionBook XML representation.
294blockToXml :: PandocMonad m => Block -> FBM m [Content]
303blockToXml :: PandocMonad m => Block -> FBM m [Content]
295blockToXml (Plain ss) = cMapM toXml ss -- FIXME: can lead to malformed FB2
304blockToXml (Plain ss) = cMapM toXml ss -- FIXME: can lead to malformed FB2
@@ -297,40 +306,26 @@ blockToXml (Para [Math DisplayMath formula]) = insertMath NormalImage formula
297-- title beginning with fig: indicates that the image is a figure
306-- title beginning with fig: indicates that the image is a figure
298blockToXml (Para [Image atr alt (src,'f':'i':'g':':':tit)]) =
307blockToXml (Para [Image atr alt (src,'f':'i':'g':':':tit)]) =
299 insertImage NormalImage (Image atr alt (src,tit))
308 insertImage NormalImage (Image atr alt (src,tit))
300−blockToXml (Para ss) = (list . el "p") <$> cMapM toXml ss
309+blockToXml (Para ss) = list . el "p" <$> cMapM toXml ss
301blockToXml (CodeBlock _ s) = return . spaceBeforeAfter .
310blockToXml (CodeBlock _ s) = return . spaceBeforeAfter .
302 map (el "p" . el "code") . lines $ s
311 map (el "p" . el "code") . lines $ s
303−blockToXml (RawBlock f str) = do
312+blockToXml (RawBlock f str) =
304 if f == Format "fb2"
313 if f == Format "fb2"
305 then return $ XI.parseXML str
314 then return $ XI.parseXML str
306 else return []
315 else return []
307blockToXml (Div _ bs) = cMapM blockToXml bs
316blockToXml (Div _ bs) = cMapM blockToXml bs
308−blockToXml (BlockQuote bs) = (list . el "cite") <$> cMapM blockToXml bs
317+blockToXml (BlockQuote bs) = list . el "cite" <$> cMapM blockToXml bs
309blockToXml (LineBlock lns) =
318blockToXml (LineBlock lns) =
310− (list . el "poem") <$> mapM stanza (split null lns)
319+ list . el "poem" <$> mapM stanza (split null lns)
312 v xs = el "v" <$> cMapM toXml xs
321 v xs = el "v" <$> cMapM toXml xs
313 stanza xs = el "stanza" <$> mapM v xs
322 stanza xs = el "stanza" <$> mapM v xs
314−blockToXml (OrderedList a bss) = do
323+blockToXml (OrderedList a bss) =
316− let pmrk = parentListMarker state
317− let markers = (pmrk ++) <$> orderedListMarkers a
318− let mkitem mrk bs = do
319− modify (\s -> s { parentListMarker = mrk ++ " "})
320− item <- cMapM blockToXml $ plainToPara $ indentBlocks (mrk ++ " ") bs
321− modify (\s -> s { parentListMarker = pmrk }) -- old parent marker
323 concat <$> zipWithM mkitem markers bss
324 concat <$> zipWithM mkitem markers bss
326+ markers = orderedListMarkers a
324−blockToXml (BulletList bss) = do
327+blockToXml (BulletList bss) =
325− state <- get
328+ cMapM (mkitem "•") bss
326− let pmrk = parentListMarker state
327− let mrk = pmrk ++ "•"
329− modify (\s -> s { parentListMarker = mrk ++ " "})
330− item <- cMapM blockToXml $ plainToPara $ indentBlocks (mrk ++ " ") bs
331− modify (\s -> s { parentListMarker = pmrk }) -- old parent marker
334blockToXml (DefinitionList defs) =
329blockToXml (DefinitionList defs) =
335 cMapM mkdef defs
330 cMapM mkdef defs