From 63010da18dd384da9fec0e62f2a3a051503a0181 Mon Sep 17 00:00:00 2001 From: Yu Cong Date: Mon, 20 Apr 2026 15:07:24 +0800 Subject: [PATCH] Add section indexing and update autoref functionality in ChaoDoc module --- assets/math-macros.tex | 1 + src/ChaoDoc.hs | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/assets/math-macros.tex b/assets/math-macros.tex index 79437d5..5ef985f 100644 --- a/assets/math-macros.tex +++ b/assets/math-macros.tex @@ -20,3 +20,4 @@ \newcommand{\del}{\setminus} \newcommand{\con}{/} \newcommand{\minor}{\times} +\newcommand{\FF}{\mathbb{F}} diff --git a/src/ChaoDoc.hs b/src/ChaoDoc.hs index 27fec0d..a5c485f 100644 --- a/src/ChaoDoc.hs +++ b/src/ChaoDoc.hs @@ -13,6 +13,7 @@ where import Control.Monad (guard) import Control.Monad.State +import qualified Control.Monad.State.Strict as Strict import Data.Char (isSpace) import Data.Either import Data.Functor @@ -105,7 +106,8 @@ incrementalBlock = "Proposition", "Corollary", "Observation", - "Figure" + "Figure", + "Table" ] otherBlock :: [Text] @@ -221,7 +223,41 @@ autoref _ y = y autorefFilter :: Pandoc -> Pandoc autorefFilter x = walk (autoref links) x where - links = query theoremIndex x + links = query theoremIndex x ++ sectionIndex x + +sectionIndex :: Pandoc -> [(Text, (Text, Text))] +sectionIndex doc = snd $ Strict.execState (walkM collectSectionIndex doc) ([], []) + +collectSectionIndex :: Block -> Strict.State ([Int], [(Text, (Text, Text))]) Block +collectSectionIndex header@(Header level attr@(ident, _, _) _) + | isNumberedSectionHeader attr = do + (curNums, refs) <- Strict.get + let nextNums = nextSectionNumbers level curNums + refs' + | isSectionIdentifier ident = (ident, ("Section", renderSectionNumber nextNums)) : refs + | otherwise = refs + Strict.put (nextNums, refs') + pure header +collectSectionIndex block = pure block + +isNumberedSectionHeader :: Attr -> Bool +isNumberedSectionHeader (_, classes, _) = "unnumbered" `notElem` classes + +isSectionIdentifier :: Text -> Bool +isSectionIdentifier = T.isPrefixOf "sec:" + +nextSectionNumbers :: Int -> [Int] -> [Int] +nextSectionNumbers level nums = + reverse $ bumpLast $ reverse prefix + where + prefix = take level (nums ++ repeat 0) + +bumpLast :: [Int] -> [Int] +bumpLast [] = [1] +bumpLast (x : xs) = (x + 1) : xs + +renderSectionNumber :: [Int] -> Text +renderSectionNumber = T.intercalate "." . map (pack . show) equationFilter :: Pandoc -> Pandoc equationFilter doc = walk (equationAutoref links) processed