packages feed

pandoc-crossref 0.1.6.2 → 0.1.6.3

raw patch · 40 files changed

+1044/−1038 lines, 40 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.md view
@@ -296,6 +296,8 @@ lotTitle: "# Lista de tablas" ``` +pandoc-crossref will send this data to pandoc wrapped in lines of `---`. The YAML file's first line should specify a variable; it will not pass the variables if it is `---` or a blank line.+ One could use this with pandoc-crossref as follows:  `pandoc -F pandoc-crossref.hs -M "crossrefYaml=$HOME/misc/pandoc-crossref-es.yaml"`
+ lib/Text/Pandoc/CrossRef.hs view
@@ -0,0 +1,143 @@+{- |+   Module      : Text.Pandoc.CrossRef+   Copyright   : Copyright (C) 2015 Nikolay Yakimov+   License     : GNU GPL, version 2 or above++   Maintainer  : Nikolay Yakimov <root@livid.pp.ru>+   Stability   : alpha+   Portability : portable++Public interface to pandoc-crossref library++Example of use:++> import Text.Pandoc+> import Text.Pandoc.JSON+>+> import Text.Pandoc.CrossRef+>+> main :: IO ()+> main = toJSONFilter go+>   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'++This module also exports utility functions for setting up meta-settings for+pandoc-crossref. Refer to documentation for a complete list of metadata field+names. All functions accept a single argument of type, returned by+"Text.Pandoc.Builder" functions, and return 'Meta'.++Example:++> runCrossRefIO meta fmt crossRefBlocks blocks+>   where+>     meta =+>          figureTitle (str "Figura")+>       <> tableTitle (str "Tabla")+>       <> figPrefix (str "fig.")+>       <> eqnPrefix (str "ec.")+>       <> tblPrefix (str "tbl.")+>       <> loftitle (header 1 $ text "Lista de figuras")+>       <> lotTitle (header 1 $ text "Lista de tablas")+>       <> chaptersDepth (MetaString "2")++-}+{-# LANGUAGE RankNTypes #-}++module Text.Pandoc.CrossRef (+    crossRefBlocks+  , crossRefMeta+  , defaultCrossRefAction+  , runCrossRef+  , runCrossRefIO+  , module SG+  , CrossRefM+  , CrossRefEnv(..)+  ) 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++-- | Enviromnent for 'CrossRefM'+data CrossRefEnv = CrossRefEnv {+                      creSettings :: Meta -- ^Metadata settings+                    , creOptions :: Options -- ^Internal pandoc-crossref options+                   }++-- | Essentially a reader monad for basic pandoc-crossref environment+type CrossRefM a = R.Reader CrossRefEnv a++{- | Walk over blocks, while inserting cross-references, list-of, etc.++Works in 'CrossRefM' monad. -}+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++{- | Modifies metadata for LaTeX output, adding header-includes instructions+to setup custom and builtin environments.++Note, that if output format is not "latex", this function does nothing.++Works in 'CrossRefM' monad. -}+crossRefMeta :: CrossRefM Meta+crossRefMeta = do+  opts <- R.asks creOptions+  dtv <- R.asks creSettings+  return $ modifyMeta opts dtv++{- | Combines 'crossRefMeta' and 'crossRefBlocks'++Works in 'CrossRefM' monad. -}+defaultCrossRefAction :: Pandoc -> CrossRefM Pandoc+defaultCrossRefAction (Pandoc _ bs) = do+  meta' <- crossRefMeta+  bs' <- crossRefBlocks bs+  return $ Pandoc meta' bs'++{- | Run an action in 'CrossRefM' monad with argument, and return pure result.++This is primary function to work with 'CrossRefM' -}+runCrossRef :: forall 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+         }++{- | Run an action in 'CrossRefM' monad with argument, and return 'IO' result.++This function will attempt to read pandoc-crossref settings from settings+file specified by crossrefYaml metadata field. -}+runCrossRefIO :: forall 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
+ lib/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 (divBlocks, replaceBlocks)+import Text.Pandoc.CrossRef.References.Refs as X+import Text.Pandoc.CrossRef.References.List as X
+ lib/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})
+ lib/Text/Pandoc/CrossRef/References/Blocks.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.CrossRef.References.Blocks+  ( divBlocks+  , replaceBlocks+  , spanInlines+  , replaceInlines+  ) where++import Text.Pandoc.Definition+import Text.Pandoc.Generic+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+            cl = lookup "label" attrs+            inc l = init l ++ [(fst (last l) + 1, cl)]+            cc' | ln > n = inc $ take n cc+                | ln == n = inc cc+                | otherwise = cc ++ take (n-ln-1) (zip [1,1..] $ repeat Nothing) ++ [(1,cl)]+        in r{curChap=cc'}+      when ("sec:" `isPrefixOf` label') $ replaceAttrSec label' text' secRefs'+    return $ Header n (label', cls, attrs) text'+#if MIN_VERSION_pandoc(1,16,0)+#else+replaceBlocks opts (Div (label,_,attrs) [Plain [Image alt img]])+  | "fig:" `isPrefixOf` label+  = do+    idxStr <- replaceAttr opts label (lookup "label" attrs) 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' img]+#endif+replaceBlocks opts (Div (label,_,attrs) [Table title align widths header cells])+  | not $ null title+  , "tbl:" `isPrefixOf` label+  = do+    idxStr <- replaceAttr opts label (lookup "label" attrs) title tblRefs'+    let title' =+          case outFormat opts of+              f | isFormat "latex" f ->+                RawInline (Format "tex") ("\\label{"++label++"}") : title+              _  -> applyTemplate idxStr 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 (lookup "label" attrs) 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+              , RawInline (Format "tex") "}"+              ]+            , CodeBlock (label,classes,attrs) code+            , RawBlock (Format "tex") "\\end{codelisting}"+            ]+      _ -> do+        idxStr <- replaceAttr opts label (lookup "label" attrs) caption lstRefs'+        let caption' = applyTemplate idxStr caption $ listingTemplate opts+        return $ Div (label, "listing":classes, []) [+            Para caption'+          , CodeBlock ([], classes, attrs) code+          ]+replaceBlocks opts x = bottomUpM (replaceInlines opts) x++replaceInlines :: Options -> [Inline] -> WS [Inline]+replaceInlines opts (Span (label,_,attrs) [Math DisplayMath eq]:ils')+  | "eq:" `isPrefixOf` label+  = case outFormat opts of+      f | isFormat "latex" f ->+        let eqn = "\\begin{equation}"++eq++"\\label{"++label++"}\\end{equation}"+        in return $ RawInline (Format "tex") eqn : ils'+      _ -> do+        idxStr <- replaceAttr opts label (lookup "label" attrs) [] eqnRefs'+        let eq' = eq++"\\qquad("++stringify idxStr++")"+        return $ Math DisplayMath eq' : ils'+#if MIN_VERSION_pandoc(1,16,0)+replaceInlines opts (Image attr@(label,_,attrs) alt img:ils')+  | "fig:" `isPrefixOf` label, "fig:" `isPrefixOf` snd img+  = do+    idxStr <- replaceAttr opts label (lookup "label" attrs) alt imgRefs'+    let alt' = case outFormat opts of+          f | isFormat "latex" f ->+            RawInline (Format "tex") ("\\label{"++label++"}") : alt+          _  -> applyTemplate idxStr alt $ figureTemplate opts+    return $ Image attr alt' img : ils'+#else+#endif+replaceInlines _ x = return x++divBlocks :: Block -> Block+#if MIN_VERSION_pandoc(1,16,0)+#else+divBlocks (Para (Image alt (img, title):c))+  | Just label <- getRefLabel "fig" c+  = Div (label,[],[]) [Plain [Image alt (img, "fig:" ++ title)]]+#endif+divBlocks (Table title align widths header cells)+  | not $ null title+  , Just label <- getRefLabel "tbl" [last title]+  = Div (label,[],[]) [Table (init title) align widths header cells]+divBlocks x = bottomUp spanInlines x++spanInlines :: [Inline] -> [Inline]+spanInlines (math@(Math DisplayMath _eq):ils)+  | c:ils' <- dropWhile (==Space) ils+  , Just label <- getRefLabel "eq" [c]+  = Span (label,[],[]) [math]:ils'+spanInlines 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 -> Maybe String -> [Inline] -> Accessor References RefMap -> WS [Inline]+replaceAttr o label refLabel title prop+  = do+    chap  <- take (chapDepth o) `fmap` gets curChap+    i     <- (1+) `fmap` gets (M.size . M.filter ((==chap) . init . refIndex) . getProp prop)+    let index = chap ++ [(i, refLabel)]+    modify $ modifyProp prop $ M.insert label RefRec {+      refIndex= index+    , refTitle=normalizeSpaces title+    }+    return $ chapPrefix (chapDelim o) index++replaceAttrSec :: String -> [Inline] -> Accessor References RefMap -> WS ()+replaceAttrSec label title prop+  = do+    index  <- gets curChap+    modify $ modifyProp prop $ M.insert label RefRec {+      refIndex=index+    , refTitle=normalizeSpaces title+    }+    return ()
+ lib/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 = chapPrefix (chapDelim opts)+    style = (1,DefaultStyle,DefaultDelim)
+ lib/Text/Pandoc/CrossRef/References/Refs.hs view
@@ -0,0 +1,142 @@+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 init . 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 Index, [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 Index, [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 :: [[(Index, [Inline])]] -> (Index, [Inline]) -> [[(Index, [Inline])]]+  f2 [] (i,suf) = [[(i,suf)]]+  f2 ([]:xs) (i,suf) = [(i,suf)]:xs+  f2 l@(x@((ix,sufp):_):xs) (i,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+    where+      hx = fst $ last ix+      ni = fst $ last i+  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' (i,suf) = chapPrefix (chapDelim o) i ++ suf
+ lib/Text/Pandoc/CrossRef/References/Types.hs view
@@ -0,0 +1,36 @@+module Text.Pandoc.CrossRef.References.Types ( References(..)+                        , WS+                        , RefRec(..)+                        , RefMap+                        , Index+                        , def+                        ) where++import qualified Data.Map as M+import Text.Pandoc.Definition+import Control.Monad.State+import Data.Default++type Index = [(Int, Maybe String)]++data RefRec = RefRec { refIndex :: Index+                     , 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 :: Index+                             } 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
+ lib/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
+ lib/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
+ lib/Text/Pandoc/CrossRef/Util/Gap.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE CPP #-}++module Text.Pandoc.CrossRef.Util.Gap where++import qualified Text.Pandoc as P++readMarkdown :: P.ReaderOptions -> String -> P.Pandoc+#if MIN_VERSION_pandoc(1,14,0)+readMarkdown = (either (error . show) id .) . P.readMarkdown+#else+readMarkdown = P.readMarkdown+#endif
+ lib/Text/Pandoc/CrossRef/Util/Meta.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.CrossRef.Util.Meta where++import Text.Pandoc.CrossRef.Util.Gap+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) =+  return $ getInlines $ readMarkdown def s+  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) =+  return $ getBlocks $ readMarkdown def s+  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
+ lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs view
@@ -0,0 +1,84 @@+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{section}" ++ prefix secPrefix False+          , "\\Crefname{figure}" ++ prefix figPrefix True+          , "\\Crefname{table}" ++ prefix tblPrefix True+          , "\\Crefname{equation}" ++ prefix eqnPrefix True+          , "\\Crefname{listing}" ++ prefix lstPrefix True+          , "\\Crefname{section}" ++ prefix secPrefix 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) ++ "}"
+ lib/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 .)
+ lib/Text/Pandoc/CrossRef/Util/Settings.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE CPP #-}+module Text.Pandoc.CrossRef.Util.Settings (getSettings, defaultMeta) where++import Text.Pandoc hiding (readMarkdown)+import Text.Pandoc.CrossRef.Util.Gap+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))+  let Pandoc dtve _ = readMarkdown def ("---\n" ++ yaml ++ "\n---")+  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
+ lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs view
@@ -0,0 +1,61 @@+module Text.Pandoc.CrossRef.Util.Settings.Gen where++import Text.Pandoc.CrossRef.Util.Settings.Template+import Text.Pandoc.Builder++figureTitle :: ToMetaValue a => a -> Meta+figureTitle = template "figureTitle"++tableTitle :: ToMetaValue a => a -> Meta+tableTitle = template "tableTitle"++listingTitle :: ToMetaValue a => a -> Meta+listingTitle = template "listingTitle"++titleDelim :: ToMetaValue a => a -> Meta+titleDelim = template "titleDelim"++chapDelim :: ToMetaValue a => a -> Meta+chapDelim = template "chapDelim"++rangeDelim :: ToMetaValue a => a -> Meta+rangeDelim = template "rangeDelim"++figPrefix :: ToMetaValue a => a -> Meta+figPrefix = template "figPrefix"++eqnPrefix :: ToMetaValue a => a -> Meta+eqnPrefix = template "eqnPrefix"++tblPrefix :: ToMetaValue a => a -> Meta+tblPrefix = template "tblPrefix"++lstPrefix :: ToMetaValue a => a -> Meta+lstPrefix = template "lstPrefix"++secPrefix :: ToMetaValue a => a -> Meta+secPrefix = template "secPrefix"++lofTitle :: ToMetaValue a => a -> Meta+lofTitle = template "lofTitle"++lotTitle :: ToMetaValue a => a -> Meta+lotTitle = template "lotTitle"++lolTitle :: ToMetaValue a => a -> Meta+lolTitle = template "lolTitle"++figureTemplate :: ToMetaValue a => a -> Meta+figureTemplate = template "figureTemplate"++tableTemplate :: ToMetaValue a => a -> Meta+tableTemplate = template "tableTemplate"++listingTemplate :: ToMetaValue a => a -> Meta+listingTemplate = template "listingTemplate"++crossrefYaml :: ToMetaValue a => a -> Meta+crossrefYaml = template "crossrefYaml"++chaptersDepth :: ToMetaValue a => a -> Meta+chaptersDepth = template "chaptersDepth"
+ lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs view
@@ -0,0 +1,8 @@+module Text.Pandoc.CrossRef.Util.Settings.Template where++import Text.Pandoc.Definition+import Text.Pandoc.Builder+import qualified Data.Map as M++template :: ToMetaValue a => String -> a -> Meta+template name = Meta . M.singleton name . toMetaValue
+ lib/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
+ lib/Text/Pandoc/CrossRef/Util/Util.hs view
@@ -0,0 +1,26 @@+module Text.Pandoc.CrossRef.Util.Util where++import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.Definition+import Data.Char (toUpper, toLower, isUpper)+import Data.List (intercalate)+import Data.Maybe (fromMaybe)++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] -> Index -> [Inline]+chapPrefix delim index = intercalate delim (map (return . Str . uncurry (fromMaybe . show)) index)
pandoc-crossref.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                pandoc-crossref-version:             0.1.6.2+version:             0.1.6.3 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@@ -24,7 +24,7 @@ source-repository this   type: git   location: https://github.com/lierdakil/pandoc-crossref-  tag: v0.1.6.2+  tag: v0.1.6.3  library   exposed-modules:     Text.Pandoc.CrossRef@@ -53,7 +53,7 @@                      , yaml >= 0.8 && <0.9                      , data-default >= 0.4 && <0.6                      , bytestring >=0.9 && <0.11-  hs-source-dirs:      src+  hs-source-dirs:      lib   Ghc-Options:         -Wall   default-language:    Haskell2010   other-extensions:    RankNTypes@@ -71,14 +71,14 @@                      , data-default >= 0.4 && <0.6                      , bytestring >=0.9 && <0.11                      , pandoc-crossref-  hs-source-dirs:      .+  hs-source-dirs:      src   Ghc-Options:         -Wall   default-language:    Haskell2010  Test-Suite test-pandoc-crossref   Type:           exitcode-stdio-1.0   Main-Is:        test-pandoc-crossref.hs-  hs-source-dirs: test, src+  hs-source-dirs: test, lib   Build-Depends:   base >=4.2 && <5                  , pandoc >= 1.13 && <1.17                  , mtl >= 1.1 && <2.3
− pandoc-crossref.hs
@@ -1,14 +0,0 @@-import Text.Pandoc-import Text.Pandoc.JSON--import Text.Pandoc.CrossRef--main :: IO ()-main = toJSONFilter go-  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/Text/Pandoc/CrossRef.hs
@@ -1,143 +0,0 @@-{- |-   Module      : Text.Pandoc.CrossRef-   Copyright   : Copyright (C) 2015 Nikolay Yakimov-   License     : GNU GPL, version 2 or above--   Maintainer  : Nikolay Yakimov <root@livid.pp.ru>-   Stability   : alpha-   Portability : portable--Public interface to pandoc-crossref library--Example of use:--> import Text.Pandoc-> import Text.Pandoc.JSON->-> import Text.Pandoc.CrossRef->-> main :: IO ()-> main = toJSONFilter go->   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'--This module also exports utility functions for setting up meta-settings for-pandoc-crossref. Refer to documentation for a complete list of metadata field-names. All functions accept a single argument of type, returned by-"Text.Pandoc.Builder" functions, and return 'Meta'.--Example:--> runCrossRefIO meta fmt crossRefBlocks blocks->   where->     meta =->          figureTitle (str "Figura")->       <> tableTitle (str "Tabla")->       <> figPrefix (str "fig.")->       <> eqnPrefix (str "ec.")->       <> tblPrefix (str "tbl.")->       <> loftitle (header 1 $ text "Lista de figuras")->       <> lotTitle (header 1 $ text "Lista de tablas")->       <> chaptersDepth (MetaString "2")---}-{-# LANGUAGE RankNTypes #-}--module Text.Pandoc.CrossRef (-    crossRefBlocks-  , crossRefMeta-  , defaultCrossRefAction-  , runCrossRef-  , runCrossRefIO-  , module SG-  , CrossRefM-  , CrossRefEnv(..)-  ) 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---- | Enviromnent for 'CrossRefM'-data CrossRefEnv = CrossRefEnv {-                      creSettings :: Meta -- ^Metadata settings-                    , creOptions :: Options -- ^Internal pandoc-crossref options-                   }---- | Essentially a reader monad for basic pandoc-crossref environment-type CrossRefM a = R.Reader CrossRefEnv a--{- | Walk over blocks, while inserting cross-references, list-of, etc.--Works in 'CrossRefM' monad. -}-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--{- | Modifies metadata for LaTeX output, adding header-includes instructions-to setup custom and builtin environments.--Note, that if output format is not "latex", this function does nothing.--Works in 'CrossRefM' monad. -}-crossRefMeta :: CrossRefM Meta-crossRefMeta = do-  opts <- R.asks creOptions-  dtv <- R.asks creSettings-  return $ modifyMeta opts dtv--{- | Combines 'crossRefMeta' and 'crossRefBlocks'--Works in 'CrossRefM' monad. -}-defaultCrossRefAction :: Pandoc -> CrossRefM Pandoc-defaultCrossRefAction (Pandoc _ bs) = do-  meta' <- crossRefMeta-  bs' <- crossRefBlocks bs-  return $ Pandoc meta' bs'--{- | Run an action in 'CrossRefM' monad with argument, and return pure result.--This is primary function to work with 'CrossRefM' -}-runCrossRef :: forall 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-         }--{- | Run an action in 'CrossRefM' monad with argument, and return 'IO' result.--This function will attempt to read pandoc-crossref settings from settings-file specified by crossrefYaml metadata field. -}-runCrossRefIO :: forall 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
@@ -1,7 +0,0 @@-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 (divBlocks, replaceBlocks)-import Text.Pandoc.CrossRef.References.Refs as X-import Text.Pandoc.CrossRef.References.List as X
− src/Text/Pandoc/CrossRef/References/Accessors.hs
@@ -1,19 +0,0 @@-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
@@ -1,190 +0,0 @@-{-# LANGUAGE CPP #-}-module Text.Pandoc.CrossRef.References.Blocks-  ( divBlocks-  , replaceBlocks-  , spanInlines-  , replaceInlines-  ) where--import Text.Pandoc.Definition-import Text.Pandoc.Generic-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-            cl = lookup "label" attrs-            inc l = init l ++ [(fst (last l) + 1, cl)]-            cc' | ln > n = inc $ take n cc-                | ln == n = inc cc-                | otherwise = cc ++ take (n-ln-1) (zip [1,1..] $ repeat Nothing) ++ [(1,cl)]-        in r{curChap=cc'}-      when ("sec:" `isPrefixOf` label') $ replaceAttrSec label' text' secRefs'-    return $ Header n (label', cls, attrs) text'-#if MIN_VERSION_pandoc(1,16,0)-#else-replaceBlocks opts (Div (label,_,attrs) [Plain [Image alt img]])-  | "fig:" `isPrefixOf` label-  = do-    idxStr <- replaceAttr opts label (lookup "label" attrs) 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' img]-#endif-replaceBlocks opts (Div (label,_,attrs) [Table title align widths header cells])-  | not $ null title-  , "tbl:" `isPrefixOf` label-  = do-    idxStr <- replaceAttr opts label (lookup "label" attrs) title tblRefs'-    let title' =-          case outFormat opts of-              f | isFormat "latex" f ->-                RawInline (Format "tex") ("\\label{"++label++"}") : title-              _  -> applyTemplate idxStr 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 (lookup "label" attrs) 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 (lookup "label" attrs) caption lstRefs'-        let caption' = applyTemplate idxStr caption $ listingTemplate opts-        return $ Div (label, "listing":classes, []) [-            Para caption'-          , CodeBlock ([], classes, attrs) code-          ]-replaceBlocks opts x = bottomUpM (replaceInlines opts) x--replaceInlines :: Options -> [Inline] -> WS [Inline]-replaceInlines opts (Span (label,_,attrs) [Math DisplayMath eq]:ils')-  | "eq:" `isPrefixOf` label-  = case outFormat opts of-      f | isFormat "latex" f ->-        let eqn = "\\begin{equation}"++eq++"\\label{"++label++"}\\end{equation}"-        in return $ RawInline (Format "tex") eqn : ils'-      _ -> do-        idxStr <- replaceAttr opts label (lookup "label" attrs) [] eqnRefs'-        let eq' = eq++"\\qquad("++stringify idxStr++")"-        return $ Math DisplayMath eq' : ils'-#if MIN_VERSION_pandoc(1,16,0)-replaceInlines opts (Image attr@(label,_,attrs) alt img:ils')-  | "fig:" `isPrefixOf` label, "fig:" `isPrefixOf` snd img-  = do-    idxStr <- replaceAttr opts label (lookup "label" attrs) alt imgRefs'-    let alt' = case outFormat opts of-          f | isFormat "latex" f ->-            RawInline (Format "tex") ("\\label{"++label++"}") : alt-          _  -> applyTemplate idxStr alt $ figureTemplate opts-    return $ Image attr alt' img : ils'-#else-#endif-replaceInlines _ x = return x--divBlocks :: Block -> Block-#if MIN_VERSION_pandoc(1,16,0)-#else-divBlocks (Para (Image alt (img, title):c))-  | Just label <- getRefLabel "fig" c-  = Div (label,[],[]) [Plain [Image alt (img, "fig:" ++ title)]]-#endif-divBlocks (Table title align widths header cells)-  | not $ null title-  , Just label <- getRefLabel "tbl" [last title]-  = Div (label,[],[]) [Table (init title) align widths header cells]-divBlocks x = bottomUp spanInlines x--spanInlines :: [Inline] -> [Inline]-spanInlines (math@(Math DisplayMath _eq):ils)-  | c:ils' <- dropWhile (==Space) ils-  , Just label <- getRefLabel "eq" [c]-  = Span (label,[],[]) [math]:ils'-spanInlines 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 -> Maybe String -> [Inline] -> Accessor References RefMap -> WS [Inline]-replaceAttr o label refLabel title prop-  = do-    chap  <- take (chapDepth o) `fmap` gets curChap-    i     <- (1+) `fmap` gets (M.size . M.filter ((==chap) . init . refIndex) . getProp prop)-    let index = chap ++ [(i, refLabel)]-    modify $ modifyProp prop $ M.insert label RefRec {-      refIndex= index-    , refTitle=normalizeSpaces title-    }-    return $ chapPrefix (chapDelim o) index--replaceAttrSec :: String -> [Inline] -> Accessor References RefMap -> WS ()-replaceAttrSec label title prop-  = do-    index  <- gets curChap-    modify $ modifyProp prop $ M.insert label RefRec {-      refIndex=index-    , refTitle=normalizeSpaces title-    }-    return ()
− src/Text/Pandoc/CrossRef/References/List.hs
@@ -1,37 +0,0 @@-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 = chapPrefix (chapDelim opts)-    style = (1,DefaultStyle,DefaultDelim)
− src/Text/Pandoc/CrossRef/References/Refs.hs
@@ -1,142 +0,0 @@-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 init . 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 Index, [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 Index, [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 :: [[(Index, [Inline])]] -> (Index, [Inline]) -> [[(Index, [Inline])]]-  f2 [] (i,suf) = [[(i,suf)]]-  f2 ([]:xs) (i,suf) = [(i,suf)]:xs-  f2 l@(x@((ix,sufp):_):xs) (i,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-    where-      hx = fst $ last ix-      ni = fst $ last i-  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' (i,suf) = chapPrefix (chapDelim o) i ++ suf
− src/Text/Pandoc/CrossRef/References/Types.hs
@@ -1,36 +0,0 @@-module Text.Pandoc.CrossRef.References.Types ( References(..)-                        , WS-                        , RefRec(..)-                        , RefMap-                        , Index-                        , def-                        ) where--import qualified Data.Map as M-import Text.Pandoc.Definition-import Control.Monad.State-import Data.Default--type Index = [(Int, Maybe String)]--data RefRec = RefRec { refIndex :: Index-                     , 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 :: Index-                             } 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
@@ -1,17 +0,0 @@-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
@@ -1,37 +0,0 @@-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/Gap.hs
@@ -1,12 +0,0 @@-{-# LANGUAGE CPP #-}--module Text.Pandoc.CrossRef.Util.Gap where--import qualified Text.Pandoc as P--readMarkdown :: P.ReaderOptions -> String -> P.Pandoc-#if MIN_VERSION_pandoc(1,14,0)-readMarkdown = (either (error . show) id .) . P.readMarkdown-#else-readMarkdown = P.readMarkdown-#endif
− src/Text/Pandoc/CrossRef/Util/Meta.hs
@@ -1,59 +0,0 @@-{-# LANGUAGE CPP #-}-module Text.Pandoc.CrossRef.Util.Meta where--import Text.Pandoc.CrossRef.Util.Gap-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) =-  return $ getInlines $ readMarkdown def s-  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) =-  return $ getBlocks $ readMarkdown def s-  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
@@ -1,84 +0,0 @@-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{section}" ++ prefix secPrefix False-          , "\\Crefname{figure}" ++ prefix figPrefix True-          , "\\Crefname{table}" ++ prefix tblPrefix True-          , "\\Crefname{equation}" ++ prefix eqnPrefix True-          , "\\Crefname{listing}" ++ prefix lstPrefix True-          , "\\Crefname{section}" ++ prefix secPrefix 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
@@ -1,74 +0,0 @@-{-# 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
@@ -1,41 +0,0 @@-{-# LANGUAGE CPP #-}-module Text.Pandoc.CrossRef.Util.Settings (getSettings, defaultMeta) where--import Text.Pandoc hiding (readMarkdown)-import Text.Pandoc.CrossRef.Util.Gap-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))-  let Pandoc dtve _ = readMarkdown def ("---\n" ++ yaml ++ "\n---")-  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
@@ -1,61 +0,0 @@-module Text.Pandoc.CrossRef.Util.Settings.Gen where--import Text.Pandoc.CrossRef.Util.Settings.Template-import Text.Pandoc.Builder--figureTitle :: ToMetaValue a => a -> Meta-figureTitle = template "figureTitle"--tableTitle :: ToMetaValue a => a -> Meta-tableTitle = template "tableTitle"--listingTitle :: ToMetaValue a => a -> Meta-listingTitle = template "listingTitle"--titleDelim :: ToMetaValue a => a -> Meta-titleDelim = template "titleDelim"--chapDelim :: ToMetaValue a => a -> Meta-chapDelim = template "chapDelim"--rangeDelim :: ToMetaValue a => a -> Meta-rangeDelim = template "rangeDelim"--figPrefix :: ToMetaValue a => a -> Meta-figPrefix = template "figPrefix"--eqnPrefix :: ToMetaValue a => a -> Meta-eqnPrefix = template "eqnPrefix"--tblPrefix :: ToMetaValue a => a -> Meta-tblPrefix = template "tblPrefix"--lstPrefix :: ToMetaValue a => a -> Meta-lstPrefix = template "lstPrefix"--secPrefix :: ToMetaValue a => a -> Meta-secPrefix = template "secPrefix"--lofTitle :: ToMetaValue a => a -> Meta-lofTitle = template "lofTitle"--lotTitle :: ToMetaValue a => a -> Meta-lotTitle = template "lotTitle"--lolTitle :: ToMetaValue a => a -> Meta-lolTitle = template "lolTitle"--figureTemplate :: ToMetaValue a => a -> Meta-figureTemplate = template "figureTemplate"--tableTemplate :: ToMetaValue a => a -> Meta-tableTemplate = template "tableTemplate"--listingTemplate :: ToMetaValue a => a -> Meta-listingTemplate = template "listingTemplate"--crossrefYaml :: ToMetaValue a => a -> Meta-crossrefYaml = template "crossrefYaml"--chaptersDepth :: ToMetaValue a => a -> Meta-chaptersDepth = template "chaptersDepth"
− src/Text/Pandoc/CrossRef/Util/Settings/Template.hs
@@ -1,8 +0,0 @@-module Text.Pandoc.CrossRef.Util.Settings.Template where--import Text.Pandoc.Definition-import Text.Pandoc.Builder-import qualified Data.Map as M--template :: ToMetaValue a => String -> a -> Meta-template name = Meta . M.singleton name . toMetaValue
− src/Text/Pandoc/CrossRef/Util/Template.hs
@@ -1,26 +0,0 @@-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
@@ -1,26 +0,0 @@-module Text.Pandoc.CrossRef.Util.Util where--import Text.Pandoc.CrossRef.References.Types-import Text.Pandoc.Definition-import Data.Char (toUpper, toLower, isUpper)-import Data.List (intercalate)-import Data.Maybe (fromMaybe)--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] -> Index -> [Inline]-chapPrefix delim index = intercalate delim (map (return . Str . uncurry (fromMaybe . show)) index)
+ src/pandoc-crossref.hs view
@@ -0,0 +1,14 @@+import Text.Pandoc+import Text.Pandoc.JSON++import Text.Pandoc.CrossRef++main :: IO ()+main = toJSONFilter go+  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'