diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -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"`
diff --git a/lib/Text/Pandoc/CrossRef.hs b/lib/Text/Pandoc/CrossRef.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/References.hs b/lib/Text/Pandoc/CrossRef/References.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/References.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/References/Accessors.hs b/lib/Text/Pandoc/CrossRef/References/Accessors.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/References/Accessors.hs
@@ -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})
diff --git a/lib/Text/Pandoc/CrossRef/References/Blocks.hs b/lib/Text/Pandoc/CrossRef/References/Blocks.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/References/Blocks.hs
@@ -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 ()
diff --git a/lib/Text/Pandoc/CrossRef/References/List.hs b/lib/Text/Pandoc/CrossRef/References/List.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/References/List.hs
@@ -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)
diff --git a/lib/Text/Pandoc/CrossRef/References/Refs.hs b/lib/Text/Pandoc/CrossRef/References/Refs.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/References/Refs.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/References/Types.hs b/lib/Text/Pandoc/CrossRef/References/Types.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/References/Types.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/Accessor.hs b/lib/Text/Pandoc/CrossRef/Util/Accessor.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Accessor.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs b/lib/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/Gap.hs b/lib/Text/Pandoc/CrossRef/Util/Gap.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Gap.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/Meta.hs b/lib/Text/Pandoc/CrossRef/Util/Meta.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Meta.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs b/lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
@@ -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) ++ "}"
diff --git a/lib/Text/Pandoc/CrossRef/Util/Options.hs b/lib/Text/Pandoc/CrossRef/Util/Options.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Options.hs
@@ -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 .)
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings.hs b/lib/Text/Pandoc/CrossRef/Util/Settings.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Settings.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs b/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
@@ -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"
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs b/lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/Template.hs b/lib/Text/Pandoc/CrossRef/Util/Template.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Template.hs
@@ -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
diff --git a/lib/Text/Pandoc/CrossRef/Util/Util.hs b/lib/Text/Pandoc/CrossRef/Util/Util.hs
new file mode 100644
--- /dev/null
+++ b/lib/Text/Pandoc/CrossRef/Util/Util.hs
@@ -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)
diff --git a/pandoc-crossref.cabal b/pandoc-crossref.cabal
--- a/pandoc-crossref.cabal
+++ b/pandoc-crossref.cabal
@@ -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
diff --git a/pandoc-crossref.hs b/pandoc-crossref.hs
deleted file mode 100644
--- a/pandoc-crossref.hs
+++ /dev/null
@@ -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'
diff --git a/src/Text/Pandoc/CrossRef.hs b/src/Text/Pandoc/CrossRef.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/References.hs b/src/Text/Pandoc/CrossRef/References.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/References.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/References/Accessors.hs b/src/Text/Pandoc/CrossRef/References/Accessors.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/References/Accessors.hs
+++ /dev/null
@@ -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})
diff --git a/src/Text/Pandoc/CrossRef/References/Blocks.hs b/src/Text/Pandoc/CrossRef/References/Blocks.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/References/Blocks.hs
+++ /dev/null
@@ -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 ()
diff --git a/src/Text/Pandoc/CrossRef/References/List.hs b/src/Text/Pandoc/CrossRef/References/List.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/References/List.hs
+++ /dev/null
@@ -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)
diff --git a/src/Text/Pandoc/CrossRef/References/Refs.hs b/src/Text/Pandoc/CrossRef/References/Refs.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/References/Refs.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/References/Types.hs b/src/Text/Pandoc/CrossRef/References/Types.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/References/Types.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/Accessor.hs b/src/Text/Pandoc/CrossRef/Util/Accessor.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Accessor.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs b/src/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/Gap.hs b/src/Text/Pandoc/CrossRef/Util/Gap.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Gap.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/Meta.hs b/src/Text/Pandoc/CrossRef/Util/Meta.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Meta.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/ModifyMeta.hs b/src/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
+++ /dev/null
@@ -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) ++ "}"
diff --git a/src/Text/Pandoc/CrossRef/Util/Options.hs b/src/Text/Pandoc/CrossRef/Util/Options.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Options.hs
+++ /dev/null
@@ -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 .)
diff --git a/src/Text/Pandoc/CrossRef/Util/Settings.hs b/src/Text/Pandoc/CrossRef/Util/Settings.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Settings.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/Settings/Gen.hs b/src/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
+++ /dev/null
@@ -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"
diff --git a/src/Text/Pandoc/CrossRef/Util/Settings/Template.hs b/src/Text/Pandoc/CrossRef/Util/Settings/Template.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Settings/Template.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/Template.hs b/src/Text/Pandoc/CrossRef/Util/Template.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Template.hs
+++ /dev/null
@@ -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
diff --git a/src/Text/Pandoc/CrossRef/Util/Util.hs b/src/Text/Pandoc/CrossRef/Util/Util.hs
deleted file mode 100644
--- a/src/Text/Pandoc/CrossRef/Util/Util.hs
+++ /dev/null
@@ -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)
diff --git a/src/pandoc-crossref.hs b/src/pandoc-crossref.hs
new file mode 100644
--- /dev/null
+++ b/src/pandoc-crossref.hs
@@ -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'
