git.iko.soy/typeable/pandoc
on master help sign in
EPUB writer: improve splitting into chapters.
8408e58John MacFarlane
src/Text/Pandoc/Shared.hs+6−3
@@ -510,9 +510,12 @@ makeSections numbering mbBaseLevel bs =
510 S.modify $ \(_, ln) -> (mbLevel, ln)
510 S.modify $ \(_, ln) -> (mbLevel, ln)
511 rest' <- go rest
511 rest' <- go rest
512 let divattr = (ident, ["section"], [])
512 let divattr = (ident, ["section"], [])
513− let attr = ("",classes,kvs ++
513+ let attr = ("",classes,
514+ -- don't touch number if already present
515+ case lookup "number" kvs of
516+ Nothing | numbering ->
514− [("number", intercalate "." (map show newnum))
517+ ("number", intercalate "." (map show newnum)) : kvs
515− | numbering])
518+ _ -> kvs)
516 return $
519 return $
517 Div divattr (Header level' attr title' : sectionContents') : rest'
520 Div divattr (Header level' attr title' : sectionContents') : rest'
518 go (Div (dident,dclasses,dkvs)
521 go (Div (dident,dclasses,dkvs)
src/Text/Pandoc/Writers/EPUB.hs+23−36
@@ -21,12 +21,13 @@ import Codec.Archive.Zip (Entry, addEntryToArchive, eRelativePath, emptyArchive,
21import Control.Applicative ( (<|>) )
21import Control.Applicative ( (<|>) )
22import Control.Monad (mplus, unless, when, zipWithM)
22import Control.Monad (mplus, unless, when, zipWithM)
23import Control.Monad.Except (catchError, throwError)
23import Control.Monad.Except (catchError, throwError)
24−import Control.Monad.State.Strict (State, StateT, evalState, evalStateT, get,
24+import Control.Monad.State.Strict (StateT, evalState, evalStateT, get,
25− gets, lift, modify, put)
25+ gets, lift, modify)
26import qualified Data.ByteString.Lazy as B
26import qualified Data.ByteString.Lazy as B
27import qualified Data.ByteString.Lazy.Char8 as B8
27import qualified Data.ByteString.Lazy.Char8 as B8
28import Data.Char (isAlphaNum, isAscii, isDigit, toLower)
28import Data.Char (isAlphaNum, isAscii, isDigit, toLower)
29import Data.List (isInfixOf, isPrefixOf)
29import Data.List (isInfixOf, isPrefixOf)
30+import Data.List.Split (splitWhen)
30import qualified Data.Map as M
31import qualified Data.Map as M
31import Data.Maybe (fromMaybe, isNothing, mapMaybe, isJust)
32import Data.Maybe (fromMaybe, isNothing, mapMaybe, isJust)
32import qualified Data.Set as Set
33import qualified Data.Set as Set
@@ -513,38 +514,24 @@ pandocToEPUB version opts doc = do
513
514
514 let chapterHeaderLevel = writerEpubChapterLevel opts
515 let chapterHeaderLevel = writerEpubChapterLevel opts
515
516
516− let isChapterHeader (Header n _ _) = n <= chapterHeaderLevel
517− isChapterHeader (Div ("refs",_,_) (Header n _ _:_)) =
518− n <= chapterHeaderLevel
517+ let isChapterHeader (Div _ (Header n _ _:_)) = n <= chapterHeaderLevel
519 isChapterHeader _ = False
518 isChapterHeader _ = False
520
519
521− let toChapters :: [Block] -> State [Int] [Chapter]
520+ let secsToChapters :: [Block] -> [Chapter]
522− toChapters [] = return []
521+ secsToChapters [] = []
523− toChapters (Div _ bs@(Header 1 _ _:_) : rest) =
522+ secsToChapters (d@(Div (_,"section":_,_) bs) : rest)
524− toChapters (bs ++ rest)
523+ | isChapterHeader d =
525− toChapters (Header n (ident,classes,kvs) ils : bs) = do
524+ Chapter mbnum [d] : secsToChapters rest
526− nums <- get
525+ where mbnum = case bs of
527− mbnum <- if "unnumbered" `elem` classes
526+ (Header _ (_,_,kvs) _ : _) ->
528− then return Nothing
527+ map (fromMaybe 0 . safeRead) .
529− else case splitAt (n - 1) nums of
528+ splitWhen (=='.') <$> lookup "number" kvs
530− (ks, m:_) -> do
529+ _ -> Nothing
531− let nums' = ks ++ [m+1]
530+ secsToChapters bs =
532− put nums'
531+ Chapter Nothing xs : secsToChapters ys
533− return $ Just (ks ++ [m])
534− -- note, this is the offset not the sec number
535− (ks, []) -> do
536− let nums' = ks ++ [1]
537− put nums'
538− return $ Just ks
539− let (xs,ys) = break isChapterHeader bs
540− (Chapter mbnum
541− (Header n (ident,"chapter-title":classes,kvs) ils : xs) :) <$>
542− toChapters ys
543− toChapters (b:bs) = do
544− let (xs,ys) = break isChapterHeader bs
532+ where (xs, ys) = break isChapterHeader bs
545− (Chapter Nothing (b:xs) :) <$> toChapters ys
533+
546−
534+ let chapters' = secsToChapters $ makeSections True Nothing blocks'
547− let chapters' = evalState (toChapters blocks') []
548
535
549 let extractLinkURL' :: Int -> Inline -> [(String, String)]
536 let extractLinkURL' :: Int -> Inline -> [(String, String)]
550 extractLinkURL' num (Span (ident, _, _) _)
537 extractLinkURL' num (Span (ident, _, _) _)
@@ -576,11 +563,11 @@ pandocToEPUB version opts doc = do
576 Chapter mbnum $ walk fixInternalReferences bs)
563 Chapter mbnum $ walk fixInternalReferences bs)
577 chapters'
564 chapters'
578
565
579− let chapToEntry num (Chapter mbnum bs) =
566+ let chapToEntry num (Chapter _ bs) =
580 mkEntry ("text/" ++ showChapter num) =<<
567 mkEntry ("text/" ++ showChapter num) =<<
581− writeHtml opts'{ writerNumberOffset = fromMaybe [] mbnum
582− , writerVariables = ("body-type", bodyType) :
568+ writeHtml opts'{ writerVariables = ("body-type", bodyType) :
569+ ("pagetitle", showChapter num) :
583− cssvars True ++ vars } pdoc
570+ cssvars True ++ vars } pdoc
584 where (pdoc, bodyType) =
571 where (pdoc, bodyType) =
585 case bs of
572 case bs of
586 (Header _ (_,_,kvs) xs : _) ->
573 (Header _ (_,_,kvs) xs : _) ->