git.iko.soy/typeable/pandoc
on master help sign in
LaTeX reader: track header numbers and correlate with labels.
253a7c6John MacFarlane
src/Text/Pandoc/Readers/LaTeX.hs+49−22
@@ -119,6 +119,19 @@ parseLaTeX = do
119-- Left e -> error (show e)
119-- Left e -> error (show e)
120-- Right r -> return r
120-- Right r -> return r
121
121
122+newtype HeaderNum = HeaderNum [Int]
123+ deriving (Show)
124+
125+renderHeaderNum :: HeaderNum -> String
126+renderHeaderNum (HeaderNum xs) =
127+ intercalate "." (map show xs)
128+
129+incrementHeaderNum :: Int -> HeaderNum -> HeaderNum
130+incrementHeaderNum level (HeaderNum ns) = HeaderNum $
131+ case reverse (take level (ns ++ repeat 0)) of
132+ (x:xs) -> reverse (x+1 : xs)
133+ [] -> [] -- shouldn't happen
134+
122data LaTeXState = LaTeXState{ sOptions :: ReaderOptions
135data LaTeXState = LaTeXState{ sOptions :: ReaderOptions
123 , sMeta :: Meta
136 , sMeta :: Meta
124 , sQuoteContext :: QuoteContext
137 , sQuoteContext :: QuoteContext
@@ -131,6 +144,8 @@ data LaTeXState = LaTeXState{ sOptions :: ReaderOptions
131 , sCaption :: Maybe Inlines
144 , sCaption :: Maybe Inlines
132 , sInListItem :: Bool
145 , sInListItem :: Bool
133 , sInTableCell :: Bool
146 , sInTableCell :: Bool
147+ , sLastHeaderNum :: HeaderNum
148+ , sLabels :: M.Map String Inlines
134 }
149 }
135 deriving Show
150 deriving Show
136
151
@@ -147,6 +162,8 @@ defaultLaTeXState = LaTeXState{ sOptions = def
147 , sCaption = Nothing
162 , sCaption = Nothing
148 , sInListItem = False
163 , sInListItem = False
149 , sInTableCell = False
164 , sInTableCell = False
165+ , sLastHeaderNum = HeaderNum []
166+ , sLabels = M.empty
150 }
167 }
151
168
152instance PandocMonad m => HasQuoteContext LaTeXState m where
169instance PandocMonad m => HasQuoteContext LaTeXState m where
@@ -1448,14 +1465,16 @@ treatAsInline = Set.fromList
1448dolabel :: PandocMonad m => LP m Inlines
1465dolabel :: PandocMonad m => LP m Inlines
1449dolabel = do
1466dolabel = do
1450 v <- braced
1467 v <- braced
1451− return $ spanWith ("",[],[("label", toksToString v)])
1468+ return $ spanWith ("",[],[("label", toksToString v)])
1452 $ inBrackets $ str $ toksToString v
1469 $ inBrackets $ str $ toksToString v
1453
1470
1454doref :: PandocMonad m => String -> LP m Inlines
1471doref :: PandocMonad m => String -> LP m Inlines
1455doref cls = do
1472doref cls = do
1456 v <- braced
1473 v <- braced
1474+ let refstr = toksToString v
1457− return $ spanWith ("",[],[("reference-type", cls), ("reference", toksToString v)])
1475+ return $ spanWith ("",[],[ ("reference-type", cls)
1476+ , ("reference", refstr)])
1458− $ inBrackets $ str $ toksToString v
1477+ $ inBrackets $ str refstr
1459
1478
1460lookupListDefault :: (Show k, Ord k) => v -> [k] -> M.Map k v -> v
1479lookupListDefault :: (Show k, Ord k) => v -> [k] -> M.Map k v -> v
1461lookupListDefault d = (fromMaybe d .) . lookupList
1480lookupListDefault d = (fromMaybe d .) . lookupList
@@ -1688,14 +1707,22 @@ looseItem = do
1688resetCaption :: PandocMonad m => LP m ()
1707resetCaption :: PandocMonad m => LP m ()
1689resetCaption = updateState $ \st -> st{ sCaption = Nothing }
1708resetCaption = updateState $ \st -> st{ sCaption = Nothing }
1690
1709
1691−section :: PandocMonad m => Attr -> Int -> LP m Blocks
1710+section :: PandocMonad m => Bool -> Attr -> Int -> LP m Blocks
1692−section (ident, classes, kvs) lvl = do
1711+section starred (ident, classes, kvs) lvl = do
1693 skipopts
1712 skipopts
1694 contents <- grouped inline
1713 contents <- grouped inline
1695 lab <- option ident $
1714 lab <- option ident $
1696 try (spaces >> controlSeq "label"
1715 try (spaces >> controlSeq "label"
1697 >> spaces >> toksToString <$> braced)
1716 >> spaces >> toksToString <$> braced)
1717+ let classes' = if starred then "unnumbered" : classes else classes
1718+ unless starred $ do
1719+ hn <- sLastHeaderNum <$> getState
1720+ let num = incrementHeaderNum lvl hn
1721+ updateState $ \st -> st{ sLastHeaderNum = num }
1722+ updateState $ \st -> st{ sLabels = M.insert lab
1723+ (str (renderHeaderNum num))
1724+ (sLabels st) }
1698− attr' <- registerHeader (lab, classes, kvs) contents
1725+ attr' <- registerHeader (lab, classes', kvs) contents
1699 return $ headerWith attr' lvl contents
1726 return $ headerWith attr' lvl contents
1700
1727
1701blockCommand :: PandocMonad m => LP m Blocks
1728blockCommand :: PandocMonad m => LP m Blocks
@@ -1756,23 +1783,23 @@ blockCommands = M.fromList $
1756 -- Koma-script metadata commands
1783 -- Koma-script metadata commands
1757 , ("dedication", mempty <$ (skipopts *> tok >>= addMeta "dedication"))
1784 , ("dedication", mempty <$ (skipopts *> tok >>= addMeta "dedication"))
1758 -- sectioning
1785 -- sectioning
1759− , ("part", section nullAttr (-1))
1786+ , ("part", section False nullAttr (-1))
1760− , ("part*", section nullAttr (-1))
1787+ , ("part*", section True nullAttr (-1))
1761− , ("chapter", section nullAttr 0)
1788+ , ("chapter", section False nullAttr 0)
1762− , ("chapter*", section ("",["unnumbered"],[]) 0)
1789+ , ("chapter*", section True ("",["unnumbered"],[]) 0)
1763− , ("section", section nullAttr 1)
1790+ , ("section", section False nullAttr 1)
1764− , ("section*", section ("",["unnumbered"],[]) 1)
1791+ , ("section*", section True ("",["unnumbered"],[]) 1)
1765− , ("subsection", section nullAttr 2)
1792+ , ("subsection", section False nullAttr 2)
1766− , ("subsection*", section ("",["unnumbered"],[]) 2)
1793+ , ("subsection*", section True ("",["unnumbered"],[]) 2)
1767− , ("subsubsection", section nullAttr 3)
1794+ , ("subsubsection", section False nullAttr 3)
1768− , ("subsubsection*", section ("",["unnumbered"],[]) 3)
1795+ , ("subsubsection*", section True ("",["unnumbered"],[]) 3)
1769− , ("paragraph", section nullAttr 4)
1796+ , ("paragraph", section False nullAttr 4)
1770− , ("paragraph*", section ("",["unnumbered"],[]) 4)
1797+ , ("paragraph*", section True ("",["unnumbered"],[]) 4)
1771− , ("subparagraph", section nullAttr 5)
1798+ , ("subparagraph", section False nullAttr 5)
1772− , ("subparagraph*", section ("",["unnumbered"],[]) 5)
1799+ , ("subparagraph*", section True ("",["unnumbered"],[]) 5)
1773 -- beamer slides
1800 -- beamer slides
1774− , ("frametitle", section nullAttr 3)
1801+ , ("frametitle", section False nullAttr 3)
1775− , ("framesubtitle", section nullAttr 4)
1802+ , ("framesubtitle", section False nullAttr 4)
1776 -- letters
1803 -- letters
1777 , ("opening", (para . trimInlines) <$> (skipopts *> tok))
1804 , ("opening", (para . trimInlines) <$> (skipopts *> tok))
1778 , ("closing", skipopts *> closing)
1805 , ("closing", skipopts *> closing)