pandoc-crossref 0.1.4.0 → 0.1.5.1
raw patch · 35 files changed
+943/−835 lines, 35 filesdep +pandoc-crossrefdep +template-haskell
Dependencies added: pandoc-crossref, template-haskell
Files
- README.md +5/−5
- pandoc-crossref.cabal +38/−33
- pandoc-crossref.hs +8/−20
- src/References.hs +0/−7
- src/References/Accessors.hs +0/−19
- src/References/Blocks.hs +0/−156
- src/References/List.hs +0/−37
- src/References/Refs.hs +0/−138
- src/References/Types.hs +0/−33
- src/Text/Pandoc/CrossRef.hs +64/−0
- src/Text/Pandoc/CrossRef/References.hs +7/−0
- src/Text/Pandoc/CrossRef/References/Accessors.hs +19/−0
- src/Text/Pandoc/CrossRef/References/Blocks.hs +156/−0
- src/Text/Pandoc/CrossRef/References/List.hs +37/−0
- src/Text/Pandoc/CrossRef/References/Refs.hs +138/−0
- src/Text/Pandoc/CrossRef/References/Types.hs +33/−0
- src/Text/Pandoc/CrossRef/Util/Accessor.hs +17/−0
- src/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs +37/−0
- src/Text/Pandoc/CrossRef/Util/Meta.hs +69/−0
- src/Text/Pandoc/CrossRef/Util/ModifyMeta.hs +82/−0
- src/Text/Pandoc/CrossRef/Util/Options.hs +74/−0
- src/Text/Pandoc/CrossRef/Util/Settings.hs +44/−0
- src/Text/Pandoc/CrossRef/Util/Settings/Gen.hs +31/−0
- src/Text/Pandoc/CrossRef/Util/Settings/Template.hs +20/−0
- src/Text/Pandoc/CrossRef/Util/Template.hs +26/−0
- src/Text/Pandoc/CrossRef/Util/Util.hs +24/−0
- src/Util/Accessor.hs +0/−17
- src/Util/CodeBlockCaptions.hs +0/−37
- src/Util/Meta.hs +0/−69
- src/Util/ModifyMeta.hs +0/−82
- src/Util/Options.hs +0/−74
- src/Util/Settings.hs +0/−45
- src/Util/Template.hs +0/−26
- src/Util/Util.hs +0/−24
- test-pandoc-crossref.hs +14/−13
README.md view
@@ -73,10 +73,6 @@ To label a table, append `{#tbl:label}` at the end of table caption (with `label` being something unique to reference this table by). Caption and label *must* be separated by at least one space. -### Code Block labels--There are a couple options to add code block labels. Those work only if code block id starts with `lst:`, e.g. `{#lst:label}`- ### Section labels You can also reference sections of any level. Section labels use native pandoc syntax, but must start with "sec:", e.g.@@ -87,6 +83,10 @@ You can also use `autoSectionLabels` variable to automatically prepend all section labels (automatically generated with pandoc included) with "sec:". Bear in mind that references can't contain periods, commas etc, so some auto-generated labels will still be unusable. +### Code Block labels++There are a couple options to add code block labels. Those work only if code block id starts with `lst:`, e.g. `{#lst:label}`+ #### `caption` attribute `caption` attribute will be treated as code block caption. If code block has both id and `caption` attributes, it will be treated as numbered code block.@@ -204,7 +204,7 @@ `figPrefix`, `eqnPrefix`, `tblPrefix`, `lstPrefix` can be YAML arrays. That way, value at index corresponds to total number of references in group, f.ex. ```yaml-fixPrefix:+figPrefix: - "fig." - "figs." ```
pandoc-crossref.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: pandoc-crossref-version: 0.1.4.0+version: 0.1.5.1 synopsis: Pandoc filter for cross-references description: pandoc-crossref is a pandoc filter for numbering figures, equations, tables and cross-references to them. license: GPL-2@@ -23,25 +23,41 @@ source-repository this type: git location: https://github.com/lierdakil/pandoc-crossref- tag: v0.1.4.0+ tag: v0.1.5.1 +library+ exposed-modules: Text.Pandoc.CrossRef+ other-modules: Text.Pandoc.CrossRef.References+ , Text.Pandoc.CrossRef.References.Accessors+ , Text.Pandoc.CrossRef.References.Blocks+ , Text.Pandoc.CrossRef.References.List+ , Text.Pandoc.CrossRef.References.Refs+ , Text.Pandoc.CrossRef.References.Types+ , Text.Pandoc.CrossRef.Util.Settings+ , Text.Pandoc.CrossRef.Util.Accessor+ , Text.Pandoc.CrossRef.Util.Meta+ , Text.Pandoc.CrossRef.Util.Options+ , Text.Pandoc.CrossRef.Util.Template+ , Text.Pandoc.CrossRef.Util.Util+ , Text.Pandoc.CrossRef.Util.CodeBlockCaptions+ , Text.Pandoc.CrossRef.Util.ModifyMeta+ , Text.Pandoc.CrossRef.Util.Settings.Gen+ , Text.Pandoc.CrossRef.Util.Settings.Template+ build-depends: base >=4.2 && <5+ , pandoc >= 1.13 && <1.16+ , mtl >= 1.1 && <2.3+ , containers >= 0.1 && <0.6+ , pandoc-types >= 1.12.4.1 && < 1.13+ , yaml >= 0.8 && <0.9+ , data-default >= 0.4 && <0.6+ , bytestring >=0.9 && <0.11+ , template-haskell+ hs-source-dirs: src+ Ghc-Options: -Wall+ default-language: Haskell2010+ executable pandoc-crossref main-is: pandoc-crossref.hs- other-modules: References- , References.Accessors- , References.Blocks- , References.List- , References.Refs- , References.Types- , Util.Settings- , Util.Accessor- , Util.Meta- , Util.Options- , Util.Template- , Util.Util- , Util.CodeBlockCaptions- , Util.ModifyMeta- other-extensions: CPP build-depends: base >=4.2 && <5 , pandoc >= 1.13 && <1.16 , mtl >= 1.1 && <2.3@@ -50,27 +66,14 @@ , yaml >= 0.8 && <0.9 , data-default >= 0.4 && <0.6 , bytestring >=0.9 && <0.11- hs-source-dirs: ., src+ , pandoc-crossref+ hs-source-dirs: .+ Ghc-Options: -Wall default-language: Haskell2010 Test-Suite test-pandoc-crossref Type: exitcode-stdio-1.0 Main-Is: test-pandoc-crossref.hs- other-modules: References- , References.Accessors- , References.Blocks- , References.List- , References.Refs- , References.Types- , Util.Settings- , Util.Accessor- , Util.Meta- , Util.Options- , Util.Template- , Util.Util- , Util.CodeBlockCaptions- , Util.ModifyMeta- other-extensions: CPP hs-source-dirs: ., src Build-Depends: base >=4.2 && <5 , pandoc >= 1.13 && <1.16@@ -82,5 +85,7 @@ , bytestring >=0.9 && <0.11 , hspec , process >=1 && <1.3+ , pandoc-crossref+ , template-haskell Ghc-Options: -rtsopts -Wall -fno-warn-unused-do-bind -threaded Default-Language: Haskell2010
pandoc-crossref.hs view
@@ -1,26 +1,14 @@ import Text.Pandoc import Text.Pandoc.JSON-import Text.Pandoc.Walk-import Control.Monad.State -import References-import Util.Settings-import Util.Options-import Util.CodeBlockCaptions-import Util.ModifyMeta+import Text.Pandoc.CrossRef main :: IO () main = toJSONFilter go--go :: Maybe Format -> Pandoc -> IO Pandoc-go fmt (Pandoc meta bs) = do- dtv <- getSettings meta- let- doWalk =- bottomUpM (codeBlockCaptions opts) (walk divBlocks bs)- >>= walkM (replaceBlocks opts)- >>= bottomUpM (replaceRefs opts)- >>= bottomUpM (listOf opts)- opts = getOptions dtv fmt- meta' = modifyMeta opts dtv- return $ Pandoc meta' $ evalState doWalk def+ where+ go fmt p@(Pandoc meta _) = runCrossRefIO meta fmt action p+ where+ action (Pandoc _ bs) = do+ meta' <- crossRefMeta+ bs' <- crossRefBlocks bs+ return $ Pandoc meta' bs'
− src/References.hs
@@ -1,7 +0,0 @@-module References ( module X ) where--import References.Accessors as X-import References.Types as X-import References.Blocks as X-import References.Refs as X-import References.List as X
− src/References/Accessors.hs
@@ -1,19 +0,0 @@-module References.Accessors where--import References.Types-import Util.Accessor--imgRefs' :: Accessor References RefMap-imgRefs' new r@References{imgRefs=old} = (old, r{imgRefs=new})--eqnRefs' :: Accessor References RefMap-eqnRefs' new r@References{eqnRefs=old} = (old, r{eqnRefs=new})--tblRefs' :: Accessor References RefMap-tblRefs' new r@References{tblRefs=old} = (old, r{tblRefs=new})--lstRefs' :: Accessor References RefMap-lstRefs' new r@References{lstRefs=old} = (old, r{lstRefs=new})--secRefs' :: Accessor References RefMap-secRefs' new r@References{secRefs=old} = (old, r{secRefs=new})
− src/References/Blocks.hs
@@ -1,156 +0,0 @@-module References.Blocks (divBlocks, replaceBlocks) where--import Text.Pandoc.Definition-import Text.Pandoc.Builder (text, toList)-import Text.Pandoc.Shared (stringify, normalizeSpaces)-import Control.Monad.State-import Data.List-import qualified Data.Map as M--import Util.Accessor-import References.Types-import References.Accessors-import Util.Util-import Util.Options-import Util.Template--replaceBlocks :: Options -> Block -> WS Block-replaceBlocks opts (Header n (label, cls, attrs) text')- = do- let label' = if autoSecLab opts && not ("sec:" `isPrefixOf` label)- then "sec:"++label- else label- unless ("unnumbered" `elem` cls) $ do- modify $ \r@References{curChap=cc} ->- let ln = length cc- inc l = init l ++ [last l + 1]- cc' | ln > n = inc $ take n cc- | ln == n = inc cc- | otherwise = cc ++ take (n-ln) [1,1..]- in r{curChap=cc'}- when ("sec:" `isPrefixOf` label') $ replaceAttrSec label' text' secRefs'- return $ Header n (label', cls, attrs) text'-replaceBlocks opts (Div (label,_,_) [Plain [Image alt img]])- | "fig:" `isPrefixOf` label- = do- idxStr <- replaceAttr opts label alt imgRefs'- let alt' = case outFormat opts of- f | isFormat "latex" f ->- RawInline (Format "tex") ("\\label{"++label++"}") : alt- _ -> applyTemplate idxStr alt $ figureTemplate opts- return $ Para [Image alt' (fst img,"fig:")]-replaceBlocks opts (Div (label,_,_) [Plain [Math DisplayMath eq]])- | "eq:" `isPrefixOf` label- = case outFormat opts of- f | isFormat "latex" f ->- let eqn = "\\begin{equation}"++eq++"\\label{"++label++"}\\end{equation}"- in return $ Para [RawInline (Format "tex") eqn]- _ -> do- idxStr <- replaceAttr opts label [] eqnRefs'- let eq' = eq++"\\qquad("++stringify idxStr++")"- return $ Para [Math DisplayMath eq']-replaceBlocks opts (Div (label,_,_) [Table title align widths header cells])- | not $ null title- , "tbl:" `isPrefixOf` label- = do- idxStr <- replaceAttr opts label (init title) tblRefs'- let title' =- case outFormat opts of- f | isFormat "latex" f ->- RawInline (Format "tex") ("\\label{"++label++"}") : init title- _ -> applyTemplate idxStr (init title) $ tableTemplate opts- return $ Table title' align widths header cells-replaceBlocks opts cb@(CodeBlock (label, classes, attrs) code)- | not $ null label- , "lst:" `isPrefixOf` label- , Just caption <- lookup "caption" attrs- = case outFormat opts of- f- --if used with listings package,nothing shoud be done- | isFormat "latex" f, useListings opts -> return cb- --if not using listings, however, wrap it in a codelisting environment- | isFormat "latex" f ->- return $ Div nullAttr [- RawBlock (Format "tex")- $ "\\begin{codelisting}\n\\caption{"++caption++"}"- , cb- , RawBlock (Format "tex") "\\end{codelisting}"- ]- _ -> do- let cap = toList $ text caption- idxStr <- replaceAttr opts label cap lstRefs'- let caption' = applyTemplate idxStr cap $ listingTemplate opts- return $ Div (label, "listing":classes, []) [- Para caption'- , CodeBlock ([], classes, attrs \\ [("caption", caption)]) code- ]-replaceBlocks opts- (Div (label,"listing":_, [])- [Para caption, CodeBlock ([],classes,attrs) code])- | not $ null label- , "lst:" `isPrefixOf` label- = case outFormat opts of- f- --if used with listings package, return code block with caption- | isFormat "latex" f, useListings opts ->- return $ CodeBlock (label,classes,("caption",stringify caption):attrs) code- --if not using listings, however, wrap it in a codelisting environment- | isFormat "latex" f ->- return $ Div nullAttr [- RawBlock (Format "tex") "\\begin{codelisting}"- , Para [RawInline (Format "tex") "\\caption",Span nullAttr caption]- , CodeBlock (label,classes,attrs) code- , RawBlock (Format "tex") "\\end{codelisting}"- ]- _ -> do- idxStr <- replaceAttr opts label caption lstRefs'- let caption' = applyTemplate idxStr caption $ listingTemplate opts- return $ Div (label, "listing":classes, []) [- Para caption'- , CodeBlock ([], classes, attrs) code- ]-replaceBlocks _ x = return x--divBlocks :: Block -> Block-divBlocks (Para (Image alt img:c))- | Just label <- getRefLabel "fig" c- = Div (label,[],[]) [Plain [Image alt (fst img, "fig:")]]-divBlocks (Para (math@(Math DisplayMath _eq):c))- | Just label <- getRefLabel "eq" c- = Div (label,[],[]) [Plain [math]]-divBlocks (table@(Table title _align _widths _header _cells))- | not $ null title- , Just label <- getRefLabel "tbl" [last title]- = Div (label,[],[]) [table]-divBlocks x = x--getRefLabel :: String -> [Inline] -> Maybe String-getRefLabel _ [] = Nothing-getRefLabel tag ils- | Str attr <- last ils- , all (==Space) (init ils)- , "}" `isSuffixOf` attr- , ("{#"++tag++":") `isPrefixOf` attr- = init `fmap` stripPrefix "{#" attr-getRefLabel _ _ = Nothing--replaceAttr :: Options -> String -> [Inline] -> Accessor References RefMap -> WS [Inline]-replaceAttr o label title prop- = do- chap <- take (chapDepth o) `fmap` gets curChap- index <- (1+) `fmap` gets (M.size . M.filter ((==chap) . fst . refIndex) . getProp prop)- modify $ modifyProp prop $ M.insert label RefRec {- refIndex=(chap,index)- , refTitle=normalizeSpaces title- }- return $ chapPrefix (chapDelim o) chap index--replaceAttrSec :: String -> [Inline] -> Accessor References RefMap -> WS ()-replaceAttrSec label title prop- = do- chap <- gets curChap- modify $ modifyProp prop $ M.insert label RefRec {- refIndex=(init chap,last chap)- , refTitle=normalizeSpaces title- }- return ()
− src/References/List.hs
@@ -1,37 +0,0 @@-module References.List (listOf) where--import Text.Pandoc.Definition-import Control.Monad.State-import Control.Arrow-import Data.List-import qualified Data.Map as M--import References.Types-import Util.Util-import Util.Options--listOf :: Options -> [Block] -> WS [Block]-listOf Options{outFormat=f} x | isFormat "latex" f = return x-listOf opts (Para [RawInline (Format "tex") "\\listoffigures"]:xs)- = gets imgRefs >>= makeList opts lofTitle xs-listOf opts (Para [RawInline (Format "tex") "\\listoftables"]:xs)- = gets tblRefs >>= makeList opts lotTitle xs-listOf opts (Para [RawInline (Format "tex") "\\listoflistings"]:xs)- = gets lstRefs >>= makeList opts lolTitle xs-listOf _ x = return x--makeList :: Options -> (Options -> [Block]) -> [Block] -> M.Map String RefRec -> WS [Block]-makeList opts titlef xs refs- = return $- titlef opts ++- (if chapDepth opts > 0- then Div ("", ["list"], []) (itemChap `map` refsSorted)- else OrderedList style (item `map` refsSorted))- : xs- where- refsSorted = sortBy compare' $ M.toList refs- compare' (_,RefRec{refIndex=i}) (_,RefRec{refIndex=j}) = compare i j- item = (:[]) . Plain . refTitle . snd- itemChap = Para . uncurry ((. (Space :)) . (++)) . (numWithChap . refIndex &&& refTitle) . snd- numWithChap = uncurry $ chapPrefix (chapDelim opts)- style = (1,DefaultStyle,DefaultDelim)
− src/References/Refs.hs
@@ -1,138 +0,0 @@-module References.Refs (replaceRefs) where--import Text.Pandoc.Definition-import Text.Pandoc.Shared (normalizeInlines, normalizeSpaces)-import Control.Monad.State-import Data.List-import Data.Maybe-import Data.Function-import qualified Data.Map as M-import Control.Arrow as A--import Util.Accessor-import References.Types-import References.Accessors-import Util.Util-import Util.Options--replaceRefs :: Options -> [Inline] -> WS [Inline]-replaceRefs opts (Cite cits _:xs)- = (++ xs) `fmap` intercalate [Str ",", Space] `fmap`- mapM replaceRefs' (groupBy eqPrefix cits)- where- eqPrefix a b = uncurry (==) $- (fmap uncapitalizeFirst . getLabelPrefix . citationId) <***> (a,b)- (<***>) = join (***)- replaceRefs' cits'- | Just prefix <- allCitsPrefix cits'- = replaceRefs'' prefix opts cits'- | otherwise = return [Cite cits' il']- where- il' = normalizeInlines $- [Str "["]- ++intercalate [Str ";", Space] (map citationToInlines cits')- ++[Str "]"]- citationToInlines c = normalizeSpaces $- citationPrefix c ++ [Space, Str $ "@"++citationId c] ++ citationSuffix c- replaceRefs'' = case outFormat opts of- f | isFormat "latex" f -> replaceRefsLatex- _ -> replaceRefsOther-replaceRefs _ x = return x---- accessors to state variables-accMap :: M.Map String (Accessor References RefMap)-accMap = M.fromList [("fig:",imgRefs')- ,("eq:" ,eqnRefs')- ,("tbl:",tblRefs')- ,("lst:",lstRefs')- ,("sec:",secRefs')- ]---- accessors to options-prefMap :: M.Map String (Options -> Bool -> Int -> [Inline])-prefMap = M.fromList [("fig:",figPrefix)- ,("eq:" ,eqnPrefix)- ,("tbl:",tblPrefix)- ,("lst:",lstPrefix)- ,("sec:",secPrefix)- ]--prefixes :: [String]-prefixes = M.keys accMap--getRefPrefix :: Options -> String -> Bool -> Int -> [Inline]-getRefPrefix opts prefix capitalize num- | null refprefix = []- | otherwise = refprefix ++ [Str "\160"]- where refprefix = lookupUnsafe prefix prefMap opts capitalize num--lookupUnsafe :: Ord k => k -> M.Map k v -> v-lookupUnsafe = (fromJust .) . M.lookup--allCitsPrefix :: [Citation] -> Maybe String-allCitsPrefix cits = find isCitationPrefix prefixes- where- isCitationPrefix p =- all (p `isPrefixOf`) $ map (uncapitalizeFirst . citationId) cits--replaceRefsLatex :: String -> Options -> [Citation] -> WS [Inline]-replaceRefsLatex prefix opts cits =- return $ p ++ [texcit]- where- texcit =- RawInline (Format "tex") $- if useCleveref opts then- cref++"{"++listLabels prefix "" "," "" cits++"}"- else- listLabels prefix "\\ref{" ", " "}" cits- p | useCleveref opts = []- | otherwise = getRefPrefix opts prefix cap (length cits - 1)- cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits- cref | cap = "\\Cref"- | otherwise = "\\cref"--listLabels :: String -> String -> String -> String -> [Citation] -> String-listLabels prefix p sep s =- intercalate sep . map ((p ++) . (++ s) . (prefix++) . getLabelWithoutPrefix . citationId)--getLabelWithoutPrefix :: String -> String-getLabelWithoutPrefix = drop 1 . dropWhile (/=':')--getLabelPrefix :: String -> Maybe String-getLabelPrefix lab- | uncapitalizeFirst p `elem` prefixes = Just p- | otherwise = Nothing- where p = (++ ":") . takeWhile (/=':') $ lab--replaceRefsOther :: String -> Options -> [Citation] -> WS [Inline]-replaceRefsOther prefix opts cits = do- indices <- mapM (getRefIndex prefix) cits- let- indices' = groupBy ((==) `on` (fmap fst . fst)) (sort indices)- cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits- return $ normalizeInlines $ getRefPrefix opts prefix cap (length cits - 1) ++ intercalate [Str ",", Space] (makeIndices opts `map` indices')--getRefIndex :: String -> Citation -> WS (Maybe ([Int], Int), [Inline])-getRefIndex prefix Citation{citationId=cid,citationSuffix=suf}- = (\x -> (x,suf)) `fmap` gets (fmap refIndex . M.lookup lab . getProp prop)- where- prop = lookupUnsafe prefix accMap- lab = prefix ++ getLabelWithoutPrefix cid--makeIndices :: Options -> [(Maybe ([Int], Int), [Inline])] -> [Inline]-makeIndices _ s | any (isNothing . fst) s = [Strong [Str "??"]]-makeIndices o s = intercalate sep $ reverse $ map f $ foldl' f2 [] $ map (A.first fromJust) $ filter (isJust . fst) s- where- f2 [] (i,suf) = [[(i,suf)]]- f2 ([]:xs) (i,suf) = [(i,suf)]:xs- f2 l@(x@(((_,hx),sufp):_):xs) (i@(_,ni),suf)- | not (null suf) || not (null sufp) = [(i,suf)]:l- | ni-hx == 0 = l -- remove duplicates- | ni-hx == 1 = ((i,[]):x):xs -- group sequental- | otherwise = [(i,[])]:l -- new group- f [] = [] -- drop empty lists- f [w] = show' w -- single value- f [w1,w2] = show' w2 ++ sep ++ show' w1 -- two values- f (x:xs) = show' (last xs) ++ rangeDelim o ++ show' x -- shorten more than two values- sep = [Str ",", Space]- show' ((c,n),suf) = chapPrefix (chapDelim o) c n ++ suf
− src/References/Types.hs
@@ -1,33 +0,0 @@-module References.Types ( References(..)- , WS- , RefRec(..)- , RefMap- , def- ) where--import qualified Data.Map as M-import Text.Pandoc.Definition-import Control.Monad.State-import Data.Default--data RefRec = RefRec { refIndex :: ([Int], Int)- , refTitle :: [Inline]- } deriving (Show, Eq)--type RefMap = M.Map String RefRec---- state data type-data References = References { imgRefs :: RefMap- , eqnRefs :: RefMap- , tblRefs :: RefMap- , lstRefs :: RefMap- , secRefs :: RefMap- , curChap :: [Int]- } deriving (Show, Eq)----state monad-type WS a = State References a--instance Default References where- def = References n n n n n []- where n = M.empty
+ src/Text/Pandoc/CrossRef.hs view
@@ -0,0 +1,64 @@+module Text.Pandoc.CrossRef (+ getSettings+ , crossRefBlocks+ , crossRefMeta+ , runCrossRef+ , runCrossRefIO+ , module SG+ ) where++import Control.Monad.State+import qualified Control.Monad.Reader as R+import Text.Pandoc+import Text.Pandoc.Walk+import Data.Monoid ((<>))++import Text.Pandoc.CrossRef.References+import Text.Pandoc.CrossRef.Util.Settings+import Text.Pandoc.CrossRef.Util.Options+import Text.Pandoc.CrossRef.Util.CodeBlockCaptions+import Text.Pandoc.CrossRef.Util.ModifyMeta+import Text.Pandoc.CrossRef.Util.Settings.Gen as SG++data CrossRefEnv = CrossRefEnv {+ creSettings :: Meta+ , creOptions :: Options+ }++type CrossRefM a = R.Reader CrossRefEnv a++crossRefBlocks :: [Block] -> CrossRefM [Block]+crossRefBlocks blocks = do+ opts <- R.asks creOptions+ let+ doWalk =+ bottomUpM (codeBlockCaptions opts) (walk divBlocks blocks)+ >>= walkM (replaceBlocks opts)+ >>= bottomUpM (replaceRefs opts)+ >>= bottomUpM (listOf opts)+ return $ evalState doWalk def++crossRefMeta :: CrossRefM Meta+crossRefMeta = do+ opts <- R.asks creOptions+ dtv <- R.asks creSettings+ return $ modifyMeta opts dtv++runCrossRef :: (Walkable a b) => Meta -> Maybe Format -> (a -> CrossRefM b) -> a -> b+runCrossRef meta fmt action arg = R.runReader (action arg) env+ where+ settings = meta <> defaultMeta+ env = CrossRefEnv {+ creSettings = settings+ , creOptions = getOptions settings fmt+ }++runCrossRefIO :: (Walkable a b) => Meta -> Maybe Format -> (a -> CrossRefM b) -> a -> IO b+runCrossRefIO meta fmt action arg = do+ settings <- getSettings meta+ let+ env = CrossRefEnv {+ creSettings = settings+ , creOptions = getOptions settings fmt+ }+ return $ R.runReader (action arg) env
+ src/Text/Pandoc/CrossRef/References.hs view
@@ -0,0 +1,7 @@+module Text.Pandoc.CrossRef.References ( module X ) where++import Text.Pandoc.CrossRef.References.Accessors as X+import Text.Pandoc.CrossRef.References.Types as X+import Text.Pandoc.CrossRef.References.Blocks as X+import Text.Pandoc.CrossRef.References.Refs as X+import Text.Pandoc.CrossRef.References.List as X
+ src/Text/Pandoc/CrossRef/References/Accessors.hs view
@@ -0,0 +1,19 @@+module Text.Pandoc.CrossRef.References.Accessors where++import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.Util.Accessor++imgRefs' :: Accessor References RefMap+imgRefs' new r@References{imgRefs=old} = (old, r{imgRefs=new})++eqnRefs' :: Accessor References RefMap+eqnRefs' new r@References{eqnRefs=old} = (old, r{eqnRefs=new})++tblRefs' :: Accessor References RefMap+tblRefs' new r@References{tblRefs=old} = (old, r{tblRefs=new})++lstRefs' :: Accessor References RefMap+lstRefs' new r@References{lstRefs=old} = (old, r{lstRefs=new})++secRefs' :: Accessor References RefMap+secRefs' new r@References{secRefs=old} = (old, r{secRefs=new})
+ src/Text/Pandoc/CrossRef/References/Blocks.hs view
@@ -0,0 +1,156 @@+module Text.Pandoc.CrossRef.References.Blocks (divBlocks, replaceBlocks) where++import Text.Pandoc.Definition+import Text.Pandoc.Builder (text, toList)+import Text.Pandoc.Shared (stringify, normalizeSpaces)+import Control.Monad.State+import Data.List+import qualified Data.Map as M++import Text.Pandoc.CrossRef.Util.Accessor+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.References.Accessors+import Text.Pandoc.CrossRef.Util.Util+import Text.Pandoc.CrossRef.Util.Options+import Text.Pandoc.CrossRef.Util.Template++replaceBlocks :: Options -> Block -> WS Block+replaceBlocks opts (Header n (label, cls, attrs) text')+ = do+ let label' = if autoSecLab opts && not ("sec:" `isPrefixOf` label)+ then "sec:"++label+ else label+ unless ("unnumbered" `elem` cls) $ do+ modify $ \r@References{curChap=cc} ->+ let ln = length cc+ inc l = init l ++ [last l + 1]+ cc' | ln > n = inc $ take n cc+ | ln == n = inc cc+ | otherwise = cc ++ take (n-ln) [1,1..]+ in r{curChap=cc'}+ when ("sec:" `isPrefixOf` label') $ replaceAttrSec label' text' secRefs'+ return $ Header n (label', cls, attrs) text'+replaceBlocks opts (Div (label,_,_) [Plain [Image alt img]])+ | "fig:" `isPrefixOf` label+ = do+ idxStr <- replaceAttr opts label alt imgRefs'+ let alt' = case outFormat opts of+ f | isFormat "latex" f ->+ RawInline (Format "tex") ("\\label{"++label++"}") : alt+ _ -> applyTemplate idxStr alt $ figureTemplate opts+ return $ Para [Image alt' (fst img,"fig:")]+replaceBlocks opts (Div (label,_,_) [Plain [Math DisplayMath eq]])+ | "eq:" `isPrefixOf` label+ = case outFormat opts of+ f | isFormat "latex" f ->+ let eqn = "\\begin{equation}"++eq++"\\label{"++label++"}\\end{equation}"+ in return $ Para [RawInline (Format "tex") eqn]+ _ -> do+ idxStr <- replaceAttr opts label [] eqnRefs'+ let eq' = eq++"\\qquad("++stringify idxStr++")"+ return $ Para [Math DisplayMath eq']+replaceBlocks opts (Div (label,_,_) [Table title align widths header cells])+ | not $ null title+ , "tbl:" `isPrefixOf` label+ = do+ idxStr <- replaceAttr opts label (init title) tblRefs'+ let title' =+ case outFormat opts of+ f | isFormat "latex" f ->+ RawInline (Format "tex") ("\\label{"++label++"}") : init title+ _ -> applyTemplate idxStr (init title) $ tableTemplate opts+ return $ Table title' align widths header cells+replaceBlocks opts cb@(CodeBlock (label, classes, attrs) code)+ | not $ null label+ , "lst:" `isPrefixOf` label+ , Just caption <- lookup "caption" attrs+ = case outFormat opts of+ f+ --if used with listings package,nothing shoud be done+ | isFormat "latex" f, useListings opts -> return cb+ --if not using listings, however, wrap it in a codelisting environment+ | isFormat "latex" f ->+ return $ Div nullAttr [+ RawBlock (Format "tex")+ $ "\\begin{codelisting}\n\\caption{"++caption++"}"+ , cb+ , RawBlock (Format "tex") "\\end{codelisting}"+ ]+ _ -> do+ let cap = toList $ text caption+ idxStr <- replaceAttr opts label cap lstRefs'+ let caption' = applyTemplate idxStr cap $ listingTemplate opts+ return $ Div (label, "listing":classes, []) [+ Para caption'+ , CodeBlock ([], classes, attrs \\ [("caption", caption)]) code+ ]+replaceBlocks opts+ (Div (label,"listing":_, [])+ [Para caption, CodeBlock ([],classes,attrs) code])+ | not $ null label+ , "lst:" `isPrefixOf` label+ = case outFormat opts of+ f+ --if used with listings package, return code block with caption+ | isFormat "latex" f, useListings opts ->+ return $ CodeBlock (label,classes,("caption",stringify caption):attrs) code+ --if not using listings, however, wrap it in a codelisting environment+ | isFormat "latex" f ->+ return $ Div nullAttr [+ RawBlock (Format "tex") "\\begin{codelisting}"+ , Para [RawInline (Format "tex") "\\caption",Span nullAttr caption]+ , CodeBlock (label,classes,attrs) code+ , RawBlock (Format "tex") "\\end{codelisting}"+ ]+ _ -> do+ idxStr <- replaceAttr opts label caption lstRefs'+ let caption' = applyTemplate idxStr caption $ listingTemplate opts+ return $ Div (label, "listing":classes, []) [+ Para caption'+ , CodeBlock ([], classes, attrs) code+ ]+replaceBlocks _ x = return x++divBlocks :: Block -> Block+divBlocks (Para (Image alt img:c))+ | Just label <- getRefLabel "fig" c+ = Div (label,[],[]) [Plain [Image alt (fst img, "fig:")]]+divBlocks (Para (math@(Math DisplayMath _eq):c))+ | Just label <- getRefLabel "eq" c+ = Div (label,[],[]) [Plain [math]]+divBlocks (table@(Table title _align _widths _header _cells))+ | not $ null title+ , Just label <- getRefLabel "tbl" [last title]+ = Div (label,[],[]) [table]+divBlocks x = x++getRefLabel :: String -> [Inline] -> Maybe String+getRefLabel _ [] = Nothing+getRefLabel tag ils+ | Str attr <- last ils+ , all (==Space) (init ils)+ , "}" `isSuffixOf` attr+ , ("{#"++tag++":") `isPrefixOf` attr+ = init `fmap` stripPrefix "{#" attr+getRefLabel _ _ = Nothing++replaceAttr :: Options -> String -> [Inline] -> Accessor References RefMap -> WS [Inline]+replaceAttr o label title prop+ = do+ chap <- take (chapDepth o) `fmap` gets curChap+ index <- (1+) `fmap` gets (M.size . M.filter ((==chap) . fst . refIndex) . getProp prop)+ modify $ modifyProp prop $ M.insert label RefRec {+ refIndex=(chap,index)+ , refTitle=normalizeSpaces title+ }+ return $ chapPrefix (chapDelim o) chap index++replaceAttrSec :: String -> [Inline] -> Accessor References RefMap -> WS ()+replaceAttrSec label title prop+ = do+ chap <- gets curChap+ modify $ modifyProp prop $ M.insert label RefRec {+ refIndex=(init chap,last chap)+ , refTitle=normalizeSpaces title+ }+ return ()
+ src/Text/Pandoc/CrossRef/References/List.hs view
@@ -0,0 +1,37 @@+module Text.Pandoc.CrossRef.References.List (listOf) where++import Text.Pandoc.Definition+import Control.Monad.State+import Control.Arrow+import Data.List+import qualified Data.Map as M++import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.Util.Util+import Text.Pandoc.CrossRef.Util.Options++listOf :: Options -> [Block] -> WS [Block]+listOf Options{outFormat=f} x | isFormat "latex" f = return x+listOf opts (Para [RawInline (Format "tex") "\\listoffigures"]:xs)+ = gets imgRefs >>= makeList opts lofTitle xs+listOf opts (Para [RawInline (Format "tex") "\\listoftables"]:xs)+ = gets tblRefs >>= makeList opts lotTitle xs+listOf opts (Para [RawInline (Format "tex") "\\listoflistings"]:xs)+ = gets lstRefs >>= makeList opts lolTitle xs+listOf _ x = return x++makeList :: Options -> (Options -> [Block]) -> [Block] -> M.Map String RefRec -> WS [Block]+makeList opts titlef xs refs+ = return $+ titlef opts +++ (if chapDepth opts > 0+ then Div ("", ["list"], []) (itemChap `map` refsSorted)+ else OrderedList style (item `map` refsSorted))+ : xs+ where+ refsSorted = sortBy compare' $ M.toList refs+ compare' (_,RefRec{refIndex=i}) (_,RefRec{refIndex=j}) = compare i j+ item = (:[]) . Plain . refTitle . snd+ itemChap = Para . uncurry ((. (Space :)) . (++)) . (numWithChap . refIndex &&& refTitle) . snd+ numWithChap = uncurry $ chapPrefix (chapDelim opts)+ style = (1,DefaultStyle,DefaultDelim)
+ src/Text/Pandoc/CrossRef/References/Refs.hs view
@@ -0,0 +1,138 @@+module Text.Pandoc.CrossRef.References.Refs (replaceRefs) where++import Text.Pandoc.Definition+import Text.Pandoc.Shared (normalizeInlines, normalizeSpaces)+import Control.Monad.State+import Data.List+import Data.Maybe+import Data.Function+import qualified Data.Map as M+import Control.Arrow as A++import Text.Pandoc.CrossRef.Util.Accessor+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.References.Accessors+import Text.Pandoc.CrossRef.Util.Util+import Text.Pandoc.CrossRef.Util.Options++replaceRefs :: Options -> [Inline] -> WS [Inline]+replaceRefs opts (Cite cits _:xs)+ = (++ xs) `fmap` intercalate [Str ",", Space] `fmap`+ mapM replaceRefs' (groupBy eqPrefix cits)+ where+ eqPrefix a b = uncurry (==) $+ (fmap uncapitalizeFirst . getLabelPrefix . citationId) <***> (a,b)+ (<***>) = join (***)+ replaceRefs' cits'+ | Just prefix <- allCitsPrefix cits'+ = replaceRefs'' prefix opts cits'+ | otherwise = return [Cite cits' il']+ where+ il' = normalizeInlines $+ [Str "["]+ ++intercalate [Str ";", Space] (map citationToInlines cits')+ ++[Str "]"]+ citationToInlines c = normalizeSpaces $+ citationPrefix c ++ [Space, Str $ "@"++citationId c] ++ citationSuffix c+ replaceRefs'' = case outFormat opts of+ f | isFormat "latex" f -> replaceRefsLatex+ _ -> replaceRefsOther+replaceRefs _ x = return x++-- accessors to state variables+accMap :: M.Map String (Accessor References RefMap)+accMap = M.fromList [("fig:",imgRefs')+ ,("eq:" ,eqnRefs')+ ,("tbl:",tblRefs')+ ,("lst:",lstRefs')+ ,("sec:",secRefs')+ ]++-- accessors to options+prefMap :: M.Map String (Options -> Bool -> Int -> [Inline])+prefMap = M.fromList [("fig:",figPrefix)+ ,("eq:" ,eqnPrefix)+ ,("tbl:",tblPrefix)+ ,("lst:",lstPrefix)+ ,("sec:",secPrefix)+ ]++prefixes :: [String]+prefixes = M.keys accMap++getRefPrefix :: Options -> String -> Bool -> Int -> [Inline]+getRefPrefix opts prefix capitalize num+ | null refprefix = []+ | otherwise = refprefix ++ [Str "\160"]+ where refprefix = lookupUnsafe prefix prefMap opts capitalize num++lookupUnsafe :: Ord k => k -> M.Map k v -> v+lookupUnsafe = (fromJust .) . M.lookup++allCitsPrefix :: [Citation] -> Maybe String+allCitsPrefix cits = find isCitationPrefix prefixes+ where+ isCitationPrefix p =+ all (p `isPrefixOf`) $ map (uncapitalizeFirst . citationId) cits++replaceRefsLatex :: String -> Options -> [Citation] -> WS [Inline]+replaceRefsLatex prefix opts cits =+ return $ p ++ [texcit]+ where+ texcit =+ RawInline (Format "tex") $+ if useCleveref opts then+ cref++"{"++listLabels prefix "" "," "" cits++"}"+ else+ listLabels prefix "\\ref{" ", " "}" cits+ p | useCleveref opts = []+ | otherwise = getRefPrefix opts prefix cap (length cits - 1)+ cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits+ cref | cap = "\\Cref"+ | otherwise = "\\cref"++listLabels :: String -> String -> String -> String -> [Citation] -> String+listLabels prefix p sep s =+ intercalate sep . map ((p ++) . (++ s) . (prefix++) . getLabelWithoutPrefix . citationId)++getLabelWithoutPrefix :: String -> String+getLabelWithoutPrefix = drop 1 . dropWhile (/=':')++getLabelPrefix :: String -> Maybe String+getLabelPrefix lab+ | uncapitalizeFirst p `elem` prefixes = Just p+ | otherwise = Nothing+ where p = (++ ":") . takeWhile (/=':') $ lab++replaceRefsOther :: String -> Options -> [Citation] -> WS [Inline]+replaceRefsOther prefix opts cits = do+ indices <- mapM (getRefIndex prefix) cits+ let+ indices' = groupBy ((==) `on` (fmap fst . fst)) (sort indices)+ cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits+ return $ normalizeInlines $ getRefPrefix opts prefix cap (length cits - 1) ++ intercalate [Str ",", Space] (makeIndices opts `map` indices')++getRefIndex :: String -> Citation -> WS (Maybe ([Int], Int), [Inline])+getRefIndex prefix Citation{citationId=cid,citationSuffix=suf}+ = (\x -> (x,suf)) `fmap` gets (fmap refIndex . M.lookup lab . getProp prop)+ where+ prop = lookupUnsafe prefix accMap+ lab = prefix ++ getLabelWithoutPrefix cid++makeIndices :: Options -> [(Maybe ([Int], Int), [Inline])] -> [Inline]+makeIndices _ s | any (isNothing . fst) s = [Strong [Str "??"]]+makeIndices o s = intercalate sep $ reverse $ map f $ foldl' f2 [] $ map (A.first fromJust) $ filter (isJust . fst) s+ where+ f2 [] (i,suf) = [[(i,suf)]]+ f2 ([]:xs) (i,suf) = [(i,suf)]:xs+ f2 l@(x@(((_,hx),sufp):_):xs) (i@(_,ni),suf)+ | not (null suf) || not (null sufp) = [(i,suf)]:l+ | ni-hx == 0 = l -- remove duplicates+ | ni-hx == 1 = ((i,[]):x):xs -- group sequental+ | otherwise = [(i,[])]:l -- new group+ f [] = [] -- drop empty lists+ f [w] = show' w -- single value+ f [w1,w2] = show' w2 ++ sep ++ show' w1 -- two values+ f (x:xs) = show' (last xs) ++ rangeDelim o ++ show' x -- shorten more than two values+ sep = [Str ",", Space]+ show' ((c,n),suf) = chapPrefix (chapDelim o) c n ++ suf
+ src/Text/Pandoc/CrossRef/References/Types.hs view
@@ -0,0 +1,33 @@+module Text.Pandoc.CrossRef.References.Types ( References(..)+ , WS+ , RefRec(..)+ , RefMap+ , def+ ) where++import qualified Data.Map as M+import Text.Pandoc.Definition+import Control.Monad.State+import Data.Default++data RefRec = RefRec { refIndex :: ([Int], Int)+ , refTitle :: [Inline]+ } deriving (Show, Eq)++type RefMap = M.Map String RefRec++-- state data type+data References = References { imgRefs :: RefMap+ , eqnRefs :: RefMap+ , tblRefs :: RefMap+ , lstRefs :: RefMap+ , secRefs :: RefMap+ , curChap :: [Int]+ } deriving (Show, Eq)++--state monad+type WS a = State References a++instance Default References where+ def = References n n n n n []+ where n = M.empty
+ src/Text/Pandoc/CrossRef/Util/Accessor.hs view
@@ -0,0 +1,17 @@+module Text.Pandoc.CrossRef.Util.Accessor (Accessor, setProp, getProp, modifyProp) where++-- from data-accessor http://www.haskell.org/haskellwiki/Record_access+-- Copyright (c) Henning Thielemann <haskell@henning-thielemann.de>, Luke Palmer <lrpalmer@gmail.com>+-- Licensed under BSD3 -- see BSD3.md+type Accessor r a = a -> r -> (a, r)++setProp :: Accessor r a -> a -> r -> r+setProp f x = snd . f x++getProp :: Accessor r a -> r -> a+getProp f = fst . f undefined++modifyProp :: Accessor r a -> (a -> a) -> r -> r+modifyProp f g rOld =+ let (a,rNew) = f (g a) rOld+ in rNew
+ src/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs view
@@ -0,0 +1,37 @@+module Text.Pandoc.CrossRef.Util.CodeBlockCaptions+ (+ codeBlockCaptions+ ) where++import Text.Pandoc.Definition+import Text.Pandoc.Shared (normalizeSpaces)+import Data.List (isPrefixOf, stripPrefix)+import Data.Maybe (fromMaybe)+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.Util.Options++codeBlockCaptions :: Options -> [Block] -> WS [Block]+codeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)+ = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs+codeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)+ = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs+codeBlockCaptions _ x = return x++orderAgnostic :: Options -> [Block] -> Maybe [Block]+orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)+ | cbCaptions opts+ , Just caption <- getCodeBlockCaption ils+ , not $ null label+ , "lst" `isPrefixOf` label+ = return $ Div (label,"listing":classes, [])+ [Para caption, CodeBlock ([],classes,attrs) code] : xs+orderAgnostic _ _ = Nothing++getCodeBlockCaption :: [Inline] -> Maybe [Inline]+getCodeBlockCaption ils+ | Just caption <- [Str "Listing:",Space] `stripPrefix` normalizeSpaces ils+ = Just caption+ | Just caption <- [Str ":",Space] `stripPrefix` normalizeSpaces ils+ = Just caption+ | otherwise+ = Nothing
+ src/Text/Pandoc/CrossRef/Util/Meta.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.CrossRef.Util.Meta where++import Text.Pandoc (readMarkdown)+import Text.Pandoc.Shared (stringify)+import Text.Pandoc.Definition+import Data.Maybe (fromMaybe)+import Data.Default++getMetaList :: (Default a) => (MetaValue -> Maybe a) -> String -> Meta -> Int -> a+getMetaList f name meta i = fromMaybe def $ lookupMeta name meta >>= getList i >>= f++getMetaBool :: String -> Meta -> Bool+getMetaBool name meta = fromMaybe False $ lookupMeta name meta >>= toBool++getMetaInlines :: String -> Meta -> [Inline]+getMetaInlines name meta = fromMaybe [] $ lookupMeta name meta >>= toInlines++getMetaBlock :: String -> Meta -> [Block]+getMetaBlock name meta = fromMaybe [] $ lookupMeta name meta >>= toBlocks++getMetaString :: String -> Meta -> String+getMetaString name meta = fromMaybe [] $ lookupMeta name meta >>= toString++toInlines :: MetaValue -> Maybe [Inline]+toInlines (MetaString s) =+#if MIN_VERSION_pandoc(1,14,0)+ return $ getInlines $+ either (error . show) id $ readMarkdown def s+#else+ return $ getInlines $ readMarkdown def s+#endif+ where getInlines (Pandoc _ bs) = concatMap getInline bs+ getInline (Plain ils) = ils+ getInline (Para ils) = ils+ getInline _ = []+toInlines (MetaInlines s) = return s+toInlines _ = Nothing++toBool :: MetaValue -> Maybe Bool+toBool (MetaBool b) = return b+toBool _ = Nothing++toBlocks :: MetaValue -> Maybe [Block]+toBlocks (MetaBlocks bs) = return bs+toBlocks (MetaInlines ils) = return [Plain ils]+toBlocks (MetaString s) =+#if MIN_VERSION_pandoc(1,14,0)+ return $ getBlocks $+ either (error . show) id $ readMarkdown def s+#else+ return $ getBlocks $ readMarkdown def s+#endif+ where getBlocks (Pandoc _ bs) = bs+toBlocks _ = Nothing++toString :: MetaValue -> Maybe String+toString (MetaString s) = Just s+toString (MetaBlocks b) = Just $ stringify b+toString (MetaInlines i) = Just $ stringify i+toString _ = Nothing++getList :: Int -> MetaValue -> Maybe MetaValue+getList i (MetaList l) = l !!? i+ where+ list !!? index | index >= 0 && index < length list = Just $ list !! index+ | not $ null list = Just $ last list+ | otherwise = Nothing+getList _ x = Just x
+ src/Text/Pandoc/CrossRef/Util/ModifyMeta.hs view
@@ -0,0 +1,82 @@+module Text.Pandoc.CrossRef.Util.ModifyMeta+ (+ modifyMeta+ ) where++import Text.Pandoc+import Text.Pandoc.Builder+import Text.Pandoc.CrossRef.Util.Options+import Text.Pandoc.CrossRef.Util.Meta+import Text.Pandoc.CrossRef.Util.Util++modifyMeta :: Options -> Meta -> Meta+modifyMeta opts meta+ | isFormat "latex" (outFormat opts)+ = setMeta "header-includes"+ (headerInc $ lookupMeta "header-includes" meta)+ meta+ | otherwise = meta+ where+ headerInc :: Maybe MetaValue -> MetaValue+ headerInc Nothing = MetaList incList+ headerInc (Just (MetaList x)) = MetaList $ x ++ incList+ headerInc (Just x) = MetaList $ x:incList+ incList = map MetaString $+ floatnames +++ listnames +++ [ x | x <- codelisting, not $ useListings opts] +++ lolcommand +++ [ x | x <- cleveref, useCleveref opts] +++ [ x | x <- cleverefCodelisting, useCleveref opts && not (useListings opts)] +++ []+ where+ floatnames = [+ "\\AtBeginDocument{%"+ , "\\renewcommand*\\figurename{"++metaString "figureTitle"++"}"+ , "\\renewcommand*\\tablename{"++metaString "tableTitle"++"}"+ , "}"+ ]+ listnames = [+ "\\AtBeginDocument{%"+ , "\\renewcommand*\\listfigurename{"++metaString' "lofTitle"++"}"+ , "\\renewcommand*\\listtablename{"++metaString' "lotTitle"++"}"+ , "}"+ ]+ codelisting = [+ "\\usepackage{float}"+ , "\\floatstyle{ruled}"+ , "\\makeatletter"+ , "\\@ifundefined{c@chapter}{\\newfloat{codelisting}{h}{lop}}{\\newfloat{codelisting}{h}{lop}[chapter]}"+ , "\\makeatother"+ , "\\floatname{codelisting}{"++metaString "listingTitle"++"}"+ ]+ lolcommand+ | useListings opts = [+ "\\newcommand*\\listoflistings\\lstlistoflistings"+ , "\\AtBeginDocument{%"+ , "\\renewcommand*{\\lstlistlistingname}{"++metaString' "lolTitle"++"}"+ , "}"+ ]+ | otherwise = ["\\newcommand*\\listoflistings{\\listof{codelisting}{"++metaString' "lolTitle"++"}}"]+ cleveref = [+ "\\usepackage{cleveref}"+ , "\\crefname{figure}" ++ prefix figPrefix False+ , "\\crefname{table}" ++ prefix tblPrefix False+ , "\\crefname{equation}" ++ prefix eqnPrefix False+ , "\\crefname{listing}" ++ prefix lstPrefix False+ , "\\Crefname{figure}" ++ prefix figPrefix True+ , "\\Crefname{table}" ++ prefix tblPrefix True+ , "\\Crefname{equation}" ++ prefix eqnPrefix True+ , "\\Crefname{listing}" ++ prefix lstPrefix True+ ]+ cleverefCodelisting = [+ "\\makeatletter"+ , "\\crefname{codelisting}{\\cref@listing@name}{\\cref@listing@name@plural}"+ , "\\Crefname{codelisting}{\\Cref@listing@name}{\\Cref@listing@name@plural}"+ , "\\makeatother"+ ]+ toLatex = writeLaTeX def . Pandoc nullMeta . return . Plain+ metaString s = toLatex $ getMetaInlines s meta+ metaString' s = toLatex [Str $ getMetaString s meta]+ prefix f uc = "{" ++ toLatex (f opts uc 0) ++ "}" +++ "{" ++ toLatex (f opts uc 1) ++ "}"
+ src/Text/Pandoc/CrossRef/Util/Options.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE FlexibleContexts #-}++module Text.Pandoc.CrossRef.Util.Options (Options(..), getOptions) where+import Text.Pandoc.Definition+import Text.Pandoc.CrossRef.Util.Meta+import Text.Pandoc.CrossRef.Util.Template+import Text.Pandoc.CrossRef.Util.Util (capitalizeFirst)+import Text.Pandoc.Walk+import Data.Default+-- import Control.Monad.Identity++data Options = Options { useCleveref :: Bool+ , chapDepth :: Int+ , useListings :: Bool+ , cbCaptions :: Bool+ , autoSecLab :: Bool+ , figPrefix :: Bool -> Int -> [Inline]+ , eqnPrefix :: Bool -> Int -> [Inline]+ , tblPrefix :: Bool -> Int -> [Inline]+ , lstPrefix :: Bool -> Int -> [Inline]+ , secPrefix :: Bool -> Int -> [Inline]+ , chapDelim :: [Inline]+ , rangeDelim :: [Inline]+ , lofTitle :: [Block]+ , lotTitle :: [Block]+ , lolTitle :: [Block]+ , outFormat :: Maybe Format+ , figureTemplate :: Template+ , tableTemplate :: Template+ , listingTemplate :: Template+ }++getOptions :: Meta -> Maybe Format -> Options+getOptions dtv fmt =+ Options {+ useCleveref = getMetaBool "cref" dtv+ , chapDepth = if getMetaBool "chapters" dtv+ then read $ getMetaString "chaptersDepth" dtv+ else 0+ , useListings = getMetaBool "listings" dtv+ , cbCaptions = getMetaBool "codeBlockCaptions" dtv+ , autoSecLab = getMetaBool "autoSectionLabels" dtv+ , figPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "figPrefix"+ , eqnPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "eqnPrefix"+ , tblPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "tblPrefix"+ , lstPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "lstPrefix"+ , secPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "secPrefix"+ , chapDelim = getMetaInlines "chapDelim" dtv+ , rangeDelim = getMetaInlines "rangeDelim" dtv+ , lofTitle = getMetaBlock "lofTitle" dtv+ , lotTitle = getMetaBlock "lotTitle" dtv+ , lolTitle = getMetaBlock "lolTitle" dtv+ , outFormat = fmt+ , figureTemplate = makeTemplate dtv $ getMetaInlines "figureTemplate" dtv+ , tableTemplate = makeTemplate dtv $ getMetaInlines "tableTemplate" dtv+ , listingTemplate = makeTemplate dtv $ getMetaInlines "listingTemplate" dtv+ }++tryCapitalizeM :: (Functor m, Monad m, Walkable Inline a, Default a, Eq a) =>+ (String -> m a) -> String -> Bool -> m a+tryCapitalizeM f varname capitalize+ | capitalize = do+ res <- f (capitalizeFirst varname)+ case res of+ xs | xs == def -> f varname >>= walkM capStrFst+ | otherwise -> return xs+ | otherwise = f varname+ where+ capStrFst (Str s) = return $ Str $ capitalizeFirst s+ capStrFst x = return x++-- tryCapitalize :: (Walkable Inline a, Default a, Eq a) =>+-- (String -> a) -> String -> Bool -> a+-- tryCapitalize = ((runIdentity .) .) . tryCapitalizeM . (return .)
+ src/Text/Pandoc/CrossRef/Util/Settings.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.CrossRef.Util.Settings (getSettings, defaultMeta) where++import Text.Pandoc+import Text.Pandoc.Builder+import Control.Exception (handle,IOException)++import Text.Pandoc.CrossRef.Util.Settings.Gen+import Text.Pandoc.CrossRef.Util.Meta++getSettings :: Meta -> IO Meta+getSettings meta = do+ let handler :: IOException -> IO String+ handler _ = return []+ yaml <- handle handler $ readFile (getMetaString "crossrefYaml" (meta <> defaultMeta))+#if MIN_VERSION_pandoc(1,14,0)+ let Pandoc dtve _ = either (error . show) id $ readMarkdown def ("---\n" ++ yaml ++ "\n---")+#else+ let Pandoc dtve _ = readMarkdown def ("---\n" ++ yaml ++ "\n---")+#endif+ return $ meta <> dtve <> defaultMeta++defaultMeta :: Meta+defaultMeta =+ figureTitle (str "Figure")+ <> tableTitle (str "Table")+ <> listingTitle (str "Listing")+ <> titleDelim (str ":")+ <> chapDelim (str ".")+ <> rangeDelim (str "-")+ <> figPrefix ([str "fig.", str "figs."])+ <> eqnPrefix ([str "eq." , str "eqns."])+ <> tblPrefix ([str "tbl.", str "tbls."])+ <> lstPrefix ([str "lst.", str "lsts."])+ <> secPrefix ([str "sec.", str "secs."])+ <> lofTitle (header 1 $ text "List of Figures")+ <> lotTitle (header 1 $ text "List of Tables")+ <> lolTitle (header 1 $ text "List of Listings")+ <> figureTemplate (var "figureTitle" <> space <> var "i" <> var "titleDelim" <> space <> var "t")+ <> tableTemplate (var "tableTitle" <> space <> var "i" <> var "titleDelim" <> space <> var "t")+ <> listingTemplate (var "listingTitle" <> space <> var "i" <> var "titleDelim" <> space <> var "t")+ <> crossrefYaml (MetaString "pandoc-crossref.yaml")+ <> chaptersDepth (MetaString "1")+ where var = displayMath
+ src/Text/Pandoc/CrossRef/Util/Settings/Gen.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE TemplateHaskell #-}++module Text.Pandoc.CrossRef.Util.Settings.Gen where++import Text.Pandoc+import qualified Data.Map as M++import Text.Pandoc.CrossRef.Util.Settings.Template+import Text.Pandoc.Builder++$(concat `fmap` mapM genSetting+ [ "figureTitle"+ , "tableTitle"+ , "listingTitle"+ , "titleDelim"+ , "chapDelim"+ , "rangeDelim"+ , "figPrefix"+ , "eqnPrefix"+ , "tblPrefix"+ , "lstPrefix"+ , "secPrefix"+ , "lofTitle"+ , "lotTitle"+ , "lolTitle"+ , "figureTemplate"+ , "tableTemplate"+ , "listingTemplate"+ , "crossrefYaml"+ , "chaptersDepth"+ ])
+ src/Text/Pandoc/CrossRef/Util/Settings/Template.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE QuasiQuotes, TemplateHaskell, RankNTypes, FlexibleInstances #-}+module Text.Pandoc.CrossRef.Util.Settings.Template where++import Language.Haskell.TH+import Text.Pandoc+import Text.Pandoc.Builder++genSetting :: String -> Q [Dec]+genSetting name = do+ sig <- [t| forall a. ToMetaValue a => a -> Meta |]+ return+ [ SigD func sig+ , FunD func [Clause [VarP value] (NormalB+ (AppE (ConE $ mkName "Meta")+ (AppE (AppE (VarE (mkName "M.singleton")) (LitE (StringL name)))+ (AppE (VarE (mkName "toMetaValue")) (VarE value))))+ ) []]]+ where+ func = mkName name+ value = mkName "value"
+ src/Text/Pandoc/CrossRef/Util/Template.hs view
@@ -0,0 +1,26 @@+module Text.Pandoc.CrossRef.Util.Template (Template,makeTemplate,applyTemplate) where++import Text.Pandoc.Definition+import Text.Pandoc.Generic+import Text.Pandoc.Shared (normalizeInlines)+import Data.Maybe+import Text.Pandoc.CrossRef.Util.Meta++type VarFunc = String -> Maybe MetaValue+newtype Template = Template (VarFunc -> [Inline])++makeTemplate :: Meta -> [Inline] -> Template+makeTemplate dtv = Template . flip scan . scan (`lookupMeta` dtv)+ where+ scan = bottomUp . go+ go vf (x@(Math DisplayMath var):xs) = replaceVar (vf var) [x] ++ xs+ go _ x = x+ replaceVar val def' = fromMaybe def' $ val >>= toInlines++applyTemplate :: [Inline] -> [Inline] -> Template -> [Inline]+applyTemplate i t (Template g) =+ normalizeInlines $ g internalVars+ where+ internalVars "i" = Just $ MetaInlines i+ internalVars "t" = Just $ MetaInlines t+ internalVars _ = Nothing
+ src/Text/Pandoc/CrossRef/Util/Util.hs view
@@ -0,0 +1,24 @@+module Text.Pandoc.CrossRef.Util.Util where++import Text.Pandoc.Definition+import Data.Char (toUpper, toLower, isUpper)+import Data.List (intercalate)++isFormat :: String -> Maybe Format -> Bool+isFormat fmt (Just (Format f)) = takeWhile (`notElem` "+-") f == fmt+isFormat _ Nothing = False++capitalizeFirst :: String -> String+capitalizeFirst (x:xs) = toUpper x : xs+capitalizeFirst [] = []++uncapitalizeFirst :: String -> String+uncapitalizeFirst (x:xs) = toLower x : xs+uncapitalizeFirst [] = []++isFirstUpper :: String -> Bool+isFirstUpper (x:_) = isUpper x+isFirstUpper [] = False++chapPrefix :: [Inline] -> [Int] -> Int -> [Inline]+chapPrefix delim chap index = intercalate delim (map (return . Str . show) (chap++[index]))
− src/Util/Accessor.hs
@@ -1,17 +0,0 @@-module Util.Accessor (Accessor, setProp, getProp, modifyProp) where---- from data-accessor http://www.haskell.org/haskellwiki/Record_access--- Copyright (c) Henning Thielemann <haskell@henning-thielemann.de>, Luke Palmer <lrpalmer@gmail.com>--- Licensed under BSD3 -- see BSD3.md-type Accessor r a = a -> r -> (a, r)--setProp :: Accessor r a -> a -> r -> r-setProp f x = snd . f x--getProp :: Accessor r a -> r -> a-getProp f = fst . f undefined--modifyProp :: Accessor r a -> (a -> a) -> r -> r-modifyProp f g rOld =- let (a,rNew) = f (g a) rOld- in rNew
− src/Util/CodeBlockCaptions.hs
@@ -1,37 +0,0 @@-module Util.CodeBlockCaptions- (- codeBlockCaptions- ) where--import Text.Pandoc.Definition-import Text.Pandoc.Shared (normalizeSpaces)-import Data.List (isPrefixOf, stripPrefix)-import Data.Maybe (fromMaybe)-import References.Types-import Util.Options--codeBlockCaptions :: Options -> [Block] -> WS [Block]-codeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)- = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs-codeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)- = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs-codeBlockCaptions _ x = return x--orderAgnostic :: Options -> [Block] -> Maybe [Block]-orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)- | cbCaptions opts- , Just caption <- getCodeBlockCaption ils- , not $ null label- , "lst" `isPrefixOf` label- = return $ Div (label,"listing":classes, [])- [Para caption, CodeBlock ([],classes,attrs) code] : xs-orderAgnostic _ _ = Nothing--getCodeBlockCaption :: [Inline] -> Maybe [Inline]-getCodeBlockCaption ils- | Just caption <- [Str "Listing:",Space] `stripPrefix` normalizeSpaces ils- = Just caption- | Just caption <- [Str ":",Space] `stripPrefix` normalizeSpaces ils- = Just caption- | otherwise- = Nothing
− src/Util/Meta.hs
@@ -1,69 +0,0 @@-{-# LANGUAGE CPP #-}-module Util.Meta where--import Text.Pandoc (readMarkdown)-import Text.Pandoc.Shared (stringify)-import Text.Pandoc.Definition-import Data.Maybe (fromMaybe)-import Data.Default--getMetaList :: (Default a) => (MetaValue -> Maybe a) -> String -> Meta -> Int -> a-getMetaList f name meta i = fromMaybe def $ lookupMeta name meta >>= getList i >>= f--getMetaBool :: String -> Meta -> Bool-getMetaBool name meta = fromMaybe False $ lookupMeta name meta >>= toBool--getMetaInlines :: String -> Meta -> [Inline]-getMetaInlines name meta = fromMaybe [] $ lookupMeta name meta >>= toInlines--getMetaBlock :: String -> Meta -> [Block]-getMetaBlock name meta = fromMaybe [] $ lookupMeta name meta >>= toBlocks--getMetaString :: String -> Meta -> String-getMetaString name meta = fromMaybe [] $ lookupMeta name meta >>= toString--toInlines :: MetaValue -> Maybe [Inline]-toInlines (MetaString s) =-#if MIN_VERSION_pandoc(1,14,0)- return $ getInlines $- either (error . show) id $ readMarkdown def s-#else- return $ getInlines $ readMarkdown def s-#endif- where getInlines (Pandoc _ bs) = concatMap getInline bs- getInline (Plain ils) = ils- getInline (Para ils) = ils- getInline _ = []-toInlines (MetaInlines s) = return s-toInlines _ = Nothing--toBool :: MetaValue -> Maybe Bool-toBool (MetaBool b) = return b-toBool _ = Nothing--toBlocks :: MetaValue -> Maybe [Block]-toBlocks (MetaBlocks bs) = return bs-toBlocks (MetaInlines ils) = return [Plain ils]-toBlocks (MetaString s) =-#if MIN_VERSION_pandoc(1,14,0)- return $ getBlocks $- either (error . show) id $ readMarkdown def s-#else- return $ getBlocks $ readMarkdown def s-#endif- where getBlocks (Pandoc _ bs) = bs-toBlocks _ = Nothing--toString :: MetaValue -> Maybe String-toString (MetaString s) = Just s-toString (MetaBlocks b) = Just $ stringify b-toString (MetaInlines i) = Just $ stringify i-toString _ = Nothing--getList :: Int -> MetaValue -> Maybe MetaValue-getList i (MetaList l) = l !!? i- where- list !!? index | index >= 0 && index < length list = Just $ list !! index- | not $ null list = Just $ last list- | otherwise = Nothing-getList _ x = Just x
− src/Util/ModifyMeta.hs
@@ -1,82 +0,0 @@-module Util.ModifyMeta- (- modifyMeta- ) where--import Text.Pandoc-import Text.Pandoc.Builder-import Util.Options-import Util.Meta-import Util.Util--modifyMeta :: Options -> Meta -> Meta-modifyMeta opts meta- | isFormat "latex" (outFormat opts)- = setMeta "header-includes"- (headerInc $ lookupMeta "header-includes" meta)- meta- | otherwise = meta- where- headerInc :: Maybe MetaValue -> MetaValue- headerInc Nothing = MetaList incList- headerInc (Just (MetaList x)) = MetaList $ x ++ incList- headerInc (Just x) = MetaList $ x:incList- incList = map MetaString $- floatnames ++- listnames ++- [ x | x <- codelisting, not $ useListings opts] ++- lolcommand ++- [ x | x <- cleveref, useCleveref opts] ++- [ x | x <- cleverefCodelisting, useCleveref opts && not (useListings opts)] ++- []- where- floatnames = [- "\\AtBeginDocument{%"- , "\\renewcommand*\\figurename{"++metaString "figureTitle"++"}"- , "\\renewcommand*\\tablename{"++metaString "tableTitle"++"}"- , "}"- ]- listnames = [- "\\AtBeginDocument{%"- , "\\renewcommand*\\listfigurename{"++metaString' "lofTitle"++"}"- , "\\renewcommand*\\listtablename{"++metaString' "lotTitle"++"}"- , "}"- ]- codelisting = [- "\\usepackage{float}"- , "\\floatstyle{ruled}"- , "\\makeatletter"- , "\\@ifundefined{c@chapter}{\\newfloat{codelisting}{h}{lop}}{\\newfloat{codelisting}{h}{lop}[chapter]}"- , "\\makeatother"- , "\\floatname{codelisting}{"++metaString "listingTitle"++"}"- ]- lolcommand- | useListings opts = [- "\\newcommand*\\listoflistings\\lstlistoflistings"- , "\\AtBeginDocument{%"- , "\\renewcommand*{\\lstlistlistingname}{"++metaString' "lolTitle"++"}"- , "}"- ]- | otherwise = ["\\newcommand*\\listoflistings{\\listof{codelisting}{"++metaString' "lolTitle"++"}}"]- cleveref = [- "\\usepackage{cleveref}"- , "\\crefname{figure}" ++ prefix figPrefix False- , "\\crefname{table}" ++ prefix tblPrefix False- , "\\crefname{equation}" ++ prefix eqnPrefix False- , "\\crefname{listing}" ++ prefix lstPrefix False- , "\\Crefname{figure}" ++ prefix figPrefix True- , "\\Crefname{table}" ++ prefix tblPrefix True- , "\\Crefname{equation}" ++ prefix eqnPrefix True- , "\\Crefname{listing}" ++ prefix lstPrefix True- ]- cleverefCodelisting = [- "\\makeatletter"- , "\\crefname{codelisting}{\\cref@listing@name}{\\cref@listing@name@plural}"- , "\\Crefname{codelisting}{\\Cref@listing@name}{\\Cref@listing@name@plural}"- , "\\makeatother"- ]- toLatex = writeLaTeX def . Pandoc nullMeta . return . Plain- metaString s = toLatex $ getMetaInlines s meta- metaString' s = toLatex [Str $ getMetaString s meta]- prefix f uc = "{" ++ toLatex (f opts uc 0) ++ "}" ++- "{" ++ toLatex (f opts uc 1) ++ "}"
− src/Util/Options.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}--module Util.Options (Options(..), getOptions) where-import Text.Pandoc.Definition-import Util.Meta-import Util.Template-import Util.Util (capitalizeFirst)-import Text.Pandoc.Walk-import Data.Default--- import Control.Monad.Identity--data Options = Options { useCleveref :: Bool- , chapDepth :: Int- , useListings :: Bool- , cbCaptions :: Bool- , autoSecLab :: Bool- , figPrefix :: Bool -> Int -> [Inline]- , eqnPrefix :: Bool -> Int -> [Inline]- , tblPrefix :: Bool -> Int -> [Inline]- , lstPrefix :: Bool -> Int -> [Inline]- , secPrefix :: Bool -> Int -> [Inline]- , chapDelim :: [Inline]- , rangeDelim :: [Inline]- , lofTitle :: [Block]- , lotTitle :: [Block]- , lolTitle :: [Block]- , outFormat :: Maybe Format- , figureTemplate :: Template- , tableTemplate :: Template- , listingTemplate :: Template- }--getOptions :: Meta -> Maybe Format -> Options-getOptions dtv fmt =- Options {- useCleveref = getMetaBool "cref" dtv- , chapDepth = if getMetaBool "chapters" dtv- then read $ getMetaString "chaptersDepth" dtv- else 0- , useListings = getMetaBool "listings" dtv- , cbCaptions = getMetaBool "codeBlockCaptions" dtv- , autoSecLab = getMetaBool "autoSectionLabels" dtv- , figPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "figPrefix"- , eqnPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "eqnPrefix"- , tblPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "tblPrefix"- , lstPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "lstPrefix"- , secPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "secPrefix"- , chapDelim = getMetaInlines "chapDelim" dtv- , rangeDelim = getMetaInlines "rangeDelim" dtv- , lofTitle = getMetaBlock "lofTitle" dtv- , lotTitle = getMetaBlock "lotTitle" dtv- , lolTitle = getMetaBlock "lolTitle" dtv- , outFormat = fmt- , figureTemplate = makeTemplate dtv $ getMetaInlines "figureTemplate" dtv- , tableTemplate = makeTemplate dtv $ getMetaInlines "tableTemplate" dtv- , listingTemplate = makeTemplate dtv $ getMetaInlines "listingTemplate" dtv- }--tryCapitalizeM :: (Functor m, Monad m, Walkable Inline a, Default a, Eq a) =>- (String -> m a) -> String -> Bool -> m a-tryCapitalizeM f varname capitalize- | capitalize = do- res <- f (capitalizeFirst varname)- case res of- xs | xs == def -> f varname >>= walkM capStrFst- | otherwise -> return xs- | otherwise = f varname- where- capStrFst (Str s) = return $ Str $ capitalizeFirst s- capStrFst x = return x---- tryCapitalize :: (Walkable Inline a, Default a, Eq a) =>--- (String -> a) -> String -> Bool -> a--- tryCapitalize = ((runIdentity .) .) . tryCapitalizeM . (return .)
− src/Util/Settings.hs
@@ -1,45 +0,0 @@-{-# LANGUAGE CPP #-}-module Util.Settings (getSettings, defaultMeta) where--import Text.Pandoc-import Control.Exception (handle,IOException)-import qualified Data.Map as M-import Data.Monoid--import Util.Meta (getMetaString)--getSettings :: Meta -> IO Meta-getSettings meta = do- let handler :: IOException -> IO String- handler _ = return []- yaml <- handle handler $ readFile (getMetaString "crossrefYaml" (meta <> defaultMeta))-#if MIN_VERSION_pandoc(1,14,0)- let Pandoc dtve _ = either (error . show) id $ readMarkdown def ("---\n" ++ yaml ++ "\n---")-#else- let Pandoc dtve _ = readMarkdown def ("---\n" ++ yaml ++ "\n---")-#endif- return $ meta <> dtve <> defaultMeta--defaultMeta :: Meta-defaultMeta = Meta $ M.fromList- [ ("figureTitle" , MetaInlines [Str "Figure"])- , ("tableTitle" , MetaInlines [Str "Table"])- , ("listingTitle" , MetaInlines [Str "Listing"])- , ("titleDelim" , MetaInlines [Str ":"])- , ("chapDelim" , MetaInlines [Str "."])- , ("rangeDelim" , MetaInlines [Str "-"])- , ("figPrefix" , MetaList [MetaInlines [Str "fig."], MetaInlines [Str "figs."]])- , ("eqnPrefix" , MetaList [MetaInlines [Str "eq."], MetaInlines [Str "eqns."]])- , ("tblPrefix" , MetaList [MetaInlines [Str "tbl."], MetaInlines [Str "tbls."]])- , ("lstPrefix" , MetaList [MetaInlines [Str "lst."], MetaInlines [Str "lsts."]])- , ("secPrefix" , MetaList [MetaInlines [Str "sec."], MetaInlines [Str "secs."]])- , ("lofTitle" , MetaBlocks [Header 1 nullAttr [Str "List",Space,Str "of",Space,Str "Figures"]])- , ("lotTitle" , MetaBlocks [Header 1 nullAttr [Str "List",Space,Str "of",Space,Str "Tables"]])- , ("lolTitle" , MetaBlocks [Header 1 nullAttr [Str "List",Space,Str "of",Space,Str "Listings"]])- , ("figureTemplate" , MetaInlines [var "figureTitle",Space,var "i",var "titleDelim",Space,var "t"])- , ("tableTemplate" , MetaInlines [var "tableTitle",Space,var "i",var "titleDelim",Space,var "t"])- , ("listingTemplate", MetaInlines [var "listingTitle",Space,var "i",var "titleDelim",Space,var "t"])- , ("crossrefYaml" , MetaString "pandoc-crossref.yaml")- , ("chaptersDepth" , MetaString "1")- ]- where var = Math DisplayMath
− src/Util/Template.hs
@@ -1,26 +0,0 @@-module Util.Template (Template,makeTemplate,applyTemplate) where--import Text.Pandoc.Definition-import Text.Pandoc.Generic-import Text.Pandoc.Shared (normalizeInlines)-import Data.Maybe-import Util.Meta--type VarFunc = String -> Maybe MetaValue-newtype Template = Template (VarFunc -> [Inline])--makeTemplate :: Meta -> [Inline] -> Template-makeTemplate dtv = Template . flip scan . scan (`lookupMeta` dtv)- where- scan = bottomUp . go- go vf (x@(Math DisplayMath var):xs) = replaceVar (vf var) [x] ++ xs- go _ x = x- replaceVar val def' = fromMaybe def' $ val >>= toInlines--applyTemplate :: [Inline] -> [Inline] -> Template -> [Inline]-applyTemplate i t (Template g) =- normalizeInlines $ g internalVars- where- internalVars "i" = Just $ MetaInlines i- internalVars "t" = Just $ MetaInlines t- internalVars _ = Nothing
− src/Util/Util.hs
@@ -1,24 +0,0 @@-module Util.Util where--import Text.Pandoc.Definition-import Data.Char (toUpper, toLower, isUpper)-import Data.List (intercalate)--isFormat :: String -> Maybe Format -> Bool-isFormat fmt (Just (Format f)) = takeWhile (`notElem` "+-") f == fmt-isFormat _ Nothing = False--capitalizeFirst :: String -> String-capitalizeFirst (x:xs) = toUpper x : xs-capitalizeFirst [] = []--uncapitalizeFirst :: String -> String-uncapitalizeFirst (x:xs) = toLower x : xs-uncapitalizeFirst [] = []--isFirstUpper :: String -> Bool-isFirstUpper (x:_) = isUpper x-isFirstUpper [] = False--chapPrefix :: [Inline] -> [Int] -> Int -> [Inline]-chapPrefix delim chap index = intercalate delim (map (return . Str . show) (chap++[index]))
test-pandoc-crossref.hs view
@@ -3,22 +3,23 @@ import Text.Pandoc.Builder import Text.Pandoc.Walk import Text.Pandoc.Generic-import Util.Options-import Util.Util import Control.Monad.State-import References.Types-import Util.Settings-import Util.Accessor-import References.Accessors-import qualified References.Blocks-import qualified References.Refs-import qualified References.List-import qualified Util.Template-import qualified Util.CodeBlockCaptions-import qualified Data.Map as M-import Data.Monoid import Data.List import Control.Arrow+import Data.Monoid -- needed for ghc<7.10+import qualified Data.Map as M++import Text.Pandoc.CrossRef.Util.Options+import Text.Pandoc.CrossRef.Util.Util+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.Util.Settings+import Text.Pandoc.CrossRef.Util.Accessor+import Text.Pandoc.CrossRef.References.Accessors+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+import qualified Text.Pandoc.CrossRef.Util.Template as Util.Template+import qualified Text.Pandoc.CrossRef.Util.CodeBlockCaptions as Util.CodeBlockCaptions main :: IO () main = hspec $ do