diff options
| author | John MacFarlane <jgm@berkeley.edu> | 2023-01-15 22:13:57 -0800 |
|---|---|---|
| committer | John MacFarlane <jgm@berkeley.edu> | 2023-01-15 22:32:16 -0800 |
| commit | c6551433b2229130000bd547c879751270430867 (patch) | |
| tree | 49b21f1967c1e86d7f52a90156384014bd4cce4a /src/Text | |
| parent | cdf8c69fb94aeae4f0284a6b534321552d4bed2a (diff) | |
T.P.Chunks changes.
+ Re-use `toTocTree` in constructing `chunkedTOC`.
Previously we used an entirely different function toTOCTree'.
+ Improve `tocToList` so that it avoids empty lists of
items that are omitted because they are below the toc depth.
pandoc-lua-engine:
+ Fix structure tests in light of last change.
T.P.Writers.ChunkedHTML:
+ Reuse `tocToList` in `buildTOC`.
T.P.Writers.EPUB:
+ Adjust EPUB writer for Chunks changes.
Diffstat (limited to 'src/Text')
| -rw-r--r-- | src/Text/Pandoc/Chunks.hs | 71 | ||||
| -rw-r--r-- | src/Text/Pandoc/Writers/ChunkedHTML.hs | 23 | ||||
| -rw-r--r-- | src/Text/Pandoc/Writers/EPUB.hs | 6 |
3 files changed, 45 insertions, 55 deletions
diff --git a/src/Text/Pandoc/Chunks.hs b/src/Text/Pandoc/Chunks.hs index 3d144f325..196893f04 100644 --- a/src/Text/Pandoc/Chunks.hs +++ b/src/Text/Pandoc/Chunks.hs @@ -51,12 +51,14 @@ splitIntoChunks pathTemplate numberSections mbBaseLevel chunklev (Pandoc meta blocks) = addNav . fixInternalReferences . - walk rmNavAttrs . - (\chunks -> ChunkedDoc{ chunkedMeta = meta - , chunkedChunks = chunks - , chunkedTOC = toTOCTree' chunks }) . - makeChunks chunklev pathTemplate meta . - makeSections numberSections mbBaseLevel $ blocks + walk rmNavAttrs $ + ChunkedDoc{ chunkedMeta = meta + , chunkedChunks = chunks + , chunkedTOC = tocTree } + where + tocTree = fixTOCTreePaths chunks $ toTOCTree sections + chunks = makeChunks chunklev pathTemplate meta $ sections + sections = makeSections numberSections mbBaseLevel $ blocks -- | Add chunkNext, chunkPrev, chunkUp addNav :: ChunkedDoc -> ChunkedDoc @@ -321,7 +323,7 @@ data SecInfo = { secTitle :: [Inline] , secNumber :: Maybe Text , secId :: Text - , secPath :: Text + , secPath :: Text -- including fragment, e.g. chunk001.html#section-one , secLevel :: Int } deriving (Show, Eq, Generic) @@ -354,25 +356,22 @@ toTOCTree = go (Div _ [d@Div{}]) = go d -- #8402 go _ = id -toTOCTree' :: [Chunk] -> Tree SecInfo -toTOCTree' = - Node SecInfo{ secTitle = [] - , secNumber = Nothing - , secId = "" - , secPath = "" - , secLevel = 0 } . getNodes . filter (not . skippable) +-- | Adjusts paths in the TOC tree generated by 'toTOCTree' +-- to reflect division into Chunks. +fixTOCTreePaths :: [Chunk] -> Tree SecInfo -> Tree SecInfo +fixTOCTreePaths chunks = go "" where - skippable c = isNothing (chunkSectionNumber c) && chunkUnlisted c - getNodes :: [Chunk] -> [Tree SecInfo] - getNodes (c:cs) = - let (as, bs) = span (\d -> chunkLevel d > chunkLevel c) cs - secinfo = SecInfo{ secTitle = chunkHeading c, - secNumber = chunkSectionNumber c, - secId = chunkId c, - secPath = T.pack $ chunkPath c, - secLevel = chunkLevel c } - in Node secinfo (getNodes as) : getNodes bs - getNodes [] = [] + idMap = foldr (\chunk -> M.insert (chunkId chunk) (chunkPath chunk)) + mempty chunks + go :: FilePath -> Tree SecInfo -> Tree SecInfo + go fp (Node secinfo subtrees) = + let newpath = M.lookup (secId secinfo) idMap + fp' = fromMaybe fp newpath + fragment = case newpath of + Nothing -> "#" <> secId secinfo + Just _ -> "" -- link to top of file + in Node secinfo{ secPath = T.pack fp' <> fragment } + (map (go fp') subtrees) -- | Creates a TOC link to the respective document section. tocEntryToLink :: SecInfo -> [Inline] @@ -385,19 +384,27 @@ tocEntryToLink secinfo = headerLink clean (Link _ xs _) = xs clean (Note _) = [] clean x = [x] - ident = secId secinfo + anchor = if T.null (secPath secinfo) + then if T.null (secId secinfo) + then "" + else "#" <> secId secinfo + else secPath secinfo headerText = addNumber $ walk (concatMap clean) (secTitle secinfo) - headerLink = if T.null ident + headerLink = if T.null anchor then headerText - else [Link ("toc-" <> ident, [], []) - headerText (secPath secinfo <> "#" <> ident, "")] + else [Link ((if T.null (secId secinfo) + then "" + else "toc-" <> secId secinfo), [], []) + headerText (anchor, "")] -- | Generate a table of contents of the given depth. tocToList :: Int -> Tree SecInfo -> Block -tocToList tocDepth (Node _ subtrees) - = BulletList (toItems subtrees) +tocToList tocDepth (Node _ subtrees) = BulletList (toItems subtrees) where toItems = map go . filter isBelowTocDepth isBelowTocDepth (Node sec _) = secLevel sec <= tocDepth go (Node secinfo xs) = - Plain (tocEntryToLink secinfo) : [BulletList (toItems xs) | not (null xs)] + Plain (tocEntryToLink secinfo) : + case toItems xs of + [] -> [] + ys -> [BulletList ys] diff --git a/src/Text/Pandoc/Writers/ChunkedHTML.hs b/src/Text/Pandoc/Writers/ChunkedHTML.hs index 5efcfb0ab..61dcdbd80 100644 --- a/src/Text/Pandoc/Writers/ChunkedHTML.hs +++ b/src/Text/Pandoc/Writers/ChunkedHTML.hs @@ -28,7 +28,7 @@ import Text.Pandoc.Class (PandocMonad, getPOSIXTime, runPure, import Text.Pandoc.MediaBag (mediaItems) import qualified Data.ByteString.Lazy as BL import Text.Pandoc.Chunks (splitIntoChunks, Chunk(..), ChunkedDoc(..), - SecInfo(..)) + SecInfo(..), tocToList) import Data.Text (Text) import Data.Tree import qualified Data.Text as T @@ -86,9 +86,8 @@ writeChunkedHTML opts (Pandoc meta blocks) = do let Node secinfo secs = chunkedTOC chunkedDoc let tocTree = Node secinfo{ secTitle = docTitle meta, secPath = "index.html" } secs - let tocBlocks = buildTOC opts tocTree renderedTOC <- writeHtml5String opts{ writerTemplate = Nothing } - (Pandoc nullMeta tocBlocks) + (Pandoc nullMeta [buildTOC opts tocTree]) let opts' = opts{ writerVariables = defField "table-of-contents" renderedTOC $ writerVariables opts } @@ -110,22 +109,8 @@ addMedia il@(Image _ _ (src,_)) return il addMedia il = return il -buildTOC :: WriterOptions -> Tree SecInfo -> [Block] -buildTOC opts tocTree = buildTOCPart tocTree - where - buildTOCPart (Node secinfo subsecs) = - Plain [Link nullAttr - ((maybe [] (\num -> - if writerNumberSections opts - then [Span ("",["toc-section-number"],[]) - [Str num, Space]] - else []) (secNumber secinfo)) - ++ secTitle secinfo) - (secPath secinfo, "") | secLevel secinfo > 0] : - if null subsecs - then [] - else [BulletList (map buildTOCPart $ filter aboveThreshold subsecs)] - aboveThreshold (Node sec _) = secLevel sec <= writerTOCDepth opts +buildTOC :: WriterOptions -> Tree SecInfo -> Block +buildTOC opts = tocToList (writerTOCDepth opts) chunkToEntry :: PandocMonad m => WriterOptions -> Meta -> Chunk -> Chunk -> m Entry diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs index 832ddb0b2..7faad746e 100644 --- a/src/Text/Pandoc/Writers/EPUB.hs +++ b/src/Text/Pandoc/Writers/EPUB.hs @@ -842,8 +842,7 @@ createTocEntry opts meta metadata plainTitle (Node _ secs) = do [("id", "navPoint-" <> tshow n)] $ [ unode "navLabel" $ unode "text" title' , unode "content" ! - [("src", "text/" <> secPath secinfo <> - "#" <> secId secinfo)] $ () + [("src", "text/" <> secPath secinfo)] $ () ] ++ subs let tpNode = unode "navPoint" ! [("id", "navPoint-0")] $ @@ -921,8 +920,7 @@ createNavEntry opts meta metadata return $ Just $ unode "li" ! [("id", "toc-li-" <> tshow n)] $ (unode "a" ! - [("href", "text/" <> secPath secinfo <> - "#" <> secId secinfo)] + [("href", "text/" <> secPath secinfo)] $ titElements) : case subs of [] -> [] |
