pandoc-crossref 0.3.14.0 → 0.3.15.0
raw patch · 35 files changed
+1678/−782 lines, 35 filesdep ~pandocdep ~pandoc-typesPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: pandoc, pandoc-types
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- lib-internal/Text/Pandoc/CrossRef/References/Blocks.hs +65/−369
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/CodeBlock.hs +67/−0
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Header.hs +79/−0
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Math.hs +77/−0
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Subfigures.hs +218/−0
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Table.hs +53/−0
- lib-internal/Text/Pandoc/CrossRef/References/Blocks/Util.hs +78/−0
- lib-internal/Text/Pandoc/CrossRef/References/List.hs +33/−31
- lib-internal/Text/Pandoc/CrossRef/References/Monad.hs +31/−0
- lib-internal/Text/Pandoc/CrossRef/References/Refs.hs +13/−9
- lib-internal/Text/Pandoc/CrossRef/References/Types.hs +0/−4
- lib-internal/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs +13/−8
- lib/Text/Pandoc/CrossRef.hs +6/−5
- pandoc-crossref.cabal +25/−16
- test/demo-chapters.inc +144/−92
- test/demo.inc +144/−92
- test/m2m/emptyChapterLabels/expect.md +7/−1
- test/m2m/label-precedence/expect.md +14/−2
- test/m2m/listOfTemplates-buillet-list/expect.md +63/−9
- test/m2m/listOfTemplates-ord-list/expect.md +63/−9
- test/m2m/listOfTemplates/expect.md +63/−9
- test/m2m/listOfTemplates/expect.tex +12/−10
- test/m2m/loxItemTitle/expect.md +63/−9
- test/m2m/loxItemTitle/expect.tex +12/−10
- test/m2m/secLabels/expect.md +7/−1
- test/m2m/secLabels/expect.tex +6/−5
- test/m2m/setLabelAttribute/expect.md +7/−1
- test/m2m/setLabelAttribute/expect.tex +6/−5
- test/m2m/subfigures-ccsDelim/expect.md +72/−17
- test/m2m/subfigures-grid/expect.md +99/−20
- test/m2m/subfigures/expect.md +72/−17
- test/m2m/titlesInRefs/expect.md +7/−1
- test/test-integrative.hs +1/−1
- test/test-pandoc-crossref.hs +52/−29
CHANGELOG.md view
@@ -1,3 +1,9 @@+## 0.3.15.0++- Update demos+- Updates for pandoc 3.0 and bump version+- Reshuffle and deduplicate block handling code+ ## 0.3.14.0 ### Main changes
lib-internal/Text/Pandoc/CrossRef/References/Blocks.hs view
@@ -18,342 +18,100 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}+{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts, ScopedTypeVariables, LambdaCase #-} module Text.Pandoc.CrossRef.References.Blocks ( replaceAll ) where -import Control.Monad.State hiding (get, modify)+import Control.Monad.Reader import Data.List-import qualified Data.Map as M-import Data.Maybe import qualified Data.Text as T-import qualified Data.Text.Read as T-import qualified Text.Pandoc.Builder as B+import Lens.Micro import Text.Pandoc.Definition-import Text.Pandoc.Shared (blocksToInlines, stringify)-import Text.Pandoc.Walk (walk)+import Text.Pandoc.Shared (blocksToInlines) -import Control.Applicative-import Data.Default-import Lens.Micro-import Lens.Micro.Mtl-import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.References.Blocks.CodeBlock+import Text.Pandoc.CrossRef.References.Blocks.Header+import Text.Pandoc.CrossRef.References.Blocks.Math+import Text.Pandoc.CrossRef.References.Blocks.Subfigures+import Text.Pandoc.CrossRef.References.Blocks.Table+import Text.Pandoc.CrossRef.References.Blocks.Util+import Text.Pandoc.CrossRef.References.Monad import Text.Pandoc.CrossRef.Util.Options-import Text.Pandoc.CrossRef.Util.Template import Text.Pandoc.CrossRef.Util.Util -replaceAll :: (Data a) => Options -> a -> WS a-replaceAll opts =- runReplace (mkRR (replaceBlock opts)- `extRR` replaceInline opts- `extRR` replaceInlineMany opts- )- . runSplitMath- . everywhere (mkT divBlocks `extT` spanInlines opts)- where- runSplitMath | tableEqns opts- , not $ isLatexFormat (outFormat opts)- = everywhere (mkT splitMath)- | otherwise = id--simpleTable :: [Alignment] -> [ColWidth] -> [[[Block]]] -> Block-simpleTable align width bod = Table nullAttr noCaption (zip align width)- noTableHead [mkBody bod] noTableFoot+replaceAll :: (Data a) => a -> WS a+replaceAll x = do+ opts <- ask+ x & runReplace (mkRR replaceBlock+ `extRR` replaceInlineMany+ )+ . runSplitMath opts+ . everywhere (mkT divBlocks `extT` spanInlines opts) where- mkBody xs = TableBody nullAttr (RowHeadColumns 0) [] (map mkRow xs)- mkRow xs = Row nullAttr (map mkCell xs)- mkCell xs = Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) xs- noCaption = Caption Nothing mempty- noTableHead = TableHead nullAttr []- noTableFoot = TableFoot nullAttr []+ runSplitMath opts+ | tableEqns opts+ , not $ isLatexFormat (outFormat opts)+ = everywhere (mkT splitMath)+ | otherwise = id -setLabel :: Options -> [Inline] -> [(T.Text, T.Text)] -> [(T.Text, T.Text)]-setLabel opts idx- | setLabelAttribute opts- = (("label", stringify idx) :)- . filter ((/= "label") . fst)- | otherwise = id+extractCaption :: Block -> Maybe [Inline]+extractCaption = \case+ Para caption -> Just caption+ Div (_, dcls, _) [Para caption] | "caption" `elem` dcls -> Just caption+ _ -> Nothing -replaceBlock :: Options -> Block -> WS (ReplacedResult Block)-replaceBlock opts (Header n (label, cls, attrs) text')- = do- 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--- subfigures-replaceBlock opts (Div (label,cls,attrs) images)+replaceBlock :: Block -> WS (ReplacedResult Block)+replaceBlock (Header n attr text') = runHeader n attr text'+replaceBlock (Figure attr@(label, _, _) caption content) | "fig:" `T.isPrefixOf` label- , Para caption <- last images- = do- idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) caption imgRefs- let (cont, st) = runState (runReplace (mkRR $ replaceSubfigs opts') $ init images) def- collectedCaptions = B.toList $- intercalate' (B.fromList $ ccsDelim opts)- $ map (B.fromList . collectCaps . snd)- $ sortOn (refIndex . snd)- $ filter (not . null . refTitle . snd)- $ M.toList- $ st^.imgRefs- collectCaps v =- applyTemplate- (chapPrefix (chapDelim opts) (refIndex v))- (refTitle v)- (ccsTemplate opts)- vars = M.fromDistinctAscList- [ ("ccs", collectedCaptions)- , ("i", idxStr)- , ("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)- case outFormat opts of- f | isLatexFormat f ->- replaceNoRecurse $ Div nullAttr $- [ RawBlock (Format "latex") "\\begin{pandoccrossrefsubfigures}" ]- <> cont <>- [ Para [RawInline (Format "latex") "\\caption["- , Span nullAttr (removeFootnotes caption)- , RawInline (Format "latex") "]"- , Span nullAttr caption]- , RawBlock (Format "latex") $ mkLaTeXLabel label- , RawBlock (Format "latex") "\\end{pandoccrossrefsubfigures}"]- _ -> replaceNoRecurse $ Div (label, "subfigures":cls, setLabel opts idxStr attrs) $ toTable cont capt- where- opts' = opts- { figureTemplate = subfigureChildTemplate opts- , customLabel = \r i -> customLabel opts ("sub"<>r) i- }- removeFootnotes = walk removeFootnote- removeFootnote Note{} = Str ""- removeFootnote x = x- toTable :: [Block] -> [Inline] -> [Block]- toTable blks capt- | subfigGrid opts = [ simpleTable align (map ColWidth widths) (map blkToRow blks)- , mkCaption opts "Image Caption" capt]- | otherwise = blks <> [mkCaption opts "Image Caption" capt]- where- align | Para ils:_ <- blks = replicate (length $ mapMaybe getWidth ils) AlignCenter- | otherwise = error "Misformatted subfigures block"- widths | Para ils:_ <- blks- = fixZeros $ mapMaybe getWidth ils- | otherwise = error "Misformatted subfigures block"- getWidth (Image (_id, _class, as) _ _)- = Just $ maybe 0 percToDouble $ lookup "width" as- getWidth _ = Nothing- fixZeros :: [Double] -> [Double]- fixZeros ws- = let nz = length $ filter (== 0) ws- rzw = (0.99 - sum ws) / fromIntegral nz- in if nz>0- then map (\x -> if x == 0 then rzw else x) ws- else ws- percToDouble :: T.Text -> Double- percToDouble percs- | Right (perc, "%") <- T.double percs- = perc/100.0- | otherwise = error "Only percent allowed in subfigure width!"- blkToRow :: Block -> [[Block]]- blkToRow (Para inls) = mapMaybe inlToCell inls- blkToRow x = [[x]]- inlToCell :: Inline -> Maybe [Block]- inlToCell (Image (id', cs, as) txt tgt) = Just [Para [Image (id', cs, setW as) txt tgt]]- inlToCell _ = Nothing- setW as = ("width", "100%"):filter ((/="width") . fst) as-replaceBlock opts (Div (label,clss,attrs) [Table tattr (Caption short (btitle:rest)) colspec header cells foot])- | not $ null title+ = runFigure False attr caption content+replaceBlock (Div attr@(label, _, _) content)+ | "fig:" `T.isPrefixOf` label+ , Just caption <- extractCaption $ last content+ = case init content of+ [Figure ("", [], []) _ content'] -- nested figure due to implicit_figures...+ -> runFigure False attr (Caption Nothing [Para caption]) content'+ [x] -> runFigure False attr (Caption Nothing [Para caption]) [x]+ xs -> runSubfigures attr xs caption+replaceBlock (Div attr@(label, _, _) [Table tattr (Caption short (btitle:rest)) colspec header cells foot])+ | not $ null $ blocksToInlines [btitle] , "tbl:" `T.isPrefixOf` label- = do- idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) title tblRefs- let title' =- case outFormat opts of- f | isLatexFormat f ->- RawInline (Format "latex") (mkLaTeXLabel label) : title- _ -> applyTemplate idxStr title $ tableTemplate opts- caption' = Caption short (walkReplaceInlines title' title btitle:rest)- replaceNoRecurse $ Div (label, clss, setLabel opts idxStr attrs) [Table tattr caption' colspec header cells foot]- where title = blocksToInlines [btitle]-replaceBlock opts (Table (label,clss,attrs) (Caption short (btitle:rest)) colspec header cells foot)- | not $ null title+ = runTable attr (Just tattr) short btitle rest colspec header cells foot+replaceBlock (Table attr@(label, _, _) (Caption short (btitle:rest)) colspec header cells foot)+ | not $ null $ blocksToInlines [btitle] , "tbl:" `T.isPrefixOf` label- = do- idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) title tblRefs- let title' =- case outFormat opts of- f | isLatexFormat f ->- RawInline (Format "latex") (mkLaTeXLabel label) : title- _ -> applyTemplate idxStr title $ tableTemplate opts- caption' = Caption short (walkReplaceInlines title' title btitle:rest)- replaceNoRecurse $ Table (label, clss, setLabel opts idxStr attrs) caption' colspec header cells foot- where title = blocksToInlines [btitle]-replaceBlock opts cb@(CodeBlock (label, classes, attrs) code)+ = runTable attr Nothing short btitle rest colspec header cells foot+replaceBlock (CodeBlock attr@(label, _, attrs) code) | not $ T.null label , "lst:" `T.isPrefixOf` label , Just caption <- lookup "caption" attrs- = case outFormat opts of- f- --if used with listings package,nothing shoud be done- | isLatexFormat f, listings opts -> noReplaceNoRecurse- --if not using listings, however, wrap it in a codelisting environment- | isLatexFormat f ->- replaceNoRecurse $ Div nullAttr [- RawBlock (Format "latex") "\\begin{codelisting}"- , Plain [- RawInline (Format "latex") "\\caption{"- , Str caption- , RawInline (Format "latex") "}"- ]- , cb- , RawBlock (Format "latex") "\\end{codelisting}"- ]- _ -> do- let cap = B.toList $ B.text caption- idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) cap lstRefs- let caption' = applyTemplate idxStr cap $ listingTemplate opts- replaceNoRecurse $ Div (label, "listing":classes, []) [- mkCaption opts "Caption" caption'- , CodeBlock ("", classes, filter ((/="caption") . fst) $ setLabel opts idxStr attrs) code- ]-replaceBlock opts+ = runCodeBlock attr code $ Left caption+replaceBlock (Div (label,"listing":divClasses, divAttrs) [Para caption, CodeBlock ("",cbClasses,cbAttrs) code]) | not $ T.null label , "lst:" `T.isPrefixOf` label- = case outFormat opts of- f- --if used with listings package, return code block with caption- | isLatexFormat f, listings opts ->- replaceNoRecurse $ CodeBlock (label,classes,("caption",escapeLaTeX $ stringify caption):attrs) code- --if not using listings, however, wrap it in a codelisting environment- | isLatexFormat f ->- replaceNoRecurse $ Div nullAttr [- RawBlock (Format "latex") "\\begin{codelisting}"- , Para [- RawInline (Format "latex") "\\caption"- , Span nullAttr caption- ]- , CodeBlock (label,classes,attrs) code- , RawBlock (Format "latex") "\\end{codelisting}"- ]- _ -> do- idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) caption lstRefs- let caption' = applyTemplate idxStr caption $ listingTemplate opts- replaceNoRecurse $ Div (label, "listing":classes, []) [- mkCaption opts "Caption" caption'- , CodeBlock ("", classes, setLabel opts idxStr attrs) code- ]- where attrs = divAttrs <> cbAttrs- classes = nub $ divClasses <> cbClasses-replaceBlock opts (Para [Span sattrs@(label, cls, attrs) [Math DisplayMath eq]])- | not $ isLatexFormat (outFormat opts)- , tableEqns opts- = do- (eq', idxStr) <- replaceEqn opts sattrs eq- let mathfmt = if eqnBlockInlineMath opts then InlineMath else DisplayMath- replaceNoRecurse $ Div (label,cls,setLabel opts idxStr attrs) $- applyTemplate [Math mathfmt $ stringify idxStr] [Math mathfmt eq']- $ eqnBlockTemplate opts-replaceBlock _ _ = noReplaceRecurse--replaceEqn :: Options -> Attr -> T.Text -> WS (T.Text, [Inline])-replaceEqn opts (label, _, attrs) eq = do- let label' | T.null label = Left "eq"- | otherwise = Right label- idxStrRaw <- replaceAttr opts label' (lookup "label" attrs) [] eqnRefs- let idxStr = applyTemplate' (M.fromDistinctAscList [("i", idxStrRaw)]) $ eqnIndexTemplate opts- eqTxt = applyTemplate' eqTxtVars $ eqnInlineTemplate opts :: [Inline]- eqTxtVars = M.fromDistinctAscList- [ ("e", [Str eq])- , ("i", idxStr)- , ("ri", idxStrRaw)- ]- eq' | tableEqns opts = eq- | otherwise = stringify eqTxt- return (eq', idxStr)+ = runCodeBlock (label, nub $ divClasses <> cbClasses, divAttrs <> cbAttrs) code $ Right caption+replaceBlock (Para [Span attr [Math DisplayMath eq]])+ = runBlockMath attr eq+replaceBlock _ = noReplaceRecurse -replaceInlineMany :: Options -> [Inline] -> WS (ReplacedResult [Inline])-replaceInlineMany opts (Span spanAttr@(label,clss,attrs) [Math DisplayMath eq]:xs)- | "eq:" `T.isPrefixOf` label || T.null label && autoEqnLabels opts- = replaceRecurse . (<>xs) =<< case outFormat opts of- f | isLatexFormat f ->+replaceInlineMany :: [Inline] -> WS (ReplacedResult [Inline])+replaceInlineMany (Span spanAttr@(label,clss,attrs) [Math DisplayMath eq]:xs) = do+ opts <- ask+ if "eq:" `T.isPrefixOf` label || T.null label && autoEqnLabels opts+ then do+ replaceRecurse . (<> xs) =<< if isLatexFormat $ outFormat opts+ then pure [RawInline (Format "latex") "\\begin{equation}" , Span spanAttr [RawInline (Format "latex") eq] , RawInline (Format "latex") $ mkLaTeXLabel label <> "\\end{equation}"]- _ -> do- (eq', idxStr) <- replaceEqn opts spanAttr eq+ else do+ (eq', idxStr) <- replaceEqn spanAttr eq pure [Span (label,clss,setLabel opts idxStr attrs) [Math DisplayMath eq']]-replaceInlineMany _ _ = noReplaceRecurse--replaceInline :: Options -> Inline -> WS (ReplacedResult Inline)-replaceInline opts (Image (label,cls,attrs) alt img@(_, tit))- | "fig:" `T.isPrefixOf` label && "fig:" `T.isPrefixOf` tit- = do- idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) alt imgRefs- let alt' = case outFormat opts of- f | isLatexFormat f -> alt- _ -> applyTemplate idxStr alt $ figureTemplate opts- replaceNoRecurse $ Image (label,cls,setLabel opts idxStr attrs) alt' img-replaceInline _ _ = noReplaceRecurse--replaceSubfigs :: Options -> [Inline] -> WS (ReplacedResult [Inline])-replaceSubfigs opts = (replaceNoRecurse . concat) <=< mapM (replaceSubfig opts)--replaceSubfig :: Options -> Inline -> WS [Inline]-replaceSubfig opts x@(Image (label,cls,attrs) alt (src, tit))- = do- let label' | "fig:" `T.isPrefixOf` label = Right label- | T.null label = Left "fig"- | otherwise = Right $ "fig:" <> label- idxStr <- replaceAttr opts label' (lookup "label" attrs) alt imgRefs- case outFormat opts of- f | isLatexFormat f ->- return $ latexSubFigure x label- _ ->- let alt' = applyTemplate idxStr alt $ figureTemplate opts- tit' | "nocaption" `elem` cls = fromMaybe tit $ T.stripPrefix "fig:" tit- | "fig:" `T.isPrefixOf` tit = tit- | otherwise = "fig:" <> tit- in return [Image (label, cls, setLabel opts idxStr attrs) alt' (src, tit')]-replaceSubfig _ x = return [x]+ else noReplaceRecurse+replaceInlineMany _ = noReplaceRecurse divBlocks :: Block -> Block divBlocks (Table tattr (Caption short (btitle:rest)) colspec header cells foot)@@ -365,25 +123,6 @@ title = blocksToInlines [btitle] divBlocks x = x -walkReplaceInlines :: [Inline] -> [Inline] -> Block -> Block-walkReplaceInlines newTitle title = walk replaceInlines- where- replaceInlines xs- | xs == title = newTitle- | otherwise = xs--splitMath :: [Block] -> [Block]-splitMath (Para ils:xs)- | length ils > 1 = map Para (split [] [] ils) <> xs- where- split res acc [] = reverse (reverse acc : res)- split res acc (x@(Span _ [Math DisplayMath _]):ys) =- split ([x] : reverse (dropSpaces acc) : res)- [] (dropSpaces ys)- split res acc (y:ys) = split res (y:acc) ys- dropSpaces = dropWhile isSpace-splitMath xs = xs- spanInlines :: Options -> [Inline] -> [Inline] spanInlines opts (math@(Math DisplayMath _eq):ils) | c:ils' <- dropWhile isSpace ils@@ -392,46 +131,3 @@ | autoEqnLabels opts = Span nullAttr [math]:ils spanInlines _ x = x--replaceAttr :: Options -> Either T.Text T.Text -> Maybe T.Text -> [Inline] -> Lens References References RefMap RefMap -> WS [Inline]-replaceAttr o label refLabel title prop- = do- 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--latexSubFigure :: Inline -> T.Text -> [Inline]-latexSubFigure (Image (_, cls, attrs) alt (src, title)) label =- let- title' = fromMaybe title $ T.stripPrefix "fig:" title- texlabel | T.null label = []- | otherwise = [RawInline (Format "latex") $ mkLaTeXLabel label]- texalt | "nocaption" `elem` cls = []- | otherwise = concat- [ [ RawInline (Format "latex") "["]- , alt- , [ RawInline (Format "latex") "]"]- ]- img = Image (label, cls, attrs) alt (src, title')- in concat [- [ RawInline (Format "latex") "\\subfloat" ]- , texalt- , [Span nullAttr $ img:texlabel]- ]-latexSubFigure x _ = [x]--mkCaption :: Options -> T.Text -> [Inline] -> Block-mkCaption opts style- | outFormat opts == Just (Format "docx") = Div ("", [], [("custom-style", style)]) . return . Para- | otherwise = Para
+ lib-internal/Text/Pandoc/CrossRef/References/Blocks/CodeBlock.hs view
@@ -0,0 +1,67 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}++module Text.Pandoc.CrossRef.References.Blocks.CodeBlock where++import Control.Monad.Reader.Class+import qualified Data.Text as T+import Text.Pandoc.Definition+import Text.Pandoc.Shared (stringify)+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.Util.Options+import Text.Pandoc.CrossRef.Util.Template+import Text.Pandoc.CrossRef.Util.Util++runCodeBlock :: Attr -> T.Text -> Either T.Text [Inline] -> WS (ReplacedResult Block)+runCodeBlock (label, classes, attrs) code eCaption = do+ opts <- ask+ case outFormat opts of+ f --if used with listings package,nothing should be done+ | isLatexFormat f, listings opts -> eCaption &+ either+ (const noReplaceNoRecurse)+ (\caption -> replaceNoRecurse $+ CodeBlock (label,classes,("caption",escapeLaTeX $ stringify caption):attrs) code)+ --if not using listings, however, wrap it in a codelisting environment+ | isLatexFormat f ->+ replaceNoRecurse $ Div nullAttr [+ RawBlock (Format "latex") "\\begin{codelisting}"+ , Plain [+ RawInline (Format "latex") "\\caption"+ , Span nullAttr $ either (pure . Str) id eCaption+ ]+ , CodeBlock (label, classes, attrs) code+ , RawBlock (Format "latex") "\\end{codelisting}"+ ]+ _ -> do+ let cap = either (B.toList . B.text) id eCaption+ idxStr <- replaceAttr (Right label) (lookup "label" attrs) cap lstRefs+ let caption' = applyTemplate idxStr cap $ listingTemplate opts+ replaceNoRecurse $ Div (label, "listing":classes, []) [+ mkCaption opts "Caption" caption'+ , CodeBlock ("", classes, filter ((/="caption") . fst) $ setLabel opts idxStr attrs) code+ ]
+ lib-internal/Text/Pandoc/CrossRef/References/Blocks/Header.hs view
@@ -0,0 +1,79 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}++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.Text as T+import Text.Pandoc.Definition++import Control.Applicative+import Lens.Micro.Mtl+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.References.Monad+import Text.Pandoc.CrossRef.References.Blocks.Util (setLabel)+import Text.Pandoc.CrossRef.Util.Options+import Text.Pandoc.CrossRef.Util.Template+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
+ lib-internal/Text/Pandoc/CrossRef/References/Blocks/Math.hs view
@@ -0,0 +1,77 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}++module Text.Pandoc.CrossRef.References.Blocks.Math where++import Control.Monad.Reader.Class+import qualified Data.Map as M+import qualified Data.Text as T+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.Util.Options+import Text.Pandoc.CrossRef.Util.Template+import Text.Pandoc.CrossRef.Util.Util++runBlockMath :: Attr -> T.Text -> WS (ReplacedResult Block)+runBlockMath (label, cls, attrs) eq = do+ opts <- ask+ if tableEqns opts && not (isLatexFormat (outFormat opts))+ then do+ (eq', idxStr) <- replaceEqn (label, cls, attrs) eq+ let mathfmt = if eqnBlockInlineMath opts then InlineMath else DisplayMath+ replaceNoRecurse $ Div (label,cls,setLabel opts idxStr attrs) $+ applyTemplate [Math mathfmt $ stringify idxStr] [Math mathfmt eq']+ $ eqnBlockTemplate opts+ else noReplaceRecurse++replaceEqn :: Attr -> T.Text -> WS (T.Text, [Inline])+replaceEqn (label, _, attrs) eq = do+ opts <- ask+ let label' | T.null label = Left "eq"+ | otherwise = Right label+ idxStrRaw <- replaceAttr label' (lookup "label" attrs) [] eqnRefs+ let idxStr = applyTemplate' (M.fromDistinctAscList [("i", idxStrRaw)]) $ eqnIndexTemplate opts+ eqTxt = applyTemplate' eqTxtVars $ eqnInlineTemplate opts :: [Inline]+ eqTxtVars = M.fromDistinctAscList+ [ ("e", [Str eq])+ , ("i", idxStr)+ , ("ri", idxStrRaw)+ ]+ eq' | tableEqns opts = eq+ | otherwise = stringify eqTxt+ return (eq', idxStr)++splitMath :: [Block] -> [Block]+splitMath (Para ils:xs)+ | length ils > 1 = map Para (split [] [] ils) <> xs+ where+ split res acc [] = reverse (reverse acc : res)+ split res acc (x@(Span _ [Math DisplayMath _]):ys) =+ split ([x] : reverse (dropSpaces acc) : res)+ [] (dropSpaces ys)+ split res acc (y:ys) = split res (y:acc) ys+ dropSpaces = dropWhile isSpace+splitMath xs = xs
+ lib-internal/Text/Pandoc/CrossRef/References/Blocks/Subfigures.hs view
@@ -0,0 +1,218 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts, LambdaCase #-}++module Text.Pandoc.CrossRef.References.Blocks.Subfigures where++import Control.Monad.Reader+import Control.Monad.State hiding (get, modify)+import qualified Data.Map as M+import qualified Data.Text as T+import qualified Data.Text.Read as T+import Text.Pandoc.Definition+import qualified Text.Pandoc.Builder as B+import Data.Default (def)+import Data.List+import Data.Maybe+import Text.Pandoc.Walk (walk)+import Lens.Micro+import Lens.Micro.Mtl+import Text.Pandoc.Shared (blocksToInlines)++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.Util.Options+import Text.Pandoc.CrossRef.Util.Template+import Text.Pandoc.CrossRef.Util.Util++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+ doFigure :: Block -> WS (ReplacedResult Block)+ doFigure (Figure attr caption' content) = runFigure True attr caption' content+ doFigure _ = noReplaceRecurse+ opts' = opts+ { figureTemplate = subfigureChildTemplate opts+ , customLabel = \r i -> customLabel opts ("sub"<>r) i+ }+ collectedCaptions = B.toList $+ intercalate' (B.fromList $ ccsDelim opts)+ $ map (B.fromList . collectCaps . snd)+ $ sortOn (refIndex . snd)+ $ filter (not . null . refTitle . snd)+ $ M.toList+ $ st^.imgRefs+ collectCaps v =+ applyTemplate+ (chapPrefix (chapDelim opts) (refIndex v))+ (refTitle v)+ (ccsTemplate opts)+ vars = M.fromDistinctAscList+ [ ("ccs", collectedCaptions)+ , ("i", idxStr)+ , ("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)+ case outFormat opts of+ f | isLatexFormat f ->+ replaceNoRecurse $ Div nullAttr $+ [ RawBlock (Format "latex") "\\begin{pandoccrossrefsubfigures}" ]+ <> cont <>+ [ Para [RawInline (Format "latex") "\\caption["+ , Span nullAttr (removeFootnotes caption)+ , RawInline (Format "latex") "]"+ , Span nullAttr caption]+ , RawBlock (Format "latex") $ mkLaTeXLabel label+ , RawBlock (Format "latex") "\\end{pandoccrossrefsubfigures}"]+ _ -> replaceNoRecurse+ $ Figure (label, "subfigures":cls, setLabel opts idxStr attrs) (Caption Nothing [Para capt])+ $ toTable opts cont+ where+ removeFootnotes = walk removeFootnote+ removeFootnote Note{} = Str ""+ removeFootnote x = x+ toTable :: Options -> [Block] -> [Block]+ toTable opts blks+ | isLatexFormat $ outFormat opts = concatMap imagesToFigures blks+ | subfigGrid opts = [simpleTable align (map ColWidth widths) (map (fmap pure . blkToRow) blks)]+ | otherwise = blks+ where+ align | b:_ <- blks = let ils = blocksToInlines [b] in replicate (length $ mapMaybe getWidth ils) AlignCenter+ | otherwise = error "Misformatted subfigures block"+ widths | b:_ <- blks = let ils = blocksToInlines [b] in fixZeros $ mapMaybe getWidth ils+ | otherwise = error "Misformatted subfigures block"+ getWidth (Image (_id, _class, as) _ _)+ = Just $ maybe 0 percToDouble $ lookup "width" as+ getWidth _ = Nothing+ fixZeros :: [Double] -> [Double]+ fixZeros ws+ = let nz = length $ filter (== 0) ws+ rzw = (0.99 - sum ws) / fromIntegral nz+ in if nz>0+ then map (\x -> if x == 0 then rzw else x) ws+ else ws+ percToDouble :: T.Text -> Double+ percToDouble percs+ | Right (perc, "%") <- T.double percs+ = perc/100.0+ | otherwise = error "Only percent allowed in subfigure width!"+ blkToRow :: Block -> [Block]+ blkToRow (Para inls) = mapMaybe inlToCell inls+ blkToRow x = [x]+ inlToCell :: Inline -> Maybe Block+ inlToCell (Image (id', cs, as) txt tgt) = Just $+ Figure (id', cs, as) (Caption Nothing [Para txt]) [Plain [Image ("", cs, setW as) txt tgt]]+ inlToCell _ = Nothing+ setW as = ("width", "100%"):filter ((/="width") . fst) as++replaceSubfigs :: [Inline] -> WS (ReplacedResult [Inline])+replaceSubfigs = (replaceNoRecurse . concat) <=< mapM replaceSubfig++imagesToFigures :: Block -> [Block]+imagesToFigures = \case+ x@Figure{} -> [x]+ Para xs -> mapMaybe imageToFigure xs+ Plain xs -> mapMaybe imageToFigure xs+ _ -> []++imageToFigure :: Inline -> Maybe Block+imageToFigure = \case+ Image (label,cls,attrs) alt tgt -> Just $ Figure (label, cls, attrs) (Caption Nothing [Para alt])+ [Plain [Image ("",cls,attrs) alt tgt]]+ _ -> 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+ _ -> return [Image (label, cls, setLabel opts idxStr attrs) alt' tgt]+replaceSubfig x = return [x]++latexSubFigure :: Inline -> T.Text -> [Inline]+latexSubFigure (Image (_, cls, attrs) alt (src, title)) label =+ let+ title' = fromMaybe title $ T.stripPrefix "fig:" title+ texlabel | T.null label = []+ | otherwise = [RawInline (Format "latex") $ mkLaTeXLabel label]+ texalt | "nocaption" `elem` cls = []+ | otherwise = concat+ [ [ RawInline (Format "latex") "["]+ , alt+ , [ RawInline (Format "latex") "]"]+ ]+ img = Image (label, cls, attrs) alt (src, title')+ in concat [+ [ RawInline (Format "latex") "\\subfloat" ]+ , texalt+ , [Span nullAttr $ img:texlabel]+ ]+latexSubFigure x _ = [x]++normalizeLabel :: T.Text -> Either T.Text T.Text+normalizeLabel label+ | "fig:" `T.isPrefixOf` label = Right label+ | T.null label = Left "fig"+ | otherwise = Right $ "fig:" <> label++simpleTable :: [Alignment] -> [ColWidth] -> [[[Block]]] -> Block+simpleTable align width bod = Table nullAttr noCaption (zip align width)+ noTableHead [mkBody bod] noTableFoot+ where+ mkBody xs = TableBody nullAttr (RowHeadColumns 0) [] (map mkRow xs)+ mkRow xs = Row nullAttr (map mkCell xs)+ mkCell xs = Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) xs+ noCaption = Caption Nothing mempty+ noTableHead = TableHead nullAttr []+ noTableFoot = TableFoot nullAttr []++runFigure :: Bool -> Attr -> Caption -> [Block] -> WS (ReplacedResult Block)+runFigure subFigure (label, cls, fattrs) (Caption short (btitle : rest)) content = do+ opts <- ask+ let label' = normalizeLabel label+ let title = blocksToInlines [btitle]+ attrs = fromMaybe fattrs $ case blocksToInlines content of+ [Image (_, _, as) _ _] -> Just as+ _ -> Nothing+ idxStr <- replaceAttr label' (lookup "label" attrs) title imgRefs+ let title' = case outFormat opts of+ f | isLatexFormat f -> title+ _ -> applyTemplate idxStr title $ figureTemplate opts+ caption' = Caption short (walkReplaceInlines title' title btitle:rest)+ replaceNoRecurse $+ if subFigure && isLatexFormat (outFormat opts)+ then Plain $ latexSubFigure (head $ blocksToInlines content) label+ else Figure (label,cls,setLabel opts idxStr attrs) caption' content+runFigure _ _ _ _ = noReplaceNoRecurse
+ lib-internal/Text/Pandoc/CrossRef/References/Blocks/Table.hs view
@@ -0,0 +1,53 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}++module Text.Pandoc.CrossRef.References.Blocks.Table where++import Control.Monad.Reader.Class+import Text.Pandoc.Definition+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.Util.Options+import Text.Pandoc.CrossRef.Util.Template+import Text.Pandoc.CrossRef.Util.Util++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+ let title' =+ case outFormat opts of+ f | isLatexFormat f ->+ RawInline (Format "latex") (mkLaTeXLabel label) : title+ _ -> applyTemplate idxStr title $ tableTemplate opts+ caption' = Caption short (walkReplaceInlines title' title btitle:rest)+ replaceNoRecurse $ (mtattr &+ maybe+ (Table (label, clss, setLabel opts idxStr attrs))+ (\tattr a b c d -> Div (label, clss, setLabel opts idxStr attrs) . pure . Table tattr a b c d)+ )+ caption' colspec header cells foot+ where title = blocksToInlines [btitle]
+ lib-internal/Text/Pandoc/CrossRef/References/Blocks/Util.hs view
@@ -0,0 +1,78 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}++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 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++setLabel :: Options -> [Inline] -> [(T.Text, T.Text)] -> [(T.Text, T.Text)]+setLabel opts idx+ | setLabelAttribute opts+ = (("label", stringify idx) :)+ . filter ((/= "label") . fst)+ | otherwise = id++walkReplaceInlines :: [Inline] -> [Inline] -> Block -> Block+walkReplaceInlines newTitle title = walk replaceInlines+ where+ replaceInlines xs+ | 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++mkCaption :: Options -> T.Text -> [Inline] -> Block+mkCaption opts style+ | outFormat opts == Just (Format "docx") = Div ("", [], [("custom-style", style)]) . return . Para+ | otherwise = Para
lib-internal/Text/Pandoc/CrossRef/References/List.hs view
@@ -18,10 +18,11 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE OverloadedStrings, RecordWildCards #-}+{-# LANGUAGE OverloadedStrings, RecordWildCards, LambdaCase #-} module Text.Pandoc.CrossRef.References.List (listOf) where import Data.List+import Control.Monad.Reader import qualified Data.Map as M import qualified Data.Text as T import Text.Pandoc.Definition@@ -29,38 +30,39 @@ 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 Text.Pandoc.CrossRef.Util.Template -listOf :: Options -> [Block] -> WS [Block]-listOf Options{outFormat=f} x | isLatexFormat f = return x-listOf opts (RawBlock fmt "\\listoffigures":xs)- | isLaTeXRawBlockFmt fmt- = use imgRefs >>= makeList "fig" opts lofItemTemplate lofTitle xs-listOf opts (RawBlock fmt "\\listoftables":xs)- | isLaTeXRawBlockFmt fmt- = use tblRefs >>= makeList "tbl" opts lotItemTemplate lotTitle xs-listOf opts (RawBlock fmt "\\listoflistings":xs)- | isLaTeXRawBlockFmt fmt- = use lstRefs >>= makeList "lst" opts lolItemTemplate lolTitle xs-listOf _ x = return x+listOf :: [Block] -> WS [Block]+listOf blocks = asks (isLatexFormat . outFormat) >>= \case+ True -> pure blocks+ False -> case blocks of+ (RawBlock fmt "\\listoffigures":xs)+ | isLaTeXRawBlockFmt fmt+ -> use imgRefs >>= makeList "fig" lofItemTemplate lofTitle xs+ (RawBlock fmt "\\listoftables":xs)+ | isLaTeXRawBlockFmt fmt+ -> use tblRefs >>= makeList "tbl" lotItemTemplate lotTitle xs+ (RawBlock fmt "\\listoflistings":xs)+ | isLaTeXRawBlockFmt fmt+ -> use lstRefs >>= makeList "lst" lolItemTemplate lolTitle xs+ _ -> pure blocks makeList :: T.Text- -> Options- -> (Options- -> BlockTemplate)- -> (Options- -> [Block])+ -> (Options -> BlockTemplate)+ -> (Options -> [Block]) -> [Block] -> M.Map T.Text RefRec -> WS [Block]-makeList pfx o tf titlef xs refs =- pure $ titlef o <> (Div ("", ["list", "list-of-" <> pfx], []) items : xs)+makeList pfx tf titlef xs refs = do+ o <- ask+ pure $ titlef o <> (Div ("", ["list", "list-of-" <> pfx], []) (items o) : xs) where- items = fromMaybe items'$ pure <$> mergeList Nothing [] items'- items' = concatMap (itemChap . snd) refsSorted+ items o = let is = items' o in fromMaybe is $ pure <$> mergeList Nothing [] is+ items' o = concatMap (itemChap o . snd) refsSorted mergeList Nothing acc (OrderedList style item : ys) = mergeList (Just $ OrderedList style) (item <> acc) ys mergeList Nothing acc (BulletList item : ys) =@@ -78,22 +80,22 @@ (_,RefRec{refIndex=i, refSubfigure=si}) (_,RefRec{refIndex=j, refSubfigure=sj}) = compare (i, si) (j, sj)- itemChap :: RefRec -> [Block]- itemChap ref@RefRec{..} = applyTemplate (numWithChap ref) refTitle (tf o)- numWithChap :: RefRec -> [Inline]- numWithChap RefRec{..} = case refSubfigure of+ itemChap :: Options -> RefRec -> [Block]+ itemChap o ref@RefRec{..} = applyTemplate (numWithChap o ref) refTitle (tf o)+ numWithChap :: Options -> RefRec -> [Inline]+ numWithChap Options{..} RefRec{..} = case refSubfigure of Nothing -> let vars = M.fromDistinctAscList- [ ("i", chapPrefix (chapDelim o) refIndex)+ [ ("i", chapPrefix chapDelim refIndex) , ("suf", mempty) , ("t", refTitle) ]- in applyTemplate' vars $ refIndexTemplate o pfx+ in applyTemplate' vars $ refIndexTemplate pfx Just s -> let vars = M.fromDistinctAscList- [ ("i", chapPrefix (chapDelim o) refIndex)- , ("s", chapPrefix (chapDelim o) s)+ [ ("i", chapPrefix chapDelim refIndex)+ , ("s", chapPrefix chapDelim s) , ("suf", mempty) , ("t", refTitle) ]- in applyTemplate' vars $ subfigureRefIndexTemplate o+ in applyTemplate' vars subfigureRefIndexTemplate
+ lib-internal/Text/Pandoc/CrossRef/References/Monad.hs view
@@ -0,0 +1,31 @@+{-+pandoc-crossref is a pandoc filter for numbering figures,+equations, tables and cross-references to them.+Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>++This program is free software; you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation; either version 2 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License along+with this program; if not, write to the Free Software Foundation, Inc.,+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.+-}++{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module Text.Pandoc.CrossRef.References.Monad where++import Control.Monad.State+import Control.Monad.Reader+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.Util.Options++--state monad+newtype WS a = WS { runWS :: ReaderT Options (State References) a }+ deriving (Functor, Applicative, Monad, MonadReader Options, MonadState References)
lib-internal/Text/Pandoc/CrossRef/References/Refs.hs view
@@ -22,7 +22,7 @@ module Text.Pandoc.CrossRef.References.Refs (replaceRefs) where import Control.Arrow as A-import Control.Monad.State hiding (get, modify)+import Control.Monad.Reader import Data.Function import Data.List import qualified Data.List.HT as HT@@ -35,20 +35,23 @@ import Debug.Trace 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.Template import Text.Pandoc.CrossRef.Util.Util -replaceRefs :: Options -> [Inline] -> WS [Inline]-replaceRefs opts (Cite cits _:xs)- = toList . (<> fromList xs) . intercalate' (text ", ") . map fromList <$> mapM replaceRefs' (groupBy eqPrefix cits)+replaceRefs :: [Inline] -> WS [Inline]+replaceRefs (Cite cits _:xs) = do+ opts <- ask :: WS Options+ toList . (<> fromList xs) . intercalate' (text ", ") . map fromList <$> mapM (replaceRefs' opts) (groupBy eqPrefix cits) where eqPrefix a b = uncurry (==) $ (fmap uncapitalizeFirst . getLabelPrefix . citationId) <***> (a,b) (<***>) = join (***)- replaceRefs' cits'+ replaceRefs' :: Options -> [Citation] -> WS [Inline]+ replaceRefs' opts cits' | Just prefix <- allCitsPrefix cits'- = replaceRefs'' prefix opts cits'+ = replaceRefs'' opts prefix cits' | otherwise = return [Cite cits' il'] where il' = toList $@@ -58,10 +61,11 @@ citationToInlines c = fromList (citationPrefix c) <> text ("@" <> citationId c) <> fromList (citationSuffix c)- replaceRefs'' = case outFormat opts of+ replaceRefs'' :: Options -> T.Text -> [Citation] -> WS [Inline]+ replaceRefs'' opts = ($ opts) . flip $ case outFormat opts of f | isLatexFormat f -> replaceRefsLatex- _ -> replaceRefsOther-replaceRefs _ x = return x+ _ -> replaceRefsOther+replaceRefs x = return x -- accessors to state variables accMap :: M.Map T.Text ((RefMap -> Const RefMap RefMap) -> References -> Const RefMap References)
lib-internal/Text/Pandoc/CrossRef/References/Types.hs view
@@ -21,7 +21,6 @@ {-# LANGUAGE TemplateHaskell #-} module Text.Pandoc.CrossRef.References.Types where -import Control.Monad.State import Data.Default import qualified Data.Map as M import Data.Text (Text)@@ -45,9 +44,6 @@ , _secRefs :: RefMap , _curChap :: Index } deriving (Show, Eq)----state monad-type WS a = State References a instance Default References where def = References n n n n n []
lib-internal/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs view
@@ -18,26 +18,31 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -} -{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, LambdaCase #-} module Text.Pandoc.CrossRef.Util.CodeBlockCaptions ( mkCodeBlockCaptions ) where +import Control.Monad.Reader (ask) import Data.List (stripPrefix) import Data.Maybe (fromMaybe) import qualified Data.Text as T-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 Text.Pandoc.Definition -mkCodeBlockCaptions :: Options -> [Block] -> WS [Block]-mkCodeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)- = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs-mkCodeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)- = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs-mkCodeBlockCaptions _ x = return x+mkCodeBlockCaptions :: [Block] -> WS [Block]+mkCodeBlockCaptions = \case+ x@(cb@CodeBlock{}:p@Para{}:xs) -> go x p cb xs+ x@(p@Para{}:cb@CodeBlock{}:xs) -> go x p cb xs+ x -> pure x+ where+ go :: [Block] -> Block -> Block -> [Block] -> WS [Block]+ go x p cb xs = do+ opts <- ask+ return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs orderAgnostic :: Options -> [Block] -> Maybe [Block] orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)
lib/Text/Pandoc/CrossRef.hs view
@@ -85,6 +85,7 @@ import Text.Pandoc import Text.Pandoc.CrossRef.References+import Text.Pandoc.CrossRef.References.Monad import Text.Pandoc.CrossRef.Util.CodeBlockCaptions import Text.Pandoc.CrossRef.Util.ModifyMeta import Text.Pandoc.CrossRef.Util.Options as O@@ -108,11 +109,11 @@ opts <- R.asks creOptions let doWalk =- bottomUpM (mkCodeBlockCaptions opts) blocks- >>= replaceAll opts- >>= bottomUpM (replaceRefs opts)- >>= bottomUpM (listOf opts)- (result, st) = runState doWalk def+ bottomUpM mkCodeBlockCaptions blocks+ >>= replaceAll+ >>= bottomUpM replaceRefs+ >>= bottomUpM listOf+ (result, st) = flip runState def $ flip R.runReaderT opts $ runWS doWalk st `seq` return result {- | Modifies metadata for LaTeX output, adding header-includes instructions
pandoc-crossref.cabal view
@@ -1,11 +1,11 @@ cabal-version: 2.0 --- This file has been generated from package.yaml by hpack version 0.34.4.+-- This file has been generated from package.yaml by hpack version 0.35.0. -- -- see: https://github.com/sol/hpack name: pandoc-crossref-version: 0.3.14.0+version: 0.3.15.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@@ -127,9 +127,9 @@ build-depends: base >=4.11 && <5 , mtl >=1.1 && <2.4- , pandoc >=2.18 && <2.20+ , pandoc ==3.0.* , pandoc-crossref-internal- , pandoc-types >=1.22.2 && <1.23+ , pandoc-types , text >=1.2.2 && <2.1 default-language: Haskell2010 @@ -138,7 +138,14 @@ Text.Numeral.Roman Text.Pandoc.CrossRef.References Text.Pandoc.CrossRef.References.Blocks+ Text.Pandoc.CrossRef.References.Blocks.CodeBlock+ Text.Pandoc.CrossRef.References.Blocks.Header+ Text.Pandoc.CrossRef.References.Blocks.Math+ Text.Pandoc.CrossRef.References.Blocks.Subfigures+ Text.Pandoc.CrossRef.References.Blocks.Table+ Text.Pandoc.CrossRef.References.Blocks.Util Text.Pandoc.CrossRef.References.List+ Text.Pandoc.CrossRef.References.Monad Text.Pandoc.CrossRef.References.Refs Text.Pandoc.CrossRef.References.Types Text.Pandoc.CrossRef.Util.CodeBlockCaptions@@ -163,8 +170,8 @@ , 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 >=2.18 && <2.20- , pandoc-types >=1.22.2 && <1.23+ , pandoc ==3.0.*+ , pandoc-types , syb >=0.4 && <0.8 , template-haskell >=2.7.0.0 && <3.0.0.0 , text >=1.2.2 && <2.1@@ -184,9 +191,9 @@ , gitrev >=1.3.1 && <1.4 , open-browser ==0.2.* , optparse-applicative >=0.13 && <0.18- , pandoc >=2.18 && <2.20+ , pandoc ==3.0.* , pandoc-crossref- , pandoc-types >=1.22.2 && <1.23+ , pandoc-types , template-haskell >=2.7.0.0 && <3.0.0.0 , temporary >=1.2 && <1.4 , text >=1.2.2 && <2.1@@ -198,18 +205,20 @@ hs-source-dirs: test ghc-options: -Wall -fno-warn-unused-do-bind -threaded+ build-tool-depends:+ pandoc-cli:pandoc build-depends: base >=4.11 && <5 , directory >=1 && <1.4 , filepath >=1.1 && <1.5 , hspec >=2.4.4 && <3- , pandoc >=2.18 && <2.20+ , pandoc ==3.0.* , pandoc-crossref- , pandoc-types >=1.22.2 && <1.23+ , pandoc-types , 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@@ -229,14 +238,14 @@ , hspec >=2.4.4 && <3 , microlens >=0.4.12.0 && <0.5.0.0 , mtl >=1.1 && <2.3- , pandoc >=2.18 && <2.20+ , pandoc ==3.0.* , pandoc-crossref , pandoc-crossref-internal- , pandoc-types >=1.22.2 && <1.23+ , pandoc-types , 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@@ -249,8 +258,8 @@ build-depends: base >=4.11 && <5 , criterion >=1.5.9.0 && <1.7- , pandoc >=2.18 && <2.20+ , pandoc ==3.0.* , pandoc-crossref- , pandoc-types >=1.22.2 && <1.23+ , pandoc-types , text >=1.2.2 && <2.1 default-language: Haskell2010
test/demo-chapters.inc view
@@ -67,20 +67,28 @@ , Space , Str "fig.\160\&1" ]- , Para- [ Image- ( "fig:figure0" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "1:"- , Space- , Str "A"- , Space- , Str "figure"+ , Figure+ ( "fig:figure0" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "1:"+ , Space+ , Str "A"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "A" , Space , Str "figure" ]+ ( "img1.jpg" , "" ) ]- ( "img1.jpg" , "fig:" ) ] , Para [ Str "There"@@ -292,94 +300,138 @@ 1 ( "sec:sec1" , [] , [] ) [ Str "Chapter" , Space , Str "1." , Space , Str "Figures" ]- , Para- [ Image- ( "fig:figure1" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "1.1:"- , Space- , Str "First"- , Space- , Str "figure"+ , Figure+ ( "fig:figure1" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "1.1:"+ , Space+ , Str "First"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "First" , Space , Str "figure" ]+ ( "img1.jpg" , "" ) ]- ( "img1.jpg" , "fig:" ) ]- , Para- [ Image- ( "fig:figure2" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "1.2:"- , Space- , Str "Second"- , Space- , Str "figure"+ , Figure+ ( "fig:figure2" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "1.2:"+ , Space+ , Str "Second"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Second" , Space , Str "figure" ]+ ( "img2.jpg" , "" ) ]- ( "img2.jpg" , "fig:" ) ]- , Para- [ Image- ( "fig:figure3" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "1.3:"- , Space- , Str "Third"- , Space- , Str "figure"+ , Figure+ ( "fig:figure3" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "1.3:"+ , Space+ , Str "Third"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Third" , Space , Str "figure" ]+ ( "img3.jpg" , "" ) ]- ( "img3.jpg" , "fig:" ) ]- , Para- [ Image- ( "" , [] , [] )- [ Str "Unlabelled" , Space , Str "image" ]- ( "img1.jpg" , "fig:" )+ , Figure+ ( "" , [] , [] )+ (Caption+ Nothing+ [ Plain [ Str "Unlabelled" , Space , Str "image" ] ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Unlabelled" , Space , Str "image" ]+ ( "img1.jpg" , "" )+ ] ]- , Div+ , Figure ( "fig:subfigures" , [ "subfigures" ] , [] )- [ Para- [ Image ( "" , [] , [] ) [ Str "a" ] ( "img1.jpg" , "fig:" )- ]- , Para- [ Image- ( "fig:subfigureB" , [] , [] )- [ Str "b" ]- ( "img1.jpg" , "fig:" )+ (Caption+ Nothing+ [ Para+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "1.4:"+ , Space+ , Str "Subfigures"+ , Space+ , Str "caption."+ , Space+ , Str "a"+ , Space+ , Str "\8212"+ , Space+ , Str "Subfigure"+ , Space+ , Str "a,"+ , Space+ , Str "b"+ , Space+ , Str "\8212"+ , Space+ , Str "Subfigure"+ , Space+ , Str "b"+ ]+ ])+ [ Figure+ ( "" , [] , [] )+ (Caption Nothing [ Plain [ Str "a" ] ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Subfigure" , Space , Str "a" ]+ ( "img1.jpg" , "" )+ ] ]- , Para- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "1.4:"- , Space- , Str "Subfigures"- , Space- , Str "caption."- , Space- , Str "a"- , Space- , Str "\8212"- , Space- , Str "Subfigure"- , Space- , Str "a,"- , Space- , Str "b"- , Space- , Str "\8212"- , Space- , Str "Subfigure"- , Space- , Str "b"+ , Figure+ ( "fig:subfigureB" , [] , [] )+ (Caption Nothing [ Plain [ Str "b" ] ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Subfigure" , Space , Str "b" ]+ ( "img1.jpg" , "" )+ ] ] ] , Header
test/demo.inc view
@@ -67,20 +67,28 @@ , Space , Str "fig.\160\&1" ]- , Para- [ Image- ( "fig:figure0" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "1:"- , Space- , Str "A"- , Space- , Str "figure"+ , Figure+ ( "fig:figure0" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "1:"+ , Space+ , Str "A"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "A" , Space , Str "figure" ]+ ( "img1.jpg" , "" ) ]- ( "img1.jpg" , "fig:" ) ] , Para [ Str "There"@@ -292,94 +300,138 @@ 1 ( "sec:sec1" , [] , [] ) [ Str "Chapter" , Space , Str "1." , Space , Str "Figures" ]- , Para- [ Image- ( "fig:figure1" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "2:"- , Space- , Str "First"- , Space- , Str "figure"+ , Figure+ ( "fig:figure1" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "2:"+ , Space+ , Str "First"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "First" , Space , Str "figure" ]+ ( "img1.jpg" , "" ) ]- ( "img1.jpg" , "fig:" ) ]- , Para- [ Image- ( "fig:figure2" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "3:"- , Space- , Str "Second"- , Space- , Str "figure"+ , Figure+ ( "fig:figure2" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "3:"+ , Space+ , Str "Second"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Second" , Space , Str "figure" ]+ ( "img2.jpg" , "" ) ]- ( "img2.jpg" , "fig:" ) ]- , Para- [ Image- ( "fig:figure3" , [] , [] )- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "4:"- , Space- , Str "Third"- , Space- , Str "figure"+ , Figure+ ( "fig:figure3" , [] , [] )+ (Caption+ Nothing+ [ Plain+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "4:"+ , Space+ , Str "Third"+ , Space+ , Str "figure"+ ]+ ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Third" , Space , Str "figure" ]+ ( "img3.jpg" , "" ) ]- ( "img3.jpg" , "fig:" ) ]- , Para- [ Image- ( "" , [] , [] )- [ Str "Unlabelled" , Space , Str "image" ]- ( "img1.jpg" , "fig:" )+ , Figure+ ( "" , [] , [] )+ (Caption+ Nothing+ [ Plain [ Str "Unlabelled" , Space , Str "image" ] ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Unlabelled" , Space , Str "image" ]+ ( "img1.jpg" , "" )+ ] ]- , Div+ , Figure ( "fig:subfigures" , [ "subfigures" ] , [] )- [ Para- [ Image ( "" , [] , [] ) [ Str "a" ] ( "img1.jpg" , "fig:" )- ]- , Para- [ Image- ( "fig:subfigureB" , [] , [] )- [ Str "b" ]- ( "img1.jpg" , "fig:" )+ (Caption+ Nothing+ [ Para+ [ Str "Figure"+ , Space+ , Str "#"+ , Space+ , Str "5:"+ , Space+ , Str "Subfigures"+ , Space+ , Str "caption."+ , Space+ , Str "a"+ , Space+ , Str "\8212"+ , Space+ , Str "Subfigure"+ , Space+ , Str "a,"+ , Space+ , Str "b"+ , Space+ , Str "\8212"+ , Space+ , Str "Subfigure"+ , Space+ , Str "b"+ ]+ ])+ [ Figure+ ( "" , [] , [] )+ (Caption Nothing [ Plain [ Str "a" ] ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Subfigure" , Space , Str "a" ]+ ( "img1.jpg" , "" )+ ] ]- , Para- [ Str "Figure"- , Space- , Str "#"- , Space- , Str "5:"- , Space- , Str "Subfigures"- , Space- , Str "caption."- , Space- , Str "a"- , Space- , Str "\8212"- , Space- , Str "Subfigure"- , Space- , Str "a,"- , Space- , Str "b"- , Space- , Str "\8212"- , Space- , Str "Subfigure"- , Space- , Str "b"+ , Figure+ ( "fig:subfigureB" , [] , [] )+ (Caption Nothing [ Plain [ Str "b" ] ])+ [ Plain+ [ Image+ ( "" , [] , [] )+ [ Str "Subfigure" , Space , Str "b" ]+ ( "img1.jpg" , "" )+ ] ] ] , Header
test/m2m/emptyChapterLabels/expect.md view
@@ -2,7 +2,13 @@ ## 1 Subsection {#sec:subsection label=""} -{#fig:figure1}+::: {#fig:figure1 .figure}+++::: caption+Figure 1: Figure1+:::+::: ### 1.1 Subsubsection {#sec:subsubsection}
test/m2m/label-precedence/expect.md view
@@ -2,13 +2,25 @@ text -{#fig:fig1}+::: {#fig:fig1 .figure}+ +::: caption+Figure α: A figure+:::+:::+ ## \*.A Subsection {#subsection} other text -{#fig:fig2 label="+"}+::: {#fig:fig2 .figure label="+"}+{label="+"}++::: caption+Figure +: A figure with custom label+:::+::: ### \*.A.A Subsubsection {#subsubsection}
test/m2m/listOfTemplates-buillet-list/expect.md view
@@ -1,20 +1,74 @@-{#fig:1}+::: {#fig:1 .figure}+ -{#fig:2}+::: caption+Figure 1: 1+:::+::: -{#fig:3}+::: {#fig:2 .figure}+ -{#fig:4}+::: caption+Figure 2: 2+:::+::: -{#fig:5}+::: {#fig:3 .figure}+ -{#fig:6}+::: caption+Figure 3: 3+:::+::: -{#fig:7}+::: {#fig:4 .figure}+ -{#fig:8}+::: caption+Figure 4: 4+:::+::: -{#fig:9}+::: {#fig:5 .figure}+++::: caption+Figure 5: 5+:::+:::++::: {#fig:6 .figure}+++::: caption+Figure 6: 6+:::+:::++::: {#fig:7 .figure}+++::: caption+Figure 7: 7+:::+:::++::: {#fig:8 .figure}+++::: caption+Figure 8: 8+:::+:::++::: {#fig:9 .figure}+++::: caption+Figure 9: 9+:::+::: # List of Figures
test/m2m/listOfTemplates-ord-list/expect.md view
@@ -1,20 +1,74 @@-{#fig:1}+::: {#fig:1 .figure}+ -{#fig:2}+::: caption+Figure 1: 1+:::+::: -{#fig:3}+::: {#fig:2 .figure}+ -{#fig:4}+::: caption+Figure 2: 2+:::+::: -{#fig:5}+::: {#fig:3 .figure}+ -{#fig:6}+::: caption+Figure 3: 3+:::+::: -{#fig:7}+::: {#fig:4 .figure}+ -{#fig:8}+::: caption+Figure 4: 4+:::+::: -{#fig:9}+::: {#fig:5 .figure}+++::: caption+Figure 5: 5+:::+:::++::: {#fig:6 .figure}+++::: caption+Figure 6: 6+:::+:::++::: {#fig:7 .figure}+++::: caption+Figure 7: 7+:::+:::++::: {#fig:8 .figure}+++::: caption+Figure 8: 8+:::+:::++::: {#fig:9 .figure}+++::: caption+Figure 9: 9+:::+::: # List of Figures
test/m2m/listOfTemplates/expect.md view
@@ -1,20 +1,74 @@-{#fig:1}+::: {#fig:1 .figure}+ -{#fig:2}+::: caption+Figure 1: 1+:::+::: -{#fig:3}+::: {#fig:2 .figure}+ -{#fig:4}+::: caption+Figure 2: 2+:::+::: -{#fig:5}+::: {#fig:3 .figure}+ -{#fig:6}+::: caption+Figure 3: 3+:::+::: -{#fig:7}+::: {#fig:4 .figure}+ -{#fig:8}+::: caption+Figure 4: 4+:::+::: -{#fig:9}+::: {#fig:5 .figure}+++::: caption+Figure 5: 5+:::+:::++::: {#fig:6 .figure}+++::: caption+Figure 6: 6+:::+:::++::: {#fig:7 .figure}+++::: caption+Figure 7: 7+:::+:::++::: {#fig:8 .figure}+++::: caption+Figure 8: 8+:::+:::++::: {#fig:9 .figure}+++::: caption+Figure 9: 9+:::+::: ::: {#lst:code1 .listing .haskell} Listing 1: Listing caption 1
test/m2m/listOfTemplates/expect.tex view
@@ -135,32 +135,34 @@ \hypertarget{tbl:mytable}{} \begin{longtable}[]{@{}lll@{}} \caption{\label{tbl:mytable}My table}\tabularnewline-\toprule()+\toprule\noalign{} a & b & c \\-\midrule()+\midrule\noalign{} \endfirsthead-\toprule()+\toprule\noalign{} a & b & c \\-\midrule()+\midrule\noalign{} \endhead+\bottomrule\noalign{}+\endlastfoot 1 & 2 & 3 \\ 4 & 5 & 6 \\-\bottomrule() \end{longtable} \hypertarget{tbl:1}{} \begin{longtable}[]{@{}ll@{}} \caption{\label{tbl:1}Table}\tabularnewline-\toprule()+\toprule\noalign{} a & b \\-\midrule()+\midrule\noalign{} \endfirsthead-\toprule()+\toprule\noalign{} a & b \\-\midrule()+\midrule\noalign{} \endhead+\bottomrule\noalign{}+\endlastfoot 1 & 2 \\-\bottomrule() \end{longtable} \listoffigures
test/m2m/loxItemTitle/expect.md view
@@ -1,20 +1,74 @@-{#fig:1}+::: {#fig:1 .figure}+ -{#fig:2}+::: caption+Figure 1: 1+:::+::: -{#fig:3}+::: {#fig:2 .figure}+ -{#fig:4}+::: caption+Figure 2: 2+:::+::: -{#fig:5}+::: {#fig:3 .figure}+ -{#fig:6}+::: caption+Figure 3: 3+:::+::: -{#fig:7}+::: {#fig:4 .figure}+ -{#fig:8}+::: caption+Figure 4: 4+:::+::: -{#fig:9}+::: {#fig:5 .figure}+++::: caption+Figure 5: 5+:::+:::++::: {#fig:6 .figure}+++::: caption+Figure 6: 6+:::+:::++::: {#fig:7 .figure}+++::: caption+Figure 7: 7+:::+:::++::: {#fig:8 .figure}+++::: caption+Figure 8: 8+:::+:::++::: {#fig:9 .figure}+++::: caption+Figure 9: 9+:::+::: ::: {#lst:code1 .listing .haskell} Listing 1: Listing caption 1
test/m2m/loxItemTitle/expect.tex view
@@ -135,32 +135,34 @@ \hypertarget{tbl:mytable}{} \begin{longtable}[]{@{}lll@{}} \caption{\label{tbl:mytable}My table}\tabularnewline-\toprule()+\toprule\noalign{} a & b & c \\-\midrule()+\midrule\noalign{} \endfirsthead-\toprule()+\toprule\noalign{} a & b & c \\-\midrule()+\midrule\noalign{} \endhead+\bottomrule\noalign{}+\endlastfoot 1 & 2 & 3 \\ 4 & 5 & 6 \\-\bottomrule() \end{longtable} \hypertarget{tbl:1}{} \begin{longtable}[]{@{}ll@{}} \caption{\label{tbl:1}Table}\tabularnewline-\toprule()+\toprule\noalign{} a & b \\-\midrule()+\midrule\noalign{} \endfirsthead-\toprule()+\toprule\noalign{} a & b \\-\midrule()+\midrule\noalign{} \endhead+\bottomrule\noalign{}+\endlastfoot 1 & 2 \\-\bottomrule() \end{longtable} \listoffigures
test/m2m/secLabels/expect.md view
@@ -2,7 +2,13 @@ ## a.a Second Level Section {#second-level-section} -{#fig:myfig}+::: {#fig:myfig .figure}+++::: caption+Figure a: my figure+:::+::: ## a.b Other Second Level Section {#other-second-level-section}
test/m2m/secLabels/expect.tex view
@@ -19,15 +19,16 @@ \hypertarget{tbl:mytable}{} \begin{longtable}[]{@{}lll@{}} \caption{\label{tbl:mytable}My table}\tabularnewline-\toprule()+\toprule\noalign{} a & b & c \\-\midrule()+\midrule\noalign{} \endfirsthead-\toprule()+\toprule\noalign{} a & b & c \\-\midrule()+\midrule\noalign{} \endhead+\bottomrule\noalign{}+\endlastfoot 1 & 2 & 3 \\ 4 & 5 & 6 \\-\bottomrule() \end{longtable}
test/m2m/setLabelAttribute/expect.md view
@@ -1,6 +1,12 @@ # Section {#section label="1"} -{#fig:1 label="1.1"}+::: {#fig:1 .figure label="1.1"}+++::: caption+Figure 1.1: Figure+:::+::: [$$equation\qquad{(1.1)}$$]{#eq:1 label="(1.1)"}
test/m2m/setLabelAttribute/expect.tex view
@@ -14,16 +14,17 @@ \hypertarget{tbl:1}{} \begin{longtable}[]{@{}ll@{}} \caption{\label{tbl:1}Table}\tabularnewline-\toprule()+\toprule\noalign{} a & b \\-\midrule()+\midrule\noalign{} \endfirsthead-\toprule()+\toprule\noalign{} a & b \\-\midrule()+\midrule\noalign{} \endhead+\bottomrule\noalign{}+\endlastfoot 1 & 2 \\-\bottomrule() \end{longtable} \begin{codelisting}
test/m2m/subfigures-ccsDelim/expect.md view
@@ -1,40 +1,95 @@ You can define subfigures: -::: {#fig:subfigures .subfigures}-{#fig:subfig1} {#fig:subfig2}-+::: {#fig:subfigures .figure .subfigures}+{#fig:subfig1} {#fig:subfig2}  -{#fig:subfig4} -{#fig:subfig6}+{#fig:subfig4}  {#fig:subfig6} -{#fig:subfig7} -{#fig:subfig9}+{#fig:subfig7}  {#fig:subfig9} +::: caption Figure 1: Caption. a --- 1; b --- 2; c --- 3; d --- 4; e --- 5; f --- 6; g --- 7; h --- 8; i --- 9 :::+::: -::: {#fig:subfigures2 .subfigures}-{#fig:subfig21}+::: {#fig:subfigures2 .figure .subfigures}+::: {#fig:subfig21 .figure}+ -{#fig:subfig22}+::: caption+a+:::+::: -+::: {#fig:subfig22 .figure}+ -{#fig:subfig24}+::: caption+b+:::+::: -+::: figure+ -{#fig:subfig26}+::: caption+c+:::+::: -{#fig:subfig27}+::: {#fig:subfig24 .figure}+ -+::: caption+d+:::+::: -{#fig:subfig29}+::: figure+ +::: caption+e+:::+:::++::: {#fig:subfig26 .figure}+++::: caption+f+:::+:::++::: {#fig:subfig27 .figure}+++::: caption+g+:::+:::++::: figure+++::: caption+h+:::+:::++::: {#fig:subfig29 .figure}+++::: caption+i+:::+:::++::: caption Figure 2: Caption. a --- 1; b --- 2; c --- 3; d --- 4; e --- 5; f --- 6; g --- 7; h --- 8; i --- 9+::: ::: Figures themselves can be referenced fig. 2, as well as individual
test/m2m/subfigures-grid/expect.md view
@@ -1,47 +1,126 @@ You can define subfigures: -::: {#fig:subfigures .subfigures}+::: {#fig:subfigures .figure .subfigures} +:------------------:+:------------------:+:------------------:+-| {#fig:subfig1 | .png){#fig:subfig2 | png){width="100%"} |-| width="100%"} | width="100%"} | |+| :: | :: | ::: {.f |+| : {#fig:subfig1 .f | : {#fig:subfig2 .f | igure width="30%"} |+| igure width="30%"} | igure width="30%"} | {width="100%"} |+| png){width="100%"} | png){width="100%"} | |+| | | ::: caption |+| ::: caption | ::: caption | c |+| a | b | ::: |+| ::: | ::: | ::: |+| ::: | ::: | | +--------------------+--------------------+--------------------+-| {#fig:subfig4 | png){width="100%"} | .png){#fig:subfig6 |-| width="100%"} | | width="100%"} |+| :: | ::: {.f | :: |+| : {#fig:subfig4 .f | igure width="30%"} | : {#fig:subfig6 .f |+| igure width="30%"} | {width="100%"} | {width="100%"} | | png){width="100%"} |+| | ::: caption | |+| ::: caption | e | ::: caption |+| d | ::: | f |+| ::: | ::: | ::: |+| ::: | | ::: | +--------------------+--------------------+--------------------+-| {#fig:subfig7 | png){width="100%"} | .png){#fig:subfig9 |-| width="100%"} | | width="100%"} |+| :: | ::: {.f | :: |+| : {#fig:subfig7 .f | igure width="30%"} | : {#fig:subfig9 .f |+| igure width="30%"} | {width="100%"} | {width="100%"} | | png){width="100%"} |+| | ::: caption | |+| ::: caption | h | ::: caption |+| g | ::: | i |+| ::: | ::: | ::: |+| ::: | | ::: | +--------------------+--------------------+--------------------+ +::: caption Figure 1: Caption. a --- 1, b --- 2, c --- 3, d --- 4, e --- 5, f --- 6, g --- 7, h --- 8, i --- 9 :::+::: -::: {#fig:subfigures2 .subfigures}+::: {#fig:subfigures2 .figure .subfigures} +:--------------------------------------------------------------------:+-| {#fig:subfig21 width="100%"} |+| ::: {#fig:subfig21 .figure} |+|  |+| |+| ::: caption |+| a |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {#fig:subfig22 width="100%"} |+| ::: {#fig:subfig22 .figure} |+|  |+| |+| ::: caption |+| b |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {width="100%"} |+| ::: figure |+|  |+| |+| ::: caption |+| c |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {#fig:subfig24 width="100%"} |+| ::: {#fig:subfig24 .figure} |+|  |+| |+| ::: caption |+| d |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {width="100%"} |+| ::: figure |+|  |+| |+| ::: caption |+| e |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {#fig:subfig26 width="100%"} |+| ::: {#fig:subfig26 .figure} |+|  |+| |+| ::: caption |+| f |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {#fig:subfig27 width="100%"} |+| ::: {#fig:subfig27 .figure} |+|  |+| |+| ::: caption |+| g |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {width="100%"} |+| ::: figure |+|  |+| |+| ::: caption |+| h |+| ::: |+| ::: | +----------------------------------------------------------------------+-| {#fig:subfig29 width="100%"} |+| ::: {#fig:subfig29 .figure} |+|  |+| |+| ::: caption |+| i |+| ::: |+| ::: | +----------------------------------------------------------------------+ +::: caption Figure 2: Caption. a --- 1, b --- 2, c --- 3, d --- 4, e --- 5, f --- 6, g --- 7, h --- 8, i --- 9+::: ::: Figures themselves can be referenced fig. 2, as well as individual
test/m2m/subfigures/expect.md view
@@ -1,40 +1,95 @@ You can define subfigures: -::: {#fig:subfigures .subfigures}-{#fig:subfig1} {#fig:subfig2}-+::: {#fig:subfigures .figure .subfigures}+{#fig:subfig1} {#fig:subfig2}  -{#fig:subfig4} -{#fig:subfig6}+{#fig:subfig4}  {#fig:subfig6} -{#fig:subfig7} -{#fig:subfig9}+{#fig:subfig7}  {#fig:subfig9} +::: caption Figure 1: Caption. a --- 1, b --- 2, c --- 3, d --- 4, e --- 5, f --- 6, g --- 7, h --- 8, i --- 9 :::+::: -::: {#fig:subfigures2 .subfigures}-{#fig:subfig21}+::: {#fig:subfigures2 .figure .subfigures}+::: {#fig:subfig21 .figure}+ -{#fig:subfig22}+::: caption+a+:::+::: -+::: {#fig:subfig22 .figure}+ -{#fig:subfig24}+::: caption+b+:::+::: -+::: figure+ -{#fig:subfig26}+::: caption+c+:::+::: -{#fig:subfig27}+::: {#fig:subfig24 .figure}+ -+::: caption+d+:::+::: -{#fig:subfig29}+::: figure+ +::: caption+e+:::+:::++::: {#fig:subfig26 .figure}+++::: caption+f+:::+:::++::: {#fig:subfig27 .figure}+++::: caption+g+:::+:::++::: figure+++::: caption+h+:::+:::++::: {#fig:subfig29 .figure}+++::: caption+i+:::+:::++::: caption Figure 2: Caption. a --- 1, b --- 2, c --- 3, d --- 4, e --- 5, f --- 6, g --- 7, h --- 8, i --- 9+::: ::: Figures themselves can be referenced fig. 2, as well as individual
test/m2m/titlesInRefs/expect.md view
@@ -1,6 +1,12 @@ # Section {#sec:section} -{#fig:figure}+::: {#fig:figure .figure}+++::: caption+Figure 1: A Figure+:::+::: sec. 1 (Section)
test/test-integrative.hs view
@@ -41,7 +41,7 @@ input <- runIO $ readFile ("test" </> "m2m" </> dir </> "input.md") expect_md <- runIO $ readFile ("test" </> "m2m" </> dir </> "expect.md") let ro = def { readerExtensions = pandocExtensions }- wo = def { writerExtensions = disableExtension Ext_raw_attribute pandocExtensions+ wo = def { writerExtensions = disableExtension Ext_raw_html $ disableExtension Ext_raw_attribute pandocExtensions , writerHighlightStyle=Just pygments , writerListings = dir `elem` listingsDirs } p@(Pandoc meta _) <- runIO $ either (error . show) id <$> P.runIO (readMarkdown ro $ T.pack input)
test/test-pandoc-crossref.hs view
@@ -21,19 +21,23 @@ {-# LANGUAGE FlexibleContexts, CPP, OverloadedStrings, RankNTypes, ScopedTypeVariables #-} import Test.Hspec import Text.Pandoc hiding (getDataFileName)-import Text.Pandoc.Builder+import Text.Pandoc.Builder hiding (figure)+import qualified Text.Pandoc.Builder as B+import Control.Monad.Reader import Control.Monad.State import Data.List 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 import Text.Pandoc.CrossRef.Util.Options import Text.Pandoc.CrossRef.Util.Util import Text.Pandoc.CrossRef.References.Types import Lens.Micro+import Text.Pandoc.CrossRef.References.Monad import qualified Text.Pandoc.CrossRef.References.Blocks as References.Blocks import qualified Text.Pandoc.CrossRef.References.Refs as References.Refs import qualified Text.Pandoc.CrossRef.References.List as References.List@@ -85,32 +89,32 @@ describe "References.Blocks.replaceBlocks" $ do it "Labels images" $- testAll (figure "test.jpg" "" "Test figure" "figure")- (figure "test.jpg" "" "Figure 1: Test figure" "figure",+ 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") it "Labels subfigures" $ testAll ( divWith ("fig:subfigure",[],[]) (- para (figure' "fig:" "test1.jpg" "" "Test figure 1" "figure1")- <>para (figure' "fig:" "test2.jpg" "" "Test figure 2" "figure2")+ para (figure' "test1.jpg" "" "Test figure 1" "figure1")+ <>para (figure' "test2.jpg" "" "Test figure 2" "figure2") <>para (text "figure caption") ) <> divWith ("fig:subfigure2",[],[]) (- para (figure' "fig:" "test21.jpg" "" "Test figure 21" "figure21")- <>para (figure' "fig:" "test22.jpg" "" "Test figure 22" "figure22")+ para (figure' "test21.jpg" "" "Test figure 21" "figure21")+ <>para (figure' "test22.jpg" "" "Test figure 22" "figure22") <>para (text "figure caption 2") ) ) (- divWith ("fig:subfigure",["subfigures"],[]) (- para (figure' "fig:" "test1.jpg" "" "a" "figure1")- <> para (figure' "fig:" "test2.jpg" "" "b" "figure2")- <> para (text "Figure 1: figure caption. a — Test figure 1, b — Test figure 2")+ figureWith ("fig:subfigure",["subfigures"],[])+ (caption Nothing $ para (text "Figure 1: figure caption. a — Test figure 1, b — Test figure 2"))+ ( para (figure' "test1.jpg" "" "a" "figure1")+ <> para (figure' "test2.jpg" "" "b" "figure2") ) <>- divWith ("fig:subfigure2",["subfigures"],[]) (- para (figure' "fig:" "test21.jpg" "" "a" "figure21")- <> para (figure' "fig:" "test22.jpg" "" "b" "figure22")- <> para (text "Figure 2: figure caption 2. a — Test figure 21, b — Test figure 22")+ figureWith ("fig:subfigure2",["subfigures"],[])+ (caption Nothing $ para (text "Figure 2: figure caption 2. a — Test figure 21, b — Test figure 22"))+ ( para (figure' "test21.jpg" "" "a" "figure21")+ <> para (figure' "test22.jpg" "" "b" "figure22") ) , imgRefs =: M.fromList [("fig:figure1",RefRec { refIndex = [(1,Nothing)],@@ -302,7 +306,7 @@ `test` "\\hypertarget{sec:section_label1}{%\n\\section{Section}\\label{sec:section_label1}}\n\nsec.~\\ref{sec:section_label1}" it "Image labels" $- figure "img.png" "" "Title" "figure_label1"+ figure "img.png" "" "Title" Nothing "figure_label1" <> para (citeGen "fig:figure_label" [1]) `test` "\\begin{figure}\n\\hypertarget{fig:figure_label1}{%\n\\centering\n\\includegraphics{img.png}\n\\caption{Title}\\label{fig:figure_label1}\n}\n\\end{figure}\n\nfig.~\\ref{fig:figure_label1}" @@ -315,7 +319,19 @@ it "Tbl labels" $ table' "A table" "some_table1" <> para (citeGen "tbl:some_table" [1])- `test` "\\hypertarget{tbl:some_table1}{}\n\\begin{longtable}[]{@{}@{}}\n\\caption{\\label{tbl:some_table1}A table}\\tabularnewline\n\\toprule()\n\\endhead\n \\\\\n\\bottomrule()\n\\end{longtable}\n\ntbl.~\\ref{tbl:some_table1}"+ `test` concat+ [ "\\hypertarget{tbl:some_table1}{}\n"+ , "\\begin{longtable}[]{@{}@{}}\n"+ , "\\caption{\\label{tbl:some_table1}A table}\\tabularnewline\n"+ , "\\toprule\\noalign{}\n"+ , "\\endfirsthead\n"+ , "\\endhead\n"+ , "\\bottomrule\\noalign{}\n"+ , "\\endlastfoot\n"+ , " \\\\\n"+ , "\\end{longtable}\n\n"+ , "tbl.~\\ref{tbl:some_table1}"+ ] #endif it "Code block labels" $ do@@ -357,27 +373,34 @@ testRefs'' p l1 l2 prop res = testRefs (para $ citeGen p l1) (set prop (refGen' p l1 l2) def) (para $ text res) testAll :: (Eq a, Data a, Show a) => Many a -> (Many a, References) -> Expectation-testAll = testState f def- where f = References.Blocks.replaceAll defaultOptions+testAll = testState References.Blocks.replaceAll def -testState :: (Eq s, Eq a1, Show s, Show a1, Df.Default s) =>- ([a] -> State s [a1]) -> s -> Many a -> (Many a1, s) -> Expectation-testState f init' arg res = runState (f $ toList arg) init' `shouldBe` first toList res+testState :: (Show a1, Eq a1) => ([a2] -> WS [a1]) -> References -> Many a2 -> (Many a1, References) -> Expectation+testState f init' arg res = runWSWithOptsInit defaultOptions init' (f $ toList arg) `shouldBe` first toList res +runWSWithOptsInit :: Options -> References -> WS a -> (a, References)+runWSWithOptsInit opts st = flip runState st . flip runReaderT opts . runWS++runWSWithOpts :: Options -> WS a -> (a, References)+runWSWithOpts opts = runWSWithOptsInit opts def+ testRefs :: Blocks -> References -> Blocks -> Expectation-testRefs bs st rbs = testState (bottomUpM (References.Refs.replaceRefs defaultOptions)) st bs (rbs, st)+testRefs bs st rbs = testState (bottomUpM References.Refs.replaceRefs) st bs (rbs, st) testCBCaptions :: Blocks -> Blocks -> Expectation-testCBCaptions bs res = runState (bottomUpM (Util.CodeBlockCaptions.mkCodeBlockCaptions defaultOptions{Text.Pandoc.CrossRef.Util.Options.codeBlockCaptions=True}) (toList bs)) def `shouldBe` (toList res,def)+testCBCaptions bs res = runWSWithOpts defaultOptions{Text.Pandoc.CrossRef.Util.Options.codeBlockCaptions=True}+ (bottomUpM (Util.CodeBlockCaptions.mkCodeBlockCaptions) (toList bs)) `shouldBe` (toList res,def) testList :: Blocks -> References -> Blocks -> Expectation-testList bs st res = runState (bottomUpM (References.List.listOf defaultOptions) (toList bs)) st `shouldBe` (toList res,st)+testList bs st res = runWSWithOptsInit defaultOptions st (bottomUpM References.List.listOf (toList bs))+ `shouldBe` (toList res,st) -figure :: T.Text -> T.Text -> T.Text -> T.Text -> Blocks-figure = (((para .) .) .) . figure' "fig:"+figure :: T.Text -> T.Text -> T.Text -> Maybe T.Text -> T.Text -> Blocks+figure src title cap malt ref = B.figureWith ("fig:" <> ref, [], [])+ (caption Nothing $ para $ text cap) $ plain $ figure' src title (fromMaybe cap malt) "" -figure' :: T.Text -> T.Text -> T.Text -> T.Text -> T.Text -> Inlines-figure' p src title alt ref = imageWith ("fig:" <> ref, [], []) src (p <> title) (text alt)+figure' :: T.Text -> T.Text -> T.Text -> T.Text -> Inlines+figure' src title alt ref = imageWith (if T.null ref then mempty else "fig:" <> ref, [], []) src title (text alt) section :: T.Text -> Int -> T.Text -> Blocks section text' level label = headerWith ("sec:" <> label,[],[]) level (text text')