summaryrefslogtreecommitdiff
path: root/src/Text
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2023-01-15 22:13:57 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2023-01-15 22:32:16 -0800
commitc6551433b2229130000bd547c879751270430867 (patch)
tree49b21f1967c1e86d7f52a90156384014bd4cce4a /src/Text
parentcdf8c69fb94aeae4f0284a6b534321552d4bed2a (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.hs71
-rw-r--r--src/Text/Pandoc/Writers/ChunkedHTML.hs23
-rw-r--r--src/Text/Pandoc/Writers/EPUB.hs6
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
[] -> []