diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.3.11.0
+
+-   Add equationNumberTeX option
+-   Add title variable to refIndexTemplate; make refIndexTemplate per-prefix
+-   Update to pandoc 2.14
+-   Docs updates for --citeproc
+
 ## 0.3.10.0
 
 -   \[Fix\] Avoid expensive set difference, use filter
diff --git a/docs/index.md b/docs/index.md
--- a/docs/index.md
+++ b/docs/index.md
@@ -30,11 +30,15 @@
 
 It's a good idea to specify `--top-level-division=chapter` for any output format actually, because pandoc-crossref can't signal pandoc you want to use chapters, and vice versa.
 
-## pandoc-citeproc and pandoc-crossref
+## citeproc and pandoc-crossref
 
-Since pandoc-crossref uses the same citation syntax as pandoc-citeproc,
+Since pandoc-crossref uses the same citation syntax as citeproc,
 you *have* to run former *before* latter. For example:
 
+    pandoc -F pandoc-crossref --citeproc file.md -o file.html
+
+or
+
     pandoc -F pandoc-crossref -F pandoc-citeproc file.md -o file.html
 
 ## Note on leading/trailing spaces in metadata options
@@ -209,6 +213,14 @@
 : Caption {#tbl:label}
 ```
 
+Alternatively, for formats that support it, you can use arbitrary LaTeX command accepting a single argument (that is, label text) for typesetting. A common example is `\tag`. Use `equationNumberTeX` metadata variable for that (set to special value `qquad` by default). For instance, to use `\tag`, you would have the following in your metadata:
+
+```yaml
+equationNumberTeX: \\tag
+```
+
+This option doesn't affect LaTeX output (which offloads numbering to the LaTeX engine).
+
 To label a table, append `{#tbl:label}` at the end of table caption
 (with `label` being something unique to reference this table by).
 Caption and label *must* be separated by at least one space.
@@ -496,6 +508,9 @@
     Depending on output format, this might work better or worse.
 -   `setLabelAttribute`, default `false`: set `label` attribute on objects to
     actual number used for referencing. This can be useful for post-processing.
+-   `equationNumberTeX`, default `qquad`: use a LaTeX command for typesetting
+    equation numbers. Bear in mind, `qquad` is a special value; generally, you'll want to write out a full command, backslash and all. Also remember that metadata is parsed as Markdown, so you may need to escape backslashes.
+    This option doesn't affect LaTeX output (which offloads numbering to the LaTeX engine).
 
 ### Item title format
 
@@ -711,8 +726,24 @@
 `xPrefixTemplate`, where `x` is `fig`, `eqn`, etc, are a special case.
 Those don't have `t` variable, since there is no caption in source
 markdown, but instead have `p` variable, that binds to relevant
-`xPrefix`. This is done this way, since actual prefix vaule can depend
-on `i`.
+`xPrefix`. This is done this way, since actual prefix value can depend
+on `i`. In `xPrefixTemplate`, `i` references formatted object numbers, i.e. if given a list of references like `[@fig:1; @fig:2; @fig:3]`, here `i` will contain something like `1-3`.
+
+`refIndexTemplate` is the template for the individual reference index. It can be either a plain template, or can be a YAML object with keys corresponding to different prefixes, and a special key `default` used as a fallback, e.g.
+
+```yaml
+refIndexTemplate:
+  sec: $$i$$$$suf$$ ($$t$$)
+  default: $$i$$$$suf$$
+```
+
+`refIndexTemplate` has the following internal variables defined:
+
+- `i` -- formatted object index (possibly with chapter number)
+- `suf` -- literal suffix used in the reference, e.g. given `[@fig:1 some suffix]`, `suf` will contain literally ` some suffix` (complete with the leading space)
+- `t` -- object title, if any, or empty if the object has no title
+
+`subfigureRefIndexTemplate` is roughly the same as `refIndexTemplate` but is used specifically for subfigures. It additionally has `s` variable defined, which is described above.
 
 Additionally, a special syntax is provided for indexed access to array metadata variables: `arrayVariable[indexVariable]`, where `arrayVariable` is an array-like metadata variable, and `indexVariable` is an integer-typed template variable.
 If `indexVariable` is larger than length of `arrayVariable`, then the last
diff --git a/lib-internal/Text/Pandoc/CrossRef/References.hs b/lib-internal/Text/Pandoc/CrossRef/References.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/References.hs
@@ -0,0 +1,26 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+module Text.Pandoc.CrossRef.References ( module X ) where
+
+import Text.Pandoc.CrossRef.References.Types as X
+import Text.Pandoc.CrossRef.References.Blocks as X (replaceAll)
+import Text.Pandoc.CrossRef.References.Refs as X
+import Text.Pandoc.CrossRef.References.List as X
diff --git a/lib-internal/Text/Pandoc/CrossRef/References/Blocks.hs b/lib-internal/Text/Pandoc/CrossRef/References/Blocks.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/References/Blocks.hs
@@ -0,0 +1,439 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE Rank2Types, OverloadedStrings #-}
+module Text.Pandoc.CrossRef.References.Blocks
+  ( replaceAll
+  ) where
+
+import Text.Pandoc.Definition
+import qualified Text.Pandoc.Builder as B
+import Text.Pandoc.Shared (stringify, blocksToInlines)
+import Text.Pandoc.Walk (walk)
+import Control.Monad.State hiding (get, modify)
+import Data.List
+import Data.Maybe
+import qualified Data.Map as M
+import qualified Data.Text as T
+import qualified Data.Text.Read as T
+
+import Data.Accessor
+import Data.Accessor.Monad.Trans.State
+import Text.Pandoc.CrossRef.References.Types
+import Text.Pandoc.CrossRef.Util.Util
+import Text.Pandoc.CrossRef.Util.Options
+import Text.Pandoc.CrossRef.Util.Template
+import Control.Applicative
+import Prelude
+import Data.Default
+
+replaceAll :: (Data a) => Options -> a -> WS a
+replaceAll opts =
+    runReplace (mkRR (replaceBlock opts)
+      `extRR` replaceInline opts
+      `extRR` replaceInlineMany opts
+      )
+  . runSplitMath
+  . everywhere (mkT divBlocks `extT` spanInlines opts)
+  where
+    runSplitMath | tableEqns opts
+                 , not $ isLatexFormat (outFormat opts)
+                 = everywhere (mkT splitMath)
+                 | otherwise = id
+
+simpleTable :: [Alignment] -> [ColWidth] -> [[[Block]]] -> Block
+simpleTable align width bod = Table nullAttr noCaption (zip align width)
+  noTableHead [mkBody bod] noTableFoot
+  where
+  mkBody xs = TableBody nullAttr (RowHeadColumns 0) [] (map mkRow xs)
+  mkRow xs = Row nullAttr (map mkCell xs)
+  mkCell xs = Cell nullAttr AlignDefault (RowSpan 0) (ColSpan 0) xs
+  noCaption = Caption Nothing mempty
+  noTableHead = TableHead nullAttr []
+  noTableFoot = TableFoot nullAttr []
+
+setLabel :: Options -> [Inline] -> [(T.Text, T.Text)] -> [(T.Text, T.Text)]
+setLabel opts idx
+  | setLabelAttribute opts
+  = (("label", stringify idx) :)
+  . filter ((/= "label") . fst)
+  | otherwise = id
+
+replaceBlock :: Options -> Block -> WS (ReplacedResult Block)
+replaceBlock opts (Header n (label, cls, attrs) text')
+  = do
+    let label' = if autoSectionLabels opts && not ("sec:" `T.isPrefixOf` label)
+                 then "sec:"<>label
+                 else label
+    unless ("unnumbered" `elem` cls) $ do
+      modify curChap $ \cc ->
+        let ln = length cc
+            cl i = lookup "label" attrs <|> customHeadingLabel opts n i <|> customLabel opts "sec" i
+            inc l = let i = fst (last l) + 1 in init l <> [(i, cl i)]
+            cc' | ln > n = inc $ take n cc
+                | ln == n = inc cc
+                | otherwise = cc <> take (n-ln-1) (zip [1,1..] $ repeat Nothing) <> [(1,cl 1)]
+        in cc'
+      when ("sec:" `T.isPrefixOf` label') $ do
+        index  <- get curChap
+        modify secRefs $ M.insert label' RefRec {
+          refIndex=index
+        , refTitle= text'
+        , refSubfigure = Nothing
+        }
+    cc <- get curChap
+    let textCC | numberSections opts
+               , sectionsDepth opts < 0
+               || n <= if sectionsDepth opts == 0 then chaptersDepth opts else sectionsDepth opts
+               , "unnumbered" `notElem` cls
+               = applyTemplate' (M.fromDistinctAscList [
+                    ("i", idxStr)
+                  , ("n", [Str $ T.pack $ show $ n - 1])
+                  , ("t", text')
+                  ]) $ secHeaderTemplate opts
+               | otherwise = text'
+        idxStr = chapPrefix (chapDelim opts) cc
+        attrs' | "unnumbered" `notElem` cls
+               = setLabel opts idxStr attrs
+               | otherwise = attrs
+    replaceNoRecurse $ Header n (label', cls, attrs') textCC
+-- subfigures
+replaceBlock opts (Div (label,cls,attrs) images)
+  | "fig:" `T.isPrefixOf` label
+  , Para caption <- last images
+  = do
+    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) caption imgRefs
+    let (cont, st) = runState (runReplace (mkRR $ replaceSubfigs opts') $ init images) def
+        collectedCaptions = B.toList $
+            intercalate' (B.fromList $ ccsDelim opts)
+          $ map (B.fromList . collectCaps . snd)
+          $ sortOn (refIndex . snd)
+          $ filter (not . null . refTitle . snd)
+          $ M.toList
+          $ imgRefs_ st
+        collectCaps v =
+              applyTemplate
+                (chapPrefix (chapDelim opts) (refIndex v))
+                (refTitle v)
+                (ccsTemplate opts)
+        vars = M.fromDistinctAscList
+                  [ ("ccs", collectedCaptions)
+                  , ("i", idxStr)
+                  , ("t", caption)
+                  ]
+        capt = applyTemplate' vars $ subfigureTemplate opts
+    lastRef <- fromJust . M.lookup label <$> get imgRefs
+    modify imgRefs $ \old ->
+        M.union
+          old
+          (M.map (\v -> v{refIndex = refIndex lastRef, refSubfigure = Just $ refIndex v})
+          $ imgRefs_ st)
+    case outFormat opts of
+          f | isLatexFormat f ->
+            replaceNoRecurse $ Div nullAttr $
+              [ RawBlock (Format "latex") "\\begin{pandoccrossrefsubfigures}" ]
+              <> cont <>
+              [ Para [RawInline (Format "latex") "\\caption["
+                       , Span nullAttr (removeFootnotes caption)
+                       , RawInline (Format "latex") "]"
+                       , Span nullAttr caption]
+              , RawBlock (Format "latex") $ mkLaTeXLabel label
+              , RawBlock (Format "latex") "\\end{pandoccrossrefsubfigures}"]
+          _  -> replaceNoRecurse $ Div (label, "subfigures":cls, setLabel opts idxStr attrs) $ toTable cont capt
+  where
+    opts' = opts
+              { figureTemplate = subfigureChildTemplate opts
+              , customLabel = \r i -> customLabel opts ("sub"<>r) i
+              }
+    removeFootnotes = walk removeFootnote
+    removeFootnote Note{} = Str ""
+    removeFootnote x = x
+    toTable :: [Block] -> [Inline] -> [Block]
+    toTable blks capt
+      | subfigGrid opts = [ simpleTable align (map ColWidth widths) (map blkToRow blks)
+                          , mkCaption opts "Image Caption" capt]
+      | otherwise = blks <> [mkCaption opts "Image Caption" capt]
+      where
+        align | Para ils:_ <- blks = replicate (length $ mapMaybe getWidth ils) AlignCenter
+              | otherwise = error "Misformatted subfigures block"
+        widths | Para ils:_ <- blks
+               = fixZeros $ mapMaybe getWidth ils
+               | otherwise = error "Misformatted subfigures block"
+        getWidth (Image (_id, _class, as) _ _)
+          = Just $ maybe 0 percToDouble $ lookup "width" as
+        getWidth _ = Nothing
+        fixZeros :: [Double] -> [Double]
+        fixZeros ws
+          = let nz = length $ filter (== 0) ws
+                rzw = (0.99 - sum ws) / fromIntegral nz
+            in if nz>0
+               then map (\x -> if x == 0 then rzw else x) ws
+               else ws
+        percToDouble :: T.Text -> Double
+        percToDouble percs
+          | Right (perc, "%") <- T.double percs
+          = perc/100.0
+          | otherwise = error "Only percent allowed in subfigure width!"
+        blkToRow :: Block -> [[Block]]
+        blkToRow (Para inls) = mapMaybe inlToCell inls
+        blkToRow x = [[x]]
+        inlToCell :: Inline -> Maybe [Block]
+        inlToCell (Image (id', cs, as) txt tgt)  = Just [Para [Image (id', cs, setW as) txt tgt]]
+        inlToCell _ = Nothing
+        setW as = ("width", "100%"):filter ((/="width") . fst) as
+replaceBlock opts (Div (label,clss,attrs) [Table tattr (Caption short (btitle:rest)) colspec header cells foot])
+  | not $ null title
+  , "tbl:" `T.isPrefixOf` label
+  = do
+    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) title tblRefs
+    let title' =
+          case outFormat opts of
+              f | isLatexFormat f ->
+                RawInline (Format "latex") (mkLaTeXLabel label) : title
+              _  -> applyTemplate idxStr title $ tableTemplate opts
+        caption' = Caption short (walkReplaceInlines title' title btitle:rest)
+    replaceNoRecurse $ Div (label, clss, setLabel opts idxStr attrs) [Table tattr caption' colspec header cells foot]
+  where title = blocksToInlines [btitle]
+replaceBlock opts (Table (label,clss,attrs) (Caption short (btitle:rest)) colspec header cells foot)
+  | not $ null title
+  , "tbl:" `T.isPrefixOf` label
+  = do
+    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) title tblRefs
+    let title' =
+          case outFormat opts of
+              f | isLatexFormat f ->
+                RawInline (Format "latex") (mkLaTeXLabel label) : title
+              _  -> applyTemplate idxStr title $ tableTemplate opts
+        caption' = Caption short (walkReplaceInlines title' title btitle:rest)
+    replaceNoRecurse $ Table (label, clss, setLabel opts idxStr attrs) caption' colspec header cells foot
+  where title = blocksToInlines [btitle]
+replaceBlock opts cb@(CodeBlock (label, classes, attrs) code)
+  | not $ T.null label
+  , "lst:" `T.isPrefixOf` label
+  , Just caption <- lookup "caption" attrs
+  = case outFormat opts of
+      f
+        --if used with listings package,nothing shoud be done
+        | isLatexFormat f, listings opts -> noReplaceNoRecurse
+        --if not using listings, however, wrap it in a codelisting environment
+        | isLatexFormat f ->
+          replaceNoRecurse $ Div nullAttr [
+              RawBlock (Format "latex") "\\begin{codelisting}"
+            , Plain [
+                RawInline (Format "latex") "\\caption{"
+              , Str caption
+              , RawInline (Format "latex") "}"
+              ]
+            , cb
+            , RawBlock (Format "latex") "\\end{codelisting}"
+            ]
+      _ -> do
+        let cap = B.toList $ B.text caption
+        idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) cap lstRefs
+        let caption' = applyTemplate idxStr cap $ listingTemplate opts
+        replaceNoRecurse $ Div (label, "listing":classes, []) [
+            mkCaption opts "Caption" caption'
+          , CodeBlock ("", classes, filter ((/="caption") . fst) $ setLabel opts idxStr attrs) code
+          ]
+replaceBlock opts
+  (Div (label,"listing":divClasses, divAttrs)
+    [Para caption, CodeBlock ("",cbClasses,cbAttrs) code])
+  | not $ T.null label
+  , "lst:" `T.isPrefixOf` label
+  = case outFormat opts of
+      f
+        --if used with listings package, return code block with caption
+        | isLatexFormat f, listings opts ->
+          replaceNoRecurse $ CodeBlock (label,classes,("caption",escapeLaTeX $ stringify caption):attrs) code
+        --if not using listings, however, wrap it in a codelisting environment
+        | isLatexFormat f ->
+          replaceNoRecurse $ Div nullAttr [
+              RawBlock (Format "latex") "\\begin{codelisting}"
+            , Para [
+                RawInline (Format "latex") "\\caption"
+              , Span nullAttr caption
+              ]
+            , CodeBlock (label,classes,attrs) code
+            , RawBlock (Format "latex") "\\end{codelisting}"
+            ]
+      _ -> do
+        idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) caption lstRefs
+        let caption' = applyTemplate idxStr caption $ listingTemplate opts
+        replaceNoRecurse $ Div (label, "listing":classes, []) [
+            mkCaption opts "Caption" caption'
+          , CodeBlock ("", classes, setLabel opts idxStr attrs) code
+          ]
+  where attrs = divAttrs <> cbAttrs
+        classes = nub $ divClasses <> cbClasses
+replaceBlock opts (Para [Span sattrs@(label, cls, attrs) [Math DisplayMath eq]])
+  | not $ isLatexFormat (outFormat opts)
+  , tableEqns opts
+  = do
+    (eq', idxStr) <- replaceEqn opts sattrs eq
+    replaceNoRecurse $ Div (label,cls,setLabel opts idxStr attrs) [
+      simpleTable [AlignCenter, AlignRight] [ColWidth 0.9, ColWidth 0.09]
+       [[[Plain [Math DisplayMath eq']], [eqnNumber $ stringify idxStr]]]]
+  where
+  eqnNumber idx
+    | outFormat opts == Just (Format "docx")
+    = Div nullAttr [
+        RawBlock (Format "openxml") "<w:tcPr><w:vAlign w:val=\"center\"/></w:tcPr>"
+      , mathIdx
+      ]
+    | otherwise = mathIdx
+    where mathIdx = Plain [Math DisplayMath $ "(" <> idx <> ")"]
+replaceBlock _ _ = noReplaceRecurse
+
+replaceEqn :: Options -> Attr -> T.Text -> WS (T.Text, [Inline])
+replaceEqn opts (label, _, attrs) eq = do
+  let label' | T.null label = Left "eq"
+             | otherwise = Right label
+  idxStr <- replaceAttr opts label' (lookup "label" attrs) [] eqnRefs
+  let eq' | tableEqns opts = eq
+          | equationNumberTeX opts == "qquad" = eq<>"\\qquad("<>idxTxt<>")"
+          | otherwise = eq<>equationNumberTeX opts<>"{"<>idxTxt<>"}"
+      idxTxt = stringify idxStr
+  return (eq', idxStr)
+
+replaceInlineMany :: Options -> [Inline] -> WS (ReplacedResult [Inline])
+replaceInlineMany opts (Span spanAttr@(label,clss,attrs) [Math DisplayMath eq]:xs)
+  | "eq:" `T.isPrefixOf` label || T.null label && autoEqnLabels opts
+  = replaceRecurse . (<>xs) =<< case outFormat opts of
+      f | isLatexFormat f ->
+        pure [RawInline (Format "latex") "\\begin{equation}"
+        , Span spanAttr [RawInline (Format "latex") eq]
+        , RawInline (Format "latex") $ mkLaTeXLabel label <> "\\end{equation}"]
+      _ -> do
+        (eq', idxStr) <- replaceEqn opts spanAttr eq
+        pure [Span (label,clss,setLabel opts idxStr attrs) [Math DisplayMath eq']]
+replaceInlineMany _ _ = noReplaceRecurse
+
+replaceInline :: Options -> Inline -> WS (ReplacedResult Inline)
+replaceInline opts (Image (label,cls,attrs) alt img@(_, tit))
+  | "fig:" `T.isPrefixOf` label && "fig:" `T.isPrefixOf` tit
+  = do
+    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) alt imgRefs
+    let alt' = case outFormat opts of
+          f | isLatexFormat f -> alt
+          _  -> applyTemplate idxStr alt $ figureTemplate opts
+    replaceNoRecurse $ Image (label,cls,setLabel opts idxStr attrs) alt' img
+replaceInline _ _ = noReplaceRecurse
+
+replaceSubfigs :: Options -> [Inline] -> WS (ReplacedResult [Inline])
+replaceSubfigs opts = (replaceNoRecurse . concat) <=< mapM (replaceSubfig opts)
+
+replaceSubfig :: Options -> Inline -> WS [Inline]
+replaceSubfig opts x@(Image (label,cls,attrs) alt (src, tit))
+  = do
+      let label' | "fig:" `T.isPrefixOf` label = Right label
+                 | T.null label = Left "fig"
+                 | otherwise  = Right $ "fig:" <> label
+      idxStr <- replaceAttr opts label' (lookup "label" attrs) alt imgRefs
+      case outFormat opts of
+        f | isLatexFormat f ->
+          return $ latexSubFigure x label
+        _  ->
+          let alt' = applyTemplate idxStr alt $ figureTemplate opts
+              tit' | "nocaption" `elem` cls = fromMaybe tit $ T.stripPrefix "fig:" tit
+                   | "fig:" `T.isPrefixOf` tit = tit
+                   | otherwise = "fig:" <> tit
+          in return [Image (label, cls, setLabel opts idxStr attrs) alt' (src, tit')]
+replaceSubfig _ x = return [x]
+
+divBlocks :: Block -> Block
+divBlocks (Table tattr (Caption short (btitle:rest)) colspec header cells foot)
+  | not $ null title
+  , Just label <- getRefLabel "tbl" [last title]
+  = Div (label,[],[]) [
+    Table tattr (Caption short $ walkReplaceInlines (dropWhileEnd isSpace (init title)) title btitle:rest) colspec header cells foot]
+  where
+    title = blocksToInlines [btitle]
+divBlocks x = x
+
+walkReplaceInlines :: [Inline] -> [Inline] -> Block -> Block
+walkReplaceInlines newTitle title = walk replaceInlines
+  where
+  replaceInlines xs
+    | xs == title = newTitle
+    | otherwise = xs
+
+splitMath :: [Block] -> [Block]
+splitMath (Para ils:xs)
+  | length ils > 1 = map Para (split [] [] ils) <> xs
+  where
+    split res acc [] = reverse (reverse acc : res)
+    split res acc (x@(Span _ [Math DisplayMath _]):ys) =
+      split ([x] : reverse (dropSpaces acc) : res)
+            [] (dropSpaces ys)
+    split res acc (y:ys) = split res (y:acc) ys
+    dropSpaces = dropWhile isSpace
+splitMath xs = xs
+
+spanInlines :: Options -> [Inline] -> [Inline]
+spanInlines opts (math@(Math DisplayMath _eq):ils)
+  | c:ils' <- dropWhile isSpace ils
+  , Just label <- getRefLabel "eq" [c]
+  = Span (label,[],[]) [math]:ils'
+  | autoEqnLabels opts
+  = Span nullAttr [math]:ils
+spanInlines _ x = x
+
+replaceAttr :: Options -> Either T.Text T.Text -> Maybe T.Text -> [Inline] -> Accessor References RefMap -> WS [Inline]
+replaceAttr o label refLabel title prop
+  = do
+    chap  <- take (chaptersDepth o) `fmap` get curChap
+    prop' <- get prop
+    let i = 1+ (M.size . M.filter (\x -> (chap == init (refIndex x)) && isNothing (refSubfigure x)) $ prop')
+        index = chap <> [(i, refLabel <|> customLabel o ref i)]
+        ref = either id (T.takeWhile (/=':')) label
+        label' = either (<> T.pack (':' : show index)) id label
+    when (M.member label' prop') $
+      error . T.unpack $ "Duplicate label: " <> label'
+    modify prop $ M.insert label' RefRec {
+      refIndex= index
+    , refTitle= title
+    , refSubfigure = Nothing
+    }
+    return $ chapPrefix (chapDelim o) index
+
+latexSubFigure :: Inline -> T.Text -> [Inline]
+latexSubFigure (Image (_, cls, attrs) alt (src, title)) label =
+  let
+    title' = fromMaybe title $ T.stripPrefix "fig:" title
+    texlabel | T.null label = []
+             | otherwise = [RawInline (Format "latex") $ mkLaTeXLabel label]
+    texalt | "nocaption" `elem` cls  = []
+           | otherwise = concat
+              [ [ RawInline (Format "latex") "["]
+              , alt
+              , [ RawInline (Format "latex") "]"]
+              ]
+    img = Image (label, cls, attrs) alt (src, title')
+  in concat [
+      [ RawInline (Format "latex") "\\subfloat" ]
+      , texalt
+      , [Span nullAttr $ img:texlabel]
+      ]
+latexSubFigure x _ = [x]
+
+mkCaption :: Options -> T.Text -> [Inline] -> Block
+mkCaption opts style
+  | outFormat opts == Just (Format "docx") = Div ("", [], [("custom-style", style)]) . return . Para
+  | otherwise = Para
diff --git a/lib-internal/Text/Pandoc/CrossRef/References/List.hs b/lib-internal/Text/Pandoc/CrossRef/References/List.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/References/List.hs
@@ -0,0 +1,62 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.References.List (listOf) where
+
+import Text.Pandoc.Definition
+import Data.Accessor.Monad.Trans.State
+import Control.Arrow
+import Data.List
+import qualified Data.Map as M
+import qualified Data.Text as T
+
+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 | isLatexFormat f = return x
+listOf opts (RawBlock fmt "\\listoffigures":xs)
+  | isLaTeXRawBlockFmt fmt
+  = get imgRefs >>= makeList opts lofTitle xs
+listOf opts (RawBlock fmt "\\listoftables":xs)
+  | isLaTeXRawBlockFmt fmt
+  = get tblRefs >>= makeList opts lotTitle xs
+listOf opts (RawBlock fmt "\\listoflistings":xs)
+  | isLaTeXRawBlockFmt fmt
+  = get lstRefs >>= makeList opts lolTitle xs
+listOf _ x = return x
+
+makeList :: Options -> (Options -> [Block]) -> [Block] -> M.Map T.Text RefRec -> WS [Block]
+makeList opts titlef xs refs
+  = return $
+      titlef opts ++
+      (if chaptersDepth 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-internal/Text/Pandoc/CrossRef/References/Refs.hs b/lib-internal/Text/Pandoc/CrossRef/References/Refs.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/References/Refs.hs
@@ -0,0 +1,262 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.References.Refs (replaceRefs) where
+
+import Text.Pandoc.Definition
+import Text.Pandoc.Builder
+import Control.Monad.State hiding (get, modify)
+import Data.List
+import qualified Data.List.HT as HT
+import qualified Data.Text as T
+import Data.Maybe
+import Data.Function
+import qualified Data.Map as M
+import Control.Arrow as A
+
+import Data.Accessor
+import Data.Accessor.Monad.Trans.State
+import Text.Pandoc.CrossRef.References.Types
+import Text.Pandoc.CrossRef.Util.Template
+import Text.Pandoc.CrossRef.Util.Util
+import Text.Pandoc.CrossRef.Util.Options
+import Control.Applicative
+import Debug.Trace
+import Prelude
+
+replaceRefs :: Options -> [Inline] -> WS [Inline]
+replaceRefs opts (Cite cits _:xs)
+  = toList . (<> fromList xs) . intercalate' (text ", ") . map fromList <$> 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' = toList $
+              str "["
+            <> intercalate' (text "; ") (map citationToInlines cits')
+            <> str "]"
+          citationToInlines c =
+            fromList (citationPrefix c) <> text ("@" <> citationId c)
+              <> fromList (citationSuffix c)
+    replaceRefs'' = case outFormat opts of
+                    f | isLatexFormat f -> replaceRefsLatex
+                    _                      -> replaceRefsOther
+replaceRefs _ x = return x
+
+-- accessors to state variables
+accMap :: M.Map T.Text (Accessor References RefMap)
+accMap = M.fromList [("fig:",imgRefs)
+                    ,("eq:" ,eqnRefs)
+                    ,("tbl:",tblRefs)
+                    ,("lst:",lstRefs)
+                    ,("sec:",secRefs)
+                    ]
+
+-- accessors to options
+prefMap :: M.Map T.Text (Options -> Bool -> Int -> [Inline], Options -> Template)
+prefMap = M.fromList [("fig:",(figPrefix, figPrefixTemplate))
+                     ,("eq:" ,(eqnPrefix, eqnPrefixTemplate))
+                     ,("tbl:",(tblPrefix, tblPrefixTemplate))
+                     ,("lst:",(lstPrefix, lstPrefixTemplate))
+                     ,("sec:",(secPrefix, secPrefixTemplate))
+                     ]
+
+prefixes :: [T.Text]
+prefixes = M.keys accMap
+
+getRefPrefix :: Options -> T.Text -> Bool -> Int -> [Inline] -> [Inline]
+getRefPrefix opts prefix capitalize num cit =
+  applyTemplate' (M.fromDistinctAscList [("i", cit), ("p", refprefix)])
+        $ reftempl opts
+  where (refprefixf, reftempl) = lookupUnsafe prefix prefMap
+        refprefix = refprefixf opts capitalize num
+
+
+lookupUnsafe :: Ord k => k -> M.Map k v -> v
+lookupUnsafe = (fromJust .) . M.lookup
+
+allCitsPrefix :: [Citation] -> Maybe T.Text
+allCitsPrefix cits = find isCitationPrefix prefixes
+  where
+  isCitationPrefix p =
+    all ((p `T.isPrefixOf`) . uncapitalizeFirst . citationId) cits
+
+replaceRefsLatex :: T.Text -> Options -> [Citation] -> WS [Inline]
+replaceRefsLatex prefix opts cits
+  | cref opts
+  = replaceRefsLatex' prefix opts cits
+  | otherwise
+  = toList . intercalate' (text ", ") . map fromList <$>
+      mapM (replaceRefsLatex' prefix opts) (groupBy citationGroupPred cits)
+
+replaceRefsLatex' :: T.Text -> Options -> [Citation] -> WS [Inline]
+replaceRefsLatex' prefix opts cits =
+  return $ p [texcit]
+  where
+    texcit =
+      RawInline (Format "tex") $
+      if cref opts then
+        cref'<>"{"<>listLabels prefix "" "," "" cits<>"}"
+        else
+          listLabels prefix "\\ref{" ", " "}" cits
+    suppressAuthor = all ((==SuppressAuthor) . citationMode) cits
+    noPrefix = all (null . citationPrefix) cits
+    p | cref opts = id
+      | suppressAuthor
+      = id
+      | noPrefix
+      = getRefPrefix opts prefix cap (length cits - 1)
+      | otherwise = ((citationPrefix (head cits) <> [Space]) <>)
+    cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits
+    cref' | suppressAuthor = "\\labelcref"
+          | cap = "\\Cref"
+          | otherwise = "\\cref"
+
+listLabels :: T.Text -> T.Text -> T.Text -> T.Text -> [Citation] -> T.Text
+listLabels prefix p sep s =
+  T.intercalate sep . map ((p <>) . (<> s) . mkLaTeXLabel' . (prefix<>) . getLabelWithoutPrefix . citationId)
+
+getLabelWithoutPrefix :: T.Text -> T.Text
+getLabelWithoutPrefix = T.drop 1 . T.dropWhile (/=':')
+
+getLabelPrefix :: T.Text -> Maybe T.Text
+getLabelPrefix lab
+  | uncapitalizeFirst p `elem` prefixes = Just p
+  | otherwise = Nothing
+  where p = flip T.snoc ':' . T.takeWhile (/=':') $ lab
+
+replaceRefsOther :: T.Text -> Options -> [Citation] -> WS [Inline]
+replaceRefsOther prefix opts cits = toList . intercalate' (text ", ") . map fromList <$>
+    mapM (replaceRefsOther' prefix opts) (groupBy citationGroupPred cits)
+
+citationGroupPred :: Citation -> Citation -> Bool
+citationGroupPred = (==) `on` liftM2 (,) citationPrefix citationMode
+
+replaceRefsOther' :: T.Text -> Options -> [Citation] -> WS [Inline]
+replaceRefsOther' prefix opts cits = do
+  indices <- mapM (getRefIndex prefix opts) cits
+  let
+    cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits
+    writePrefix | all ((==SuppressAuthor) . citationMode) cits
+                = id
+                | all (null . citationPrefix) cits
+                = cmap $ getRefPrefix opts prefix cap (length cits - 1)
+                | otherwise
+                = cmap $ toList . ((fromList (citationPrefix (head cits)) <> space) <>) . fromList
+    cmap f [Link attr t w]
+      | nameInLink opts = [Link attr (f t) w]
+    cmap f x = f x
+  return $ writePrefix (makeIndices opts indices)
+
+data RefData = RefData { rdLabel :: T.Text
+                       , rdIdx :: Maybe Index
+                       , rdSubfig :: Maybe Index
+                       , rdSuffix :: [Inline]
+                       , rdTitle :: Maybe [Inline]
+                       , rdPfx :: T.Text
+                       } deriving (Eq)
+
+instance Ord RefData where
+  (<=) = (<=) `on` rdIdx
+
+getRefIndex :: T.Text -> Options -> Citation -> WS RefData
+getRefIndex prefix _opts Citation{citationId=cid,citationSuffix=suf}
+  = do
+    ref <- M.lookup lab <$> get prop
+    let sub = refSubfigure <$> ref
+        idx = refIndex <$> ref
+        tit = refTitle <$> ref
+    return RefData
+      { rdLabel = lab
+      , rdIdx = idx
+      , rdSubfig = join sub
+      , rdSuffix = suf
+      , rdTitle = tit
+      , rdPfx = prefix
+      }
+  where
+  prop = lookupUnsafe prefix accMap
+  lab = prefix <> getLabelWithoutPrefix cid
+
+data RefItem = RefRange RefData RefData | RefSingle RefData
+
+makeIndices :: Options -> [RefData] -> [Inline]
+makeIndices o s = format $ concatMap f $ HT.groupBy g $ sort $ nub s
+  where
+  g :: RefData -> RefData -> Bool
+  g a b = all (null . rdSuffix) [a, b] && (
+            all (isNothing . rdSubfig) [a, b] &&
+            Just True == (liftM2 follows `on` rdIdx) b a ||
+            rdIdx a == rdIdx b &&
+            Just True == (liftM2 follows `on` rdSubfig) b a
+          )
+  follows :: Index -> Index -> Bool
+  follows a b
+    | Just (ai, al) <- HT.viewR a
+    , Just (bi, bl) <- HT.viewR b
+    = ai == bi && A.first (+1) bl == al
+  follows _ _ = False
+  f :: [RefData] -> [RefItem]
+  f []  = []                          -- drop empty lists
+  f [w] = [RefSingle w]                   -- single value
+  f [w1,w2] = [RefSingle w1, RefSingle w2] -- two values
+  f (x:xs) = [RefRange x (last xs)] -- shorten more than two values
+  format :: [RefItem] -> [Inline]
+  format [] = []
+  format [x] = toList $ show'' x
+  format [x, y] = toList $ show'' x <> fromList (pairDelim o) <> show'' y
+  format xs = toList $ intercalate' (fromList $ refDelim o) init' <> fromList (lastDelim o) <> last'
+    where initlast []     = error "emtpy list in initlast"
+          initlast [y]    = ([], y)
+          initlast (y:ys) = first (y:) $ initlast ys
+          (init', last') = initlast $ map show'' xs
+  show'' :: RefItem -> Inlines
+  show'' (RefSingle x) = show' x
+  show'' (RefRange x y) = show' x <> fromList (rangeDelim o) <> show' y
+  show' :: RefData -> Inlines
+  show' RefData{rdLabel=l, rdIdx=Just i, rdSubfig = sub, rdSuffix = suf, rdTitle=tit, rdPfx=pfx}
+    | linkReferences o = link ('#' `T.cons` l) "" (fromList txt)
+    | otherwise = fromList txt
+    where
+      txt
+        | Just sub' <- sub
+        = let vars = M.fromDistinctAscList
+                      [ ("i", chapPrefix (chapDelim o) i)
+                      , ("s", chapPrefix (chapDelim o) sub')
+                      , ("suf", suf)
+                      , ("t", fromMaybe mempty tit)
+                      ]
+          in applyTemplate' vars $ subfigureRefIndexTemplate o
+        | otherwise
+        = let vars = M.fromDistinctAscList
+                      [ ("i", chapPrefix (chapDelim o) i)
+                      , ("suf", suf)
+                      , ("t", fromMaybe mempty tit)
+                      ]
+          in applyTemplate' vars $ refIndexTemplate o (T.dropEnd 1 pfx)
+  show' RefData{rdLabel=l, rdIdx=Nothing, rdSuffix = suf} =
+    trace (T.unpack $ "Undefined cross-reference: " <> l)
+          (strong (text $ "¿" <> l <> "?") <> fromList suf)
diff --git a/lib-internal/Text/Pandoc/CrossRef/References/Types.hs b/lib-internal/Text/Pandoc/CrossRef/References/Types.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/References/Types.hs
@@ -0,0 +1,56 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE TemplateHaskell #-}
+module Text.Pandoc.CrossRef.References.Types where
+
+import qualified Data.Map as M
+import Text.Pandoc.Definition
+import Control.Monad.State
+import Data.Default
+import Data.Accessor.Template
+import Data.Text (Text)
+
+type Index = [(Int, Maybe Text)]
+
+data RefRec = RefRec { refIndex :: Index
+                     , refTitle :: [Inline]
+                     , refSubfigure :: Maybe Index
+                     } deriving (Show, Eq)
+
+type RefMap = M.Map Text 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
+
+deriveAccessors ''References
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs b/lib-internal/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
@@ -0,0 +1,67 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.Util.CodeBlockCaptions
+    (
+    mkCodeBlockCaptions
+    ) where
+
+import Text.Pandoc.Definition
+import Data.List (stripPrefix)
+import Data.Maybe (fromMaybe)
+import Text.Pandoc.CrossRef.References.Types
+import Text.Pandoc.CrossRef.Util.Options
+import Text.Pandoc.CrossRef.Util.Util
+import qualified Data.Text as T
+
+mkCodeBlockCaptions :: Options -> [Block] -> WS [Block]
+mkCodeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)
+  = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
+mkCodeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)
+  = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
+mkCodeBlockCaptions _ x = return x
+
+orderAgnostic :: Options -> [Block] -> Maybe [Block]
+orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)
+  | codeBlockCaptions opts
+  , Just caption <- getCodeBlockCaption ils
+  , not $ T.null label
+  , "lst" `T.isPrefixOf` label
+  = return $ Div (label,["listing"], [])
+      [Para caption, CodeBlock ("",classes,attrs) code] : xs
+orderAgnostic opts (Para ils:CodeBlock (_,classes,attrs) code:xs)
+  | codeBlockCaptions opts
+  , Just (caption, labinl) <- splitLast <$> getCodeBlockCaption ils
+  , Just label <- getRefLabel "lst" labinl
+  = return $ Div (label,["listing"], [])
+      [Para $ init caption, CodeBlock ("",classes,attrs) code] : xs
+  where
+    splitLast xs' = splitAt (length xs' - 1) xs'
+orderAgnostic _ _ = Nothing
+
+getCodeBlockCaption :: [Inline] -> Maybe [Inline]
+getCodeBlockCaption ils
+  | Just caption <- [Str "Listing:",Space] `stripPrefix` ils
+  = Just caption
+  | Just caption <- [Str ":",Space] `stripPrefix` ils
+  = Just caption
+  | otherwise
+  = Nothing
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/CustomLabels.hs b/lib-internal/Text/Pandoc/CrossRef/Util/CustomLabels.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/CustomLabels.hs
@@ -0,0 +1,55 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.Util.CustomLabels (customLabel, customHeadingLabel) where
+
+import Text.Pandoc.Definition
+import Text.Pandoc.CrossRef.Util.Meta
+import Text.Numeral.Roman
+import qualified Data.Text as T
+
+customLabel :: Meta -> T.Text -> Int -> Maybe T.Text
+customLabel meta ref i
+  | refLabel <- T.takeWhile (/=':') ref
+  , Just cl <- lookupMeta (refLabel <> "Labels") meta
+  = mkLabel i (refLabel <> "Labels") cl
+  | otherwise = Nothing
+
+customHeadingLabel :: Meta -> Int -> Int -> Maybe T.Text
+customHeadingLabel meta lvl i
+  | Just cl <- getMetaList Just "secLevelLabels" meta (lvl-1)
+  = mkLabel i "secLevelLabels" cl
+  | otherwise = Nothing
+
+mkLabel :: Int -> T.Text -> MetaValue -> Maybe T.Text
+mkLabel i n lt
+  | MetaList _ <- lt
+  , Just val <- toString n <$> getList (i-1) lt
+  = Just val
+  | toString n lt == "arabic"
+  = Nothing
+  | toString n lt == "roman"
+  = Just $ toRoman i
+  | toString n lt == "lowercase roman"
+  = Just $ T.toLower $ toRoman i
+  | Just (startWith, _) <- T.uncons =<< T.stripPrefix "alpha " (toString n lt)
+  = Just . T.singleton $ [startWith..] !! (i-1)
+  | otherwise = error $ "Unknown numeration type: " ++ show lt
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/Meta.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Meta.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Meta.hs
@@ -0,0 +1,123 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE FlexibleContexts, Rank2Types #-}
+module Text.Pandoc.CrossRef.Util.Meta (
+    getMetaList
+  , getMetaBool
+  , getMetaInlines
+  , getMetaBlock
+  , getMetaString
+  , getList
+  , toString
+  , toInlines
+  , tryCapitalizeM
+  ) where
+
+import Text.Pandoc.CrossRef.Util.Util
+import Text.Pandoc.Definition
+import Text.Pandoc.Builder
+import Data.Default
+import Text.Pandoc.Walk
+import Text.Pandoc.Shared hiding (capitalize, toString)
+import qualified Data.Text as T
+
+getMetaList :: (Default a) => (MetaValue -> a) -> T.Text -> Meta -> Int -> a
+getMetaList f name meta i = maybe def f $ lookupMeta name meta >>= getList i
+
+getMetaBool :: T.Text -> Meta -> Bool
+getMetaBool = getScalar toBool
+
+getMetaInlines :: T.Text -> Meta -> [Inline]
+getMetaInlines = getScalar toInlines
+
+getMetaBlock :: T.Text -> Meta -> [Block]
+getMetaBlock = getScalar toBlocks
+
+getMetaString :: T.Text -> Meta -> T.Text
+getMetaString = getScalar toString
+
+getScalar :: Def b => (T.Text -> MetaValue -> b) -> T.Text -> Meta -> b
+getScalar conv name meta = maybe def' (conv name) $ lookupMeta name meta
+
+class Def a where
+  def' :: a
+
+instance Def Bool where
+  def' = False
+
+instance Def [a] where
+  def' = []
+
+instance Def T.Text where
+  def' = T.empty
+
+unexpectedError :: forall a. String -> T.Text -> MetaValue -> a
+unexpectedError e n x = error $ "Expected " <> e <> " in metadata field " <> T.unpack n <> " but got " <> g x
+  where
+    g (MetaBlocks _) = "blocks"
+    g (MetaString _) = "string"
+    g (MetaInlines _) = "inlines"
+    g (MetaBool _) = "bool"
+    g (MetaMap _) = "map"
+    g (MetaList _) = "list"
+
+toInlines :: T.Text -> MetaValue -> [Inline]
+toInlines _ (MetaBlocks s) = blocksToInlines s
+toInlines _ (MetaInlines s) = s
+toInlines _ (MetaString s) = toList $ text s
+toInlines n x = unexpectedError "inlines" n x
+
+toBool :: T.Text -> MetaValue -> Bool
+toBool _ (MetaBool b) = b
+toBool n x = unexpectedError "bool" n x
+
+toBlocks :: T.Text -> MetaValue -> [Block]
+toBlocks _ (MetaBlocks bs) = bs
+toBlocks _ (MetaInlines ils) = [Plain ils]
+toBlocks _ (MetaString s) = toList $ plain $ text s
+toBlocks n x = unexpectedError "blocks" n x
+
+toString :: T.Text -> MetaValue -> T.Text
+toString _ (MetaString s) = s
+toString _ (MetaBlocks b) = stringify b
+toString _ (MetaInlines i) = stringify i
+toString n x = unexpectedError "string" n x
+
+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
+
+tryCapitalizeM :: (Functor m, Monad m, Walkable Inline a, Default a, Eq a) =>
+        (T.Text -> m a) -> T.Text -> 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
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/ModifyMeta.hs b/lib-internal/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
@@ -0,0 +1,134 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.Util.ModifyMeta
+    (
+    modifyMeta
+    ) where
+
+import Text.Pandoc
+import Text.Pandoc.Builder hiding ((<>))
+import Text.Pandoc.CrossRef.Util.Options
+import Text.Pandoc.CrossRef.Util.Meta
+import Text.Pandoc.CrossRef.Util.Util
+import qualified Data.Text as T
+import Control.Monad.Writer
+
+modifyMeta :: Options -> Meta -> Meta
+modifyMeta opts meta
+  | isLatexFormat (outFormat opts)
+  = setMeta "header-includes"
+      (headerInc $ lookupMeta "header-includes" meta)
+      meta
+  | otherwise = meta
+  where
+    headerInc :: Maybe MetaValue -> MetaValue
+    headerInc Nothing = incList
+    headerInc (Just (MetaList x)) = MetaList $ x <> [incList]
+    headerInc (Just x) = MetaList [x, incList]
+    incList = MetaBlocks $ return $ RawBlock (Format "latex") $ T.unlines $ execWriter $ do
+        tell [ "\\makeatletter" ]
+        tell subfig
+        tell floatnames
+        tell listnames
+        tell subfigures
+        unless (listings opts) $
+          tell codelisting
+        tell lolcommand
+        when (cref opts) $ do
+          tell cleveref
+          unless (listings opts) $
+            tell cleverefCodelisting
+        tell [ "\\makeatother" ]
+      where
+        subfig = [
+            usepackage [] "subfig"
+          , usepackage [] "caption"
+          , "\\captionsetup[subfloat]{margin=0.5em}"
+          ]
+        floatnames = [
+            "\\AtBeginDocument{%"
+          , "\\renewcommand*\\figurename{" <> metaString "figureTitle" <> "}"
+          , "\\renewcommand*\\tablename{" <> metaString "tableTitle" <> "}"
+          , "}"
+          ]
+        listnames = [
+            "\\AtBeginDocument{%"
+          , "\\renewcommand*\\listfigurename{" <> metaString' "lofTitle" <> "}"
+          , "\\renewcommand*\\listtablename{" <> metaString' "lotTitle" <> "}"
+          , "}"
+          ]
+        subfigures = [
+            "\\newcounter{pandoccrossref@subfigures@footnote@counter}"
+          , "\\newenvironment{pandoccrossrefsubfigures}{%"
+          , "\\setcounter{pandoccrossref@subfigures@footnote@counter}{0}"
+          , "\\begin{figure}\\centering%"
+          , "\\gdef\\global@pandoccrossref@subfigures@footnotes{}%"
+          , "\\DeclareRobustCommand{\\footnote}[1]{\\footnotemark%"
+          , "\\stepcounter{pandoccrossref@subfigures@footnote@counter}%"
+          , "\\ifx\\global@pandoccrossref@subfigures@footnotes\\empty%"
+          , "\\gdef\\global@pandoccrossref@subfigures@footnotes{{##1}}%"
+          , "\\else%"
+          , "\\g@addto@macro\\global@pandoccrossref@subfigures@footnotes{, {##1}}%"
+          , "\\fi}}%"
+          , "{\\end{figure}%"
+          , "\\addtocounter{footnote}{-\\value{pandoccrossref@subfigures@footnote@counter}}"
+          , "\\@for\\f:=\\global@pandoccrossref@subfigures@footnotes\\do{\\stepcounter{footnote}\\footnotetext{\\f}}%"
+          , "\\gdef\\global@pandoccrossref@subfigures@footnotes{}}"
+          ]
+        codelisting = [
+            usepackage [] "float"
+          , "\\floatstyle{ruled}"
+          , "\\@ifundefined{c@chapter}{\\newfloat{codelisting}{h}{lop}}{\\newfloat{codelisting}{h}{lop}[chapter]}"
+          , "\\floatname{codelisting}{" <> metaString "listingTitle" <> "}"
+          ]
+        lolcommand
+          | listings opts = [
+              "\\newcommand*\\listoflistings\\lstlistoflistings"
+            , "\\AtBeginDocument{%"
+            , "\\renewcommand*{\\lstlistlistingname}{" <> metaString' "lolTitle" <> "}"
+            , "}"
+            ]
+          | otherwise = ["\\newcommand*\\listoflistings{\\listof{codelisting}{" <> metaString' "lolTitle" <> "}}"]
+        cleveref = [ usepackage cleverefOpts "cleveref" ]
+          <> crefname "figure" figPrefix
+          <> crefname "table" tblPrefix
+          <> crefname "equation" eqnPrefix
+          <> crefname "listing" lstPrefix
+          <> crefname "section" secPrefix
+        cleverefCodelisting = [
+            "\\crefname{codelisting}{\\cref@listing@name}{\\cref@listing@name@plural}"
+          , "\\Crefname{codelisting}{\\Cref@listing@name}{\\Cref@listing@name@plural}"
+          ]
+        cleverefOpts | nameInLink opts = [ "nameinlink" ]
+                     | otherwise = []
+        crefname n f = [
+            "\\crefname{" <> n <> "}" <> prefix f False
+          , "\\Crefname{" <> n <> "}" <> prefix f True
+          ]
+        usepackage [] p = "\\@ifpackageloaded{" <> p <> "}{}{\\usepackage{" <> p <> "}}"
+        usepackage xs p = "\\@ifpackageloaded{" <> p <> "}{}{\\usepackage" <> o <> "{" <> p <> "}}"
+          where o = "[" <> T.intercalate "," xs <> "]"
+        toLatex = either (error . show) id . runPure . 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-internal/Text/Pandoc/CrossRef/Util/Options.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Options.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Options.hs
@@ -0,0 +1,72 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+module Text.Pandoc.CrossRef.Util.Options (Options(..)) where
+import Text.Pandoc.Definition
+import Text.Pandoc.CrossRef.Util.Template
+import Data.Text (Text)
+
+data Options = Options { cref :: Bool
+                       , chaptersDepth   :: Int
+                       , listings :: Bool
+                       , codeBlockCaptions  :: Bool
+                       , autoSectionLabels  :: Bool
+                       , numberSections  :: Bool
+                       , sectionsDepth  :: Int
+                       , figPrefix   :: Bool -> Int -> [Inline]
+                       , eqnPrefix   :: Bool -> Int -> [Inline]
+                       , tblPrefix   :: Bool -> Int -> [Inline]
+                       , lstPrefix   :: Bool -> Int -> [Inline]
+                       , secPrefix   :: Bool -> Int -> [Inline]
+                       , figPrefixTemplate :: Template
+                       , eqnPrefixTemplate :: Template
+                       , tblPrefixTemplate :: Template
+                       , lstPrefixTemplate :: Template
+                       , secPrefixTemplate :: Template
+                       , refIndexTemplate :: Text -> Template
+                       , subfigureRefIndexTemplate :: Template
+                       , secHeaderTemplate :: Template
+                       , chapDelim   :: [Inline]
+                       , rangeDelim  :: [Inline]
+                       , pairDelim  :: [Inline]
+                       , lastDelim  :: [Inline]
+                       , refDelim  :: [Inline]
+                       , lofTitle    :: [Block]
+                       , lotTitle    :: [Block]
+                       , lolTitle    :: [Block]
+                       , outFormat   :: Maybe Format
+                       , figureTemplate :: Template
+                       , subfigureTemplate :: Template
+                       , subfigureChildTemplate :: Template
+                       , ccsTemplate :: Template
+                       , tableTemplate  :: Template
+                       , listingTemplate :: Template
+                       , customLabel :: Text -> Int -> Maybe Text
+                       , customHeadingLabel :: Int -> Int -> Maybe Text
+                       , ccsDelim :: [Inline]
+                       , ccsLabelSep :: [Inline]
+                       , tableEqns :: Bool
+                       , autoEqnLabels :: Bool
+                       , subfigGrid :: Bool
+                       , linkReferences :: Bool
+                       , nameInLink :: Bool
+                       , setLabelAttribute :: Bool
+                       , equationNumberTeX :: Text
+                       }
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/Settings.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Settings.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Settings.hs
@@ -0,0 +1,115 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+Copyright (C) 2017  Masamichi Hosoda <trueroad@trueroad.jp>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.Util.Settings (getSettings, defaultMeta) where
+
+import Text.Pandoc
+import Text.Pandoc.Builder
+import Control.Exception (handle,IOException)
+
+import Text.Pandoc.CrossRef.Util.Settings.Gen
+import Text.Pandoc.CrossRef.Util.Meta
+import System.Directory
+import System.FilePath
+import System.IO
+import qualified Data.Text as T
+
+getSettings :: Maybe Format -> Meta -> IO Meta
+getSettings fmt meta = do
+  dirConfig <- readConfig (T.unpack $ getMetaString "crossrefYaml" (defaultMeta <> meta))
+  home <- getHomeDirectory
+  globalConfig <- readConfig (home </> ".pandoc-crossref" </> "config.yaml")
+  formatConfig <- maybe (return nullMeta) (readFmtConfig home) fmt
+  return $ defaultMeta <> globalConfig <> formatConfig <> dirConfig <> meta
+  where
+    readConfig path =
+      handle handler $ do
+        h <- openFile path ReadMode
+        hSetEncoding h utf8
+        yaml <- hGetContents h
+        Pandoc meta' _ <- readMd $ T.pack $ unlines ["---", yaml, "---"]
+        return meta'
+    readMd = handleError . runPure . readMarkdown def{readerExtensions=pandocExtensions}
+    readFmtConfig home fmt' = readConfig (home </> ".pandoc-crossref" </> "config-" ++ fmtStr fmt' ++ ".yaml")
+    handler :: IOException -> IO Meta
+    handler _ = return nullMeta
+    fmtStr (Format fmtstr) = T.unpack fmtstr
+
+
+defaultMeta :: Meta
+defaultMeta =
+     cref False
+  <> chapters False
+  <> chaptersDepth (MetaString "1")
+  <> listings False
+  <> codeBlockCaptions False
+  <> autoSectionLabels False
+  <> numberSections False
+  <> sectionsDepth (MetaString "0")
+  <> figLabels (MetaString "arabic")
+  <> eqLabels (MetaString "arabic")
+  <> tblLabels (MetaString "arabic")
+  <> lstLabels (MetaString "arabic")
+  <> secLabels (MetaString "arabic")
+  <> figureTitle (str "Figure")
+  <> tableTitle (str "Table")
+  <> listingTitle (str "Listing")
+  <> titleDelim (str ":")
+  <> chapDelim (str ".")
+  <> rangeDelim (str "-")
+  <> pairDelim (str "," <> space)
+  <> lastDelim (str "," <> space)
+  <> refDelim (str "," <> space)
+  <> 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."]
+  <> figPrefixTemplate (var "p" <> str "\160" <> var "i")
+  <> eqnPrefixTemplate (var "p" <> str "\160" <> var "i")
+  <> tblPrefixTemplate (var "p" <> str "\160" <> var "i")
+  <> lstPrefixTemplate (var "p" <> str "\160" <> var "i")
+  <> secPrefixTemplate (var "p" <> str "\160" <> var "i")
+  <> refIndexTemplate (var "i" <> var "suf")
+  <> subfigureRefIndexTemplate (var "i" <> var "suf" <> space <> str "(" <> var "s" <> str ")")
+  <> secHeaderTemplate (var "i" <> var "secHeaderDelim[n]" <> var "t")
+  <> secHeaderDelim space
+  <> 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")
+  <> subfigureChildTemplate (var "i")
+  <> subfigureTemplate (var "figureTitle" <> space <> var "i" <> var "titleDelim" <> space <> var "t" <> str "." <> space <> var "ccs")
+  <> subfigLabels (MetaString "alpha a")
+  <> ccsDelim (str "," <> space)
+  <> ccsLabelSep (space <> str "—" <> space)
+  <> ccsTemplate (var "i" <> var "ccsLabelSep" <> var "t")
+  <> tableEqns False
+  <> autoEqnLabels False
+  <> subfigGrid False
+  <> linkReferences False
+  <> nameInLink False
+  <> equationNumberTeX ("qquad" :: T.Text)
+  where var = displayMath
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/Settings/Gen.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
@@ -0,0 +1,54 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
+-- {-# OPTIONS_GHC -ddump-splices #-}
+module Text.Pandoc.CrossRef.Util.Settings.Gen where
+
+import Text.Pandoc.CrossRef.Util.Settings.Template
+import Text.Pandoc.CrossRef.Util.Meta
+import Text.Pandoc.CrossRef.Util.Options as O (Options(..))
+import Language.Haskell.TH (mkName)
+import Text.Pandoc.Definition
+
+nameDeriveSetters ''Options
+
+concat <$> mapM (makeAcc . mkName)
+  [ "figureTitle"
+  , "tableTitle"
+  , "listingTitle"
+  , "titleDelim"
+  , "crossrefYaml"
+  , "subfigLabels"
+  , "chapters"
+  , "figLabels"
+  , "eqLabels"
+  , "tblLabels"
+  , "lstLabels"
+  , "secLabels"
+  , "secHeaderDelim"
+  ]
+
+getOptions :: Meta -> Maybe Format -> Options
+getOptions dtv fmt =
+  let opts = $(makeCon ''Options 'Options)
+  in if getMetaBool "chapters" dtv
+     then opts
+     else opts{O.chaptersDepth = 0}
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/Settings/Template.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Settings/Template.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Settings/Template.hs
@@ -0,0 +1,102 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE TemplateHaskell, RankNTypes, ViewPatterns, MultiWayIf #-}
+module Text.Pandoc.CrossRef.Util.Settings.Template where
+
+import Text.Pandoc.Definition
+import Text.Pandoc.Builder
+import Text.Pandoc.CrossRef.Util.Meta
+import qualified Data.Map as M
+import Language.Haskell.TH hiding (Inline)
+import Language.Haskell.TH.Syntax hiding (Inline)
+import Data.List
+import Text.Pandoc.CrossRef.Util.Template
+import Text.Pandoc.CrossRef.Util.CustomLabels
+import Data.Text (Text)
+import qualified Data.Text as T
+
+namedFields :: Con -> [VarStrictType]
+namedFields (RecC _ fs) = fs
+namedFields (ForallC _ _ c) = namedFields c
+namedFields _ = []
+
+fromRecDef :: forall t a r. Name -> t -> (Name -> Name -> Q [a]) -> (t -> [a] -> r) -> Q r
+fromRecDef t cname f c = do
+  info <- reify t
+  reified <- case info of
+                  TyConI dec -> return dec
+                  _ -> fail "No cons"
+  (_, cons) <- case reified of
+               DataD _ _ params _ cons' _ -> return (params, cons')
+               NewtypeD _ _ params _ con' _ -> return (params, [con'])
+               _ -> fail "No cons"
+  decs <- fmap concat . mapM (\ (name,_,_) -> f t name) . nub $ concatMap namedFields cons
+  return $ c cname decs
+
+nameDeriveSetters :: Name -> Q [Dec]
+nameDeriveSetters t = fromRecDef t undefined (const makeAcc) (const id)
+
+dropQualifiers :: Name -> Name
+dropQualifiers (Name occ _) = mkName (occString occ)
+
+makeAcc :: Name -> Q [Dec]
+makeAcc (dropQualifiers -> accName) = do
+    body <- [| Meta . M.singleton $(liftString $ show accName) . toMetaValue |]
+    sig <- [t|forall a. ToMetaValue a => a -> Meta|]
+    return
+      [ SigD accName sig
+      , ValD (VarP accName) (NormalB body) []
+      ]
+
+makeCon :: Name -> Name -> Q Exp
+makeCon t cname = fromRecDef t cname makeCon' RecConE
+
+makeCon' :: Name -> Name -> Q [(Name, Exp)]
+makeCon' t accName = do
+    VarI _ t' _ <- reify accName
+    funT <- [t|$(conT t) -> Bool -> Int -> [Inline]|]
+    inlT <- [t|$(conT t) -> [Inline]|]
+    blkT <- [t|$(conT t) -> [Block]|]
+    fmtT <- [t|$(conT t) -> Maybe Format|]
+    boolT <- [t|$(conT t) -> Bool|]
+    strT <- [t|$(conT t) -> Text|]
+    intT <- [t|$(conT t) -> Int|]
+    tmplT <- [t|$(conT t) -> Template|]
+    idxTmplT <- [t|$(conT t) -> Text -> Template|]
+    clT <- [t|$(conT t) -> Text -> Int -> Maybe Text|]
+    chlT <- [t|$(conT t) -> Int -> Int -> Maybe Text|]
+    let varName | Name (OccName n) _ <- accName = liftString n
+    let dtv = return $ VarE $ mkName "dtv"
+    body <-
+      if
+      | t' == boolT -> [|getMetaBool $(varName) $(dtv)|]
+      | t' == intT -> [|read $ T.unpack $ getMetaString $(varName) $(dtv)|]
+      | t' == funT -> [|tryCapitalizeM (flip (getMetaList (toInlines $(varName))) $(dtv)) $(varName)|]
+      | t' == inlT -> [|getMetaInlines $(varName) $(dtv)|]
+      | t' == blkT -> [|getMetaBlock $(varName) $(dtv)|]
+      | t' == tmplT -> [|makeTemplate $(dtv) $ getMetaInlines $(varName) $(dtv)|]
+      | t' == idxTmplT -> [|makeIndexedTemplate $(varName) $(dtv)|]
+      | t' == clT -> [|customLabel $(dtv)|]
+      | t' == chlT -> [|customHeadingLabel $(dtv)|]
+      | t' == strT -> [|getMetaString $(varName) $(dtv)|]
+      | t' == fmtT -> return $ VarE $ mkName "fmt"
+      | otherwise -> fail $ show t'
+    return [(accName, body)]
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/Template.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Template.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Template.hs
@@ -0,0 +1,79 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Pandoc.CrossRef.Util.Template
+  ( Template
+  , makeTemplate
+  , makeIndexedTemplate
+  , applyTemplate
+  , applyTemplate'
+  ) where
+
+import Text.Pandoc.Definition
+import Text.Pandoc.Builder
+import Text.Pandoc.Generic
+import qualified Data.Map as M hiding (toList, fromList, singleton)
+import Text.Pandoc.CrossRef.Util.Meta
+import Control.Applicative
+import Text.Read
+import qualified Data.Text as T
+
+type VarFunc = T.Text -> Maybe MetaValue
+newtype Template = Template (VarFunc -> [Inline])
+
+makeTemplate :: Meta -> [Inline] -> Template
+makeTemplate dtv xs' = Template $ \vf -> scan (\var -> vf var <|> lookupMeta var dtv) xs'
+  where
+  scan = bottomUp . go
+  go vf (x@(Math DisplayMath var):xs)
+    | (vn, idxBr) <- T.span (/='[') var
+    , not (T.null idxBr)
+    , T.last idxBr == ']'
+    = let idxVar = T.drop 1 $ T.takeWhile (/=']') idxBr
+          idx = readMaybe . T.unpack . toString ("index variable " <> idxVar) =<< vf idxVar
+          arr = do
+            i <- idx
+            v <- lookupMeta vn dtv
+            getList i v
+      in toList $ fromList (replaceVar var arr [x]) <> fromList xs
+    | otherwise = toList $ fromList (replaceVar var (vf var) [x]) <> fromList xs
+  go _ (x:xs) = toList $ singleton x <> fromList xs
+  go _ [] = []
+  replaceVar var val def' = maybe def' (toInlines ("variable " <> var)) val
+
+makeIndexedTemplate :: T.Text -> Meta -> T.Text -> Template
+makeIndexedTemplate name meta subname =
+  makeTemplate meta $ case lookupMeta name meta of
+    Just (MetaMap m) -> case lookupMeta subname (Meta m) of
+      Just x -> toInlines name x
+      Nothing -> getMetaInlines "default" (Meta m)
+    Just x -> toInlines name x
+    Nothing -> []
+
+applyTemplate' :: M.Map T.Text [Inline] -> Template -> [Inline]
+applyTemplate' vars (Template g) = g internalVars
+  where
+  internalVars x | Just v <- M.lookup x vars = Just $ MetaInlines v
+  internalVars _   = Nothing
+
+applyTemplate :: [Inline] -> [Inline] -> Template -> [Inline]
+applyTemplate i t =
+  applyTemplate' (M.fromDistinctAscList [("i", i), ("t", t)])
diff --git a/lib-internal/Text/Pandoc/CrossRef/Util/Util.hs b/lib-internal/Text/Pandoc/CrossRef/Util/Util.hs
new file mode 100644
--- /dev/null
+++ b/lib-internal/Text/Pandoc/CrossRef/Util/Util.hs
@@ -0,0 +1,151 @@
+{-
+pandoc-crossref is a pandoc filter for numbering figures,
+equations, tables and cross-references to them.
+Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+-}
+
+{-# LANGUAGE RankNTypes, OverloadedStrings, CPP #-}
+module Text.Pandoc.CrossRef.Util.Util
+  ( module Text.Pandoc.CrossRef.Util.Util
+  , module Data.Generics
+  ) where
+
+import Text.Pandoc.CrossRef.References.Types
+import Text.Pandoc.Definition
+import Text.Pandoc.Builder hiding ((<>))
+import Text.Pandoc.Class
+import Data.Char (toUpper, toLower, isUpper)
+import Data.Maybe (fromMaybe)
+import Data.Generics
+import Text.Pandoc.Writers.LaTeX
+import Data.Default
+import Data.Version
+import Data.List (find)
+import Text.ParserCombinators.ReadP (readP_to_S)
+import qualified Data.Text as T
+
+intercalate' :: (Eq a, Monoid a, Foldable f) => a -> f a -> a
+intercalate' s xs
+  | null xs = mempty
+  | otherwise = foldr1 (\x acc -> x <> s <> acc) xs
+
+isFormat :: T.Text -> Maybe Format -> Bool
+isFormat fmt (Just (Format f)) = T.takeWhile (`notElem` ("+-" :: String)) f == fmt
+isFormat _ Nothing = False
+
+isLatexFormat :: Maybe Format -> Bool
+isLatexFormat = isFormat "latex" `or'` isFormat "beamer"
+  where a `or'` b = (||) <$> a <*> b
+
+capitalizeFirst :: T.Text -> T.Text
+capitalizeFirst t
+  | Just (x, xs) <- T.uncons t = toUpper x `T.cons` xs
+  | otherwise = T.empty
+
+uncapitalizeFirst :: T.Text -> T.Text
+uncapitalizeFirst t
+  | Just (x, xs) <- T.uncons t = toLower x `T.cons` xs
+  | otherwise = T.empty
+
+isFirstUpper :: T.Text -> Bool
+isFirstUpper xs
+  | Just (x, _) <- T.uncons xs  = isUpper x
+  | otherwise = False
+
+chapPrefix :: [Inline] -> Index -> [Inline]
+chapPrefix delim = toList
+  . intercalate' (fromList delim)
+  . map str
+  . filter (not . T.null)
+  . map (uncurry (fromMaybe . T.pack . show))
+
+data ReplacedResult a = Replaced Bool a | NotReplaced Bool
+type GenRR m = forall a. Data a => (a -> m (ReplacedResult a))
+newtype RR m a = RR {unRR :: a -> m (ReplacedResult a)}
+
+runReplace :: (Monad m) => GenRR m -> GenericM m
+runReplace f x = do
+  res <- f x
+  case res of
+    Replaced True x' -> gmapM (runReplace f) x'
+    Replaced False x' -> return x'
+    NotReplaced True -> gmapM (runReplace f) x
+    NotReplaced False -> return x
+
+mkRR :: (Monad m, Typeable a, Typeable b)
+     => (b -> m (ReplacedResult b))
+     -> (a -> m (ReplacedResult a))
+mkRR = extRR (const noReplaceRecurse)
+
+extRR :: ( Monad m, Typeable a, Typeable b)
+     => (a -> m (ReplacedResult a))
+     -> (b -> m (ReplacedResult b))
+     -> (a -> m (ReplacedResult a))
+extRR def' ext = unRR (RR def' `ext0` RR ext)
+
+replaceRecurse :: Monad m => a -> m (ReplacedResult a)
+replaceRecurse = return . Replaced True
+
+replaceNoRecurse :: Monad m => a -> m (ReplacedResult a)
+replaceNoRecurse = return . Replaced False
+
+noReplace :: Monad m => Bool -> m (ReplacedResult a)
+noReplace recurse = return $ NotReplaced recurse
+
+noReplaceRecurse :: Monad m => m (ReplacedResult a)
+noReplaceRecurse = noReplace True
+
+noReplaceNoRecurse :: Monad m => m (ReplacedResult a)
+noReplaceNoRecurse = noReplace False
+
+mkLaTeXLabel :: T.Text -> T.Text
+mkLaTeXLabel l
+ | T.null l = ""
+ | otherwise = "\\label{" <> mkLaTeXLabel' l <> "}"
+
+mkLaTeXLabel' :: T.Text -> T.Text
+mkLaTeXLabel' l =
+  let ll = either (error . show) id $
+            runPure (writeLaTeX def $ Pandoc nullMeta [Div (l, [], []) []])
+  in T.takeWhile (/='}') . T.drop 1 . T.dropWhile (/='{') $ ll
+
+escapeLaTeX :: T.Text -> T.Text
+escapeLaTeX l =
+  let ll = either (error . show) id $
+            runPure (writeLaTeX def $ Pandoc nullMeta [Plain [Str l]])
+      pv = fmap fst . find (null . snd) . readP_to_S parseVersion $ VERSION_pandoc
+      mv = makeVersion [2,11,0,1]
+      cond = maybe False (mv >=) pv
+  in if cond then ll else l
+
+getRefLabel :: T.Text -> [Inline] -> Maybe T.Text
+getRefLabel _ [] = Nothing
+getRefLabel tag ils
+  | Str attr <- last ils
+  , all (==Space) (init ils)
+  , "}" `T.isSuffixOf` attr
+  , ("{#"<>tag<>":") `T.isPrefixOf` attr
+  = T.init `fmap` T.stripPrefix "{#" attr
+getRefLabel _ _ = Nothing
+
+isSpace :: Inline -> Bool
+isSpace = (||) <$> (==Space) <*> (==SoftBreak)
+
+isLaTeXRawBlockFmt :: Format -> Bool
+isLaTeXRawBlockFmt (Format "latex") = True
+isLaTeXRawBlockFmt (Format "tex") = True
+isLaTeXRawBlockFmt _ = False
diff --git a/lib/Text/Pandoc/CrossRef/References.hs b/lib/Text/Pandoc/CrossRef/References.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/References.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-module Text.Pandoc.CrossRef.References ( module X ) where
-
-import Text.Pandoc.CrossRef.References.Types as X
-import Text.Pandoc.CrossRef.References.Blocks as X (replaceAll)
-import Text.Pandoc.CrossRef.References.Refs as X
-import Text.Pandoc.CrossRef.References.List as X
diff --git a/lib/Text/Pandoc/CrossRef/References/Blocks.hs b/lib/Text/Pandoc/CrossRef/References/Blocks.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/References/Blocks.hs
+++ /dev/null
@@ -1,438 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE Rank2Types, OverloadedStrings #-}
-module Text.Pandoc.CrossRef.References.Blocks
-  ( replaceAll
-  ) where
-
-import Text.Pandoc.Definition
-import qualified Text.Pandoc.Builder as B
-import Text.Pandoc.Shared (stringify, blocksToInlines)
-import Text.Pandoc.Walk (walk)
-import Control.Monad.State hiding (get, modify)
-import Data.List
-import Data.Maybe
-import qualified Data.Map as M
-import qualified Data.Text as T
-import qualified Data.Text.Read as T
-
-import Data.Accessor
-import Data.Accessor.Monad.Trans.State
-import Text.Pandoc.CrossRef.References.Types
-import Text.Pandoc.CrossRef.Util.Util
-import Text.Pandoc.CrossRef.Util.Options
-import Text.Pandoc.CrossRef.Util.Template
-import Control.Applicative
-import Prelude
-import Data.Default
-
-replaceAll :: (Data a) => Options -> a -> WS a
-replaceAll opts =
-    runReplace (mkRR (replaceBlock opts)
-      `extRR` replaceInline opts
-      `extRR` replaceInlineMany opts
-      )
-  . runSplitMath
-  . everywhere (mkT divBlocks `extT` spanInlines opts)
-  where
-    runSplitMath | tableEqns opts
-                 , not $ isLatexFormat (outFormat opts)
-                 = everywhere (mkT splitMath)
-                 | otherwise = id
-
-simpleTable :: [Alignment] -> [ColWidth] -> [[[Block]]] -> Block
-simpleTable align width bod = Table nullAttr noCaption (zip align width)
-  noTableHead [mkBody bod] noTableFoot
-  where
-  mkBody xs = TableBody nullAttr (RowHeadColumns 0) [] (map mkRow xs)
-  mkRow xs = Row nullAttr (map mkCell xs)
-  mkCell xs = Cell nullAttr AlignDefault (RowSpan 0) (ColSpan 0) xs
-  noCaption = Caption Nothing mempty
-  noTableHead = TableHead nullAttr []
-  noTableFoot = TableFoot nullAttr []
-
-setLabel :: Options -> [Inline] -> [(T.Text, T.Text)] -> [(T.Text, T.Text)]
-setLabel opts idx
-  | setLabelAttribute opts
-  = (("label", stringify idx) :)
-  . filter ((/= "label") . fst)
-  | otherwise = id
-
-replaceBlock :: Options -> Block -> WS (ReplacedResult Block)
-replaceBlock opts (Header n (label, cls, attrs) text')
-  = do
-    let label' = if autoSectionLabels opts && not ("sec:" `T.isPrefixOf` label)
-                 then "sec:"<>label
-                 else label
-    unless ("unnumbered" `elem` cls) $ do
-      modify curChap $ \cc ->
-        let ln = length cc
-            cl i = lookup "label" attrs <|> customHeadingLabel opts n i <|> customLabel opts "sec" i
-            inc l = let i = fst (last l) + 1 in init l <> [(i, cl i)]
-            cc' | ln > n = inc $ take n cc
-                | ln == n = inc cc
-                | otherwise = cc <> take (n-ln-1) (zip [1,1..] $ repeat Nothing) <> [(1,cl 1)]
-        in cc'
-      when ("sec:" `T.isPrefixOf` label') $ do
-        index  <- get curChap
-        modify secRefs $ M.insert label' RefRec {
-          refIndex=index
-        , refTitle= text'
-        , refSubfigure = Nothing
-        }
-    cc <- get curChap
-    let textCC | numberSections opts
-               , sectionsDepth opts < 0
-               || n <= if sectionsDepth opts == 0 then chaptersDepth opts else sectionsDepth opts
-               , "unnumbered" `notElem` cls
-               = applyTemplate' (M.fromDistinctAscList [
-                    ("i", idxStr)
-                  , ("n", [Str $ T.pack $ show $ n - 1])
-                  , ("t", text')
-                  ]) $ secHeaderTemplate opts
-               | otherwise = text'
-        idxStr = chapPrefix (chapDelim opts) cc
-        attrs' | "unnumbered" `notElem` cls
-               = setLabel opts idxStr attrs
-               | otherwise = attrs
-    replaceNoRecurse $ Header n (label', cls, attrs') textCC
--- subfigures
-replaceBlock opts (Div (label,cls,attrs) images)
-  | "fig:" `T.isPrefixOf` label
-  , Para caption <- last images
-  = do
-    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) caption imgRefs
-    let (cont, st) = runState (runReplace (mkRR $ replaceSubfigs opts') $ init images) def
-        collectedCaptions = B.toList $
-            intercalate' (B.fromList $ ccsDelim opts)
-          $ map (B.fromList . collectCaps . snd)
-          $ sortOn (refIndex . snd)
-          $ filter (not . null . refTitle . snd)
-          $ M.toList
-          $ imgRefs_ st
-        collectCaps v =
-              applyTemplate
-                (chapPrefix (chapDelim opts) (refIndex v))
-                (refTitle v)
-                (ccsTemplate opts)
-        vars = M.fromDistinctAscList
-                  [ ("ccs", collectedCaptions)
-                  , ("i", idxStr)
-                  , ("t", caption)
-                  ]
-        capt = applyTemplate' vars $ subfigureTemplate opts
-    lastRef <- fromJust . M.lookup label <$> get imgRefs
-    modify imgRefs $ \old ->
-        M.union
-          old
-          (M.map (\v -> v{refIndex = refIndex lastRef, refSubfigure = Just $ refIndex v})
-          $ imgRefs_ st)
-    case outFormat opts of
-          f | isLatexFormat f ->
-            replaceNoRecurse $ Div nullAttr $
-              [ RawBlock (Format "latex") "\\begin{pandoccrossrefsubfigures}" ]
-              <> cont <>
-              [ Para [RawInline (Format "latex") "\\caption["
-                       , Span nullAttr (removeFootnotes caption)
-                       , RawInline (Format "latex") "]"
-                       , Span nullAttr caption]
-              , RawBlock (Format "latex") $ mkLaTeXLabel label
-              , RawBlock (Format "latex") "\\end{pandoccrossrefsubfigures}"]
-          _  -> replaceNoRecurse $ Div (label, "subfigures":cls, setLabel opts idxStr attrs) $ toTable cont capt
-  where
-    opts' = opts
-              { figureTemplate = subfigureChildTemplate opts
-              , customLabel = \r i -> customLabel opts ("sub"<>r) i
-              }
-    removeFootnotes = walk removeFootnote
-    removeFootnote Note{} = Str ""
-    removeFootnote x = x
-    toTable :: [Block] -> [Inline] -> [Block]
-    toTable blks capt
-      | subfigGrid opts = [ simpleTable align (map ColWidth widths) (map blkToRow blks)
-                          , mkCaption opts "Image Caption" capt]
-      | otherwise = blks <> [mkCaption opts "Image Caption" capt]
-      where
-        align | Para ils:_ <- blks = replicate (length $ mapMaybe getWidth ils) AlignCenter
-              | otherwise = error "Misformatted subfigures block"
-        widths | Para ils:_ <- blks
-               = fixZeros $ mapMaybe getWidth ils
-               | otherwise = error "Misformatted subfigures block"
-        getWidth (Image (_id, _class, as) _ _)
-          = Just $ maybe 0 percToDouble $ lookup "width" as
-        getWidth _ = Nothing
-        fixZeros :: [Double] -> [Double]
-        fixZeros ws
-          = let nz = length $ filter (== 0) ws
-                rzw = (0.99 - sum ws) / fromIntegral nz
-            in if nz>0
-               then map (\x -> if x == 0 then rzw else x) ws
-               else ws
-        percToDouble :: T.Text -> Double
-        percToDouble percs
-          | Right (perc, "%") <- T.double percs
-          = perc/100.0
-          | otherwise = error "Only percent allowed in subfigure width!"
-        blkToRow :: Block -> [[Block]]
-        blkToRow (Para inls) = mapMaybe inlToCell inls
-        blkToRow x = [[x]]
-        inlToCell :: Inline -> Maybe [Block]
-        inlToCell (Image (id', cs, as) txt tgt)  = Just [Para [Image (id', cs, setW as) txt tgt]]
-        inlToCell _ = Nothing
-        setW as = ("width", "100%"):filter ((/="width") . fst) as
-replaceBlock opts (Div (label,clss,attrs) [Table tattr (Caption short (btitle:rest)) colspec header cells foot])
-  | not $ null title
-  , "tbl:" `T.isPrefixOf` label
-  = do
-    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) title tblRefs
-    let title' =
-          case outFormat opts of
-              f | isLatexFormat f ->
-                RawInline (Format "latex") (mkLaTeXLabel label) : title
-              _  -> applyTemplate idxStr title $ tableTemplate opts
-        caption' = Caption short (walkReplaceInlines title' title btitle:rest)
-    replaceNoRecurse $ Div (label, clss, setLabel opts idxStr attrs) [Table tattr caption' colspec header cells foot]
-  where title = blocksToInlines [btitle]
-replaceBlock opts (Table (label,clss,attrs) (Caption short (btitle:rest)) colspec header cells foot)
-  | not $ null title
-  , "tbl:" `T.isPrefixOf` label
-  = do
-    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) title tblRefs
-    let title' =
-          case outFormat opts of
-              f | isLatexFormat f ->
-                RawInline (Format "latex") (mkLaTeXLabel label) : title
-              _  -> applyTemplate idxStr title $ tableTemplate opts
-        caption' = Caption short (walkReplaceInlines title' title btitle:rest)
-    replaceNoRecurse $ Table (label, clss, setLabel opts idxStr attrs) caption' colspec header cells foot
-  where title = blocksToInlines [btitle]
-replaceBlock opts cb@(CodeBlock (label, classes, attrs) code)
-  | not $ T.null label
-  , "lst:" `T.isPrefixOf` label
-  , Just caption <- lookup "caption" attrs
-  = case outFormat opts of
-      f
-        --if used with listings package,nothing shoud be done
-        | isLatexFormat f, listings opts -> noReplaceNoRecurse
-        --if not using listings, however, wrap it in a codelisting environment
-        | isLatexFormat f ->
-          replaceNoRecurse $ Div nullAttr [
-              RawBlock (Format "latex") "\\begin{codelisting}"
-            , Plain [
-                RawInline (Format "latex") "\\caption{"
-              , Str caption
-              , RawInline (Format "latex") "}"
-              ]
-            , cb
-            , RawBlock (Format "latex") "\\end{codelisting}"
-            ]
-      _ -> do
-        let cap = B.toList $ B.text caption
-        idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) cap lstRefs
-        let caption' = applyTemplate idxStr cap $ listingTemplate opts
-        replaceNoRecurse $ Div (label, "listing":classes, []) [
-            mkCaption opts "Caption" caption'
-          , CodeBlock ("", classes, filter ((/="caption") . fst) $ setLabel opts idxStr attrs) code
-          ]
-replaceBlock opts
-  (Div (label,"listing":divClasses, divAttrs)
-    [Para caption, CodeBlock ("",cbClasses,cbAttrs) code])
-  | not $ T.null label
-  , "lst:" `T.isPrefixOf` label
-  = case outFormat opts of
-      f
-        --if used with listings package, return code block with caption
-        | isLatexFormat f, listings opts ->
-          replaceNoRecurse $ CodeBlock (label,classes,("caption",escapeLaTeX $ stringify caption):attrs) code
-        --if not using listings, however, wrap it in a codelisting environment
-        | isLatexFormat f ->
-          replaceNoRecurse $ Div nullAttr [
-              RawBlock (Format "latex") "\\begin{codelisting}"
-            , Para [
-                RawInline (Format "latex") "\\caption"
-              , Span nullAttr caption
-              ]
-            , CodeBlock (label,classes,attrs) code
-            , RawBlock (Format "latex") "\\end{codelisting}"
-            ]
-      _ -> do
-        idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) caption lstRefs
-        let caption' = applyTemplate idxStr caption $ listingTemplate opts
-        replaceNoRecurse $ Div (label, "listing":classes, []) [
-            mkCaption opts "Caption" caption'
-          , CodeBlock ("", classes, setLabel opts idxStr attrs) code
-          ]
-  where attrs = divAttrs <> cbAttrs
-        classes = nub $ divClasses <> cbClasses
-replaceBlock opts (Para [Span sattrs@(label, cls, attrs) [Math DisplayMath eq]])
-  | not $ isLatexFormat (outFormat opts)
-  , tableEqns opts
-  = do
-    (eq', idxStr) <- replaceEqn opts sattrs eq
-    replaceNoRecurse $ Div (label,cls,setLabel opts idxStr attrs) [
-      simpleTable [AlignCenter, AlignRight] [ColWidth 0.9, ColWidth 0.09]
-       [[[Plain [Math DisplayMath eq']], [eqnNumber $ stringify idxStr]]]]
-  where
-  eqnNumber idx
-    | outFormat opts == Just (Format "docx")
-    = Div nullAttr [
-        RawBlock (Format "openxml") "<w:tcPr><w:vAlign w:val=\"center\"/></w:tcPr>"
-      , mathIdx
-      ]
-    | otherwise = mathIdx
-    where mathIdx = Plain [Math DisplayMath $ "(" <> idx <> ")"]
-replaceBlock _ _ = noReplaceRecurse
-
-replaceEqn :: Options -> Attr -> T.Text -> WS (T.Text, [Inline])
-replaceEqn opts (label, _, attrs) eq = do
-  let label' | T.null label = Left "eq"
-             | otherwise = Right label
-  idxStr <- replaceAttr opts label' (lookup "label" attrs) [] eqnRefs
-  let eq' | tableEqns opts = eq
-          | otherwise = eq<>"\\qquad("<>idxTxt<>")"
-      idxTxt = stringify idxStr
-  return (eq', idxStr)
-
-replaceInlineMany :: Options -> [Inline] -> WS (ReplacedResult [Inline])
-replaceInlineMany opts (Span spanAttr@(label,clss,attrs) [Math DisplayMath eq]:xs)
-  | "eq:" `T.isPrefixOf` label || T.null label && autoEqnLabels opts
-  = replaceRecurse . (<>xs) =<< case outFormat opts of
-      f | isLatexFormat f ->
-        pure [RawInline (Format "latex") "\\begin{equation}"
-        , Span spanAttr [RawInline (Format "latex") eq]
-        , RawInline (Format "latex") $ mkLaTeXLabel label <> "\\end{equation}"]
-      _ -> do
-        (eq', idxStr) <- replaceEqn opts spanAttr eq
-        pure [Span (label,clss,setLabel opts idxStr attrs) [Math DisplayMath eq']]
-replaceInlineMany _ _ = noReplaceRecurse
-
-replaceInline :: Options -> Inline -> WS (ReplacedResult Inline)
-replaceInline opts (Image (label,cls,attrs) alt img@(_, tit))
-  | "fig:" `T.isPrefixOf` label && "fig:" `T.isPrefixOf` tit
-  = do
-    idxStr <- replaceAttr opts (Right label) (lookup "label" attrs) alt imgRefs
-    let alt' = case outFormat opts of
-          f | isLatexFormat f -> alt
-          _  -> applyTemplate idxStr alt $ figureTemplate opts
-    replaceNoRecurse $ Image (label,cls,setLabel opts idxStr attrs) alt' img
-replaceInline _ _ = noReplaceRecurse
-
-replaceSubfigs :: Options -> [Inline] -> WS (ReplacedResult [Inline])
-replaceSubfigs opts = (replaceNoRecurse . concat) <=< mapM (replaceSubfig opts)
-
-replaceSubfig :: Options -> Inline -> WS [Inline]
-replaceSubfig opts x@(Image (label,cls,attrs) alt (src, tit))
-  = do
-      let label' | "fig:" `T.isPrefixOf` label = Right label
-                 | T.null label = Left "fig"
-                 | otherwise  = Right $ "fig:" <> label
-      idxStr <- replaceAttr opts label' (lookup "label" attrs) alt imgRefs
-      case outFormat opts of
-        f | isLatexFormat f ->
-          return $ latexSubFigure x label
-        _  ->
-          let alt' = applyTemplate idxStr alt $ figureTemplate opts
-              tit' | "nocaption" `elem` cls = fromMaybe tit $ T.stripPrefix "fig:" tit
-                   | "fig:" `T.isPrefixOf` tit = tit
-                   | otherwise = "fig:" <> tit
-          in return [Image (label, cls, setLabel opts idxStr attrs) alt' (src, tit')]
-replaceSubfig _ x = return [x]
-
-divBlocks :: Block -> Block
-divBlocks (Table tattr (Caption short (btitle:rest)) colspec header cells foot)
-  | not $ null title
-  , Just label <- getRefLabel "tbl" [last title]
-  = Div (label,[],[]) [
-    Table tattr (Caption short $ walkReplaceInlines (dropWhileEnd isSpace (init title)) title btitle:rest) colspec header cells foot]
-  where
-    title = blocksToInlines [btitle]
-divBlocks x = x
-
-walkReplaceInlines :: [Inline] -> [Inline] -> Block -> Block
-walkReplaceInlines newTitle title = walk replaceInlines
-  where
-  replaceInlines xs
-    | xs == title = newTitle
-    | otherwise = xs
-
-splitMath :: [Block] -> [Block]
-splitMath (Para ils:xs)
-  | length ils > 1 = map Para (split [] [] ils) <> xs
-  where
-    split res acc [] = reverse (reverse acc : res)
-    split res acc (x@(Span _ [Math DisplayMath _]):ys) =
-      split ([x] : reverse (dropSpaces acc) : res)
-            [] (dropSpaces ys)
-    split res acc (y:ys) = split res (y:acc) ys
-    dropSpaces = dropWhile isSpace
-splitMath xs = xs
-
-spanInlines :: Options -> [Inline] -> [Inline]
-spanInlines opts (math@(Math DisplayMath _eq):ils)
-  | c:ils' <- dropWhile isSpace ils
-  , Just label <- getRefLabel "eq" [c]
-  = Span (label,[],[]) [math]:ils'
-  | autoEqnLabels opts
-  = Span nullAttr [math]:ils
-spanInlines _ x = x
-
-replaceAttr :: Options -> Either T.Text T.Text -> Maybe T.Text -> [Inline] -> Accessor References RefMap -> WS [Inline]
-replaceAttr o label refLabel title prop
-  = do
-    chap  <- take (chaptersDepth o) `fmap` get curChap
-    prop' <- get prop
-    let i = 1+ (M.size . M.filter (\x -> (chap == init (refIndex x)) && isNothing (refSubfigure x)) $ prop')
-        index = chap <> [(i, refLabel <|> customLabel o ref i)]
-        ref = either id (T.takeWhile (/=':')) label
-        label' = either (<> T.pack (':' : show index)) id label
-    when (M.member label' prop') $
-      error . T.unpack $ "Duplicate label: " <> label'
-    modify prop $ M.insert label' RefRec {
-      refIndex= index
-    , refTitle= title
-    , refSubfigure = Nothing
-    }
-    return $ chapPrefix (chapDelim o) index
-
-latexSubFigure :: Inline -> T.Text -> [Inline]
-latexSubFigure (Image (_, cls, attrs) alt (src, title)) label =
-  let
-    title' = fromMaybe title $ T.stripPrefix "fig:" title
-    texlabel | T.null label = []
-             | otherwise = [RawInline (Format "latex") $ mkLaTeXLabel label]
-    texalt | "nocaption" `elem` cls  = []
-           | otherwise = concat
-              [ [ RawInline (Format "latex") "["]
-              , alt
-              , [ RawInline (Format "latex") "]"]
-              ]
-    img = Image (label, cls, attrs) alt (src, title')
-  in concat [
-      [ RawInline (Format "latex") "\\subfloat" ]
-      , texalt
-      , [Span nullAttr $ img:texlabel]
-      ]
-latexSubFigure x _ = [x]
-
-mkCaption :: Options -> T.Text -> [Inline] -> Block
-mkCaption opts style
-  | outFormat opts == Just (Format "docx") = Div ("", [], [("custom-style", style)]) . return . Para
-  | otherwise = Para
diff --git a/lib/Text/Pandoc/CrossRef/References/List.hs b/lib/Text/Pandoc/CrossRef/References/List.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/References/List.hs
+++ /dev/null
@@ -1,62 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.References.List (listOf) where
-
-import Text.Pandoc.Definition
-import Data.Accessor.Monad.Trans.State
-import Control.Arrow
-import Data.List
-import qualified Data.Map as M
-import qualified Data.Text as T
-
-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 | isLatexFormat f = return x
-listOf opts (RawBlock fmt "\\listoffigures":xs)
-  | isLaTeXRawBlockFmt fmt
-  = get imgRefs >>= makeList opts lofTitle xs
-listOf opts (RawBlock fmt "\\listoftables":xs)
-  | isLaTeXRawBlockFmt fmt
-  = get tblRefs >>= makeList opts lotTitle xs
-listOf opts (RawBlock fmt "\\listoflistings":xs)
-  | isLaTeXRawBlockFmt fmt
-  = get lstRefs >>= makeList opts lolTitle xs
-listOf _ x = return x
-
-makeList :: Options -> (Options -> [Block]) -> [Block] -> M.Map T.Text RefRec -> WS [Block]
-makeList opts titlef xs refs
-  = return $
-      titlef opts ++
-      (if chaptersDepth 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
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/References/Refs.hs
+++ /dev/null
@@ -1,255 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.References.Refs (replaceRefs) where
-
-import Text.Pandoc.Definition
-import Text.Pandoc.Builder
-import Control.Monad.State hiding (get, modify)
-import Data.List
-import qualified Data.List.HT as HT
-import qualified Data.Text as T
-import Data.Maybe
-import Data.Function
-import qualified Data.Map as M
-import Control.Arrow as A
-
-import Data.Accessor
-import Data.Accessor.Monad.Trans.State
-import Text.Pandoc.CrossRef.References.Types
-import Text.Pandoc.CrossRef.Util.Template
-import Text.Pandoc.CrossRef.Util.Util
-import Text.Pandoc.CrossRef.Util.Options
-import Control.Applicative
-import Debug.Trace
-import Prelude
-
-replaceRefs :: Options -> [Inline] -> WS [Inline]
-replaceRefs opts (Cite cits _:xs)
-  = toList . (<> fromList xs) . intercalate' (text ", ") . map fromList <$> 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' = toList $
-              str "["
-            <> intercalate' (text "; ") (map citationToInlines cits')
-            <> str "]"
-          citationToInlines c =
-            fromList (citationPrefix c) <> text ("@" <> citationId c)
-              <> fromList (citationSuffix c)
-    replaceRefs'' = case outFormat opts of
-                    f | isLatexFormat f -> replaceRefsLatex
-                    _                      -> replaceRefsOther
-replaceRefs _ x = return x
-
--- accessors to state variables
-accMap :: M.Map T.Text (Accessor References RefMap)
-accMap = M.fromList [("fig:",imgRefs)
-                    ,("eq:" ,eqnRefs)
-                    ,("tbl:",tblRefs)
-                    ,("lst:",lstRefs)
-                    ,("sec:",secRefs)
-                    ]
-
--- accessors to options
-prefMap :: M.Map T.Text (Options -> Bool -> Int -> [Inline], Options -> Template)
-prefMap = M.fromList [("fig:",(figPrefix, figPrefixTemplate))
-                     ,("eq:" ,(eqnPrefix, eqnPrefixTemplate))
-                     ,("tbl:",(tblPrefix, tblPrefixTemplate))
-                     ,("lst:",(lstPrefix, lstPrefixTemplate))
-                     ,("sec:",(secPrefix, secPrefixTemplate))
-                     ]
-
-prefixes :: [T.Text]
-prefixes = M.keys accMap
-
-getRefPrefix :: Options -> T.Text -> Bool -> Int -> [Inline] -> [Inline]
-getRefPrefix opts prefix capitalize num cit =
-  applyTemplate' (M.fromDistinctAscList [("i", cit), ("p", refprefix)])
-        $ reftempl opts
-  where (refprefixf, reftempl) = lookupUnsafe prefix prefMap
-        refprefix = refprefixf opts capitalize num
-
-
-lookupUnsafe :: Ord k => k -> M.Map k v -> v
-lookupUnsafe = (fromJust .) . M.lookup
-
-allCitsPrefix :: [Citation] -> Maybe T.Text
-allCitsPrefix cits = find isCitationPrefix prefixes
-  where
-  isCitationPrefix p =
-    all ((p `T.isPrefixOf`) . uncapitalizeFirst . citationId) cits
-
-replaceRefsLatex :: T.Text -> Options -> [Citation] -> WS [Inline]
-replaceRefsLatex prefix opts cits
-  | cref opts
-  = replaceRefsLatex' prefix opts cits
-  | otherwise
-  = toList . intercalate' (text ", ") . map fromList <$>
-      mapM (replaceRefsLatex' prefix opts) (groupBy citationGroupPred cits)
-
-replaceRefsLatex' :: T.Text -> Options -> [Citation] -> WS [Inline]
-replaceRefsLatex' prefix opts cits =
-  return $ p [texcit]
-  where
-    texcit =
-      RawInline (Format "tex") $
-      if cref opts then
-        cref'<>"{"<>listLabels prefix "" "," "" cits<>"}"
-        else
-          listLabels prefix "\\ref{" ", " "}" cits
-    suppressAuthor = all ((==SuppressAuthor) . citationMode) cits
-    noPrefix = all (null . citationPrefix) cits
-    p | cref opts = id
-      | suppressAuthor
-      = id
-      | noPrefix
-      = getRefPrefix opts prefix cap (length cits - 1)
-      | otherwise = ((citationPrefix (head cits) <> [Space]) <>)
-    cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits
-    cref' | suppressAuthor = "\\labelcref"
-          | cap = "\\Cref"
-          | otherwise = "\\cref"
-
-listLabels :: T.Text -> T.Text -> T.Text -> T.Text -> [Citation] -> T.Text
-listLabels prefix p sep s =
-  T.intercalate sep . map ((p <>) . (<> s) . mkLaTeXLabel' . (prefix<>) . getLabelWithoutPrefix . citationId)
-
-getLabelWithoutPrefix :: T.Text -> T.Text
-getLabelWithoutPrefix = T.drop 1 . T.dropWhile (/=':')
-
-getLabelPrefix :: T.Text -> Maybe T.Text
-getLabelPrefix lab
-  | uncapitalizeFirst p `elem` prefixes = Just p
-  | otherwise = Nothing
-  where p = flip T.snoc ':' . T.takeWhile (/=':') $ lab
-
-replaceRefsOther :: T.Text -> Options -> [Citation] -> WS [Inline]
-replaceRefsOther prefix opts cits = toList . intercalate' (text ", ") . map fromList <$>
-    mapM (replaceRefsOther' prefix opts) (groupBy citationGroupPred cits)
-
-citationGroupPred :: Citation -> Citation -> Bool
-citationGroupPred = (==) `on` liftM2 (,) citationPrefix citationMode
-
-replaceRefsOther' :: T.Text -> Options -> [Citation] -> WS [Inline]
-replaceRefsOther' prefix opts cits = do
-  indices <- mapM (getRefIndex prefix opts) cits
-  let
-    cap = maybe False isFirstUpper $ getLabelPrefix . citationId . head $ cits
-    writePrefix | all ((==SuppressAuthor) . citationMode) cits
-                = id
-                | all (null . citationPrefix) cits
-                = cmap $ getRefPrefix opts prefix cap (length cits - 1)
-                | otherwise
-                = cmap $ toList . ((fromList (citationPrefix (head cits)) <> space) <>) . fromList
-    cmap f [Link attr t w]
-      | nameInLink opts = [Link attr (f t) w]
-    cmap f x = f x
-  return $ writePrefix (makeIndices opts indices)
-
-data RefData = RefData { rdLabel :: T.Text
-                       , rdIdx :: Maybe Index
-                       , rdSubfig :: Maybe Index
-                       , rdSuffix :: [Inline]
-                       } deriving (Eq)
-
-instance Ord RefData where
-  (<=) = (<=) `on` rdIdx
-
-getRefIndex :: T.Text -> Options -> Citation -> WS RefData
-getRefIndex prefix _opts Citation{citationId=cid,citationSuffix=suf}
-  = do
-    ref <- M.lookup lab <$> get prop
-    let sub = refSubfigure <$> ref
-        idx = refIndex <$> ref
-    return RefData
-      { rdLabel = lab
-      , rdIdx = idx
-      , rdSubfig = join sub
-      , rdSuffix = suf
-      }
-  where
-  prop = lookupUnsafe prefix accMap
-  lab = prefix <> getLabelWithoutPrefix cid
-
-data RefItem = RefRange RefData RefData | RefSingle RefData
-
-makeIndices :: Options -> [RefData] -> [Inline]
-makeIndices o s = format $ concatMap f $ HT.groupBy g $ sort $ nub s
-  where
-  g :: RefData -> RefData -> Bool
-  g a b = all (null . rdSuffix) [a, b] && (
-            all (isNothing . rdSubfig) [a, b] &&
-            Just True == (liftM2 follows `on` rdIdx) b a ||
-            rdIdx a == rdIdx b &&
-            Just True == (liftM2 follows `on` rdSubfig) b a
-          )
-  follows :: Index -> Index -> Bool
-  follows a b
-    | Just (ai, al) <- HT.viewR a
-    , Just (bi, bl) <- HT.viewR b
-    = ai == bi && A.first (+1) bl == al
-  follows _ _ = False
-  f :: [RefData] -> [RefItem]
-  f []  = []                          -- drop empty lists
-  f [w] = [RefSingle w]                   -- single value
-  f [w1,w2] = [RefSingle w1, RefSingle w2] -- two values
-  f (x:xs) = [RefRange x (last xs)] -- shorten more than two values
-  format :: [RefItem] -> [Inline]
-  format [] = []
-  format [x] = toList $ show'' x
-  format [x, y] = toList $ show'' x <> fromList (pairDelim o) <> show'' y
-  format xs = toList $ intercalate' (fromList $ refDelim o) init' <> fromList (lastDelim o) <> last'
-    where initlast []     = error "emtpy list in initlast"
-          initlast [y]    = ([], y)
-          initlast (y:ys) = first (y:) $ initlast ys
-          (init', last') = initlast $ map show'' xs
-  show'' :: RefItem -> Inlines
-  show'' (RefSingle x) = show' x
-  show'' (RefRange x y) = show' x <> fromList (rangeDelim o) <> show' y
-  show' :: RefData -> Inlines
-  show' RefData{rdLabel=l, rdIdx=Just i, rdSubfig = sub, rdSuffix = suf}
-    | linkReferences o = link ('#' `T.cons` l) "" (fromList txt)
-    | otherwise = fromList txt
-    where
-      txt
-        | Just sub' <- sub
-        = let vars = M.fromDistinctAscList
-                      [ ("i", chapPrefix (chapDelim o) i)
-                      , ("s", chapPrefix (chapDelim o) sub')
-                      , ("suf", suf)
-                      ]
-          in applyTemplate' vars $ subfigureRefIndexTemplate o
-        | otherwise
-        = let vars = M.fromDistinctAscList
-                      [ ("i", chapPrefix (chapDelim o) i)
-                      , ("suf", suf)
-                      ]
-          in applyTemplate' vars $ refIndexTemplate o
-  show' RefData{rdLabel=l, rdIdx=Nothing, rdSuffix = suf} =
-    trace (T.unpack $ "Undefined cross-reference: " <> l)
-          (strong (text $ "¿" <> l <> "?") <> fromList suf)
diff --git a/lib/Text/Pandoc/CrossRef/References/Types.hs b/lib/Text/Pandoc/CrossRef/References/Types.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/References/Types.hs
+++ /dev/null
@@ -1,56 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE TemplateHaskell #-}
-module Text.Pandoc.CrossRef.References.Types where
-
-import qualified Data.Map as M
-import Text.Pandoc.Definition
-import Control.Monad.State
-import Data.Default
-import Data.Accessor.Template
-import Data.Text (Text)
-
-type Index = [(Int, Maybe Text)]
-
-data RefRec = RefRec { refIndex :: Index
-                     , refTitle :: [Inline]
-                     , refSubfigure :: Maybe Index
-                     } deriving (Show, Eq)
-
-type RefMap = M.Map Text 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
-
-deriveAccessors ''References
diff --git a/lib/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs b/lib/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs
+++ /dev/null
@@ -1,67 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.Util.CodeBlockCaptions
-    (
-    mkCodeBlockCaptions
-    ) where
-
-import Text.Pandoc.Definition
-import Data.List (stripPrefix)
-import Data.Maybe (fromMaybe)
-import Text.Pandoc.CrossRef.References.Types
-import Text.Pandoc.CrossRef.Util.Options
-import Text.Pandoc.CrossRef.Util.Util
-import qualified Data.Text as T
-
-mkCodeBlockCaptions :: Options -> [Block] -> WS [Block]
-mkCodeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)
-  = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
-mkCodeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)
-  = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
-mkCodeBlockCaptions _ x = return x
-
-orderAgnostic :: Options -> [Block] -> Maybe [Block]
-orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)
-  | codeBlockCaptions opts
-  , Just caption <- getCodeBlockCaption ils
-  , not $ T.null label
-  , "lst" `T.isPrefixOf` label
-  = return $ Div (label,["listing"], [])
-      [Para caption, CodeBlock ("",classes,attrs) code] : xs
-orderAgnostic opts (Para ils:CodeBlock (_,classes,attrs) code:xs)
-  | codeBlockCaptions opts
-  , Just (caption, labinl) <- splitLast <$> getCodeBlockCaption ils
-  , Just label <- getRefLabel "lst" labinl
-  = return $ Div (label,["listing"], [])
-      [Para $ init caption, CodeBlock ("",classes,attrs) code] : xs
-  where
-    splitLast xs' = splitAt (length xs' - 1) xs'
-orderAgnostic _ _ = Nothing
-
-getCodeBlockCaption :: [Inline] -> Maybe [Inline]
-getCodeBlockCaption ils
-  | Just caption <- [Str "Listing:",Space] `stripPrefix` ils
-  = Just caption
-  | Just caption <- [Str ":",Space] `stripPrefix` ils
-  = Just caption
-  | otherwise
-  = Nothing
diff --git a/lib/Text/Pandoc/CrossRef/Util/CustomLabels.hs b/lib/Text/Pandoc/CrossRef/Util/CustomLabels.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/CustomLabels.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.Util.CustomLabels (customLabel, customHeadingLabel) where
-
-import Text.Pandoc.Definition
-import Text.Pandoc.CrossRef.Util.Meta
-import Text.Numeral.Roman
-import qualified Data.Text as T
-
-customLabel :: Meta -> T.Text -> Int -> Maybe T.Text
-customLabel meta ref i
-  | refLabel <- T.takeWhile (/=':') ref
-  , Just cl <- lookupMeta (refLabel <> "Labels") meta
-  = mkLabel i (refLabel <> "Labels") cl
-  | otherwise = Nothing
-
-customHeadingLabel :: Meta -> Int -> Int -> Maybe T.Text
-customHeadingLabel meta lvl i
-  | Just cl <- getMetaList Just "secLevelLabels" meta (lvl-1)
-  = mkLabel i "secLevelLabels" cl
-  | otherwise = Nothing
-
-mkLabel :: Int -> T.Text -> MetaValue -> Maybe T.Text
-mkLabel i n lt
-  | MetaList _ <- lt
-  , Just val <- toString n <$> getList (i-1) lt
-  = Just val
-  | toString n lt == "arabic"
-  = Nothing
-  | toString n lt == "roman"
-  = Just $ toRoman i
-  | toString n lt == "lowercase roman"
-  = Just $ T.toLower $ toRoman i
-  | Just (startWith, _) <- T.uncons =<< T.stripPrefix "alpha " (toString n lt)
-  = Just . T.singleton $ [startWith..] !! (i-1)
-  | otherwise = error $ "Unknown numeration type: " ++ show lt
diff --git a/lib/Text/Pandoc/CrossRef/Util/Meta.hs b/lib/Text/Pandoc/CrossRef/Util/Meta.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Meta.hs
+++ /dev/null
@@ -1,123 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE FlexibleContexts, Rank2Types #-}
-module Text.Pandoc.CrossRef.Util.Meta (
-    getMetaList
-  , getMetaBool
-  , getMetaInlines
-  , getMetaBlock
-  , getMetaString
-  , getList
-  , toString
-  , toInlines
-  , tryCapitalizeM
-  ) where
-
-import Text.Pandoc.CrossRef.Util.Util
-import Text.Pandoc.Definition
-import Text.Pandoc.Builder
-import Data.Default
-import Text.Pandoc.Walk
-import Text.Pandoc.Shared hiding (capitalize, toString)
-import qualified Data.Text as T
-
-getMetaList :: (Default a) => (MetaValue -> a) -> T.Text -> Meta -> Int -> a
-getMetaList f name meta i = maybe def f $ lookupMeta name meta >>= getList i
-
-getMetaBool :: T.Text -> Meta -> Bool
-getMetaBool = getScalar toBool
-
-getMetaInlines :: T.Text -> Meta -> [Inline]
-getMetaInlines = getScalar toInlines
-
-getMetaBlock :: T.Text -> Meta -> [Block]
-getMetaBlock = getScalar toBlocks
-
-getMetaString :: T.Text -> Meta -> T.Text
-getMetaString = getScalar toString
-
-getScalar :: Def b => (T.Text -> MetaValue -> b) -> T.Text -> Meta -> b
-getScalar conv name meta = maybe def' (conv name) $ lookupMeta name meta
-
-class Def a where
-  def' :: a
-
-instance Def Bool where
-  def' = False
-
-instance Def [a] where
-  def' = []
-
-instance Def T.Text where
-  def' = T.empty
-
-unexpectedError :: forall a. String -> T.Text -> MetaValue -> a
-unexpectedError e n x = error $ "Expected " <> e <> " in metadata field " <> T.unpack n <> " but got " <> g x
-  where
-    g (MetaBlocks _) = "blocks"
-    g (MetaString _) = "string"
-    g (MetaInlines _) = "inlines"
-    g (MetaBool _) = "bool"
-    g (MetaMap _) = "map"
-    g (MetaList _) = "list"
-
-toInlines :: T.Text -> MetaValue -> [Inline]
-toInlines _ (MetaBlocks s) = blocksToInlines s
-toInlines _ (MetaInlines s) = s
-toInlines _ (MetaString s) = toList $ text s
-toInlines n x = unexpectedError "inlines" n x
-
-toBool :: T.Text -> MetaValue -> Bool
-toBool _ (MetaBool b) = b
-toBool n x = unexpectedError "bool" n x
-
-toBlocks :: T.Text -> MetaValue -> [Block]
-toBlocks _ (MetaBlocks bs) = bs
-toBlocks _ (MetaInlines ils) = [Plain ils]
-toBlocks _ (MetaString s) = toList $ plain $ text s
-toBlocks n x = unexpectedError "blocks" n x
-
-toString :: T.Text -> MetaValue -> T.Text
-toString _ (MetaString s) = s
-toString _ (MetaBlocks b) = stringify b
-toString _ (MetaInlines i) = stringify i
-toString n x = unexpectedError "string" n x
-
-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
-
-tryCapitalizeM :: (Functor m, Monad m, Walkable Inline a, Default a, Eq a) =>
-        (T.Text -> m a) -> T.Text -> 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
diff --git a/lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs b/lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/ModifyMeta.hs
+++ /dev/null
@@ -1,134 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.Util.ModifyMeta
-    (
-    modifyMeta
-    ) where
-
-import Text.Pandoc
-import Text.Pandoc.Builder hiding ((<>))
-import Text.Pandoc.CrossRef.Util.Options
-import Text.Pandoc.CrossRef.Util.Meta
-import Text.Pandoc.CrossRef.Util.Util
-import qualified Data.Text as T
-import Control.Monad.Writer
-
-modifyMeta :: Options -> Meta -> Meta
-modifyMeta opts meta
-  | isLatexFormat (outFormat opts)
-  = setMeta "header-includes"
-      (headerInc $ lookupMeta "header-includes" meta)
-      meta
-  | otherwise = meta
-  where
-    headerInc :: Maybe MetaValue -> MetaValue
-    headerInc Nothing = incList
-    headerInc (Just (MetaList x)) = MetaList $ x <> [incList]
-    headerInc (Just x) = MetaList [x, incList]
-    incList = MetaBlocks $ return $ RawBlock (Format "latex") $ T.unlines $ execWriter $ do
-        tell [ "\\makeatletter" ]
-        tell subfig
-        tell floatnames
-        tell listnames
-        tell subfigures
-        unless (listings opts) $
-          tell codelisting
-        tell lolcommand
-        when (cref opts) $ do
-          tell cleveref
-          unless (listings opts) $
-            tell cleverefCodelisting
-        tell [ "\\makeatother" ]
-      where
-        subfig = [
-            usepackage [] "subfig"
-          , usepackage [] "caption"
-          , "\\captionsetup[subfloat]{margin=0.5em}"
-          ]
-        floatnames = [
-            "\\AtBeginDocument{%"
-          , "\\renewcommand*\\figurename{" <> metaString "figureTitle" <> "}"
-          , "\\renewcommand*\\tablename{" <> metaString "tableTitle" <> "}"
-          , "}"
-          ]
-        listnames = [
-            "\\AtBeginDocument{%"
-          , "\\renewcommand*\\listfigurename{" <> metaString' "lofTitle" <> "}"
-          , "\\renewcommand*\\listtablename{" <> metaString' "lotTitle" <> "}"
-          , "}"
-          ]
-        subfigures = [
-            "\\newcounter{pandoccrossref@subfigures@footnote@counter}"
-          , "\\newenvironment{pandoccrossrefsubfigures}{%"
-          , "\\setcounter{pandoccrossref@subfigures@footnote@counter}{0}"
-          , "\\begin{figure}\\centering%"
-          , "\\gdef\\global@pandoccrossref@subfigures@footnotes{}%"
-          , "\\DeclareRobustCommand{\\footnote}[1]{\\footnotemark%"
-          , "\\stepcounter{pandoccrossref@subfigures@footnote@counter}%"
-          , "\\ifx\\global@pandoccrossref@subfigures@footnotes\\empty%"
-          , "\\gdef\\global@pandoccrossref@subfigures@footnotes{{##1}}%"
-          , "\\else%"
-          , "\\g@addto@macro\\global@pandoccrossref@subfigures@footnotes{, {##1}}%"
-          , "\\fi}}%"
-          , "{\\end{figure}%"
-          , "\\addtocounter{footnote}{-\\value{pandoccrossref@subfigures@footnote@counter}}"
-          , "\\@for\\f:=\\global@pandoccrossref@subfigures@footnotes\\do{\\stepcounter{footnote}\\footnotetext{\\f}}%"
-          , "\\gdef\\global@pandoccrossref@subfigures@footnotes{}}"
-          ]
-        codelisting = [
-            usepackage [] "float"
-          , "\\floatstyle{ruled}"
-          , "\\@ifundefined{c@chapter}{\\newfloat{codelisting}{h}{lop}}{\\newfloat{codelisting}{h}{lop}[chapter]}"
-          , "\\floatname{codelisting}{" <> metaString "listingTitle" <> "}"
-          ]
-        lolcommand
-          | listings opts = [
-              "\\newcommand*\\listoflistings\\lstlistoflistings"
-            , "\\AtBeginDocument{%"
-            , "\\renewcommand*{\\lstlistlistingname}{" <> metaString' "lolTitle" <> "}"
-            , "}"
-            ]
-          | otherwise = ["\\newcommand*\\listoflistings{\\listof{codelisting}{" <> metaString' "lolTitle" <> "}}"]
-        cleveref = [ usepackage cleverefOpts "cleveref" ]
-          <> crefname "figure" figPrefix
-          <> crefname "table" tblPrefix
-          <> crefname "equation" eqnPrefix
-          <> crefname "listing" lstPrefix
-          <> crefname "section" secPrefix
-        cleverefCodelisting = [
-            "\\crefname{codelisting}{\\cref@listing@name}{\\cref@listing@name@plural}"
-          , "\\Crefname{codelisting}{\\Cref@listing@name}{\\Cref@listing@name@plural}"
-          ]
-        cleverefOpts | nameInLink opts = [ "nameinlink" ]
-                     | otherwise = []
-        crefname n f = [
-            "\\crefname{" <> n <> "}" <> prefix f False
-          , "\\Crefname{" <> n <> "}" <> prefix f True
-          ]
-        usepackage [] p = "\\@ifpackageloaded{" <> p <> "}{}{\\usepackage{" <> p <> "}}"
-        usepackage xs p = "\\@ifpackageloaded{" <> p <> "}{}{\\usepackage" <> o <> "{" <> p <> "}}"
-          where o = "[" <> T.intercalate "," xs <> "]"
-        toLatex = either (error . show) id . runPure . 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
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Options.hs
+++ /dev/null
@@ -1,71 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-module Text.Pandoc.CrossRef.Util.Options (Options(..)) where
-import Text.Pandoc.Definition
-import Text.Pandoc.CrossRef.Util.Template
-import Data.Text (Text)
-
-data Options = Options { cref :: Bool
-                       , chaptersDepth   :: Int
-                       , listings :: Bool
-                       , codeBlockCaptions  :: Bool
-                       , autoSectionLabels  :: Bool
-                       , numberSections  :: Bool
-                       , sectionsDepth  :: Int
-                       , figPrefix   :: Bool -> Int -> [Inline]
-                       , eqnPrefix   :: Bool -> Int -> [Inline]
-                       , tblPrefix   :: Bool -> Int -> [Inline]
-                       , lstPrefix   :: Bool -> Int -> [Inline]
-                       , secPrefix   :: Bool -> Int -> [Inline]
-                       , figPrefixTemplate :: Template
-                       , eqnPrefixTemplate :: Template
-                       , tblPrefixTemplate :: Template
-                       , lstPrefixTemplate :: Template
-                       , secPrefixTemplate :: Template
-                       , refIndexTemplate :: Template
-                       , subfigureRefIndexTemplate :: Template
-                       , secHeaderTemplate :: Template
-                       , chapDelim   :: [Inline]
-                       , rangeDelim  :: [Inline]
-                       , pairDelim  :: [Inline]
-                       , lastDelim  :: [Inline]
-                       , refDelim  :: [Inline]
-                       , lofTitle    :: [Block]
-                       , lotTitle    :: [Block]
-                       , lolTitle    :: [Block]
-                       , outFormat   :: Maybe Format
-                       , figureTemplate :: Template
-                       , subfigureTemplate :: Template
-                       , subfigureChildTemplate :: Template
-                       , ccsTemplate :: Template
-                       , tableTemplate  :: Template
-                       , listingTemplate :: Template
-                       , customLabel :: Text -> Int -> Maybe Text
-                       , customHeadingLabel :: Int -> Int -> Maybe Text
-                       , ccsDelim :: [Inline]
-                       , ccsLabelSep :: [Inline]
-                       , tableEqns :: Bool
-                       , autoEqnLabels :: Bool
-                       , subfigGrid :: Bool
-                       , linkReferences :: Bool
-                       , nameInLink :: Bool
-                       , setLabelAttribute :: Bool
-                       }
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings.hs b/lib/Text/Pandoc/CrossRef/Util/Settings.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Settings.hs
+++ /dev/null
@@ -1,114 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-Copyright (C) 2017  Masamichi Hosoda <trueroad@trueroad.jp>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.Util.Settings (getSettings, defaultMeta) where
-
-import Text.Pandoc
-import Text.Pandoc.Builder
-import Control.Exception (handle,IOException)
-
-import Text.Pandoc.CrossRef.Util.Settings.Gen
-import Text.Pandoc.CrossRef.Util.Meta
-import System.Directory
-import System.FilePath
-import System.IO
-import qualified Data.Text as T
-
-getSettings :: Maybe Format -> Meta -> IO Meta
-getSettings fmt meta = do
-  dirConfig <- readConfig (T.unpack $ getMetaString "crossrefYaml" (defaultMeta <> meta))
-  home <- getHomeDirectory
-  globalConfig <- readConfig (home </> ".pandoc-crossref" </> "config.yaml")
-  formatConfig <- maybe (return nullMeta) (readFmtConfig home) fmt
-  return $ defaultMeta <> globalConfig <> formatConfig <> dirConfig <> meta
-  where
-    readConfig path =
-      handle handler $ do
-        h <- openFile path ReadMode
-        hSetEncoding h utf8
-        yaml <- hGetContents h
-        Pandoc meta' _ <- readMd $ T.pack $ unlines ["---", yaml, "---"]
-        return meta'
-    readMd = handleError . runPure . readMarkdown def{readerExtensions=pandocExtensions}
-    readFmtConfig home fmt' = readConfig (home </> ".pandoc-crossref" </> "config-" ++ fmtStr fmt' ++ ".yaml")
-    handler :: IOException -> IO Meta
-    handler _ = return nullMeta
-    fmtStr (Format fmtstr) = T.unpack fmtstr
-
-
-defaultMeta :: Meta
-defaultMeta =
-     cref False
-  <> chapters False
-  <> chaptersDepth (MetaString "1")
-  <> listings False
-  <> codeBlockCaptions False
-  <> autoSectionLabels False
-  <> numberSections False
-  <> sectionsDepth (MetaString "0")
-  <> figLabels (MetaString "arabic")
-  <> eqLabels (MetaString "arabic")
-  <> tblLabels (MetaString "arabic")
-  <> lstLabels (MetaString "arabic")
-  <> secLabels (MetaString "arabic")
-  <> figureTitle (str "Figure")
-  <> tableTitle (str "Table")
-  <> listingTitle (str "Listing")
-  <> titleDelim (str ":")
-  <> chapDelim (str ".")
-  <> rangeDelim (str "-")
-  <> pairDelim (str "," <> space)
-  <> lastDelim (str "," <> space)
-  <> refDelim (str "," <> space)
-  <> 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."]
-  <> figPrefixTemplate (var "p" <> str "\160" <> var "i")
-  <> eqnPrefixTemplate (var "p" <> str "\160" <> var "i")
-  <> tblPrefixTemplate (var "p" <> str "\160" <> var "i")
-  <> lstPrefixTemplate (var "p" <> str "\160" <> var "i")
-  <> secPrefixTemplate (var "p" <> str "\160" <> var "i")
-  <> refIndexTemplate (var "i" <> var "suf")
-  <> subfigureRefIndexTemplate (var "i" <> var "suf" <> space <> str "(" <> var "s" <> str ")")
-  <> secHeaderTemplate (var "i" <> var "secHeaderDelim[n]" <> var "t")
-  <> secHeaderDelim space
-  <> 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")
-  <> subfigureChildTemplate (var "i")
-  <> subfigureTemplate (var "figureTitle" <> space <> var "i" <> var "titleDelim" <> space <> var "t" <> str "." <> space <> var "ccs")
-  <> subfigLabels (MetaString "alpha a")
-  <> ccsDelim (str "," <> space)
-  <> ccsLabelSep (space <> str "—" <> space)
-  <> ccsTemplate (var "i" <> var "ccsLabelSep" <> var "t")
-  <> tableEqns False
-  <> autoEqnLabels False
-  <> subfigGrid False
-  <> linkReferences False
-  <> nameInLink False
-  where var = displayMath
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs b/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
+++ /dev/null
@@ -1,54 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
--- {-# OPTIONS_GHC -ddump-splices #-}
-module Text.Pandoc.CrossRef.Util.Settings.Gen where
-
-import Text.Pandoc.CrossRef.Util.Settings.Template
-import Text.Pandoc.CrossRef.Util.Meta
-import Text.Pandoc.CrossRef.Util.Options as O (Options(..))
-import Language.Haskell.TH (mkName)
-import Text.Pandoc.Definition
-
-nameDeriveSetters ''Options
-
-concat <$> mapM (makeAcc . mkName)
-  [ "figureTitle"
-  , "tableTitle"
-  , "listingTitle"
-  , "titleDelim"
-  , "crossrefYaml"
-  , "subfigLabels"
-  , "chapters"
-  , "figLabels"
-  , "eqLabels"
-  , "tblLabels"
-  , "lstLabels"
-  , "secLabels"
-  , "secHeaderDelim"
-  ]
-
-getOptions :: Meta -> Maybe Format -> Options
-getOptions dtv fmt =
-  let opts = $(makeCon ''Options 'Options)
-  in if getMetaBool "chapters" dtv
-     then opts
-     else opts{O.chaptersDepth = 0}
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs b/lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Settings/Template.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE TemplateHaskell, RankNTypes, ViewPatterns, MultiWayIf #-}
-module Text.Pandoc.CrossRef.Util.Settings.Template where
-
-import Text.Pandoc.Definition
-import Text.Pandoc.Builder
-import Text.Pandoc.CrossRef.Util.Meta
-import qualified Data.Map as M
-import Language.Haskell.TH hiding (Inline)
-import Language.Haskell.TH.Syntax hiding (Inline)
-import Data.List
-import Text.Pandoc.CrossRef.Util.Template
-import Text.Pandoc.CrossRef.Util.CustomLabels
-import Data.Text (Text)
-import qualified Data.Text as T
-
-namedFields :: Con -> [VarStrictType]
-namedFields (RecC _ fs) = fs
-namedFields (ForallC _ _ c) = namedFields c
-namedFields _ = []
-
-fromRecDef :: forall t a r. Name -> t -> (Name -> Name -> Q [a]) -> (t -> [a] -> r) -> Q r
-fromRecDef t cname f c = do
-  info <- reify t
-  reified <- case info of
-                  TyConI dec -> return dec
-                  _ -> fail "No cons"
-  (_, cons) <- case reified of
-               DataD _ _ params _ cons' _ -> return (params, cons')
-               NewtypeD _ _ params _ con' _ -> return (params, [con'])
-               _ -> fail "No cons"
-  decs <- fmap concat . mapM (\ (name,_,_) -> f t name) . nub $ concatMap namedFields cons
-  return $ c cname decs
-
-nameDeriveSetters :: Name -> Q [Dec]
-nameDeriveSetters t = fromRecDef t undefined (const makeAcc) (const id)
-
-dropQualifiers :: Name -> Name
-dropQualifiers (Name occ _) = mkName (occString occ)
-
-makeAcc :: Name -> Q [Dec]
-makeAcc (dropQualifiers -> accName) = do
-    body <- [| Meta . M.singleton $(liftString $ show accName) . toMetaValue |]
-    sig <- [t|forall a. ToMetaValue a => a -> Meta|]
-    return
-      [ SigD accName sig
-      , ValD (VarP accName) (NormalB body) []
-      ]
-
-makeCon :: Name -> Name -> Q Exp
-makeCon t cname = fromRecDef t cname makeCon' RecConE
-
-makeCon' :: Name -> Name -> Q [(Name, Exp)]
-makeCon' t accName = do
-    VarI _ t' _ <- reify accName
-    funT <- [t|$(conT t) -> Bool -> Int -> [Inline]|]
-    inlT <- [t|$(conT t) -> [Inline]|]
-    blkT <- [t|$(conT t) -> [Block]|]
-    fmtT <- [t|$(conT t) -> Maybe Format|]
-    boolT <- [t|$(conT t) -> Bool|]
-    intT <- [t|$(conT t) -> Int|]
-    tmplT <- [t|$(conT t) -> Template|]
-    clT <- [t|$(conT t) -> Text -> Int -> Maybe Text|]
-    chlT <- [t|$(conT t) -> Int -> Int -> Maybe Text|]
-    let varName | Name (OccName n) _ <- accName = liftString n
-    let dtv = return $ VarE $ mkName "dtv"
-    body <-
-      if
-      | t' == boolT -> [|getMetaBool $(varName) $(dtv)|]
-      | t' == intT -> [|read $ T.unpack $ getMetaString $(varName) $(dtv)|]
-      | t' == funT -> [|tryCapitalizeM (flip (getMetaList (toInlines $(varName))) $(dtv)) $(varName)|]
-      | t' == inlT -> [|getMetaInlines $(varName) $(dtv)|]
-      | t' == blkT -> [|getMetaBlock $(varName) $(dtv)|]
-      | t' == tmplT -> [|makeTemplate $(dtv) $ getMetaInlines $(varName) $(dtv)|]
-      | t' == clT -> [|customLabel $(dtv)|]
-      | t' == chlT -> [|customHeadingLabel $(dtv)|]
-      | t' == fmtT -> return $ VarE $ mkName "fmt"
-      | otherwise -> fail $ show t'
-    return [(accName, body)]
diff --git a/lib/Text/Pandoc/CrossRef/Util/Template.hs b/lib/Text/Pandoc/CrossRef/Util/Template.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Template.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE OverloadedStrings #-}
-module Text.Pandoc.CrossRef.Util.Template
-  ( Template
-  , makeTemplate
-  , applyTemplate
-  , applyTemplate'
-  ) where
-
-import Text.Pandoc.Definition
-import Text.Pandoc.Builder
-import Text.Pandoc.Generic
-import qualified Data.Map as M hiding (toList, fromList, singleton)
-import Text.Pandoc.CrossRef.Util.Meta
-import Control.Applicative
-import Text.Read
-import qualified Data.Text as T
-
-type VarFunc = T.Text -> Maybe MetaValue
-newtype Template = Template (VarFunc -> [Inline])
-
-makeTemplate :: Meta -> [Inline] -> Template
-makeTemplate dtv xs' = Template $ \vf -> scan (\var -> vf var <|> lookupMeta var dtv) xs'
-  where
-  scan = bottomUp . go
-  go vf (x@(Math DisplayMath var):xs)
-    | (vn, idxBr) <- T.span (/='[') var
-    , not (T.null idxBr)
-    , T.last idxBr == ']'
-    = let idxVar = T.drop 1 $ T.takeWhile (/=']') idxBr
-          idx = readMaybe . T.unpack . toString ("index variable " <> idxVar) =<< vf idxVar
-          arr = do
-            i <- idx
-            v <- lookupMeta vn dtv
-            getList i v
-      in toList $ fromList (replaceVar var arr [x]) <> fromList xs
-    | otherwise = toList $ fromList (replaceVar var (vf var) [x]) <> fromList xs
-  go _ (x:xs) = toList $ singleton x <> fromList xs
-  go _ [] = []
-  replaceVar var val def' = maybe def' (toInlines ("variable " <> var)) val
-
-applyTemplate' :: M.Map T.Text [Inline] -> Template -> [Inline]
-applyTemplate' vars (Template g) = g internalVars
-  where
-  internalVars x | Just v <- M.lookup x vars = Just $ MetaInlines v
-  internalVars _   = Nothing
-
-applyTemplate :: [Inline] -> [Inline] -> Template -> [Inline]
-applyTemplate i t =
-  applyTemplate' (M.fromDistinctAscList [("i", i), ("t", t)])
diff --git a/lib/Text/Pandoc/CrossRef/Util/Util.hs b/lib/Text/Pandoc/CrossRef/Util/Util.hs
deleted file mode 100644
--- a/lib/Text/Pandoc/CrossRef/Util/Util.hs
+++ /dev/null
@@ -1,151 +0,0 @@
-{-
-pandoc-crossref is a pandoc filter for numbering figures,
-equations, tables and cross-references to them.
-Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--}
-
-{-# LANGUAGE RankNTypes, OverloadedStrings, CPP #-}
-module Text.Pandoc.CrossRef.Util.Util
-  ( module Text.Pandoc.CrossRef.Util.Util
-  , module Data.Generics
-  ) where
-
-import Text.Pandoc.CrossRef.References.Types
-import Text.Pandoc.Definition
-import Text.Pandoc.Builder hiding ((<>))
-import Text.Pandoc.Class
-import Data.Char (toUpper, toLower, isUpper)
-import Data.Maybe (fromMaybe)
-import Data.Generics
-import Text.Pandoc.Writers.LaTeX
-import Data.Default
-import Data.Version
-import Data.List (find)
-import Text.ParserCombinators.ReadP (readP_to_S)
-import qualified Data.Text as T
-
-intercalate' :: (Eq a, Monoid a, Foldable f) => a -> f a -> a
-intercalate' s xs
-  | null xs = mempty
-  | otherwise = foldr1 (\x acc -> x <> s <> acc) xs
-
-isFormat :: T.Text -> Maybe Format -> Bool
-isFormat fmt (Just (Format f)) = T.takeWhile (`notElem` ("+-" :: String)) f == fmt
-isFormat _ Nothing = False
-
-isLatexFormat :: Maybe Format -> Bool
-isLatexFormat = isFormat "latex" `or'` isFormat "beamer"
-  where a `or'` b = (||) <$> a <*> b
-
-capitalizeFirst :: T.Text -> T.Text
-capitalizeFirst t
-  | Just (x, xs) <- T.uncons t = toUpper x `T.cons` xs
-  | otherwise = T.empty
-
-uncapitalizeFirst :: T.Text -> T.Text
-uncapitalizeFirst t
-  | Just (x, xs) <- T.uncons t = toLower x `T.cons` xs
-  | otherwise = T.empty
-
-isFirstUpper :: T.Text -> Bool
-isFirstUpper xs
-  | Just (x, _) <- T.uncons xs  = isUpper x
-  | otherwise = False
-
-chapPrefix :: [Inline] -> Index -> [Inline]
-chapPrefix delim = toList
-  . intercalate' (fromList delim)
-  . map str
-  . filter (not . T.null)
-  . map (uncurry (fromMaybe . T.pack . show))
-
-data ReplacedResult a = Replaced Bool a | NotReplaced Bool
-type GenRR m = forall a. Data a => (a -> m (ReplacedResult a))
-newtype RR m a = RR {unRR :: a -> m (ReplacedResult a)}
-
-runReplace :: (Monad m) => GenRR m -> GenericM m
-runReplace f x = do
-  res <- f x
-  case res of
-    Replaced True x' -> gmapM (runReplace f) x'
-    Replaced False x' -> return x'
-    NotReplaced True -> gmapM (runReplace f) x
-    NotReplaced False -> return x
-
-mkRR :: (Monad m, Typeable a, Typeable b)
-     => (b -> m (ReplacedResult b))
-     -> (a -> m (ReplacedResult a))
-mkRR = extRR (const noReplaceRecurse)
-
-extRR :: ( Monad m, Typeable a, Typeable b)
-     => (a -> m (ReplacedResult a))
-     -> (b -> m (ReplacedResult b))
-     -> (a -> m (ReplacedResult a))
-extRR def' ext = unRR (RR def' `ext0` RR ext)
-
-replaceRecurse :: Monad m => a -> m (ReplacedResult a)
-replaceRecurse = return . Replaced True
-
-replaceNoRecurse :: Monad m => a -> m (ReplacedResult a)
-replaceNoRecurse = return . Replaced False
-
-noReplace :: Monad m => Bool -> m (ReplacedResult a)
-noReplace recurse = return $ NotReplaced recurse
-
-noReplaceRecurse :: Monad m => m (ReplacedResult a)
-noReplaceRecurse = noReplace True
-
-noReplaceNoRecurse :: Monad m => m (ReplacedResult a)
-noReplaceNoRecurse = noReplace False
-
-mkLaTeXLabel :: T.Text -> T.Text
-mkLaTeXLabel l
- | T.null l = ""
- | otherwise = "\\label{" <> mkLaTeXLabel' l <> "}"
-
-mkLaTeXLabel' :: T.Text -> T.Text
-mkLaTeXLabel' l =
-  let ll = either (error . show) id $
-            runPure (writeLaTeX def $ Pandoc nullMeta [Div (l, [], []) []])
-  in T.takeWhile (/='}') . T.drop 1 . T.dropWhile (/='{') $ ll
-
-escapeLaTeX :: T.Text -> T.Text
-escapeLaTeX l =
-  let ll = either (error . show) id $
-            runPure (writeLaTeX def $ Pandoc nullMeta [Plain [Str l]])
-      pv = fmap fst . find (null . snd) . readP_to_S parseVersion $ VERSION_pandoc
-      mv = makeVersion [2,11,0,1]
-      cond = maybe False (mv >=) pv
-  in if cond then ll else l
-
-getRefLabel :: T.Text -> [Inline] -> Maybe T.Text
-getRefLabel _ [] = Nothing
-getRefLabel tag ils
-  | Str attr <- last ils
-  , all (==Space) (init ils)
-  , "}" `T.isSuffixOf` attr
-  , ("{#"<>tag<>":") `T.isPrefixOf` attr
-  = T.init `fmap` T.stripPrefix "{#" attr
-getRefLabel _ _ = Nothing
-
-isSpace :: Inline -> Bool
-isSpace = (||) <$> (==Space) <*> (==SoftBreak)
-
-isLaTeXRawBlockFmt :: Format -> Bool
-isLaTeXRawBlockFmt (Format "latex") = True
-isLaTeXRawBlockFmt (Format "tex") = True
-isLaTeXRawBlockFmt _ = False
diff --git a/pandoc-crossref.cabal b/pandoc-crossref.cabal
--- a/pandoc-crossref.cabal
+++ b/pandoc-crossref.cabal
@@ -1,13 +1,13 @@
-cabal-version: 1.12
+cabal-version: 2.0
 
 -- This file has been generated from package.yaml by hpack version 0.33.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 5a129dfce5b068071f7222d4862b7159b9293232e08ec191d8446632b0fe6314
+-- hash: e117c4fe3ce92561126a6cfd9a8f561d8f78d4bbc5411e58e04e0cdb1b568a3f
 
 name:           pandoc-crossref
-version:        0.3.10.0
+version:        0.3.11.0
 synopsis:       Pandoc filter for cross-references
 description:    pandoc-crossref is a pandoc filter for numbering figures, equations, tables and cross-references to them.
 category:       Text
@@ -34,6 +34,9 @@
     test/m2m/emptyChapterLabels/expect.md
     test/m2m/emptyChapterLabels/expect.tex
     test/m2m/emptyChapterLabels/input.md
+    test/m2m/equationNumberLaTeX/expect.md
+    test/m2m/equationNumberLaTeX/expect.tex
+    test/m2m/equationNumberLaTeX/input.md
     test/m2m/equations-auto/expect.md
     test/m2m/equations-auto/expect.tex
     test/m2m/equations-auto/input.md
@@ -85,6 +88,9 @@
     test/m2m/subfigures/expect.md
     test/m2m/subfigures/expect.tex
     test/m2m/subfigures/input.md
+    test/m2m/titlesInRefs/expect.md
+    test/m2m/titlesInRefs/expect.tex
+    test/m2m/titlesInRefs/input.md
 
 source-repository head
   type: git
@@ -98,7 +104,20 @@
 library
   exposed-modules:
       Text.Pandoc.CrossRef
-  other-modules:
+  hs-source-dirs:
+      lib
+  ghc-options: -Wall
+  build-depends:
+      base >=4.11 && <5
+    , mtl >=1.1 && <2.3
+    , pandoc >=2.10 && <2.15
+    , pandoc-crossref-internal
+    , pandoc-types >=1.21 && <1.23
+    , text >=1.2.2 && <1.3
+  default-language: Haskell2010
+
+library pandoc-crossref-internal
+  exposed-modules:
       Text.Pandoc.CrossRef.References
       Text.Pandoc.CrossRef.References.Blocks
       Text.Pandoc.CrossRef.References.List
@@ -114,10 +133,8 @@
       Text.Pandoc.CrossRef.Util.Settings.Template
       Text.Pandoc.CrossRef.Util.Template
       Text.Pandoc.CrossRef.Util.Util
-      Paths_pandoc_crossref
   hs-source-dirs:
-      lib
-  ghc-options: -Wall
+      lib-internal
   build-depends:
       base >=4.11 && <5
     , containers >=0.1 && <0.7
@@ -128,7 +145,7 @@
     , directory >=1 && <1.4
     , filepath >=1.1 && <1.5
     , mtl >=1.1 && <2.3
-    , pandoc >=2.10 && <2.13
+    , pandoc >=2.10 && <2.15
     , pandoc-types >=1.21 && <1.23
     , roman-numerals ==0.5.*
     , syb >=0.4 && <0.8
@@ -141,33 +158,21 @@
   main-is: pandoc-crossref.hs
   other-modules:
       ManData
-      Paths_pandoc_crossref
   hs-source-dirs:
       src
   ghc-options: -Wall -threaded
   build-depends:
       base >=4.11 && <5
-    , containers >=0.1 && <0.7
-    , data-accessor >=0.2.2.6 && <0.3.0.0
-    , data-accessor-template >=0.2.1.12 && <0.3.0.0
-    , data-accessor-transformers >=0.2.1.6 && <0.3.0.0
-    , data-default >=0.4 && <0.8
     , deepseq >=1.4 && <1.5
-    , directory >=1 && <1.4
-    , filepath >=1.1 && <1.5
     , gitrev >=1.3.1 && <1.4
-    , mtl >=1.1 && <2.3
     , open-browser >=0.2 && <0.3
     , optparse-applicative >=0.13 && <0.17
-    , pandoc >=2.10 && <2.13
+    , pandoc >=2.10 && <2.15
     , pandoc-crossref
     , pandoc-types >=1.21 && <1.23
-    , roman-numerals ==0.5.*
-    , syb >=0.4 && <0.8
     , template-haskell >=2.7.0.0 && <3.0.0.0
     , temporary >=1.2 && <1.4
     , text >=1.2.2 && <1.3
-    , utility-ht >=0.0.11 && <0.1.0
   default-language: Haskell2010
 
 test-suite test-integrative
@@ -178,23 +183,13 @@
   ghc-options: -Wall -fno-warn-unused-do-bind -threaded
   build-depends:
       base >=4.11 && <5
-    , containers >=0.1 && <0.7
-    , data-accessor >=0.2.2.6 && <0.3.0.0
-    , data-accessor-template >=0.2.1.12 && <0.3.0.0
-    , data-accessor-transformers >=0.2.1.6 && <0.3.0.0
-    , data-default >=0.4 && <0.8
     , directory >=1 && <1.4
     , filepath >=1.1 && <1.5
     , hspec >=2.4.4 && <3
-    , mtl >=1.1 && <2.3
-    , pandoc >=2.10 && <2.13
+    , pandoc >=2.10 && <2.15
     , pandoc-crossref
     , pandoc-types >=1.21 && <1.23
-    , roman-numerals ==0.5.*
-    , syb >=0.4 && <0.8
-    , template-haskell >=2.7.0.0 && <3.0.0.0
     , text >=1.2.2 && <1.3
-    , utility-ht >=0.0.11 && <0.1.0
   if flag(enable_flaky_tests)
     cpp-options: -DFLAKY
   default-language: Haskell2010
@@ -204,45 +199,41 @@
   main-is: test-pandoc-crossref.hs
   other-modules:
       Native
-      Text.Pandoc.CrossRef
-      Text.Pandoc.CrossRef.References
-      Text.Pandoc.CrossRef.References.Blocks
-      Text.Pandoc.CrossRef.References.List
-      Text.Pandoc.CrossRef.References.Refs
-      Text.Pandoc.CrossRef.References.Types
-      Text.Pandoc.CrossRef.Util.CodeBlockCaptions
-      Text.Pandoc.CrossRef.Util.CustomLabels
-      Text.Pandoc.CrossRef.Util.Meta
-      Text.Pandoc.CrossRef.Util.ModifyMeta
-      Text.Pandoc.CrossRef.Util.Options
-      Text.Pandoc.CrossRef.Util.Settings
-      Text.Pandoc.CrossRef.Util.Settings.Gen
-      Text.Pandoc.CrossRef.Util.Settings.Template
-      Text.Pandoc.CrossRef.Util.Template
-      Text.Pandoc.CrossRef.Util.Util
       Paths_pandoc_crossref
+  autogen-modules:
+      Paths_pandoc_crossref
   hs-source-dirs:
       test
-      lib
   ghc-options: -Wall -fno-warn-unused-do-bind -threaded
   build-depends:
       base >=4.11 && <5
     , containers >=0.1 && <0.7
     , data-accessor >=0.2.2.6 && <0.3.0.0
-    , data-accessor-template >=0.2.1.12 && <0.3.0.0
-    , data-accessor-transformers >=0.2.1.6 && <0.3.0.0
     , data-default >=0.4 && <0.8
-    , directory >=1 && <1.4
-    , filepath >=1.1 && <1.5
     , hspec >=2.4.4 && <3
     , mtl >=1.1 && <2.3
-    , pandoc >=2.10 && <2.13
+    , pandoc >=2.10 && <2.15
+    , pandoc-crossref
+    , pandoc-crossref-internal
     , pandoc-types >=1.21 && <1.23
-    , roman-numerals ==0.5.*
-    , syb >=0.4 && <0.8
-    , template-haskell >=2.7.0.0 && <3.0.0.0
     , text >=1.2.2 && <1.3
-    , utility-ht >=0.0.11 && <0.1.0
   if flag(enable_flaky_tests)
     cpp-options: -DFLAKY
+  default-language: Haskell2010
+
+benchmark simple
+  type: exitcode-stdio-1.0
+  main-is: bench-simple.hs
+  other-modules:
+      Native
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -fno-warn-unused-do-bind -threaded
+  build-depends:
+      base >=4.11 && <5
+    , criterion >=1.5.9.0 && <1.6
+    , pandoc >=2.10 && <2.15
+    , pandoc-crossref
+    , pandoc-types >=1.21 && <1.23
+    , text >=1.2.2 && <1.3
   default-language: Haskell2010
diff --git a/test/bench-simple.hs b/test/bench-simple.hs
new file mode 100644
--- /dev/null
+++ b/test/bench-simple.hs
@@ -0,0 +1,15 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+import Criterion.Main
+import Text.Pandoc.CrossRef
+import Text.Pandoc
+import Native
+
+main :: IO ()
+main = defaultMain [
+    bench "demo" (nf go demo)
+  , bench "demoChapters" (nf go demochapters)
+  ]
+  where
+    go = runCrossRef nullMeta Nothing crossRefBlocks
+  -- map (\l -> bench ("concat dlist " <> show l) . nf (uncurry append) $ dlists l) lengths
diff --git a/test/m2m/equationNumberLaTeX/expect.md b/test/m2m/equationNumberLaTeX/expect.md
new file mode 100644
--- /dev/null
+++ b/test/m2m/equationNumberLaTeX/expect.md
@@ -0,0 +1,44 @@
+This is a test file with some referenced equations, line $$ this $$
+
+Some equations might be inside of text, $$ for example $$ this one.
+
+Some equations might be on start of paragraphs:
+
+$$ start $$ of paragraph.
+
+Other might be on separate paragraphs of their own:
+
+$$ separate $$
+
+Some of those can be labelled:
+
+This is a test file with some referenced equations, line
+[$$ this \tag{1}$$]{#eq:0}
+
+Some equations might be inside of text,
+[$$ for example \tag{2}$$]{#eq:1} this one.
+
+Some equations might be on start of paragraphs:
+
+[$$ start \tag{3}$$]{#eq:2} of paragraph.
+
+Other might be on separate paragraphs of their own:
+
+[$$ separate \tag{4}$$]{#eq:3}
+
+Then they can be referenced:
+
+Individually eq. 1, eq. 2, eq. 3, eq. 4
+
+Or in groups eqns. 1, 2, 4
+
+Groups will be compacted eqns. 1-4
+
+Unknown references will print labels eqns. **¿eq:none?**, 1, 3, 4
+
+Reference prefix will override default prefix Equation 1, eqns. 3, 4
+
+References with `-` prepended won't have prefix at all: 1, 2, eqns. 3, 4
+
+References with suffix will have suffix printed after index
+(configurable): eqns. 1, 2 suffix, 3
diff --git a/test/m2m/equationNumberLaTeX/expect.tex b/test/m2m/equationNumberLaTeX/expect.tex
new file mode 100644
--- /dev/null
+++ b/test/m2m/equationNumberLaTeX/expect.tex
@@ -0,0 +1,51 @@
+This is a test file with some referenced equations, line \[ this \]
+
+Some equations might be inside of text, \[ for example \] this one.
+
+Some equations might be on start of paragraphs:
+
+\[ start \] of paragraph.
+
+Other might be on separate paragraphs of their own:
+
+\[ separate \]
+
+Some of those can be labelled:
+
+This is a test file with some referenced equations, line
+\begin{equation}\protect\hypertarget{eq:0}{}{ this }\label{eq:0}\end{equation}
+
+Some equations might be inside of text,
+\begin{equation}\protect\hypertarget{eq:1}{}{ for example }\label{eq:1}\end{equation}
+this one.
+
+Some equations might be on start of paragraphs:
+
+\begin{equation}\protect\hypertarget{eq:2}{}{ start }\label{eq:2}\end{equation}
+of paragraph.
+
+Other might be on separate paragraphs of their own:
+
+\begin{equation}\protect\hypertarget{eq:3}{}{ separate }\label{eq:3}\end{equation}
+
+Then they can be referenced:
+
+Individually eq.~\ref{eq:0}, eq.~\ref{eq:1}, eq.~\ref{eq:2},
+eq.~\ref{eq:3}
+
+Or in groups eqns.~\ref{eq:0}, \ref{eq:1}, \ref{eq:3}
+
+Groups will be compacted
+eqns.~\ref{eq:0}, \ref{eq:1}, \ref{eq:3}, \ref{eq:2}
+
+Unknown references will print labels
+eqns.~\ref{eq:0}, \ref{eq:none}, \ref{eq:3}, \ref{eq:2}
+
+Reference prefix will override default prefix Equation \ref{eq:0},
+eqns.~\ref{eq:3}, \ref{eq:2}
+
+References with \texttt{-} prepended won't have prefix at all:
+\ref{eq:0}, \ref{eq:1}, eqns.~\ref{eq:2}, \ref{eq:3}
+
+References with suffix will have suffix printed after index
+(configurable): eqns.~\ref{eq:0}, \ref{eq:1}, \ref{eq:2}
diff --git a/test/m2m/equationNumberLaTeX/input.md b/test/m2m/equationNumberLaTeX/input.md
new file mode 100644
--- /dev/null
+++ b/test/m2m/equationNumberLaTeX/input.md
@@ -0,0 +1,47 @@
+---
+equationNumberTeX: \\tag
+---
+
+This is a test file with some referenced equations, line $$ this $$
+
+Some equations might be inside of text, $$ for example $$ this one.
+
+Some equations might be on start of paragraphs:
+
+$$ start $$ of paragraph.
+
+Other might be on separate paragraphs of their own:
+
+$$ separate $$
+
+Some of those can be labelled:
+
+This is a test file with some referenced equations, line $$ this $${#eq:0}
+
+Some equations might be inside of text, $$ for example $${#eq:1} this one.
+
+Some equations might be on start of paragraphs:
+
+$$ start $${#eq:2} of paragraph.
+
+Other might be on separate paragraphs of their own:
+
+$$ separate $${#eq:3}
+
+Then they can be referenced:
+
+Individually @eq:0, @eq:1, @eq:2, @eq:3
+
+Or in groups [@eq:0; @eq:1; @eq:3]
+
+Groups will be compacted [@eq:0; @eq:1; @eq:3; @eq:2]
+
+Unknown references will print labels [@eq:0; @eq:none; @eq:3; @eq:2]
+
+Reference prefix will override default prefix [Equation @eq:0; @eq:3; @eq:2]
+
+References with `-` prepended won't have prefix at all:
+[-@eq:0; -@eq:1; @eq:2; @eq:3]
+
+References with suffix will have suffix printed after index (configurable):
+[@eq:0; @eq:1 suffix; @eq:2]
diff --git a/test/m2m/listing-captions-ids/expect.md b/test/m2m/listing-captions-ids/expect.md
--- a/test/m2m/listing-captions-ids/expect.md
+++ b/test/m2m/listing-captions-ids/expect.md
@@ -3,7 +3,7 @@
 ::: {#lst:code1 .listing .haskell}
 Listing 1: Listing caption 1
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -12,7 +12,7 @@
 ::: {#lst:code2 .listing .haskell}
 Listing 2: Listing caption 2
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -21,7 +21,7 @@
 ::: {#lst:code3 .listing .haskell}
 Listing 3: Listing caption 3
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -30,20 +30,20 @@
 ::: {#lst:code4 .listing .haskell}
 Listing 4: Listing caption 4
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
 :::
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
 
 : Listing caption 5 (invalid)
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -55,7 +55,7 @@
 ::: {#lst:code11 .listing .haskell}
 Listing 5: Listing caption 11
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -64,7 +64,7 @@
 ::: {#lst:code12 .listing .haskell}
 Listing 6: Listing caption 12
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -73,7 +73,7 @@
 ::: {#lst:code13 .listing .haskell}
 Listing 7: Listing caption 13
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -82,7 +82,7 @@
 ::: {#lst:code14 .listing .haskell}
 Listing 8: Listing caption 14
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
@@ -92,14 +92,14 @@
 
 : Listing caption 15 (invalid)
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
 
 : Listing caption 16 (invalid)
 
-``` {.haskell}
+``` haskell
 main :: IO ()
 main = putStrLn "Hello World!"
 ```
diff --git a/test/m2m/listings-code-block-caption-278/expect.md b/test/m2m/listings-code-block-caption-278/expect.md
--- a/test/m2m/listings-code-block-caption-278/expect.md
+++ b/test/m2m/listings-code-block-caption-278/expect.md
@@ -1,4 +1,4 @@
-This is \#278 regression test
+This is #278 regression test
 
 ::: {#lst:some_listing .listing}
 Listing 1: some_listing
diff --git a/test/m2m/titlesInRefs/expect.md b/test/m2m/titlesInRefs/expect.md
new file mode 100644
--- /dev/null
+++ b/test/m2m/titlesInRefs/expect.md
@@ -0,0 +1,7 @@
+# Section {#sec:section}
+
+![Figure 1: A Figure](figure.png){#fig:figure}
+
+sec. 1 (Section)
+
+fig. 1
diff --git a/test/m2m/titlesInRefs/expect.tex b/test/m2m/titlesInRefs/expect.tex
new file mode 100644
--- /dev/null
+++ b/test/m2m/titlesInRefs/expect.tex
@@ -0,0 +1,14 @@
+\hypertarget{sec:section}{%
+\section{Section}\label{sec:section}}
+
+\begin{figure}
+\hypertarget{fig:figure}{%
+\centering
+\includegraphics{figure.png}
+\caption{A Figure}\label{fig:figure}
+}
+\end{figure}
+
+sec.~\ref{sec:section}
+
+fig.~\ref{fig:figure}
diff --git a/test/m2m/titlesInRefs/input.md b/test/m2m/titlesInRefs/input.md
new file mode 100644
--- /dev/null
+++ b/test/m2m/titlesInRefs/input.md
@@ -0,0 +1,13 @@
+---
+refIndexTemplate:
+  sec: $$i$$$$suf$$ ($$t$$)
+  default: $$i$$$$suf$$
+---
+
+# Section {#sec:section}
+
+![A Figure](figure.png){#fig:figure}
+
+[@sec:section]
+
+[@fig:figure]
