packages feed

pandoc-crossref 0.1.5.5 → 0.1.5.6

raw patch · 9 files changed

+525/−246 lines, 9 files

Files

+ demo.md view
@@ -0,0 +1,115 @@+---+cref: False+codeBlockCaptions: True+figureTitle: "Figure \\#"+lofTitle: "## List of Figures"+lotTitle: "## List of Tables"+tableTemplate: "*$$tableTitle$$ $$i$$*$$titleDelim$$ $$t$$"+autoSectionLabels: True+---++This is a demo file for pandoc-crossref. With this filter, you can cross-reference figures (see [@fig:figure1;@fig:figure2;@fig:figure3]), display equations (see @eq:eqn1), tables (see [@tbl:table1]) and sections ([@sec:sec1; @sec:sec2; @sec:caption-attr; @sec:table-capts; @sec:wrapping-div])++For immediate example, see @fig:figure0++![A figure](img1.jpg){#fig:figure0}++There is also support for code blocks, for example, [@lst:captionAttr; @lst:tableCaption; @lst:wrappingDiv]++It's possible to capitalize reference prefixes, like this: [@Fig:figure1].++In case of multiple references, capitalization is determined by first reference. [@Fig:figure1; @fig:figure2] is capitalized, while [@fig:figure2; @Fig:figure1] is not.++It is also possible to mix different references, like [@fig:figure1; @tbl:table1; @lst:captionAttr; @lst:tableCaption; @fig:figure2; @fig:figure3], which will be grouped in order they are specified. You can even intermix this with regular citations, although it's not recommended: [@fig:figure1; @tbl:table1; @unprocessedCitation]++You can also have custom chapter reference labels, like @sec:custlabs++# Chapter 1. Figures {#sec:sec1}++![First figure](img1.jpg){#fig:figure1}++![Second figure](img2.jpg){#fig:figure2}++![Third figure](img3.jpg){#fig:figure3}++![Unlabelled image](img1.jpg)++# Chapter 2. Equations {#sec:sec2}++$$ P_i(x) = \sum_i a_i x^i $$ {#eq:eqn1}++# Chapter 3. Tables++| First Header | Second Header |+|:-------------|:--------------|+| Content Cell | Content Cell  |+| Content Cell | Content Cell  |++: Table example {#tbl:table1}++Table without caption:++| First Header | Second Header |+|:-------------|:--------------|+| Content Cell | Content Cell  |+| Content Cell | Content Cell  |++# Chapter 4. Code blocks++There are a couple options for code block labels. Those work only if code block id starts with `lst:`, e.g. `{#lst:label}`++## `caption` attribute {#sec:caption-attr}++`caption` attribute will be treated as code block caption. If code block has both id and `caption` attributes, it will be treated as numbered code block.++```{#lst:captionAttr .haskell caption="Listing caption"}+main :: IO ()+main = putStrLn "Hello World!"+```++\pagebreak++## Table-style captions  {#sec:table-capts}++Enabled with `codeBlockCaptions` metadata option. If code block is immediately+adjacent to paragraph, starting with `Listing: ` or `: `, said paragraph will be+treated as code block caption.++Listing: Listing caption++```{#lst:tableCaption .haskell}+main :: IO ()+main = putStrLn "Hello World!"+```++## Wrapping div++Wrapping code block without label in a div with id `lst:...` and class, starting with `listing`, and adding paragraph before code block, but inside div, will treat said paragraph as code block caption.++<div id="lst:wrappingDiv" class="listing">+Listing caption+```{.haskell}+main :: IO ()+main = putStrLn "Hello World!"+```+</div>++# Unnumbered chapter. {-}++This chapter doesn't change chapter prefix of referenced elements, instead keeping number of previous chapter, e.g.++$$ S(x) = \int_{x_1}^{x_2} a x+b \  \mathrm{d}x $$ {#eq:eqn2}++# Chapter 5. Reference lists++It's also possible to show lists of figures and tables, like this:++\listoffigures++\listoftables++\listoflistings++# Appendix A. Custom labels {label=AppA}++## This section will have custom label {#sec:custlabs label=CustLab}
pandoc-crossref.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                pandoc-crossref-version:             0.1.5.5+version:             0.1.5.6 synopsis:            Pandoc filter for cross-references description:         pandoc-crossref is a pandoc filter for numbering figures, equations, tables and cross-references to them. license:             GPL-2@@ -15,6 +15,7 @@ extra-doc-files:     README.md                      BSD3.md cabal-version:       >=1.10+data-files:          demo.md  source-repository head   type: git@@ -23,7 +24,7 @@ source-repository this   type: git   location: https://github.com/lierdakil/pandoc-crossref-  tag: v0.1.5.5+  tag: v0.1.5.6  library   exposed-modules:     Text.Pandoc.CrossRef@@ -43,6 +44,7 @@                      , Text.Pandoc.CrossRef.Util.ModifyMeta                      , Text.Pandoc.CrossRef.Util.Settings.Gen                      , Text.Pandoc.CrossRef.Util.Settings.Template+                     , Text.Pandoc.CrossRef.Util.Gap   build-depends:       base >=4.2 && <5                      , pandoc >= 1.13 && <1.16                      , mtl >= 1.1 && <2.3@@ -54,6 +56,9 @@   hs-source-dirs:      src   Ghc-Options:         -Wall   default-language:    Haskell2010+  other-extensions:    RankNTypes+                     , CPP+                     , FlexibleContexts  executable pandoc-crossref   main-is:             pandoc-crossref.hs@@ -73,7 +78,7 @@ Test-Suite test-pandoc-crossref   Type:           exitcode-stdio-1.0   Main-Is:        test-pandoc-crossref.hs-  hs-source-dirs: ., src+  hs-source-dirs: test, src   Build-Depends:   base >=4.2 && <5                  , pandoc >= 1.13 && <1.16                  , mtl >= 1.1 && <2.3@@ -85,5 +90,6 @@                  , hspec                  , process >=1 && <1.3                  , pandoc-crossref+  other-modules: Native   Ghc-Options:  -rtsopts -Wall -fno-warn-unused-do-bind -threaded   Default-Language: Haskell2010
src/Text/Pandoc/CrossRef.hs view
@@ -46,10 +46,12 @@ >       <> chaptersDepth (MetaString "2")  -}+{-# LANGUAGE RankNTypes #-}  module Text.Pandoc.CrossRef (     crossRefBlocks   , crossRefMeta+  , defaultCrossRefAction   , runCrossRef   , runCrossRefIO   , module SG@@ -105,10 +107,19 @@   dtv <- R.asks creSettings   return $ modifyMeta opts dtv +{- | Combines 'crossRefMeta' and 'crossRefBlocks'++Works in 'CrossRefM' monad. -}+defaultCrossRefAction :: Pandoc -> CrossRefM Pandoc+defaultCrossRefAction (Pandoc _ bs) = do+  meta' <- crossRefMeta+  bs' <- crossRefBlocks bs+  return $ Pandoc meta' bs'+ {- | Run an action in 'CrossRefM' monad with argument, and return pure result.  This is primary function to work with 'CrossRefM' -}-runCrossRef :: (Walkable a b) => Meta -> Maybe Format -> (a -> CrossRefM b) -> a -> b+runCrossRef :: forall a b. Meta -> Maybe Format -> (a -> CrossRefM b) -> a -> b runCrossRef meta fmt action arg = R.runReader (action arg) env   where     settings = meta <> defaultMeta@@ -121,7 +132,7 @@  This function will attempt to read pandoc-crossref settings from settings file specified by crossrefYaml metadata field. -}-runCrossRefIO :: (Walkable a b) => Meta -> Maybe Format -> (a -> CrossRefM b) -> a -> IO b+runCrossRefIO :: forall a b. Meta -> Maybe Format -> (a -> CrossRefM b) -> a -> IO b runCrossRefIO meta fmt action arg = do   settings <- getSettings meta   let
+ src/Text/Pandoc/CrossRef/Util/Gap.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE CPP #-}++module Text.Pandoc.CrossRef.Util.Gap where++import qualified Text.Pandoc as P++readMarkdown :: P.ReaderOptions -> String -> P.Pandoc+#if MIN_VERSION_pandoc(1,14,0)+readMarkdown = (either (error . show) id .) . P.readMarkdown+#else+readMarkdown = P.readMarkdown+#endif
src/Text/Pandoc/CrossRef/Util/Meta.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE CPP #-} module Text.Pandoc.CrossRef.Util.Meta where -import Text.Pandoc (readMarkdown)+import Text.Pandoc.CrossRef.Util.Gap import Text.Pandoc.Shared (stringify) import Text.Pandoc.Definition import Data.Maybe (fromMaybe)@@ -24,12 +24,7 @@  toInlines :: MetaValue -> Maybe [Inline] toInlines (MetaString s) =-#if MIN_VERSION_pandoc(1,14,0)-  return $ getInlines $-    either (error . show) id $ readMarkdown def s-#else   return $ getInlines $ readMarkdown def s-#endif   where getInlines (Pandoc _ bs) = concatMap getInline bs         getInline (Plain ils) = ils         getInline (Para ils) = ils@@ -45,12 +40,7 @@ toBlocks (MetaBlocks bs) = return bs toBlocks (MetaInlines ils) = return [Plain ils] toBlocks (MetaString s) =-#if MIN_VERSION_pandoc(1,14,0)-  return $ getBlocks $-    either (error . show) id $ readMarkdown def s-#else   return $ getBlocks $ readMarkdown def s-#endif   where getBlocks (Pandoc _ bs) = bs toBlocks _ = Nothing 
src/Text/Pandoc/CrossRef/Util/Settings.hs view
@@ -1,7 +1,8 @@ {-# LANGUAGE CPP #-} module Text.Pandoc.CrossRef.Util.Settings (getSettings, defaultMeta) where -import Text.Pandoc+import Text.Pandoc hiding (readMarkdown)+import Text.Pandoc.CrossRef.Util.Gap import Text.Pandoc.Builder import Control.Exception (handle,IOException) @@ -13,11 +14,7 @@   let handler :: IOException -> IO String       handler _ = return []   yaml <- handle handler $ readFile (getMetaString "crossrefYaml" (meta <> defaultMeta))-#if MIN_VERSION_pandoc(1,14,0)-  let Pandoc dtve _ = either (error . show) id $ readMarkdown def ("---\n" ++ yaml ++ "\n---")-#else   let Pandoc dtve _ = readMarkdown def ("---\n" ++ yaml ++ "\n---")-#endif   return $ meta <> dtve <> defaultMeta  defaultMeta :: Meta
− test-pandoc-crossref.hs
@@ -1,225 +0,0 @@-import Test.Hspec-import Text.Pandoc.Definition-import Text.Pandoc.Builder-import Text.Pandoc.Walk-import Text.Pandoc.Generic-import Control.Monad.State-import Data.List-import Control.Arrow-import Data.Monoid -- needed for ghc<7.10-import qualified Data.Map as M--import Text.Pandoc.CrossRef.Util.Options-import Text.Pandoc.CrossRef.Util.Util-import Text.Pandoc.CrossRef.References.Types-import Text.Pandoc.CrossRef.Util.Settings-import Text.Pandoc.CrossRef.Util.Accessor-import Text.Pandoc.CrossRef.References.Accessors-import qualified Text.Pandoc.CrossRef.References.Blocks as References.Blocks-import qualified Text.Pandoc.CrossRef.References.Refs as References.Refs-import qualified Text.Pandoc.CrossRef.References.List as References.List-import qualified Text.Pandoc.CrossRef.Util.Template as Util.Template-import qualified Text.Pandoc.CrossRef.Util.CodeBlockCaptions as Util.CodeBlockCaptions--main :: IO ()-main = hspec $ do-    describe "References.Blocks.replaceBlocks" $ do-      it "Labels images" $-        testBlocks (figure "test.jpg" [] "Test figure" "figure")-        (figure "test.jpg" "fig:" "Figure 1: Test figure" [],-          def{imgRefs=M.fromList $ refRec' "fig:figure" 1 "Test figure"})-      it "Labels equations" $-        testBlocks (equation "a^2+b^2=c^2" "equation")-        (equation "a^2+b^2=c^2\\qquad(1)" [],-          def{eqnRefs=M.fromList $ refRec'' "eq:equation" 1})-      it "Labels tables" $-        testBlocks (table' "Test table" "table")-        (table' "Table 1: Test table" [],-          def{tblRefs=M.fromList $ refRec' "tbl:table" 1 "Test table"})-      it "Labels code blocks" $-        testBlocks (codeBlock' "Test code block" "codeblock")-        (codeBlockDiv "Listing 1: Test code block" "codeblock",-          def{lstRefs=M.fromList $ refRec' "lst:codeblock" 1 "Test code block"})-      it "Labels code block divs" $-        testBlocks (codeBlockDiv "Test code block" "codeblock")-        (codeBlockDiv "Listing 1: Test code block" "codeblock",-          def{lstRefs=M.fromList $ refRec' "lst:codeblock" 1 "Test code block"})-      it "Labels sections divs" $-        testBlocks (section "Section Header" 1 "section")-        (section "Section Header" 1 "section",-          def{secRefs=M.fromList $ refRec' "sec:section" 1 "Section Header",-              curChap=[(1,Nothing)]})--    describe "References.Refs.replaceRefs" $ do-      it "References one image" $-        testRefs' "fig:" [1] [4] imgRefs' "fig.\160\&4"-      it "References multiple images" $-        testRefs' "fig:" [1..3] [4..6] imgRefs' "figs.\160\&4-6"-      it "References one equation" $-        testRefs' "eq:" [1] [4] eqnRefs' "eq.\160\&4"-      it "References multiple equations" $-        testRefs' "eq:" [1..3] [4..6] eqnRefs' "eqns.\160\&4-6"-      it "References one table" $-        testRefs' "tbl:" [1] [4] tblRefs' "tbl.\160\&4"-      it "References multiple tables" $-        testRefs' "tbl:" [1..3] [4..6] tblRefs' "tbls.\160\&4-6"-      it "References one listing" $-        testRefs' "lst:" [1] [4] lstRefs' "lst.\160\&4"-      it "References multiple listings" $-        testRefs' "lst:" [1..3] [4..6] lstRefs' "lsts.\160\&4-6"-      it "References one section" $-        testRefs' "sec:" [1] [4] secRefs' "sec.\160\&4"-      it "References multiple sections" $-        testRefs' "sec:" [1..3] [4..6] secRefs' "secs.\160\&4-6"-      it "Separates references to different chapter items by a comma" $-        testRefs'' "lst:" [1..6] (zip [1,1..] [4..6] ++ zip [2,2..] [7..9]) lstRefs' "lsts.\160\&1.4-1.6, 2.7-2.9"--    describe "References.Refs.replaceRefs capitalization" $ do-      it "References one image" $-        testRefs' "Fig:" [1] [4] imgRefs' "Fig.\160\&4"-      it "References multiple images" $-        testRefs' "Fig:" [1..3] [4..6] imgRefs' "Figs.\160\&4-6"-      it "References one equation" $-        testRefs' "Eq:" [1] [4] eqnRefs' "Eq.\160\&4"-      it "References multiple equations" $-        testRefs' "Eq:" [1..3] [4..6] eqnRefs' "Eqns.\160\&4-6"-      it "References one table" $-        testRefs' "Tbl:" [1] [4] tblRefs' "Tbl.\160\&4"-      it "References multiple tables" $-        testRefs' "Tbl:" [1..3] [4..6] tblRefs' "Tbls.\160\&4-6"-      it "References one listing" $-        testRefs' "Lst:" [1] [4] lstRefs' "Lst.\160\&4"-      it "References multiple listings" $-        testRefs' "Lst:" [1..3] [4..6] lstRefs' "Lsts.\160\&4-6"-      it "References one listing" $-        testRefs' "Sec:" [1] [4] secRefs' "Sec.\160\&4"-      it "References multiple listings" $-        testRefs' "Sec:" [1..3] [4..6] secRefs' "Secs.\160\&4-6"--    describe "References.List.listOf" $ do-      it "Generates list of tables" $-        testList (para $ rawInline "tex" "\\listoftables")-                 def{tblRefs=M.fromList $ refRec' "tbl:1" 4 "4" <> refRec' "tbl:2" 5 "5" <> refRec' "tbl:3" 6 "6"}-                 (header 1 (text "List of Tables") <> orderedList ((plain . str . show) `map` [4..6 :: Int]))-      it "Generates list of figures" $-        testList (para $ rawInline "tex" "\\listoffigures")-                 def{imgRefs=M.fromList $ refRec' "fig:1" 4 "4" <> refRec' "fig:2" 5 "5" <> refRec' "fig:3" 6 "6"}-                 (header 1 (text "List of Figures") <> orderedList ((plain . str . show) `map` [4..6 :: Int]))--    describe "Util.CodeBlockCaptions" $-      it "Transforms table-style codeBlock captions to codeblock divs" $ do-        let t x = testCBCaptions x (codeBlockDiv "Code Block" "cb")-        t (codeBlockForTable "cb" <> paraText ": Code Block")-        t (codeBlockForTable "cb" <> paraText "Listing: Code Block")-        t (paraText ": Code Block" <> codeBlockForTable "cb")-        t (paraText "Listing: Code Block" <> codeBlockForTable "cb")--    describe "Util.Template" $-      it "Applies templates" $-        let template=Util.Template.makeTemplate defaultMeta (toList $ displayMath "figureTitle" <> displayMath "i" <> displayMath "t")-        in Util.Template.applyTemplate [Str "1"] [Str "title"] template `shouldBe`-           toList (str "Figure" <> str "1" <> str "title")--    describe "Citation groups shouldn't be separated (#22 regression test)" $ do-      it "Should not separate citation groups" $ do-        let cits = para $ citeGen "" [1..3]-        testRefs cits def cits--      it "Should not separate citation groups with unknown prefix" $ do-        let cits = para $ citeGen "unk:" [1..3]-        testRefs cits def cits--      it "Should not separate citation groups with different unknown prefixes" $ do-        let cits = para $ cite (mconcat $ map (cit . uncurry (++) . second show) l) $ text $-              "[" ++ intercalate "; " (map (("@"++) . uncurry (++) . second show) l) ++ "]"-            l = zip ["unk1:", "unk2:"] [1,2::Int]-        testRefs cits def cits---citeGen :: String -> [Int] -> Inlines-citeGen p l = cite (mconcat $ map (cit . (p++) . show) l) $ text $-  "[" ++ intercalate "; " (map (("@"++) . (p++) . show) l) ++ "]"--refGen :: String -> [Int] -> [Int] -> M.Map String RefRec-refGen p l1 l2 = M.fromList $ mconcat $ zipWith refRec'' (((uncapitalizeFirst p++) . show) `map` l1) l2--refGen' :: String -> [Int] -> [(Int, Int)] -> M.Map String RefRec-refGen' p l1 l2 = M.fromList $ mconcat $ zipWith refRec''' (((uncapitalizeFirst p++) . show) `map` l1) l2--refRec' :: String -> Int -> String -> [(String, RefRec)]-refRec' ref i tit = [(ref, RefRec{refIndex=[(i,Nothing)],refTitle=toList $ text tit})]--refRec'' :: String -> Int -> [(String, RefRec)]-refRec'' ref i = refRec' ref i []--refRec''' :: String -> (Int, Int) -> [(String, RefRec)]-refRec''' ref (c,i) = [(ref, RefRec{refIndex=[(c,Nothing), (i,Nothing)],refTitle=toList $ text []})]--testRefs' :: String -> [Int] -> [Int] -> Accessor References (M.Map String RefRec) -> String -> Expectation-testRefs' p l1 l2 prop res = testRefs (para $ citeGen p l1) (setProp prop (refGen p l1 l2) def) (para $ text res)--testRefs'' :: String -> [Int] -> [(Int, Int)] -> Accessor References (M.Map String RefRec) -> String -> Expectation-testRefs'' p l1 l2 prop res = testRefs (para $ citeGen p l1) (setProp prop (refGen' p l1 l2) def) (para $ text res)--testBlocks :: Blocks -> (Blocks, References) -> Expectation-testBlocks arg res = runState (walkM (f defaultOptions) arg) def `shouldBe` res-  where f = (. References.Blocks.divBlocks) . References.Blocks.replaceBlocks--testRefs :: Blocks -> References -> Blocks -> Expectation-testRefs bs st res = runState (bottomUpM (References.Refs.replaceRefs defaultOptions) (toList bs)) st `shouldBe` (toList res,st)--testCBCaptions :: Blocks -> Blocks -> Expectation-testCBCaptions bs res = runState (bottomUpM (Util.CodeBlockCaptions.codeBlockCaptions defaultOptions{cbCaptions=True}) (toList bs)) def `shouldBe` (toList res,def)--testList :: Blocks -> References -> Blocks -> Expectation-testList bs st res = runState (bottomUpM (References.List.listOf defaultOptions) (toList bs)) st `shouldBe` (toList res,st)--figure :: String -> String -> String -> String -> Blocks-figure src title alt ref = para (image src title (text alt) <> ref' "fig" ref)--section :: String -> Int -> String -> Blocks-section text' level label = headerWith ("sec:" ++ label,[],[]) level (text text')--equation :: String -> String -> Blocks-equation eq ref = para (displayMath eq <> ref' "eq" ref)--table' :: String -> String -> Blocks-table' title ref = table (text title <> ref' "tbl" ref) []-   [para $ str "H1", para $ str "H2"]-  [[para $ str "C1", para $ str "C2"]]--codeBlock' :: String -> String -> Blocks-codeBlock' title ref = codeBlockWith-  ("lst:"++ref,["haskell"],[("caption",title)]) "main :: IO ()"--codeBlockForTable :: String -> Blocks-codeBlockForTable ref = codeBlockWith-     ("lst:"++ref,["haskell"],[]) "main :: IO ()"--paraText :: String -> Blocks-paraText s = para $ text s--codeBlockDiv :: String -> String -> Blocks-codeBlockDiv title ref = divWith ("lst:"++ref, ["listing","haskell"],[]) $-  para (text title) <>-  codeBlockWith-    ("",["haskell"],[]) "main :: IO ()"--ref' :: String -> String -> Inlines-ref' p n | null n  = mempty-         | otherwise = space <> str ("{#"++p++":"++n++"}")--defaultOptions :: Options-defaultOptions = getOptions defaultMeta Nothing--defCit :: Citation-defCit = Citation{citationId = ""-                 ,citationPrefix = []-                 ,citationSuffix = []-                 ,citationHash = 0-                 ,citationNoteNum = 0-                 ,citationMode = NormalCitation-                 }--cit :: String -> [Citation]-cit r = [defCit{citationId=r}]
+ test/Native.hs view
@@ -0,0 +1,130 @@+module Native where++import Text.Pandoc.Definition++demo :: [Block]+demo =+  [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "demo",Space,Str "file",Space,Str "for",Space,Str "pandoc-crossref.",Space,Str "With",Space,Str "this",Space,Str "filter,",Space,Str "you",Space,Str "can",Space,Str "cross-reference",Space,Str "figures",Space,Str "(see",Space,Str "figs.\160\&2-4",Str "),",Space,Str "display",Space,Str "equations",Space,Str "(see",Space,Str "eq.\160\&1",Str "),",Space,Str "tables",Space,Str "(see",Space,Str "tbl.\160\&1",Str ")",Space,Str "and",Space,Str "sections",Space,Str "(",Str "secs.\160\&1,",Space,Str "2,",Space,Str "4.1-4.3",Str ")"]+  ,Para [Str "For",Space,Str "immediate",Space,Str "example,",Space,Str "see",Space,Str "fig.\160\&1"]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "1:",Space,Str "A",Space,Str "figure"] ("img1.jpg","fig:")]+  ,Para [Str "There",Space,Str "is",Space,Str "also",Space,Str "support",Space,Str "for",Space,Str "code",Space,Str "blocks,",Space,Str "for",Space,Str "example,",Space,Str "lsts.\160\&1-3"]+  ,Para [Str "It's",Space,Str "possible",Space,Str "to",Space,Str "capitalize",Space,Str "reference",Space,Str "prefixes,",Space,Str "like",Space,Str "this:",Space,Str "Fig.\160\&2",Str "."]+  ,Para [Str "In",Space,Str "case",Space,Str "of",Space,Str "multiple",Space,Str "references,",Space,Str "capitalization",Space,Str "is",Space,Str "determined",Space,Str "by",Space,Str "first",Space,Str "reference.",Space,Str "Figs.\160\&2,",Space,Str "3",Space,Str "is",Space,Str "capitalized,",Space,Str "while",Space,Str "figs.\160\&2,",Space,Str "3",Space,Str "is",Space,Str "not."]+  ,Para [Str "It",Space,Str "is",Space,Str "also",Space,Str "possible",Space,Str "to",Space,Str "mix",Space,Str "different",Space,Str "references,",Space,Str "like",Space,Str "fig.\160\&2",Str ",",Space,Str "tbl.\160\&1",Str ",",Space,Str "lsts.\160\&1,",Space,Str "2",Str ",",Space,Str "figs.\160\&3,",Space,Str "4",Str ",",Space,Str "which",Space,Str "will",Space,Str "be",Space,Str "grouped",Space,Str "in",Space,Str "order",Space,Str "they",Space,Str "are",Space,Str "specified.",Space,Str "You",Space,Str "can",Space,Str "even",Space,Str "intermix",Space,Str "this",Space,Str "with",Space,Str "regular",Space,Str "citations,",Space,Str "although",Space,Str "it's",Space,Str "not",Space,Str "recommended:",Space,Str "fig.\160\&2",Str ",",Space,Str "tbl.\160\&1",Str ",",Space,Cite [Citation {citationId = "unprocessedCitation", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@unprocessedCitation]"]]+  ,Para [Str "You",Space,Str "can",Space,Str "also",Space,Str "have",Space,Str "custom",Space,Str "chapter",Space,Str "reference",Space,Str "labels,",Space,Str "like",Space,Str "sec.\160AppA.CustLab"]+  ,Header 1 ("sec:sec1",[],[]) [Str "Chapter",Space,Str "1.",Space,Str "Figures"]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "2:",Space,Str "First",Space,Str "figure"] ("img1.jpg","fig:")]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "3:",Space,Str "Second",Space,Str "figure"] ("img2.jpg","fig:")]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "4:",Space,Str "Third",Space,Str "figure"] ("img3.jpg","fig:")]+  ,Para [Image [Str "Unlabelled",Space,Str "image"] ("img1.jpg","fig:")]+  ,Header 1 ("sec:sec2",[],[]) [Str "Chapter",Space,Str "2.",Space,Str "Equations"]+  ,Para [Math DisplayMath " P_i(x) = \\sum_i a_i x^i \\qquad(1)"]+  ,Header 1 ("sec:chapter-3.-tables",[],[]) [Str "Chapter",Space,Str "3.",Space,Str "Tables"]+  ,Table [Emph [Str "Table",Space,Str "1"],Str ":",Space,Str "Table",Space,Str "example"] [AlignLeft,AlignLeft] [0.0,0.0]+   [[Plain [Str "First",Space,Str "Header"]]+   ,[Plain [Str "Second",Space,Str "Header"]]]+   [[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]+   ,[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]]+  ,Para [Str "Table",Space,Str "without",Space,Str "caption:"]+  ,Table [] [AlignLeft,AlignLeft] [0.0,0.0]+   [[Plain [Str "First",Space,Str "Header"]]+   ,[Plain [Str "Second",Space,Str "Header"]]]+   [[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]+   ,[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]]+  ,Header 1 ("sec:chapter-4.-code-blocks",[],[]) [Str "Chapter",Space,Str "4.",Space,Str "Code",Space,Str "blocks"]+  ,Para [Str "There",Space,Str "are",Space,Str "a",Space,Str "couple",Space,Str "options",Space,Str "for",Space,Str "code",Space,Str "block",Space,Str "labels.",Space,Str "Those",Space,Str "work",Space,Str "only",Space,Str "if",Space,Str "code",Space,Str "block",Space,Str "id",Space,Str "starts",Space,Str "with",Space,Code ("",[],[]) "lst:",Str ",",Space,Str "e.g.",Space,Code ("",[],[]) "{#lst:label}"]+  ,Header 2 ("sec:caption-attr",[],[]) [Code ("",[],[]) "caption",Space,Str "attribute"]+  ,Para [Code ("",[],[]) "caption",Space,Str "attribute",Space,Str "will",Space,Str "be",Space,Str "treated",Space,Str "as",Space,Str "code",Space,Str "block",Space,Str "caption.",Space,Str "If",Space,Str "code",Space,Str "block",Space,Str "has",Space,Str "both",Space,Str "id",Space,Str "and",Space,Code ("",[],[]) "caption",Space,Str "attributes,",Space,Str "it",Space,Str "will",Space,Str "be",Space,Str "treated",Space,Str "as",Space,Str "numbered",Space,Str "code",Space,Str "block."]+  ,Div ("lst:captionAttr",["listing","haskell"],[]) [Para [Str "Listing",Space,Str "1:",Space,Str "Listing",Space,Str "caption"],CodeBlock ("",["haskell"],[]) "main :: IO ()\nmain = putStrLn \"Hello World!\""]+  ,Para [RawInline (Format "tex") "\\pagebreak"]+  ,Header 2 ("sec:table-capts",[],[]) [Str "Table-style",Space,Str "captions"]+  ,Para [Str "Enabled",Space,Str "with",Space,Code ("",[],[]) "codeBlockCaptions",Space,Str "metadata",Space,Str "option.",Space,Str "If",Space,Str "code",Space,Str "block",Space,Str "is",Space,Str "immediately",Space,Str "adjacent",Space,Str "to",Space,Str "paragraph,",Space,Str "starting",Space,Str "with",Space,Code ("",[],[]) "Listing:",Space,Str "or",Space,Code ("",[],[]) ":",Str ",",Space,Str "said",Space,Str "paragraph",Space,Str "will",Space,Str "be",Space,Str "treated",Space,Str "as",Space,Str "code",Space,Str "block",Space,Str "caption."]+  ,Div ("lst:tableCaption",["listing","haskell"],[]) [Para [Str "Listing",Space,Str "2:",Space,Str "Listing",Space,Str "caption"],CodeBlock ("",["haskell"],[]) "main :: IO ()\nmain = putStrLn \"Hello World!\""]+  ,Header 2 ("sec:wrapping-div",[],[]) [Str "Wrapping",Space,Str "div"]+  ,Para [Str "Wrapping",Space,Str "code",Space,Str "block",Space,Str "without",Space,Str "label",Space,Str "in",Space,Str "a",Space,Str "div",Space,Str "with",Space,Str "id",Space,Code ("",[],[]) "lst:...",Space,Str "and",Space,Str "class,",Space,Str "starting",Space,Str "with",Space,Code ("",[],[]) "listing",Str ",",Space,Str "and",Space,Str "adding",Space,Str "paragraph",Space,Str "before",Space,Str "code",Space,Str "block,",Space,Str "but",Space,Str "inside",Space,Str "div,",Space,Str "will",Space,Str "treat",Space,Str "said",Space,Str "paragraph",Space,Str "as",Space,Str "code",Space,Str "block",Space,Str "caption."]+  ,Div ("lst:wrappingDiv",["listing","haskell"],[]) [Para [Str "Listing",Space,Str "3:",Space,Str "Listing",Space,Str "caption"],CodeBlock ("",["haskell"],[]) "main :: IO ()\nmain = putStrLn \"Hello World!\""]+  ,Header 1 ("sec:unnumbered-chapter.",["unnumbered"],[]) [Str "Unnumbered",Space,Str "chapter."]+  ,Para [Str "This",Space,Str "chapter",Space,Str "doesn't",Space,Str "change",Space,Str "chapter",Space,Str "prefix",Space,Str "of",Space,Str "referenced",Space,Str "elements,",Space,Str "instead",Space,Str "keeping",Space,Str "number",Space,Str "of",Space,Str "previous",Space,Str "chapter,",Space,Str "e.g."]+  ,Para [Math DisplayMath " S(x) = \\int_{x_1}^{x_2} a x+b \\  \\mathrm{d}x \\qquad(2)"]+  ,Header 1 ("sec:chapter-5.-reference-lists",[],[]) [Str "Chapter",Space,Str "5.",Space,Str "Reference",Space,Str "lists"]+  ,Para [Str "It's",Space,Str "also",Space,Str "possible",Space,Str "to",Space,Str "show",Space,Str "lists",Space,Str "of",Space,Str "figures",Space,Str "and",Space,Str "tables,",Space,Str "like",Space,Str "this:"]+  ,Header 2 ("list-of-figures",[],[]) [Str "List",Space,Str "of",Space,Str "Figures"]+  ,OrderedList (1,DefaultStyle,DefaultDelim)+   [[Plain [Str "A",Space,Str "figure"]]+   ,[Plain [Str "First",Space,Str "figure"]]+   ,[Plain [Str "Second",Space,Str "figure"]]+   ,[Plain [Str "Third",Space,Str "figure"]]]+  ,Header 2 ("list-of-tables",[],[]) [Str "List",Space,Str "of",Space,Str "Tables"]+  ,OrderedList (1,DefaultStyle,DefaultDelim)+   [[Plain [Str "Table",Space,Str "example"]]]+  ,Header 1 ("",[],[]) [Str "List",Space,Str "of",Space,Str "Listings"]+  ,OrderedList (1,DefaultStyle,DefaultDelim)+   [[Plain [Str "Listing",Space,Str "caption"]]+   ,[Plain [Str "Listing",Space,Str "caption"]]+   ,[Plain [Str "Listing",Space,Str "caption"]]]+  ,Header 1 ("sec:appendix-a.-custom-labels",[],[("label","AppA")]) [Str "Appendix",Space,Str "A.",Space,Str "Custom",Space,Str "labels"]+  ,Header 2 ("sec:custlabs",[],[("label","CustLab")]) [Str "This",Space,Str "section",Space,Str "will",Space,Str "have",Space,Str "custom",Space,Str "label"]]++demochapters :: [Block]+demochapters =+  [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "demo",Space,Str "file",Space,Str "for",Space,Str "pandoc-crossref.",Space,Str "With",Space,Str "this",Space,Str "filter,",Space,Str "you",Space,Str "can",Space,Str "cross-reference",Space,Str "figures",Space,Str "(see",Space,Str "figs.\160\&1.1-1.3",Str "),",Space,Str "display",Space,Str "equations",Space,Str "(see",Space,Str "eq.\160\&2.1",Str "),",Space,Str "tables",Space,Str "(see",Space,Str "tbl.\160\&3.1",Str ")",Space,Str "and",Space,Str "sections",Space,Str "(",Str "secs.\160\&1,",Space,Str "2,",Space,Str "4.1-4.3",Str ")"]+  ,Para [Str "For",Space,Str "immediate",Space,Str "example,",Space,Str "see",Space,Str "fig.\160\&1"]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "1:",Space,Str "A",Space,Str "figure"] ("img1.jpg","fig:")]+  ,Para [Str "There",Space,Str "is",Space,Str "also",Space,Str "support",Space,Str "for",Space,Str "code",Space,Str "blocks,",Space,Str "for",Space,Str "example,",Space,Str "lsts.\160\&4.1-4.3"]+  ,Para [Str "It's",Space,Str "possible",Space,Str "to",Space,Str "capitalize",Space,Str "reference",Space,Str "prefixes,",Space,Str "like",Space,Str "this:",Space,Str "Fig.\160\&1.1",Str "."]+  ,Para [Str "In",Space,Str "case",Space,Str "of",Space,Str "multiple",Space,Str "references,",Space,Str "capitalization",Space,Str "is",Space,Str "determined",Space,Str "by",Space,Str "first",Space,Str "reference.",Space,Str "Figs.\160\&1.1,",Space,Str "1.2",Space,Str "is",Space,Str "capitalized,",Space,Str "while",Space,Str "figs.\160\&1.1,",Space,Str "1.2",Space,Str "is",Space,Str "not."]+  ,Para [Str "It",Space,Str "is",Space,Str "also",Space,Str "possible",Space,Str "to",Space,Str "mix",Space,Str "different",Space,Str "references,",Space,Str "like",Space,Str "fig.\160\&1.1",Str ",",Space,Str "tbl.\160\&3.1",Str ",",Space,Str "lsts.\160\&4.1,",Space,Str "4.2",Str ",",Space,Str "figs.\160\&1.2,",Space,Str "1.3",Str ",",Space,Str "which",Space,Str "will",Space,Str "be",Space,Str "grouped",Space,Str "in",Space,Str "order",Space,Str "they",Space,Str "are",Space,Str "specified.",Space,Str "You",Space,Str "can",Space,Str "even",Space,Str "intermix",Space,Str "this",Space,Str "with",Space,Str "regular",Space,Str "citations,",Space,Str "although",Space,Str "it's",Space,Str "not",Space,Str "recommended:",Space,Str "fig.\160\&1.1",Str ",",Space,Str "tbl.\160\&3.1",Str ",",Space,Cite [Citation {citationId = "unprocessedCitation", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@unprocessedCitation]"]]+  ,Para [Str "You",Space,Str "can",Space,Str "also",Space,Str "have",Space,Str "custom",Space,Str "chapter",Space,Str "reference",Space,Str "labels,",Space,Str "like",Space,Str "sec.\160AppA.CustLab"]+  ,Header 1 ("sec:sec1",[],[]) [Str "Chapter",Space,Str "1.",Space,Str "Figures"]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "1.1:",Space,Str "First",Space,Str "figure"] ("img1.jpg","fig:")]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "1.2:",Space,Str "Second",Space,Str "figure"] ("img2.jpg","fig:")]+  ,Para [Image [Str "Figure",Space,Str "#",Space,Str "1.3:",Space,Str "Third",Space,Str "figure"] ("img3.jpg","fig:")]+  ,Para [Image [Str "Unlabelled",Space,Str "image"] ("img1.jpg","fig:")]+  ,Header 1 ("sec:sec2",[],[]) [Str "Chapter",Space,Str "2.",Space,Str "Equations"]+  ,Para [Math DisplayMath " P_i(x) = \\sum_i a_i x^i \\qquad(2.1)"]+  ,Header 1 ("sec:chapter-3.-tables",[],[]) [Str "Chapter",Space,Str "3.",Space,Str "Tables"]+  ,Table [Emph [Str "Table",Space,Str "3.1"],Str ":",Space,Str "Table",Space,Str "example"] [AlignLeft,AlignLeft] [0.0,0.0]+   [[Plain [Str "First",Space,Str "Header"]]+   ,[Plain [Str "Second",Space,Str "Header"]]]+   [[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]+   ,[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]]+  ,Para [Str "Table",Space,Str "without",Space,Str "caption:"]+  ,Table [] [AlignLeft,AlignLeft] [0.0,0.0]+   [[Plain [Str "First",Space,Str "Header"]]+   ,[Plain [Str "Second",Space,Str "Header"]]]+   [[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]+   ,[[Plain [Str "Content",Space,Str "Cell"]]+    ,[Plain [Str "Content",Space,Str "Cell"]]]]+  ,Header 1 ("sec:chapter-4.-code-blocks",[],[]) [Str "Chapter",Space,Str "4.",Space,Str "Code",Space,Str "blocks"]+  ,Para [Str "There",Space,Str "are",Space,Str "a",Space,Str "couple",Space,Str "options",Space,Str "for",Space,Str "code",Space,Str "block",Space,Str "labels.",Space,Str "Those",Space,Str "work",Space,Str "only",Space,Str "if",Space,Str "code",Space,Str "block",Space,Str "id",Space,Str "starts",Space,Str "with",Space,Code ("",[],[]) "lst:",Str ",",Space,Str "e.g.",Space,Code ("",[],[]) "{#lst:label}"]+  ,Header 2 ("sec:caption-attr",[],[]) [Code ("",[],[]) "caption",Space,Str "attribute"]+  ,Para [Code ("",[],[]) "caption",Space,Str "attribute",Space,Str "will",Space,Str "be",Space,Str "treated",Space,Str "as",Space,Str "code",Space,Str "block",Space,Str "caption.",Space,Str "If",Space,Str "code",Space,Str "block",Space,Str "has",Space,Str "both",Space,Str "id",Space,Str "and",Space,Code ("",[],[]) "caption",Space,Str "attributes,",Space,Str "it",Space,Str "will",Space,Str "be",Space,Str "treated",Space,Str "as",Space,Str "numbered",Space,Str "code",Space,Str "block."]+  ,Div ("lst:captionAttr",["listing","haskell"],[]) [Para [Str "Listing",Space,Str "4.1:",Space,Str "Listing",Space,Str "caption"],CodeBlock ("",["haskell"],[]) "main :: IO ()\nmain = putStrLn \"Hello World!\""]+  ,Para [RawInline (Format "tex") "\\pagebreak"]+  ,Header 2 ("sec:table-capts",[],[]) [Str "Table-style",Space,Str "captions"]+  ,Para [Str "Enabled",Space,Str "with",Space,Code ("",[],[]) "codeBlockCaptions",Space,Str "metadata",Space,Str "option.",Space,Str "If",Space,Str "code",Space,Str "block",Space,Str "is",Space,Str "immediately",Space,Str "adjacent",Space,Str "to",Space,Str "paragraph,",Space,Str "starting",Space,Str "with",Space,Code ("",[],[]) "Listing:",Space,Str "or",Space,Code ("",[],[]) ":",Str ",",Space,Str "said",Space,Str "paragraph",Space,Str "will",Space,Str "be",Space,Str "treated",Space,Str "as",Space,Str "code",Space,Str "block",Space,Str "caption."]+  ,Div ("lst:tableCaption",["listing","haskell"],[]) [Para [Str "Listing",Space,Str "4.2:",Space,Str "Listing",Space,Str "caption"],CodeBlock ("",["haskell"],[]) "main :: IO ()\nmain = putStrLn \"Hello World!\""]+  ,Header 2 ("sec:wrapping-div",[],[]) [Str "Wrapping",Space,Str "div"]+  ,Para [Str "Wrapping",Space,Str "code",Space,Str "block",Space,Str "without",Space,Str "label",Space,Str "in",Space,Str "a",Space,Str "div",Space,Str "with",Space,Str "id",Space,Code ("",[],[]) "lst:...",Space,Str "and",Space,Str "class,",Space,Str "starting",Space,Str "with",Space,Code ("",[],[]) "listing",Str ",",Space,Str "and",Space,Str "adding",Space,Str "paragraph",Space,Str "before",Space,Str "code",Space,Str "block,",Space,Str "but",Space,Str "inside",Space,Str "div,",Space,Str "will",Space,Str "treat",Space,Str "said",Space,Str "paragraph",Space,Str "as",Space,Str "code",Space,Str "block",Space,Str "caption."]+  ,Div ("lst:wrappingDiv",["listing","haskell"],[]) [Para [Str "Listing",Space,Str "4.3:",Space,Str "Listing",Space,Str "caption"],CodeBlock ("",["haskell"],[]) "main :: IO ()\nmain = putStrLn \"Hello World!\""]+  ,Header 1 ("sec:unnumbered-chapter.",["unnumbered"],[]) [Str "Unnumbered",Space,Str "chapter."]+  ,Para [Str "This",Space,Str "chapter",Space,Str "doesn't",Space,Str "change",Space,Str "chapter",Space,Str "prefix",Space,Str "of",Space,Str "referenced",Space,Str "elements,",Space,Str "instead",Space,Str "keeping",Space,Str "number",Space,Str "of",Space,Str "previous",Space,Str "chapter,",Space,Str "e.g."]+  ,Para [Math DisplayMath " S(x) = \\int_{x_1}^{x_2} a x+b \\  \\mathrm{d}x \\qquad(4.1)"]+  ,Header 1 ("sec:chapter-5.-reference-lists",[],[]) [Str "Chapter",Space,Str "5.",Space,Str "Reference",Space,Str "lists"]+  ,Para [Str "It's",Space,Str "also",Space,Str "possible",Space,Str "to",Space,Str "show",Space,Str "lists",Space,Str "of",Space,Str "figures",Space,Str "and",Space,Str "tables,",Space,Str "like",Space,Str "this:"]+  ,Header 2 ("list-of-figures",[],[]) [Str "List",Space,Str "of",Space,Str "Figures"]+  ,Div ("",["list"],[]) [Para [Str "1",Space,Str "A",Space,Str "figure"],Para [Str "1",Str ".",Str "1",Space,Str "First",Space,Str "figure"],Para [Str "1",Str ".",Str "2",Space,Str "Second",Space,Str "figure"],Para [Str "1",Str ".",Str "3",Space,Str "Third",Space,Str "figure"]]+  ,Header 2 ("list-of-tables",[],[]) [Str "List",Space,Str "of",Space,Str "Tables"]+  ,Div ("",["list"],[]) [Para [Str "3",Str ".",Str "1",Space,Str "Table",Space,Str "example"]]+  ,Header 1 ("",[],[]) [Str "List",Space,Str "of",Space,Str "Listings"]+  ,Div ("",["list"],[]) [Para [Str "4",Str ".",Str "1",Space,Str "Listing",Space,Str "caption"],Para [Str "4",Str ".",Str "2",Space,Str "Listing",Space,Str "caption"],Para [Str "4",Str ".",Str "3",Space,Str "Listing",Space,Str "caption"]]+  ,Header 1 ("sec:appendix-a.-custom-labels",[],[("label","AppA")]) [Str "Appendix",Space,Str "A.",Space,Str "Custom",Space,Str "labels"]+  ,Header 2 ("sec:custlabs",[],[("label","CustLab")]) [Str "This",Space,Str "section",Space,Str "will",Space,Str "have",Space,Str "custom",Space,Str "label"]]+
+ test/test-pandoc-crossref.hs view
@@ -0,0 +1,243 @@+import Test.Hspec+import Text.Pandoc hiding (readMarkdown)+import Text.Pandoc.Builder+import Text.Pandoc.Walk+import Control.Monad.State+import Data.List+import Control.Arrow+import Data.Monoid -- needed for ghc<7.10+import qualified Data.Map as M++import Text.Pandoc.CrossRef+import Text.Pandoc.CrossRef.Util.Options+import Text.Pandoc.CrossRef.Util.Gap+import Text.Pandoc.CrossRef.Util.Util+import Text.Pandoc.CrossRef.References.Types+import Text.Pandoc.CrossRef.Util.Settings+import Text.Pandoc.CrossRef.Util.Accessor+import Text.Pandoc.CrossRef.References.Accessors+import qualified Text.Pandoc.CrossRef.References.Blocks as References.Blocks+import qualified Text.Pandoc.CrossRef.References.Refs as References.Refs+import qualified Text.Pandoc.CrossRef.References.List as References.List+import qualified Text.Pandoc.CrossRef.Util.Template as Util.Template+import qualified Text.Pandoc.CrossRef.Util.CodeBlockCaptions as Util.CodeBlockCaptions++import qualified Native+import Paths_pandoc_crossref++main :: IO ()+main = hspec $ do+    describe "References.Blocks.replaceBlocks" $ do+      it "Labels images" $+        testBlocks (figure "test.jpg" [] "Test figure" "figure")+        (figure "test.jpg" "fig:" "Figure 1: Test figure" [],+          def{imgRefs=M.fromList $ refRec' "fig:figure" 1 "Test figure"})+      it "Labels equations" $+        testBlocks (equation "a^2+b^2=c^2" "equation")+        (equation "a^2+b^2=c^2\\qquad(1)" [],+          def{eqnRefs=M.fromList $ refRec'' "eq:equation" 1})+      it "Labels tables" $+        testBlocks (table' "Test table" "table")+        (table' "Table 1: Test table" [],+          def{tblRefs=M.fromList $ refRec' "tbl:table" 1 "Test table"})+      it "Labels code blocks" $+        testBlocks (codeBlock' "Test code block" "codeblock")+        (codeBlockDiv "Listing 1: Test code block" "codeblock",+          def{lstRefs=M.fromList $ refRec' "lst:codeblock" 1 "Test code block"})+      it "Labels code block divs" $+        testBlocks (codeBlockDiv "Test code block" "codeblock")+        (codeBlockDiv "Listing 1: Test code block" "codeblock",+          def{lstRefs=M.fromList $ refRec' "lst:codeblock" 1 "Test code block"})+      it "Labels sections divs" $+        testBlocks (section "Section Header" 1 "section")+        (section "Section Header" 1 "section",+          def{secRefs=M.fromList $ refRec' "sec:section" 1 "Section Header",+              curChap=[(1,Nothing)]})++    describe "References.Refs.replaceRefs" $ do+      it "References one image" $+        testRefs' "fig:" [1] [4] imgRefs' "fig.\160\&4"+      it "References multiple images" $+        testRefs' "fig:" [1..3] [4..6] imgRefs' "figs.\160\&4-6"+      it "References one equation" $+        testRefs' "eq:" [1] [4] eqnRefs' "eq.\160\&4"+      it "References multiple equations" $+        testRefs' "eq:" [1..3] [4..6] eqnRefs' "eqns.\160\&4-6"+      it "References one table" $+        testRefs' "tbl:" [1] [4] tblRefs' "tbl.\160\&4"+      it "References multiple tables" $+        testRefs' "tbl:" [1..3] [4..6] tblRefs' "tbls.\160\&4-6"+      it "References one listing" $+        testRefs' "lst:" [1] [4] lstRefs' "lst.\160\&4"+      it "References multiple listings" $+        testRefs' "lst:" [1..3] [4..6] lstRefs' "lsts.\160\&4-6"+      it "References one section" $+        testRefs' "sec:" [1] [4] secRefs' "sec.\160\&4"+      it "References multiple sections" $+        testRefs' "sec:" [1..3] [4..6] secRefs' "secs.\160\&4-6"+      it "Separates references to different chapter items by a comma" $+        testRefs'' "lst:" [1..6] (zip [1,1..] [4..6] ++ zip [2,2..] [7..9]) lstRefs' "lsts.\160\&1.4-1.6, 2.7-2.9"++    describe "References.Refs.replaceRefs capitalization" $ do+      it "References one image" $+        testRefs' "Fig:" [1] [4] imgRefs' "Fig.\160\&4"+      it "References multiple images" $+        testRefs' "Fig:" [1..3] [4..6] imgRefs' "Figs.\160\&4-6"+      it "References one equation" $+        testRefs' "Eq:" [1] [4] eqnRefs' "Eq.\160\&4"+      it "References multiple equations" $+        testRefs' "Eq:" [1..3] [4..6] eqnRefs' "Eqns.\160\&4-6"+      it "References one table" $+        testRefs' "Tbl:" [1] [4] tblRefs' "Tbl.\160\&4"+      it "References multiple tables" $+        testRefs' "Tbl:" [1..3] [4..6] tblRefs' "Tbls.\160\&4-6"+      it "References one listing" $+        testRefs' "Lst:" [1] [4] lstRefs' "Lst.\160\&4"+      it "References multiple listings" $+        testRefs' "Lst:" [1..3] [4..6] lstRefs' "Lsts.\160\&4-6"+      it "References one listing" $+        testRefs' "Sec:" [1] [4] secRefs' "Sec.\160\&4"+      it "References multiple listings" $+        testRefs' "Sec:" [1..3] [4..6] secRefs' "Secs.\160\&4-6"++    describe "References.List.listOf" $ do+      it "Generates list of tables" $+        testList (para $ rawInline "tex" "\\listoftables")+                 def{tblRefs=M.fromList $ refRec' "tbl:1" 4 "4" <> refRec' "tbl:2" 5 "5" <> refRec' "tbl:3" 6 "6"}+                 (header 1 (text "List of Tables") <> orderedList ((plain . str . show) `map` [4..6 :: Int]))+      it "Generates list of figures" $+        testList (para $ rawInline "tex" "\\listoffigures")+                 def{imgRefs=M.fromList $ refRec' "fig:1" 4 "4" <> refRec' "fig:2" 5 "5" <> refRec' "fig:3" 6 "6"}+                 (header 1 (text "List of Figures") <> orderedList ((plain . str . show) `map` [4..6 :: Int]))++    describe "Util.CodeBlockCaptions" $+      it "Transforms table-style codeBlock captions to codeblock divs" $ do+        let t x = testCBCaptions x (codeBlockDiv "Code Block" "cb")+        t (codeBlockForTable "cb" <> paraText ": Code Block")+        t (codeBlockForTable "cb" <> paraText "Listing: Code Block")+        t (paraText ": Code Block" <> codeBlockForTable "cb")+        t (paraText "Listing: Code Block" <> codeBlockForTable "cb")++    describe "Util.Template" $+      it "Applies templates" $+        let template=Util.Template.makeTemplate defaultMeta (toList $ displayMath "figureTitle" <> displayMath "i" <> displayMath "t")+        in Util.Template.applyTemplate [Str "1"] [Str "title"] template `shouldBe`+           toList (str "Figure" <> str "1" <> str "title")++    describe "Citation groups shouldn't be separated (#22 regression test)" $ do+      it "Should not separate citation groups" $ do+        let cits = para $ citeGen "" [1..3]+        testRefs cits def cits++      it "Should not separate citation groups with unknown prefix" $ do+        let cits = para $ citeGen "unk:" [1..3]+        testRefs cits def cits++      it "Should not separate citation groups with different unknown prefixes" $ do+        let cits = para $ cite (mconcat $ map (cit . uncurry (++) . second show) l) $ text $+              "[" ++ intercalate "; " (map (("@"++) . uncurry (++) . second show) l) ++ "]"+            l = zip ["unk1:", "unk2:"] [1,2::Int]+        testRefs cits def cits++    describe "Test files" $ do++      it "demo.md matches demo.native" $ do+        demomd <- readFile =<< getDataFileName "demo.md"+        let Pandoc m b = readMarkdown def demomd+        runCrossRef m Nothing crossRefBlocks b `shouldBe` Native.demo++      it "demo.md with chapters matches demo-chapters.native" $ do+        demomd <- readFile =<< getDataFileName "demo.md"+        let Pandoc m b = readMarkdown def demomd+            m' = setMeta "chapters" True m+        runCrossRef m' Nothing crossRefBlocks b `shouldBe` Native.demochapters++++citeGen :: String -> [Int] -> Inlines+citeGen p l = cite (mconcat $ map (cit . (p++) . show) l) $ text $+  "[" ++ intercalate "; " (map (("@"++) . (p++) . show) l) ++ "]"++refGen :: String -> [Int] -> [Int] -> M.Map String RefRec+refGen p l1 l2 = M.fromList $ mconcat $ zipWith refRec'' (((uncapitalizeFirst p++) . show) `map` l1) l2++refGen' :: String -> [Int] -> [(Int, Int)] -> M.Map String RefRec+refGen' p l1 l2 = M.fromList $ mconcat $ zipWith refRec''' (((uncapitalizeFirst p++) . show) `map` l1) l2++refRec' :: String -> Int -> String -> [(String, RefRec)]+refRec' ref i tit = [(ref, RefRec{refIndex=[(i,Nothing)],refTitle=toList $ text tit})]++refRec'' :: String -> Int -> [(String, RefRec)]+refRec'' ref i = refRec' ref i []++refRec''' :: String -> (Int, Int) -> [(String, RefRec)]+refRec''' ref (c,i) = [(ref, RefRec{refIndex=[(c,Nothing), (i,Nothing)],refTitle=toList $ text []})]++testRefs' :: String -> [Int] -> [Int] -> Accessor References (M.Map String RefRec) -> String -> Expectation+testRefs' p l1 l2 prop res = testRefs (para $ citeGen p l1) (setProp prop (refGen p l1 l2) def) (para $ text res)++testRefs'' :: String -> [Int] -> [(Int, Int)] -> Accessor References (M.Map String RefRec) -> String -> Expectation+testRefs'' p l1 l2 prop res = testRefs (para $ citeGen p l1) (setProp prop (refGen' p l1 l2) def) (para $ text res)++testBlocks :: Blocks -> (Blocks, References) -> Expectation+testBlocks arg res = runState (walkM (f defaultOptions) arg) def `shouldBe` res+  where f = (. References.Blocks.divBlocks) . References.Blocks.replaceBlocks++testRefs :: Blocks -> References -> Blocks -> Expectation+testRefs bs st res = runState (bottomUpM (References.Refs.replaceRefs defaultOptions) (toList bs)) st `shouldBe` (toList res,st)++testCBCaptions :: Blocks -> Blocks -> Expectation+testCBCaptions bs res = runState (bottomUpM (Util.CodeBlockCaptions.codeBlockCaptions defaultOptions{cbCaptions=True}) (toList bs)) def `shouldBe` (toList res,def)++testList :: Blocks -> References -> Blocks -> Expectation+testList bs st res = runState (bottomUpM (References.List.listOf defaultOptions) (toList bs)) st `shouldBe` (toList res,st)++figure :: String -> String -> String -> String -> Blocks+figure src title alt ref = para (image src title (text alt) <> ref' "fig" ref)++section :: String -> Int -> String -> Blocks+section text' level label = headerWith ("sec:" ++ label,[],[]) level (text text')++equation :: String -> String -> Blocks+equation eq ref = para (displayMath eq <> ref' "eq" ref)++table' :: String -> String -> Blocks+table' title ref = table (text title <> ref' "tbl" ref) []+   [para $ str "H1", para $ str "H2"]+  [[para $ str "C1", para $ str "C2"]]++codeBlock' :: String -> String -> Blocks+codeBlock' title ref = codeBlockWith+  ("lst:"++ref,["haskell"],[("caption",title)]) "main :: IO ()"++codeBlockForTable :: String -> Blocks+codeBlockForTable ref = codeBlockWith+     ("lst:"++ref,["haskell"],[]) "main :: IO ()"++paraText :: String -> Blocks+paraText s = para $ text s++codeBlockDiv :: String -> String -> Blocks+codeBlockDiv title ref = divWith ("lst:"++ref, ["listing","haskell"],[]) $+  para (text title) <>+  codeBlockWith+    ("",["haskell"],[]) "main :: IO ()"++ref' :: String -> String -> Inlines+ref' p n | null n  = mempty+         | otherwise = space <> str ("{#"++p++":"++n++"}")++defaultOptions :: Options+defaultOptions = getOptions defaultMeta Nothing++defCit :: Citation+defCit = Citation{citationId = ""+                 ,citationPrefix = []+                 ,citationSuffix = []+                 ,citationHash = 0+                 ,citationNoteNum = 0+                 ,citationMode = NormalCitation+                 }++cit :: String -> [Citation]+cit r = [defCit{citationId=r}]