pandoc-crossref 0.3.15.2 → 0.3.16.0
raw patch · 20 files changed
+557/−216 lines, 20 filesdep +microlens-ghcdep ~pandoc-typesPVP ok
version bump matches the API change (PVP)
Dependencies added: microlens-ghc
Dependency ranges changed: pandoc-types
API changes (from Hackage documentation)
Files
- CHANGELOG.md +10/−0
- docs/index.md +42/−9
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/CodeBlock.hs +2/−3
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Header.hs +55/−40
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Math.hs +2/−3
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Subfigures.hs +20/−20
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Table.hs +2/−3
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Util.hs +52/−21
- lib-internal/Text/Pandoc/CrossRef/References/List.hs +3/−3
- lib-internal/Text/Pandoc/CrossRef/References/Refs.hs +49/−43
- lib-internal/Text/Pandoc/CrossRef/References/Types.hs +21/−10
- lib-internal/Text/Pandoc/CrossRef/Util/Util.hs +4/−3
- pandoc-crossref.cabal +14/−10
- test/m2m/label-precedence/expect.md +23/−0
- test/m2m/label-precedence/expect.tex +32/−0
- test/m2m/label-precedence/input.md +19/−0
- test/m2m/numberOverride/expect.md +63/−0
- test/m2m/numberOverride/expect.tex +67/−0
- test/m2m/numberOverride/input.md +28/−0
- test/test-pandoc-crossref.hs +49/−48
CHANGELOG.md view
@@ -1,3 +1,13 @@+## 0.3.16.0++- Add `number` attribute++ For cases when you need to manually adjust numbering, you can specify the+ `number` attribute on referencable objects. It will set the internal counter+ for the object to that number, and all following objects of this type will+ count up from that. Conceptually, this is similar to document processors'+ "start from..." etc.+ ## 0.3.15.2 - Fix single-row subfigures
docs/index.md view
@@ -282,23 +282,43 @@ See [section on templates](#templates) for more information -## Section reference labels+## Reference labels ***Not currently supported with LaTeX output*** -If you want to reference some section by a pre-defined label instead of-by number, you can specify section attribute `label`, like this:+If you want to reference some object by a pre-defined label instead of+by number, you can specify attribute `label`, like this: -``` markdown- Section {label="Custom Label"}+```markdown+# Section {label="Custom Label"}++{fig:fig1 label="Custom label"} ``` -This label will be used instead of section number in `chapters` output-and when referencing section directly (with `@sec:section`).+Note that to use this with equations and tables, you need to use fenced div/span+syntax, not the short syntax: -Note that with `chapters` output with depth\>1, only given section will-be referenced by custom label, e.g. with+```markdown +:::{#tbl:table label="T"}+a b c+--- --- ---+1 2 3+4 5 6++: Caption+:::++[$$y = e^x$$]{#eq:equation label="E"}++```++This label will be used instead of a number in `chapters` output for sections+and when referencing the element directly.++Note that with `chapters` output with depth\>1, only the given section will be+referenced by the custom label, e.g. with+ ``` markdown Chapter 1. @@ -309,6 +329,19 @@ `@sec:scl` will translate into `sec. 1.SCL`, and `@fig:figure` into `fig. 1.SCL.1`++## Manual numbering adjustment++***Not currently supported with LaTeX output***++For cases when you need to manually adjust numbering, you can specify the+`number` attribute on the object. It will set the internal object counter for+the annotated object to the number specified, and all the following objects of+this type will count from that. Conceptually, this is similar to document+processors' "start from..." etc.++Same as with `label` attributes, to use this with equations and tables, you need+to use fenced div/span syntax, not the short syntax. ## Code Block labels
lib-internal/Text/Pandoc/CrossRef/References/Blocks/CodeBlock.hs view
@@ -29,9 +29,8 @@ import qualified Text.Pandoc.Builder as B import Data.Function ((&)) -import Text.Pandoc.CrossRef.References.Types import Text.Pandoc.CrossRef.References.Monad-import Text.Pandoc.CrossRef.References.Blocks.Util (mkCaption, replaceAttr, setLabel)+import Text.Pandoc.CrossRef.References.Blocks.Util import Text.Pandoc.CrossRef.Util.Options import Text.Pandoc.CrossRef.Util.Template import Text.Pandoc.CrossRef.Util.Util@@ -59,7 +58,7 @@ ] _ -> do let cap = either (B.toList . B.text) id eCaption- idxStr <- replaceAttr (Right label) (lookup "label" attrs) cap lstRefs+ idxStr <- replaceAttr (Right label) attrs cap SPfxLst let caption' = applyTemplate idxStr cap $ listingTemplate opts replaceNoRecurse $ Div (label, "listing":classes, []) [ mkCaption opts "Caption" caption'
lib-internal/Text/Pandoc/CrossRef/References/Blocks/Header.hs view
@@ -18,15 +18,18 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}+{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts, RecordWildCards, NamedFieldPuns #-} module Text.Pandoc.CrossRef.References.Blocks.Header where import Control.Monad.Reader.Class import Control.Monad.State hiding (get, modify) import qualified Data.Map as M+import qualified Data.Sequence as S+import Data.Sequence (ViewR(..)) import qualified Data.Text as T import Text.Pandoc.Definition+import Text.Read (readMaybe) import Control.Applicative import Lens.Micro.Mtl@@ -38,42 +41,54 @@ import Text.Pandoc.CrossRef.Util.Util runHeader :: Int -> Attr -> [Inline] -> WS (ReplacedResult Block)-runHeader n (label, cls, attrs) text' = do- opts <- ask- let label' = if autoSectionLabels opts && not ("sec:" `T.isPrefixOf` label)- then "sec:"<>label- else label- unless ("unnumbered" `elem` cls) $ do- modifying curChap $ \cc ->- let ln = length cc- cl i = lookup "label" attrs <|> customHeadingLabel opts n i <|> customLabel opts "sec" i- inc l = let i = fst (last l) + 1 in init l <> [(i, cl i)]- cc' | ln > n = inc $ take n cc- | ln == n = inc cc- | otherwise = cc <> take (n-ln-1) implicitChapters <> [(1,cl 1)]- implicitChapters | numberSections opts = repeat (1, Nothing)- | otherwise = repeat (0, Nothing)- in cc'- when ("sec:" `T.isPrefixOf` label') $ do- index <- use curChap- modifying secRefs $ M.insert label' RefRec {- refIndex=index- , refTitle= text'- , refSubfigure = Nothing- }- cc <- use curChap- let textCC | numberSections opts- , sectionsDepth opts < 0- || n <= if sectionsDepth opts == 0 then chaptersDepth opts else sectionsDepth opts- , "unnumbered" `notElem` cls- = applyTemplate' (M.fromDistinctAscList [- ("i", idxStr)- , ("n", [Str $ T.pack $ show $ n - 1])- , ("t", text')- ]) $ secHeaderTemplate opts- | otherwise = text'- idxStr = chapPrefix (chapDelim opts) cc- attrs' | "unnumbered" `notElem` cls- = setLabel opts idxStr attrs- | otherwise = attrs- replaceNoRecurse $ Header n (label', cls, attrs') textCC+runHeader n (label, cls, attrs) text'+ | "unnumbered" `elem` cls = do+ label' <- mangleLabel+ replaceNoRecurse $ Header n (label', cls, attrs) text'+ | otherwise = do+ opts@Options{..} <- ask+ label' <- mangleLabel+ ctrsAt PfxSec %= \cc ->+ let ln = length cc+ cl i = lookup "label" attrs <|> customHeadingLabel n i <|> customLabel "sec" i+ inc l = case S.viewr l of+ EmptyR -> error "impossible"+ init' :> last' ->+ let i = succ $ fst $ last'+ in init' S.|> (i, cl i)+ cc' | Just num <- readMaybe . T.unpack =<< lookup "number" attrs+ = S.take (n - 1) cc S.|> (num, cl num)+ | ln > n = inc $ S.take n cc+ | ln == n = inc cc+ | otherwise = cc <> implicitChapters S.|> (1,cl 1)+ implicitChapters+ | numberSections = S.replicate (n-ln-1) (1, Nothing)+ | otherwise = S.replicate (n-ln-1) (0, Nothing)+ in cc'+ cc <- use $ ctrsAt PfxSec+ when ("sec:" `T.isPrefixOf` label') $+ refsAt PfxSec %= M.insert label' RefRec {+ refIndex = cc+ , refTitle = text'+ , refSubfigure = Nothing+ }+ let textCC+ | numberSections+ , sectionsDepth < 0+ || n <= if sectionsDepth == 0 then chaptersDepth else sectionsDepth+ = applyTemplate' (M.fromDistinctAscList [+ ("i", idxStr)+ , ("n", [Str $ T.pack $ show $ n - 1])+ , ("t", text')+ ]) $ secHeaderTemplate+ | otherwise = text'+ idxStr = chapPrefix chapDelim cc+ attrs' = setLabel opts idxStr attrs+ replaceNoRecurse $ Header n (label', cls, attrs') textCC+ where+ mangleLabel = do+ Options{autoSectionLabels} <- ask+ pure $+ if autoSectionLabels && not ("sec:" `T.isPrefixOf` label)+ then "sec:" <> label+ else label
lib-internal/Text/Pandoc/CrossRef/References/Blocks/Math.hs view
@@ -28,9 +28,8 @@ import Text.Pandoc.Definition import Text.Pandoc.Shared (stringify) -import Text.Pandoc.CrossRef.References.Types import Text.Pandoc.CrossRef.References.Monad-import Text.Pandoc.CrossRef.References.Blocks.Util (setLabel, replaceAttr)+import Text.Pandoc.CrossRef.References.Blocks.Util import Text.Pandoc.CrossRef.Util.Options import Text.Pandoc.CrossRef.Util.Template import Text.Pandoc.CrossRef.Util.Util@@ -52,7 +51,7 @@ opts <- ask let label' | T.null label = Left "eq" | otherwise = Right label- idxStrRaw <- replaceAttr label' (lookup "label" attrs) [] eqnRefs+ idxStrRaw <- replaceAttr label' attrs [] SPfxEqn let idxStr = applyTemplate' (M.fromDistinctAscList [("i", idxStrRaw)]) $ eqnIndexTemplate opts eqTxt = applyTemplate' eqTxtVars $ eqnInlineTemplate opts :: [Inline] eqTxtVars = M.fromDistinctAscList
lib-internal/Text/Pandoc/CrossRef/References/Blocks/Subfigures.hs view
@@ -39,7 +39,7 @@ import Text.Pandoc.CrossRef.References.Types import Text.Pandoc.CrossRef.References.Monad-import Text.Pandoc.CrossRef.References.Blocks.Util (setLabel, replaceAttr, walkReplaceInlines)+import Text.Pandoc.CrossRef.References.Blocks.Util import Text.Pandoc.CrossRef.Util.Options import Text.Pandoc.CrossRef.Util.Template import Text.Pandoc.CrossRef.Util.Util@@ -47,8 +47,11 @@ runSubfigures :: Attr -> [Block] -> [Inline] -> WS (ReplacedResult Block) runSubfigures (label, cls, attrs) images caption = do opts <- ask- idxStr <- replaceAttr (Right label) (lookup "label" attrs) caption imgRefs- let (cont, st) = flip runState def $ flip runReaderT opts' $ runWS $ runReplace (mkRR replaceSubfigs `extRR` doFigure) $ images+ idxStr <- replaceAttr (Right label) attrs caption SPfxImg+ let (cont, st) = flip runState def+ $ flip runReaderT opts'+ $ runWS+ $ runReplace (mkRR replaceSubfigs `extRR` doFigure) images doFigure :: Block -> WS (ReplacedResult Block) doFigure (Figure attr caption' content) = runFigure True attr caption' content doFigure _ = noReplaceRecurse@@ -62,7 +65,7 @@ $ sortOn (refIndex . snd) $ filter (not . null . refTitle . snd) $ M.toList- $ st^.imgRefs+ $ st ^. refsAt PfxImg collectCaps v = applyTemplate (chapPrefix (chapDelim opts) (refIndex v))@@ -74,12 +77,10 @@ , ("t", caption) ] capt = applyTemplate' vars $ subfigureTemplate opts- lastRef <- fromJust . M.lookup label <$> use imgRefs- modifying imgRefs $ \old ->- M.union- old- (M.map (\v -> v{refIndex = refIndex lastRef, refSubfigure = Just $ refIndex v})- $ st^.imgRefs)+ lastRef <- fromJust . M.lookup label <$> use (refsAt PfxImg)+ let mangledSubfigures = mangleSubfigure <$> st ^. refsAt PfxImg+ mangleSubfigure v = v{refIndex = refIndex lastRef, refSubfigure = Just $ refIndex v}+ refsAt PfxImg %= (<> mangledSubfigures) case outFormat opts of f | isLatexFormat f -> replaceNoRecurse $ Div nullAttr $@@ -150,15 +151,14 @@ _ -> Nothing replaceSubfig :: Inline -> WS [Inline]-replaceSubfig x@(Image (label,cls,attrs) alt tgt)- = do- opts <- ask- let label' = normalizeLabel label- idxStr <- replaceAttr label' (lookup "label" attrs) alt imgRefs- let alt' = applyTemplate idxStr alt $ figureTemplate opts- case outFormat opts of- f | isLatexFormat f -> pure $ latexSubFigure x label- _ -> pure [Image (label, cls, setLabel opts idxStr attrs) alt' tgt]+replaceSubfig x@(Image (label,cls,attrs) alt tgt) = do+ opts <- ask+ let label' = normalizeLabel label+ idxStr <- replaceAttr label' attrs alt SPfxImg+ let alt' = applyTemplate idxStr alt $ figureTemplate opts+ case outFormat opts of+ f | isLatexFormat f -> pure $ latexSubFigure x label+ _ -> pure [Image (label, cls, setLabel opts idxStr attrs) alt' tgt] replaceSubfig x = pure [x] latexSubFigure :: Inline -> T.Text -> [Inline]@@ -206,7 +206,7 @@ attrs = case blocksToInlines content of [Image (_, _, as) _ _] -> fattrs <> as _ -> fattrs- idxStr <- replaceAttr label' (lookup "label" attrs) title imgRefs+ idxStr <- replaceAttr label' attrs title SPfxImg let title' = case outFormat opts of f | isLatexFormat f -> title _ -> applyTemplate idxStr title $ figureTemplate opts
lib-internal/Text/Pandoc/CrossRef/References/Blocks/Table.hs view
@@ -27,9 +27,8 @@ import Text.Pandoc.Shared (blocksToInlines) import Data.Function ((&)) -import Text.Pandoc.CrossRef.References.Types import Text.Pandoc.CrossRef.References.Monad-import Text.Pandoc.CrossRef.References.Blocks.Util (setLabel, replaceAttr, walkReplaceInlines)+import Text.Pandoc.CrossRef.References.Blocks.Util import Text.Pandoc.CrossRef.Util.Options import Text.Pandoc.CrossRef.Util.Template import Text.Pandoc.CrossRef.Util.Util@@ -37,7 +36,7 @@ runTable :: Attr -> Maybe Attr -> Maybe ShortCaption -> Block -> [Block] -> [ColSpec] -> TableHead -> [TableBody] -> TableFoot -> WS (ReplacedResult Block) runTable (label, clss, attrs) mtattr short btitle rest colspec header cells foot = do opts <- ask- idxStr <- replaceAttr (Right label) (lookup "label" attrs) title tblRefs+ idxStr <- replaceAttr (Right label) attrs title SPfxTbl let title' = case outFormat opts of f | isLatexFormat f ->
lib-internal/Text/Pandoc/CrossRef/References/Blocks/Util.hs view
@@ -18,26 +18,29 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}+{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts, RecordWildCards, ViewPatterns+ , LambdaCase #-} module Text.Pandoc.CrossRef.References.Blocks.Util where import Control.Monad.Reader.Class import Control.Monad.State hiding (get, modify) import qualified Data.Map as M-import Data.Maybe import qualified Data.Text as T import Text.Pandoc.Definition import Text.Pandoc.Shared (stringify) import Text.Pandoc.Walk (walk) +import Text.Read (readMaybe)+ import Control.Applicative-import Lens.Micro import Lens.Micro.Mtl import Text.Pandoc.CrossRef.References.Types import Text.Pandoc.CrossRef.References.Monad import Text.Pandoc.CrossRef.Util.Options import Text.Pandoc.CrossRef.Util.Util+import qualified Data.Sequence as S+import Data.Sequence (ViewR(..)) setLabel :: Options -> [Inline] -> [(T.Text, T.Text)] -> [(T.Text, T.Text)] setLabel opts idx@@ -53,24 +56,52 @@ | xs == title = newTitle | otherwise = xs -replaceAttr :: Either T.Text T.Text -> Maybe T.Text -> [Inline] -> Lens References References RefMap RefMap -> WS [Inline]-replaceAttr label refLabel title prop- = do- o <- ask- chap <- take (chaptersDepth o) `fmap` use curChap- prop' <- use prop- let i = 1+ (M.size . M.filter (\x -> (chap == init (refIndex x)) && isNothing (refSubfigure x)) $ prop')- index = chap <> [(i, refLabel <|> customLabel o ref i)]- ref = either id (T.takeWhile (/=':')) label- label' = either (<> T.pack (':' : show index)) id label- when (M.member label' prop') $- error . T.unpack $ "Duplicate label: " <> label'- modifying prop $ M.insert label' RefRec {- refIndex= index- , refTitle= title- , refSubfigure = Nothing- }- return $ chapPrefix (chapDelim o) index+-- | Exactly like 'Prefix' but doesn't have 'PfxSec'. @S@ stands for "safer".+-- Sections are handled specially, see+-- "Text.Pandoc.CrossRef.References.Blocks.Header"+data SPrefix+ = SPfxImg+ | SPfxEqn+ | SPfxTbl+ | SPfxLst++toPrefix :: SPrefix -> Prefix+toPrefix = \case+ SPfxImg -> PfxImg+ SPfxEqn -> PfxEqn+ SPfxTbl -> PfxTbl+ SPfxLst -> PfxLst++replaceAttr+ :: Either T.Text T.Text -- ^ Reference id+ -> [(T.Text, T.Text)] -- ^ Attributes+ -> [Inline] -- ^ Title+ -> SPrefix -- ^ Prefix type+ -> WS [Inline]+replaceAttr label attrs title (toPrefix -> pfx) = do+ let refLabel = lookup "label" attrs+ number = readMaybe . T.unpack =<< lookup "number" attrs+ Options{..} <- ask+ chap <- S.take chaptersDepth <$> use (ctrsAt PfxSec)+ prop' <- use $ refsAt pfx+ curIdx <- use $ ctrsAt pfx+ let i | Just n <- number = n+ | chap' :> last' <- S.viewr curIdx+ , chap' == chap+ = succ . fst $ last'+ | otherwise = 1+ index = chap S.|> (i, refLabel <|> customLabel ref i)+ ref = either id (T.takeWhile (/=':')) label+ label' = either (<> T.pack (':' : show index)) id label+ when (M.member label' prop') $+ error . T.unpack $ "Duplicate label: " <> label'+ ctrsAt pfx .= index+ refsAt pfx %= M.insert label' RefRec {+ refIndex= index+ , refTitle= title+ , refSubfigure = Nothing+ }+ return $ chapPrefix chapDelim index mkCaption :: Options -> T.Text -> [Inline] -> Block mkCaption opts style
lib-internal/Text/Pandoc/CrossRef/References/List.hs view
@@ -41,13 +41,13 @@ False -> case blocks of (RawBlock fmt "\\listoffigures":xs) | isLaTeXRawBlockFmt fmt- -> use imgRefs >>= makeList "fig" lofItemTemplate lofTitle xs+ -> use (refsAt PfxImg) >>= makeList "fig" lofItemTemplate lofTitle xs (RawBlock fmt "\\listoftables":xs) | isLaTeXRawBlockFmt fmt- -> use tblRefs >>= makeList "tbl" lotItemTemplate lotTitle xs+ -> use (refsAt PfxTbl) >>= makeList "tbl" lotItemTemplate lotTitle xs (RawBlock fmt "\\listoflistings":xs) | isLaTeXRawBlockFmt fmt- -> use lstRefs >>= makeList "lst" lolItemTemplate lolTitle xs+ -> use (refsAt PfxLst) >>= makeList "lst" lolItemTemplate lolTitle xs _ -> pure blocks makeList
lib-internal/Text/Pandoc/CrossRef/References/Refs.hs view
@@ -18,7 +18,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, LambdaCase, RankNTypes #-} module Text.Pandoc.CrossRef.References.Refs (replaceRefs) where import Control.Arrow as A@@ -30,8 +30,9 @@ import Data.Maybe import qualified Data.Text as T import Text.Pandoc.Builder+import qualified Data.Sequence as S+import Data.Sequence (ViewR(..)) -import Control.Applicative import Debug.Trace import Lens.Micro.Mtl import Text.Pandoc.CrossRef.References.Types@@ -61,51 +62,55 @@ citationToInlines c = fromList (citationPrefix c) <> text ("@" <> citationId c) <> fromList (citationSuffix c)- replaceRefs'' :: Options -> T.Text -> [Citation] -> WS [Inline]+ replaceRefs'' :: Options -> Prefix -> [Citation] -> WS [Inline] replaceRefs'' opts = ($ opts) . flip $ case outFormat opts of f | isLatexFormat f -> replaceRefsLatex _ -> replaceRefsOther replaceRefs x = return x --- accessors to state variables-accMap :: M.Map T.Text ((RefMap -> Const RefMap RefMap) -> References -> Const RefMap References)-accMap = M.fromList [("fig:",imgRefs)- ,("eq:" ,eqnRefs)- ,("tbl:",tblRefs)- ,("lst:",lstRefs)- ,("sec:",secRefs)- ]+pfxMap :: T.Text -> Maybe Prefix+pfxMap = \case+ "fig:" -> Just PfxImg+ "eq:" -> Just PfxEqn+ "tbl:" -> Just PfxTbl+ "lst:" -> Just PfxLst+ "sec:" -> Just PfxSec+ _ -> Nothing +pfxMapR :: Prefix -> T.Text+pfxMapR = \case+ PfxImg -> "fig:"+ PfxEqn -> "eq:"+ PfxTbl -> "tbl:"+ PfxLst -> "lst:"+ PfxSec -> "sec:"+ -- accessors to options-prefMap :: M.Map T.Text (Options -> Bool -> Int -> [Inline], Options -> Template)-prefMap = M.fromList [("fig:",(figPrefix, figPrefixTemplate))- ,("eq:" ,(eqnPrefix, eqnPrefixTemplate))- ,("tbl:",(tblPrefix, tblPrefixTemplate))- ,("lst:",(lstPrefix, lstPrefixTemplate))- ,("sec:",(secPrefix, secPrefixTemplate))- ]+prefMap :: Prefix -> (Options -> Bool -> Int -> [Inline], Options -> Template)+prefMap = \case+ PfxImg -> (figPrefix, figPrefixTemplate)+ PfxEqn -> (eqnPrefix, eqnPrefixTemplate)+ PfxTbl -> (tblPrefix, tblPrefixTemplate)+ PfxLst -> (lstPrefix, lstPrefixTemplate)+ PfxSec -> (secPrefix, secPrefixTemplate) -prefixes :: [T.Text]-prefixes = M.keys accMap+prefixes :: [Prefix]+prefixes = [minBound..] -getRefPrefix :: Options -> T.Text -> Bool -> Int -> [Inline] -> [Inline]+getRefPrefix :: Options -> Prefix -> Bool -> Int -> [Inline] -> [Inline] getRefPrefix opts prefix capitalize num cit = applyTemplate' (M.fromDistinctAscList [("i", cit), ("p", refprefix)]) $ reftempl opts- where (refprefixf, reftempl) = lookupUnsafe prefix prefMap+ where (refprefixf, reftempl) = prefMap prefix refprefix = refprefixf opts capitalize num --lookupUnsafe :: Ord k => k -> M.Map k v -> v-lookupUnsafe = (fromJust .) . M.lookup--allCitsPrefix :: [Citation] -> Maybe T.Text+allCitsPrefix :: [Citation] -> Maybe Prefix allCitsPrefix cits = find isCitationPrefix prefixes where isCitationPrefix p =- all ((p `T.isPrefixOf`) . uncapitalizeFirst . citationId) cits+ all ((pfxMapR p `T.isPrefixOf`) . uncapitalizeFirst . citationId) cits -replaceRefsLatex :: T.Text -> Options -> [Citation] -> WS [Inline]+replaceRefsLatex :: Prefix -> Options -> [Citation] -> WS [Inline] replaceRefsLatex prefix opts cits | cref opts = replaceRefsLatex' prefix opts cits@@ -113,7 +118,7 @@ = toList . intercalate' (text ", ") . map fromList <$> mapM (replaceRefsLatex' prefix opts) (groupBy citationGroupPred cits) -replaceRefsLatex' :: T.Text -> Options -> [Citation] -> WS [Inline]+replaceRefsLatex' :: Prefix -> Options -> [Citation] -> WS [Inline] replaceRefsLatex' prefix opts cits = return $ p [texcit] where@@ -136,27 +141,28 @@ | cap = "\\Cref" | otherwise = "\\cref" -listLabels :: T.Text -> T.Text -> T.Text -> T.Text -> [Citation] -> T.Text+listLabels :: Prefix -> T.Text -> T.Text -> T.Text -> [Citation] -> T.Text listLabels prefix p sep s =- T.intercalate sep . map ((p <>) . (<> s) . mkLaTeXLabel' . (prefix<>) . getLabelWithoutPrefix . citationId)+ T.intercalate sep . map ((p <>) . (<> s) . mkLaTeXLabel' . (pfxMapR prefix <>) . getLabelWithoutPrefix . citationId) getLabelWithoutPrefix :: T.Text -> T.Text getLabelWithoutPrefix = T.drop 1 . T.dropWhile (/=':') getLabelPrefix :: T.Text -> Maybe T.Text getLabelPrefix lab- | uncapitalizeFirst p `elem` prefixes = Just p+ | Just pfx <- pfxMap (uncapitalizeFirst p)+ , pfx `elem` prefixes = Just p | otherwise = Nothing where p = flip T.snoc ':' . T.takeWhile (/=':') $ lab -replaceRefsOther :: T.Text -> Options -> [Citation] -> WS [Inline]+replaceRefsOther :: Prefix -> Options -> [Citation] -> WS [Inline] replaceRefsOther prefix opts cits = toList . intercalate' (text ", ") . map fromList <$> mapM (replaceRefsOther' prefix opts) (groupBy citationGroupPred cits) citationGroupPred :: Citation -> Citation -> Bool citationGroupPred = (==) `on` liftM2 (,) citationPrefix citationMode -replaceRefsOther' :: T.Text -> Options -> [Citation] -> WS [Inline]+replaceRefsOther' :: Prefix -> Options -> [Citation] -> WS [Inline] replaceRefsOther' prefix opts cits = do indices <- mapM (getRefIndex prefix opts) cits let@@ -183,7 +189,7 @@ instance Ord RefData where (<=) = (<=) `on` rdIdx -getRefIndex :: T.Text -> Options -> Citation -> WS RefData+getRefIndex :: Prefix -> Options -> Citation -> WS RefData getRefIndex prefix _opts Citation{citationId=cid,citationSuffix=suf} = do ref <- M.lookup lab <$> use prop@@ -196,11 +202,11 @@ , rdSubfig = join sub , rdSuffix = suf , rdTitle = tit- , rdPfx = prefix+ , rdPfx = pfxMapR prefix } where- prop = lookupUnsafe prefix accMap- lab = prefix <> getLabelWithoutPrefix cid+ prop = refsAt prefix+ lab = pfxMapR prefix <> getLabelWithoutPrefix cid data RefItem = RefRange RefData RefData | RefSingle RefData @@ -216,10 +222,10 @@ ) follows :: Index -> Index -> Bool follows a b- | Just (ai, al) <- HT.viewR a- , Just (bi, bl) <- HT.viewR b- = ai == bi && A.first (+1) bl == al- follows _ _ = False+ | ai :> al <- S.viewr a+ , bi :> bl <- S.viewr b+ = ai == bi && A.first succ bl == al+ | otherwise = False f :: [RefData] -> [RefItem] f [] = [] -- drop empty lists f [w] = [RefSingle w] -- single value
lib-internal/Text/Pandoc/CrossRef/References/Types.hs view
@@ -18,16 +18,18 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, RankNTypes, DataKinds #-} module Text.Pandoc.CrossRef.References.Types where import Data.Default import qualified Data.Map as M import Data.Text (Text)+import Lens.Micro.GHC import Lens.Micro.TH import Text.Pandoc.Definition+import qualified Data.Sequence as S -type Index = [(Int, Maybe Text)]+type Index = S.Seq (Int, Maybe Text) data RefRec = RefRec { refIndex :: Index , refTitle :: [Inline]@@ -36,17 +38,26 @@ type RefMap = M.Map Text RefRec +data Prefix+ = PfxImg+ | PfxEqn+ | PfxTbl+ | PfxLst+ | PfxSec+ deriving (Eq, Ord, Enum, Bounded, Show)+ -- state data type-data References = References { _imgRefs :: RefMap- , _eqnRefs :: RefMap- , _tblRefs :: RefMap- , _lstRefs :: RefMap- , _secRefs :: RefMap- , _curChap :: Index+data References = References { _stRefs :: M.Map Prefix RefMap+ , _stCtrs :: M.Map Prefix Index } deriving (Show, Eq) instance Default References where- def = References n n n n n []- where n = M.empty+ def = References mempty mempty makeLenses ''References++refsAt :: Prefix -> Lens' References RefMap+refsAt pfx = stRefs . at pfx . non mempty++ctrsAt :: Prefix -> Lens' References Index+ctrsAt pfx = stCtrs . at pfx . non mempty
lib-internal/Text/Pandoc/CrossRef/Util/Util.hs view
@@ -36,6 +36,7 @@ import Text.Pandoc.CrossRef.References.Types import Text.Pandoc.Writers.LaTeX import Text.ParserCombinators.ReadP (readP_to_S)+import qualified Data.Sequence as S intercalate' :: (Eq a, Monoid a, Foldable f) => a -> f a -> a intercalate' s xs@@ -68,9 +69,9 @@ chapPrefix :: [Inline] -> Index -> [Inline] chapPrefix delim = toList . intercalate' (fromList delim)- . map str- . filter (not . T.null)- . map (uncurry (fromMaybe . T.pack . show))+ . fmap str+ . S.filter (not . T.null)+ . fmap (uncurry (fromMaybe . T.pack . show)) data ReplacedResult a = Replaced Bool a | NotReplaced Bool type GenRR m = forall a. Data a => (a -> m (ReplacedResult a))
pandoc-crossref.cabal view
@@ -1,11 +1,11 @@ cabal-version: 2.0 --- This file has been generated from package.yaml by hpack version 0.35.1.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack name: pandoc-crossref-version: 0.3.15.2+version: 0.3.16.0 synopsis: Pandoc filter for cross-references description: pandoc-crossref is a pandoc filter for numbering figures, equations, tables and cross-references to them. category: Text@@ -84,6 +84,9 @@ test/m2m/multiple-eqn-same-para/expect.md test/m2m/multiple-eqn-same-para/expect.tex test/m2m/multiple-eqn-same-para/input.md+ test/m2m/numberOverride/expect.md+ test/m2m/numberOverride/expect.tex+ test/m2m/numberOverride/input.md test/m2m/secLabels/expect.md test/m2m/secLabels/expect.tex test/m2m/secLabels/input.md@@ -132,7 +135,7 @@ , mtl >=1.1 && <2.4 , pandoc >=3.0 && <3.2 , pandoc-crossref-internal- , pandoc-types+ , pandoc-types ==1.23.* , text >=1.2.2 && <2.1 default-language: Haskell2010 @@ -170,11 +173,12 @@ , directory >=1 && <1.4 , filepath >=1.1 && <1.5 , microlens >=0.4.12.0 && <0.5.0.0+ , microlens-ghc >=0.4.3.10 && <0.5.0.0 , microlens-mtl >=0.2.0.1 && <0.3.0.0 , microlens-th >=0.4.3.10 && <0.5.0.0 , mtl >=1.1 && <2.3 , pandoc >=3.0 && <3.2- , pandoc-types+ , pandoc-types ==1.23.* , syb >=0.4 && <0.8 , template-haskell >=2.7.0.0 && <3.0.0.0 , text >=1.2.2 && <2.1@@ -196,7 +200,7 @@ , optparse-applicative >=0.13 && <0.18 , pandoc >=3.0 && <3.2 , pandoc-crossref- , pandoc-types+ , pandoc-types ==1.23.* , template-haskell >=2.7.0.0 && <3.0.0.0 , temporary >=1.2 && <1.4 , text >=1.2.2 && <2.1@@ -217,11 +221,11 @@ , hspec >=2.4.4 && <3 , pandoc >=3.0 && <3.2 , pandoc-crossref- , pandoc-types+ , pandoc-types ==1.23.* , text >=1.2.2 && <2.1- default-language: Haskell2010 if flag(enable_flaky_tests) cpp-options: -DFLAKY+ default-language: Haskell2010 test-suite test-pandoc-crossref type: exitcode-stdio-1.0@@ -244,11 +248,11 @@ , pandoc >=3.0 && <3.2 , pandoc-crossref , pandoc-crossref-internal- , pandoc-types+ , pandoc-types ==1.23.* , text >=1.2.2 && <2.1- default-language: Haskell2010 if flag(enable_flaky_tests) cpp-options: -DFLAKY+ default-language: Haskell2010 benchmark simple type: exitcode-stdio-1.0@@ -263,6 +267,6 @@ , criterion >=1.5.9.0 && <1.7 , pandoc >=3.0 && <3.2 , pandoc-crossref- , pandoc-types+ , pandoc-types ==1.23.* , text >=1.2.2 && <2.1 default-language: Haskell2010
test/m2m/label-precedence/expect.md view
@@ -25,3 +25,26 @@ ### \*.A.A Subsubsection {#subsubsection} text text text++# B Custom on other elements {#custom-on-other-elements}++::: {#fig:fig3 .figure}+{label="F"}++::: caption+Figure F: Figure+:::+:::++::: {#tbl:table label="T"}+ a b c+ --- --- ---+ 1 2 3+ 4 5 6++ : Table T: Caption+:::++[$$y = e^x\qquad{(E)}$$]{#eq:equation label="E"}++fig. F tbl. T eq. E
test/m2m/label-precedence/expect.tex view
@@ -28,3 +28,35 @@ \subsubsection{*.A.A Subsubsection}\label{subsubsection}} text text text++\hypertarget{custom-on-other-elements}{%+\section{B Custom on other elements}\label{custom-on-other-elements}}++\begin{figure}+\hypertarget{fig:fig3}{%+\centering+\includegraphics{fig.png}+\caption{Figure}\label{fig:fig3}+}+\end{figure}++\hypertarget{tbl:table}{}+\begin{longtable}[]{@{}lll@{}}+\caption{\label{tbl:table}Caption}\tabularnewline+\toprule\noalign{}+a & b & c \\+\midrule\noalign{}+\endfirsthead+\toprule\noalign{}+a & b & c \\+\midrule\noalign{}+\endhead+\bottomrule\noalign{}+\endlastfoot+1 & 2 & 3 \\+4 & 5 & 6 \\+\end{longtable}++\begin{equation}\protect\hypertarget{eq:equation}{}{y = e^x}\label{eq:equation}\end{equation}++fig.~\ref{fig:fig3} tbl.~\ref{tbl:table} eq.~\ref{eq:equation}
test/m2m/label-precedence/input.md view
@@ -5,6 +5,8 @@ secLevelLabels: - alpha A figLabels: alpha α+tblLabels: alpha α+eqLabels: alpha α --- # First Section {label="*"}@@ -22,3 +24,20 @@ ### Subsubsection text text text++# Custom on other elements++{#fig:fig3 label="F"}++:::{#tbl:table label="T"}+a b c+--- --- ---+1 2 3+4 5 6++: Caption+:::++[$$y = e^x$$]{#eq:equation label="E"}++@fig:fig3 @tbl:table @eq:equation
+ test/m2m/numberOverride/expect.md view
@@ -0,0 +1,63 @@+# 1 Section++## 1.1 Earlier Subsection++::: {#fig:img1 .figure}+++::: caption+Figure 1.1.1: Image 1+:::+:::++## 1.6 Title of Subsection {#title-of-subsection number="6"}++::: {#fig:img2 .figure}+++::: caption+Figure 1.6.1: Image 1.6.2+:::+:::++::: {#fig:img3 .figure}+{number="100500"}++::: caption+Figure 1.6.100500: Image 1.6.100500+:::+:::++::: {#fig:img4 .figure}+++::: caption+Figure 1.6.100501: Image 1.6.100501+:::+:::++## 1.7 Title of Subsection++::: {#fig:img21 .figure}+++::: caption+Figure 1.7.1: Image 1.7.1+:::+:::++::: {#fig:img31 .figure}+{number="100500"}++::: caption+Figure 1.7.100500: Image 1.7.100500+:::+:::++::: {#fig:img41 .figure}+++::: caption+Figure 1.7.100501: Image 1.7.100501+:::+:::
+ test/m2m/numberOverride/expect.tex view
@@ -0,0 +1,67 @@+\hypertarget{section}{%+\section{1 Section}\label{section}}++\hypertarget{earlier-subsection}{%+\subsection{1.1 Earlier Subsection}\label{earlier-subsection}}++\begin{figure}+\hypertarget{fig:img1}{%+\centering+\includegraphics{img2.png}+\caption{Image 1}\label{fig:img1}+}+\end{figure}++\hypertarget{title-of-subsection}{%+\subsection{1.6 Title of Subsection}\label{title-of-subsection}}++\begin{figure}+\hypertarget{fig:img2}{%+\centering+\includegraphics{img2.png}+\caption{Image 1.6.2}\label{fig:img2}+}+\end{figure}++\begin{figure}+\hypertarget{fig:img3}{%+\centering+\includegraphics{img2.png}+\caption{Image 1.6.100500}\label{fig:img3}+}+\end{figure}++\begin{figure}+\hypertarget{fig:img4}{%+\centering+\includegraphics{img2.png}+\caption{Image 1.6.100501}\label{fig:img4}+}+\end{figure}++\hypertarget{title-of-subsection-1}{%+\subsection{1.7 Title of Subsection}\label{title-of-subsection-1}}++\begin{figure}+\hypertarget{fig:img21}{%+\centering+\includegraphics{img2.png}+\caption{Image 1.7.1}\label{fig:img21}+}+\end{figure}++\begin{figure}+\hypertarget{fig:img31}{%+\centering+\includegraphics{img2.png}+\caption{Image 1.7.100500}\label{fig:img31}+}+\end{figure}++\begin{figure}+\hypertarget{fig:img41}{%+\centering+\includegraphics{img2.png}+\caption{Image 1.7.100501}\label{fig:img41}+}+\end{figure}
+ test/m2m/numberOverride/input.md view
@@ -0,0 +1,28 @@+---+numberSections: true+sectionsDepth: -1+chaptersDepth: 3+chapters: true+...++# Section++## Earlier Subsection++{#fig:img1}++## Title of Subsection {number=6}++{#fig:img2}++{#fig:img3 number=100500}++{#fig:img4}++## Title of Subsection++{#fig:img21}++{#fig:img31 number=100500}++{#fig:img41}
test/test-pandoc-crossref.hs view
@@ -18,7 +18,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE FlexibleContexts, CPP, OverloadedStrings, RankNTypes, ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts, CPP, OverloadedStrings, RankNTypes+ , ScopedTypeVariables, OverloadedLists #-} import Test.Hspec import Text.Pandoc hiding (getDataFileName) import Text.Pandoc.Builder hiding (figure)@@ -29,7 +30,6 @@ import Control.Arrow import qualified Data.Map as M import qualified Data.Text as T-import qualified Data.Default as Df import Data.Maybe import Text.Pandoc.CrossRef@@ -55,7 +55,7 @@ it "Labels equations" $ testAll (equation' "a^2+b^2=c^2" "equation") (spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" ""),- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels equations in the middle of text" $ testAll ( text "This is an equation: "@@ -65,7 +65,7 @@ text "This is an equation: " <> spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" "") <> text " it should be labeled",- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels equations in the beginning of text" $ testAll ( equation' "a^2+b^2=c^2" "equation"@@ -73,7 +73,7 @@ ( spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" "") <> text " it should be labeled",- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels equations in the end of text" $ testAll ( text "This is an equation: "@@ -81,7 +81,7 @@ ( text "This is an equation: " <> spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" ""),- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) -- TODO: -- describe "References.Blocks.spanInlines"@@ -91,7 +91,7 @@ it "Labels images" $ testAll (figure "test.jpg" "" "Test figure" Nothing "figure") (figure "test.jpg" "" "Figure 1: Test figure" (Just "Test figure") "figure",- imgRefs =: M.fromList $ refRec' "fig:figure" 1 "Test figure")+ PfxImg =: M.fromList $ refRec' "fig:figure" 1 "Test figure") it "Labels subfigures" $ testAll ( divWith ("fig:subfigure",[],[]) (@@ -116,7 +116,7 @@ ( para (figure' "test21.jpg" "" "a" "figure21") <> para (figure' "test22.jpg" "" "b" "figure22") )- , imgRefs =: M.fromList [("fig:figure1",RefRec {+ , PfxImg =: M.fromList [("fig:figure1",RefRec { refIndex = [(1,Nothing)], refTitle = [Str "Test",Space,Str "figure",Space,Str "1"], refSubfigure = Just [(1, Just "a")]}),@@ -145,7 +145,7 @@ it "Labels equations" $ testAll (equation "a^2+b^2=c^2" "equation") (para $ spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" ""),- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels equations in the middle of text" $ testAll (para $ text "This is an equation: "@@ -155,7 +155,7 @@ text "This is an equation: " <> spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" "") <> text " it should be labeled",- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels equations in the beginning of text" $ testAll (para $ equation' "a^2+b^2=c^2" "equation"@@ -163,7 +163,7 @@ (para $ spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" "") <> text " it should be labeled",- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels equations in the end of text" $ testAll (para $ text "This is an equation: "@@ -171,80 +171,79 @@ (para $ text "This is an equation: " <> spanWith ("eq:equation", [], []) (equation' "a^2+b^2=c^2\\qquad{(1)}" ""),- eqnRefs =: M.fromList $ refRec'' "eq:equation" 1)+ PfxEqn =: M.fromList $ refRec'' "eq:equation" 1) it "Labels tables" $ testAll (table' "Test table" "table") (divWith ("tbl:table", [], []) $ table' "Table 1: Test table" "",- tblRefs =: M.fromList $ refRec' "tbl:table" 1 "Test table")+ PfxTbl =: M.fromList $ refRec' "tbl:table" 1 "Test table") it "Labels code blocks" $ testAll (codeBlock' "Test code block" "codeblock") (codeBlockDiv "Listing 1: Test code block" "codeblock",- lstRefs =: M.fromList $ refRec' "lst:codeblock" 1 "Test code block")+ PfxLst =: M.fromList $ refRec' "lst:codeblock" 1 "Test code block") it "Labels code block divs" $ testAll (codeBlockDiv "Test code block" "codeblock") (codeBlockDiv "Listing 1: Test code block" "codeblock",- lstRefs =: M.fromList $ refRec' "lst:codeblock" 1 "Test code block")+ PfxLst =: M.fromList $ refRec' "lst:codeblock" 1 "Test code block") it "Labels sections divs" $ testAll (section "Section Header" 1 "section") (section "Section Header" 1 "section",- secRefs .~ M.fromList (refRec' "sec:section" 1 "Section Header")- $ curChap =: [(1,Nothing)])+ PfxSec =: M.fromList (refRec' "sec:section" 1 "Section Header")) describe "References.Refs.replaceRefs" $ do it "References one image" $- testRefs' "fig:" [1] [4] imgRefs "fig.\160\&4"+ testRefs' "fig:" [1] [4] PfxImg "fig.\160\&4" it "References multiple images" $- testRefs' "fig:" [1..3] [4..6] imgRefs "figs.\160\&4-6"+ testRefs' "fig:" [1..3] [4..6] PfxImg "figs.\160\&4-6" it "References one equation" $- testRefs' "eq:" [1] [4] eqnRefs "eq.\160\&4"+ testRefs' "eq:" [1] [4] PfxEqn "eq.\160\&4" it "References multiple equations" $- testRefs' "eq:" [1..3] [4..6] eqnRefs "eqns.\160\&4-6"+ testRefs' "eq:" [1..3] [4..6] PfxEqn "eqns.\160\&4-6" it "References one table" $- testRefs' "tbl:" [1] [4] tblRefs "tbl.\160\&4"+ testRefs' "tbl:" [1] [4] PfxTbl "tbl.\160\&4" it "References multiple tables" $- testRefs' "tbl:" [1..3] [4..6] tblRefs "tbls.\160\&4-6"+ testRefs' "tbl:" [1..3] [4..6] PfxTbl "tbls.\160\&4-6" it "References one listing" $- testRefs' "lst:" [1] [4] lstRefs "lst.\160\&4"+ testRefs' "lst:" [1] [4] PfxLst "lst.\160\&4" it "References multiple listings" $- testRefs' "lst:" [1..3] [4..6] lstRefs "lsts.\160\&4-6"+ testRefs' "lst:" [1..3] [4..6] PfxLst "lsts.\160\&4-6" it "References one section" $- testRefs' "sec:" [1] [4] secRefs "sec.\160\&4"+ testRefs' "sec:" [1] [4] PfxSec "sec.\160\&4" it "References multiple sections" $- testRefs' "sec:" [1..3] [4..6] secRefs "secs.\160\&4-6"+ testRefs' "sec:" [1..3] [4..6] PfxSec "secs.\160\&4-6" it "Separates references to different chapter items by a comma" $- testRefs'' "lst:" [1..6] (zip [1,1..] [4..6] <> zip [2,2..] [7..9]) lstRefs "lsts.\160\&1.4-1.6, 2.7-2.9"+ testRefs'' "lst:" [1..6] (zip [1,1..] [4..6] <> zip [2,2..] [7..9]) PfxLst "lsts.\160\&1.4-1.6, 2.7-2.9" describe "References.Refs.replaceRefs capitalization" $ do it "References one image" $- testRefs' "Fig:" [1] [4] imgRefs "Fig.\160\&4"+ testRefs' "Fig:" [1] [4] PfxImg "Fig.\160\&4" it "References multiple images" $- testRefs' "Fig:" [1..3] [4..6] imgRefs "Figs.\160\&4-6"+ testRefs' "Fig:" [1..3] [4..6] PfxImg "Figs.\160\&4-6" it "References one equation" $- testRefs' "Eq:" [1] [4] eqnRefs "Eq.\160\&4"+ testRefs' "Eq:" [1] [4] PfxEqn "Eq.\160\&4" it "References multiple equations" $- testRefs' "Eq:" [1..3] [4..6] eqnRefs "Eqns.\160\&4-6"+ testRefs' "Eq:" [1..3] [4..6] PfxEqn "Eqns.\160\&4-6" it "References one table" $- testRefs' "Tbl:" [1] [4] tblRefs "Tbl.\160\&4"+ testRefs' "Tbl:" [1] [4] PfxTbl "Tbl.\160\&4" it "References multiple tables" $- testRefs' "Tbl:" [1..3] [4..6] tblRefs "Tbls.\160\&4-6"+ testRefs' "Tbl:" [1..3] [4..6] PfxTbl "Tbls.\160\&4-6" it "References one listing" $- testRefs' "Lst:" [1] [4] lstRefs "Lst.\160\&4"+ testRefs' "Lst:" [1] [4] PfxLst "Lst.\160\&4" it "References multiple listings" $- testRefs' "Lst:" [1..3] [4..6] lstRefs "Lsts.\160\&4-6"+ testRefs' "Lst:" [1..3] [4..6] PfxLst "Lsts.\160\&4-6" it "References one listing" $- testRefs' "Sec:" [1] [4] secRefs "Sec.\160\&4"+ testRefs' "Sec:" [1] [4] PfxSec "Sec.\160\&4" it "References multiple listings" $- testRefs' "Sec:" [1..3] [4..6] secRefs "Secs.\160\&4-6"+ testRefs' "Sec:" [1..3] [4..6] PfxSec "Secs.\160\&4-6" describe "References.List.listOf" $ do it "Generates list of tables" $ testList (rawBlock "latex" "\\listoftables")- (tblRefs =: M.fromList $ refRec' "tbl:1" 4 "4" <> refRec' "tbl:2" 5 "5" <> refRec' "tbl:3" 6 "6")+ (PfxTbl =: M.fromList $ refRec' "tbl:1" 4 "4" <> refRec' "tbl:2" 5 "5" <> refRec' "tbl:3" 6 "6") (header 1 (text "List of Tables") <> divWith ("", ["list", "list-of-tbl"], []) (mconcat $ map (\n -> plain (str (T.pack $ show n <> ".") <> space <> str (T.pack $ show n) <> linebreak)) [4..6 :: Int])) it "Generates list of figures" $ testList (rawBlock "latex" "\\listoffigures")- (imgRefs =: M.fromList $ refRec' "fig:1" 4 "4" <> refRec' "fig:2" 5 "5" <> refRec' "fig:3" 6 "6")+ (PfxImg =: M.fromList $ refRec' "fig:1" 4 "4" <> refRec' "fig:2" 5 "5" <> refRec' "fig:3" 6 "6") (header 1 (text "List of Figures") <> divWith ("", ["list", "list-of-fig"], []) (mconcat $ map (\n -> plain (str (T.pack $ show n <> ".") <> space <> str (T.pack $ show n) <> linebreak)) [4..6 :: Int])) @@ -319,7 +318,7 @@ it "Tbl labels" $ table' "A table" "some_table1" <> para (citeGen "tbl:some_table" [1])- `test` concat+ `test` concat ( [ "\\hypertarget{tbl:some_table1}{}\n" , "\\begin{longtable}[]{@{}@{}}\n" , "\\caption{\\label{tbl:some_table1}A table}\\tabularnewline\n"@@ -331,7 +330,7 @@ , " \\\\\n" , "\\end{longtable}\n\n" , "tbl.~\\ref{tbl:some_table1}"- ]+ ] :: [String]) #endif it "Code block labels" $ do@@ -366,11 +365,11 @@ refRec''' :: T.Text -> (Int, Int) -> [(T.Text, RefRec)] refRec''' ref (c,i) = [(ref, RefRec{refIndex=[(c,Nothing), (i,Nothing)],refTitle=toList $ text "",refSubfigure=Nothing})] -testRefs' :: T.Text -> [Int] -> [Int] -> Lens' References (M.Map T.Text RefRec) -> T.Text -> Expectation-testRefs' p l1 l2 prop res = testRefs (para $ citeGen p l1) (set prop (refGen p l1 l2) def) (para $ text res)+testRefs' :: T.Text -> [Int] -> [Int] -> Prefix -> T.Text -> Expectation+testRefs' p l1 l2 prop res = testRefs (para $ citeGen p l1) (set (refsAt prop) (refGen p l1 l2) def) (para $ text res) -testRefs'' :: T.Text -> [Int] -> [(Int, Int)] -> Lens' References (M.Map T.Text RefRec) -> T.Text -> Expectation-testRefs'' p l1 l2 prop res = testRefs (para $ citeGen p l1) (set prop (refGen' p l1 l2) def) (para $ text res)+testRefs'' :: T.Text -> [Int] -> [(Int, Int)] -> Prefix -> T.Text -> Expectation+testRefs'' p l1 l2 prop res = testRefs (para $ citeGen p l1) (set (refsAt prop) (refGen' p l1 l2) def) (para $ text res) testAll :: (Eq a, Data a, Show a) => Many a -> (Many a, References) -> Expectation testAll = testState References.Blocks.replaceAll def@@ -460,5 +459,7 @@ cit r = [defCit{citationId=r}] infixr 0 =:-(=:) :: Df.Default r => Lens' r a -> a -> r-a =: b = a .~ b $ def+(=:) :: Prefix -> M.Map T.Text RefRec -> References+a =: b = def+ & ctrsAt a .~ (refIndex $ last $ M.elems b)+ & refsAt a .~ b