summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2024-01-30 08:28:21 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2024-01-30 08:29:21 -0800
commitb706cb0ec5c87b0a195ffc5116d4acaf72cf62e1 (patch)
treec52b6d82041d84ba660486313a3e6ca46f739918
parent32b6db15dca1201d83bb942f2d0dc1a5b108828d (diff)
Chunks: autogenerate unique ids for sections missing them.
This is needed for TOC generation to work properly. We can't create TOC links if there are no ids. This fixes some EPUB validation issues we've been getting since switching over to Chunks for chunking. Closes #9383.
-rw-r--r--src/Text/Pandoc/Chunks.hs22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/Text/Pandoc/Chunks.hs b/src/Text/Pandoc/Chunks.hs
index 1d85ac0b2..31ee8f8ee 100644
--- a/src/Text/Pandoc/Chunks.hs
+++ b/src/Text/Pandoc/Chunks.hs
@@ -29,7 +29,7 @@ module Text.Pandoc.Chunks
import Text.Pandoc.Definition
import Text.Pandoc.Shared (makeSections, stringify, inlineListToIdentifier,
- tshow)
+ tshow, uniqueIdent)
import Text.Pandoc.Walk (Walkable(..), query)
import Data.Aeson (FromJSON, ToJSON)
import Data.Text (Text)
@@ -43,6 +43,8 @@ import Text.HTML.TagSoup (Tag (TagOpen), fromAttrib, parseTags)
import Data.Tree (Tree(..))
import Data.Data (Data)
import Data.Typeable (Typeable)
+import qualified Data.Set as Set
+import Control.Monad.State
-- | Split 'Pandoc' into 'Chunk's, e.g. for conversion into
-- a set of HTML pages or EPUB chapters.
@@ -63,7 +65,23 @@ splitIntoChunks pathTemplate numberSections mbBaseLevel
where
tocTree = fixTOCTreePaths chunks $ toTOCTree sections
chunks = makeChunks chunklev pathTemplate meta $ sections
- sections = makeSections numberSections mbBaseLevel $ blocks
+ sections = ensureIds $ makeSections numberSections mbBaseLevel blocks
+
+-- The TOC won't work if we don't have unique identifiers for all sections.
+ensureIds :: [Block] -> [Block]
+ensureIds bs = evalState (walkM go bs) mempty
+ where
+ go :: Block -> State (Set.Set Text) Block
+ go b@(Div (ident,"section":cls,kvs) bs'@(Header _ _ ils : _))
+ | T.null ident
+ = do ids <- get
+ let newid = uniqueIdent mempty ils ids
+ modify $ Set.insert newid
+ pure $ Div (newid,"section":cls,kvs) bs'
+ | otherwise
+ = do modify $ Set.insert ident
+ pure b
+ go b = pure b
-- | Add chunkNext, chunkPrev, chunkUp
addNav :: ChunkedDoc -> ChunkedDoc