packages feed

pandoc-crossref 0.1.0.2 → 0.1.1.0

raw patch · 15 files changed

+402/−51 lines, 15 filesdep ~pandoc

Dependency ranges changed: pandoc

Files

README.md view
@@ -4,11 +4,11 @@  Input file (like [demo.md][demo-md]) can be converted into [html][html], [latex][latex], [pdf][pdf], [md][md] or other formats. -Optionally, you can use cleveref for latex/pdf output, e.g. [cleveref pdf][cpdf], [cleveref latex][clatex]+Optionally, you can use cleveref for latex/pdf output, e.g. [cleveref pdf][cpdf], [cleveref latex][clatex], and listings package, e.g. [listings pdf][lpdf], [listings latex][llatex]  You can also enable per-chapter numbering (as with `--chapters` for latex output). You need to specify `-M chapters` for non-latex/pdf output however. Examples: [html][chap-html], [markdown][chap-markdown], [latex][chap-latex], [pdf][chap-pdf]. -[demo-md]: http://lierdakil.github.io/pandoc-crossref/demo.md+[demo-md]: https://raw.githubusercontent.com/lierdakil/pandoc-crossref/gh-pages/demo.md [html]: http://lierdakil.github.io/pandoc-crossref/output.html [latex]: http://lierdakil.github.io/pandoc-crossref/output.latex [pdf]: http://lierdakil.github.io/pandoc-crossref/output.pdf@@ -19,16 +19,18 @@ [chap-pdf]:http://lierdakil.github.io/pandoc-crossref/output-chapters.pdf [clatex]: http://lierdakil.github.io/pandoc-crossref/output-cref.latex [cpdf]: http://lierdakil.github.io/pandoc-crossref/output-cref.pdf+[llatex]: http://lierdakil.github.io/pandoc-crossref/output-listings.latex+[lpdf]: http://lierdakil.github.io/pandoc-crossref/output-listings.pdf  -Tested with pandoc 1.13.2.+Tested with pandoc 1.13.2 and 1.14.  This work is inspired by [pandoc-fignos][1] and [pandoc-eqnos][2] by @tomduck.  [1]: https://github.com/tomduck/pandoc-fignos [2]: https://github.com/tomduck/pandoc-eqnos -This package tries to use latex labels and references if output type is latex.+This package tries to use latex labels and references if output type is LaTeX. It also tries to supplement rudimentary LaTeX configuration that should mimic metadata configuration by setting `header-includes` variable.  ## Syntax @@ -71,6 +73,61 @@  To label a table, append `{#tbl:label}` at the end of table caption (with `label` being something unique to reference this table by). Caption and label *must* be separated by at least one space. +### Code Block labels++There are a couple options to add code block labels. Those work only if code block id starts with `lst:`, e.g. `{#lst:label}`++#### `caption` attribute++`caption` attribute will be treated as code block caption. If code block has both id and `caption` attributes, it will be treated as numbered code block.++<pre>+```{#lst:code .haskell caption="Listing caption"}+main :: IO ()+main = putStrLn "Hello World!"+```+</pre>++#### Table-style captions++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.++<pre>+Listing: Listing caption++```{#lst:code .haskell}+main :: IO ()+main = putStrLn "Hello World!"+```+</pre>++or++<pre>+```{#lst:code .haskell}+main :: IO ()+main = putStrLn "Hello World!"+```++: Listing caption+</pre>++#### 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.++<pre>+&lt;div id="lst:code" class="listing"&gt;+Listing caption+```{.haskell}+main :: IO ()+main = putStrLn "Hello World!"+```+&lt;/div&gt;+</pre>+ ### References  ```markdown@@ -81,8 +138,10 @@  ### Lists -It's possible to use raw latex commands `\listoffigures` and `\listoftables`, which will produce ordered list of figure/table titles, in order of appearance in document.+It's possible to use raw latex commands `\listoffigures`, `\listoftables` and `listoflistings`, which will produce ordered list of figure/table/listings titles, in order of appearance in document. +`\listoflistings` depends on other options, and is defined in preamble, so it will work reliably only with standalone/pdf output.+ ## Installation  Assuming you already installed [Haskell platform](http://hackage.haskell.org/platform/), you can install pandoc-crossref with cabal:@@ -106,20 +165,44 @@  Following variables are supported: -* `cref`: if True, latex export will use `\cref` from cleveref package. It is user's responsibility to include relevant `\usepackage` directives in template+* `cref`: if True, latex export will use `\cref` from cleveref package. Only relevant for LaTeX output. `\usepackage{cleveref}` will be automatically added to `header-includes`. * `chapter`: if True, number elements as `chapter.item`, and restart `item` on each first-level heading (as `--chapters` for latex/pdf output)+* `listings`: if True, generate code blocks for `listings` package. Only relevant for LaTeX output. `\usepackage{listings}` will be automatically added to `header-includes`. You need to specify `--listings` option as well.+* `codeBlockCaptions`: if True, parse table-style code block captions. * `figureTitle`, default `Figure`: Word(s) to prepend to figure titles, e.g. `Figure 1: Description` * `tableTitle`, default `Table`: Word(s) to prepend to table titles, e.g. `Table 1: Description`+* `listingTitle`, default `Listing`: Word(s) to prepend to listing titles, e.g. `Listing 1: Description` * `titleDelimiter`, default `:`: What to put between object number and caption text.-* `figPrefix`, default `fig.`: Prefix for references to figures, e.g. `fig. 1-3`-* `eqnPrefix`, default `eq.`: Prefix for references to equations, e.g. `eq. 3,4`-* `tblPrefix`, default `tbl.`: Prefix for references to tables, e.g. `tbl. 2`+* `figPrefix`, default `fig.`, `figs.`: Prefix for references to figures, e.g. `figs. 1-3`+* `eqnPrefix`, default `eq.`, `eqns.`: Prefix for references to equations, e.g. `eqns. 3,4`+* `tblPrefix`, default `tbl.`, `tbls.`: Prefix for references to tables, e.g. `tbl. 2`+* `lstPrefix`, default `lst.`, `lsts.`: Prefix for references to lists, e.g. `lsts. 2,5` * `chapDelim`, default `.`: Delimiter between chapter number and item number. * `rangeDelim`, default `-`: Delimiter between reference ranges, e.g. `eq. 2-5` * `lofTitle`, default `# List of Figures`: Title for list of figures (lof) * `lotTitle`, default `# List of Tables`: Title for list of tables (lot)+* `lolTitle`, default `# List of Listings`: Title for list of listings (lol) * `figureTemplate`, default `\\[figureTitle\\] \\[i\\]\\[titleDelim\\] \\[t\\]`: template for figure captions, see [Templates](#templates) * `tableTemplate`, default `\\[tableTitle\\] \\[i\\]\\[titleDelim\\] \\[t\\]`: template for table captions, see [Templates](#templates)+* `listingTemplate`, default `\\[tableTitle\\] \\[i\\]\\[titleDelim\\] \\[t\\]`: template for listing captions, see [Templates](#templates)++`figPrefix`, `eqnPrefix`, `tblPrefix`, `lstPrefix` can be YAML arrays. That way, value at index corresponds to total number of references in group, f.ex.++```yaml+fixPrefix:+  - "fig."+  - "figs."+```++Will result in all single-value references prefixed with "fig.", and all reference groups of two and more prefixed with "figs.":++```markdown+[@fig:one] -> fig. 1+[@fig:one; @fig:two] -> figs. 1, 2+[@fig:one; @fig:two; @fig:three] -> figs. 1-3+```++They can be YAML strings as well. In that case, prefix would be the same regardless of number of references.  ### Templates 
pandoc-crossref.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                pandoc-crossref-version:             0.1.0.2+version:             0.1.1.0 synopsis:            Pandoc filter for cross-references description:         pandoc-crossref is a pandoc filter for numbering figures, equations, tables and cross-references to them. license:             GPL-2@@ -23,7 +23,7 @@ source-repository this   type: git   location: https://github.com/lierdakil/pandoc-crossref-  tag: v0.1.0.1+  tag: v0.1.1.0  executable pandoc-crossref   main-is:             pandoc-crossref.hs@@ -39,9 +39,11 @@                      , Util.Options                      , Util.Template                      , Util.Util-  -- other-extensions:+                     , Util.CodeBlockCaptions+                     , Util.ModifyMeta+  other-extensions: CPP   build-depends:       base >=4.2 && <5-                     , pandoc >= 1.13 && <1.14+                     , pandoc >= 1.13 && <1.15                      , mtl >= 1.1 && <2.3                      , containers >= 0.1 && <0.6                      , pandoc-types >= 1.12.4.1 && < 1.13@@ -66,9 +68,12 @@                      , Util.Options                      , Util.Template                      , Util.Util+                     , Util.CodeBlockCaptions+                     , Util.ModifyMeta+  other-extensions: CPP   hs-source-dirs: ., src   Build-Depends:   base >=4.2 && <5-                 , pandoc >= 1.13 && <1.14+                 , pandoc >= 1.13 && <1.15                  , mtl >= 1.1 && <2.3                  , containers >= 0.1 && <0.6                  , pandoc-types >= 1.12.4.1 && < 1.13
pandoc-crossref.hs view
@@ -6,6 +6,8 @@ import References import Util.Settings import Util.Options+import Util.CodeBlockCaptions+import Util.ModifyMeta  main :: IO () main = toJSONFilter go@@ -15,8 +17,10 @@   dtv <- getSettings meta   let     doWalk =-      walkM (replaceBlocks opts) bs+      bottomUpM (codeBlockCaptions opts) bs+      >>= walkM (replaceBlocks opts)       >>= bottomUpM (replaceRefs opts)       >>= bottomUpM (listOf opts)     opts = getOptions dtv fmt-  return $ Pandoc meta $ evalState doWalk def+    meta' = modifyMeta opts dtv+  return $ Pandoc meta' $ evalState doWalk def
src/References/Accessors.hs view
@@ -11,3 +11,6 @@  tblRefs' :: Accessor References RefMap tblRefs' new r@References{tblRefs=old} = (old, r{tblRefs=new})++lstRefs' :: Accessor References RefMap+lstRefs' new r@References{lstRefs=old} = (old, r{lstRefs=new})
src/References/Blocks.hs view
@@ -1,6 +1,7 @@ module References.Blocks (replaceBlocks) where  import Text.Pandoc.Definition+import Text.Pandoc.Builder (text, toList) import Text.Pandoc.Shared (stringify, normalizeSpaces) import Control.Monad.State import Data.List@@ -24,14 +25,14 @@   = do     idxStr <- replaceAttr opts label alt imgRefs'     let alt' = case outFormat opts of-          Just f | isFormat "latex" f ->+          f | isFormat "latex" f ->             RawInline (Format "tex") ("\\label{"++label++"}") : alt           _  -> applyTemplate idxStr alt $ figureTemplate opts     return $ Para [Image alt' (fst img,"fig:")] replaceBlocks opts (Para (Math DisplayMath eq:c))   | Just label <- getRefLabel "eq" c   = case outFormat opts of-      Just f | isFormat "latex" f ->+      f | isFormat "latex" f ->         let eqn = "\\begin{equation}"++eq++"\\label{"++label++"}\\end{equation}"         in return $ Para [RawInline (Format "tex") eqn]       _ -> do@@ -45,10 +46,59 @@     idxStr <- replaceAttr opts label (init title) tblRefs'     let title' =           case outFormat opts of-              Just f | isFormat "latex" f ->+              f | isFormat "latex" f ->                 RawInline (Format "tex") ("\\label{"++label++"}") : init title               _  -> applyTemplate idxStr (init title) $ tableTemplate opts     return $ Table title' align widths header cells+replaceBlocks opts cb@(CodeBlock (label, classes, attrs) code)+  | not $ null label+  , "lst" `isPrefixOf` label+  , Just caption <- lookup "caption" attrs+  = case outFormat opts of+      f+        --if used with listings package,nothing shoud be done+        | isFormat "latex" f, useListings opts -> return cb+        --if not using listings, however, wrap it in a codelisting environment+        | isFormat "latex" f ->+          return $ Div nullAttr [+              RawBlock (Format "tex")+                $ "\\begin{codelisting}\n\\caption{"++caption++"}"+            , cb+            , RawBlock (Format "tex") "\\end{codelisting}"+            ]+      _ -> do+        let cap = toList $ text caption+        idxStr <- replaceAttr opts label cap lstRefs'+        let caption' = applyTemplate idxStr cap $ listingTemplate opts+        return $ Div (label, "listing":classes, []) [+            Para caption'+          , CodeBlock ([], classes, attrs \\ [("caption", caption)]) code+          ]+replaceBlocks opts+  (Div (label,"listing":_, [])+    [Para caption, CodeBlock ([],classes,attrs) code])+  | not $ null label+  , "lst" `isPrefixOf` label+  = case outFormat opts of+      f+        --if used with listings package, return code block with caption+        | isFormat "latex" f, useListings opts ->+          return $ CodeBlock (label,classes,("caption",stringify caption):attrs) code+        --if not using listings, however, wrap it in a codelisting environment+        | isFormat "latex" f ->+          return $ Div nullAttr [+              RawBlock (Format "tex") "\\begin{codelisting}"+            , Para [RawInline (Format "tex") "\\caption",Span nullAttr caption]+            , CodeBlock (label,classes,attrs) code+            , RawBlock (Format "tex") "\\end{codelisting}"+            ]+      _ -> do+        idxStr <- replaceAttr opts label caption lstRefs'+        let caption' = applyTemplate idxStr caption $ listingTemplate opts+        return $ Div (label, "listing":classes, []) [+            Para caption'+          , CodeBlock ([], classes, attrs) code+          ] replaceBlocks _ x = return x  getRefLabel :: String -> [Inline] -> Maybe String
src/References/List.hs view
@@ -10,11 +10,13 @@ import Util.Options  listOf :: Options -> [Block] -> WS [Block]-listOf Options{outFormat=Just f} x | isFormat "latex" f = return x+listOf Options{outFormat=f} x | isFormat "latex" f = return x listOf opts (Para [RawInline (Format "tex") "\\listoffigures"]:xs)   = gets imgRefs >>= makeList (lofTitle opts) xs listOf opts (Para [RawInline (Format "tex") "\\listoftables"]:xs)   = gets tblRefs >>= makeList (lotTitle opts) xs+listOf opts (Para [RawInline (Format "tex") "\\listoflistings"]:xs)+  = gets lstRefs >>= makeList (lolTitle opts) xs listOf _ x = return x  makeList :: [Block] -> [Block] -> M.Map String RefRec -> WS [Block]
src/References/Refs.hs view
@@ -21,7 +21,7 @@   = (++ xs) `fmap` replaceRefs' prefix opts cits   where     replaceRefs' = case outFormat opts of-                    Just f | isFormat "latex" f -> replaceRefsLatex+                    f | isFormat "latex" f -> replaceRefsLatex                     _                           -> replaceRefsOther replaceRefs _ x = return x @@ -30,22 +30,25 @@ accMap = M.fromList [("fig:",imgRefs')                     ,("eq:" ,eqnRefs')                     ,("tbl:",tblRefs')+                    ,("lst:",lstRefs')                     ]  -- accessors to options-prefMap :: M.Map String (Options -> [Inline])+prefMap :: M.Map String (Options -> Int -> [Inline]) prefMap = M.fromList [("fig:",figPrefix)                      ,("eq:" ,eqnPrefix)                      ,("tbl:",tblPrefix)+                     ,("lst:",lstPrefix)                      ]  prefixes :: [String] prefixes = M.keys accMap -getRefPrefix :: Options -> String -> [Inline]-getRefPrefix opts prefix | null refprefix = []-                         | otherwise   = refprefix ++ [Str "\160"]-                         where refprefix = lookupUnsafe prefix prefMap opts+getRefPrefix :: Options -> String -> Int -> [Inline]+getRefPrefix opts prefix num+  | null $ refprefix num = []+  | otherwise   = refprefix num ++ [Str "\160"]+  where refprefix = lookupUnsafe prefix prefMap opts  lookupUnsafe :: Ord k => k -> M.Map k v -> v lookupUnsafe = (fromMaybe undefined .) . M.lookup@@ -64,17 +67,17 @@     texcit =       RawInline (Format "tex") $       if useCleveref opts then-        "\\cref{"++listLabels prefix "" "" cits++"}"+        "\\cref{"++listLabels prefix "" "," "" cits++"}"         else-          listLabels prefix "\\ref{" "}" cits+          listLabels prefix "\\ref{" ", " "}" cits     p | useCleveref opts = []-      | otherwise = getRefPrefix opts prefix+      | otherwise = getRefPrefix opts prefix (length cits - 1) -listLabels :: String -> String -> String -> [Citation] -> String-listLabels prefix p s = foldl' joinStr "" . mapMaybe (getLabel prefix)+listLabels :: String -> String -> String -> String -> [Citation] -> String+listLabels prefix p sep s = foldl' joinStr "" . mapMaybe (getLabel prefix)   where   joinStr acc i | null acc  = p++i++s-                | otherwise = acc++", "++p++i++s+                | otherwise = acc++sep++p++i++s  getLabel :: String -> Citation -> Maybe String getLabel prefix Citation{citationId=cid}@@ -86,7 +89,7 @@   indices <- mapM (getRefIndex prefix) cits   let     indices' = groupBy ((==) `on` (fmap fst . fst)) (sort indices)-  return $ normalizeInlines $ getRefPrefix opts prefix ++ concatMap (makeIndices opts) indices'+  return $ normalizeInlines $ getRefPrefix opts prefix (length cits - 1) ++ concatMap (makeIndices opts) indices'  getRefIndex :: String -> Citation -> WS (Maybe (Int, Int), [Inline]) getRefIndex prefix Citation{citationId=cid,citationSuffix=suf}
src/References/Types.hs view
@@ -20,6 +20,7 @@ data References = References { imgRefs :: RefMap                              , eqnRefs :: RefMap                              , tblRefs :: RefMap+                             , lstRefs :: RefMap                              , curChap :: Int                              } deriving (Show, Eq) @@ -27,5 +28,5 @@ type WS a = State References a  instance Default References where-  def = References n n n 0+  def = References n n n n 0     where n = M.empty
+ src/Util/CodeBlockCaptions.hs view
@@ -0,0 +1,37 @@+module Util.CodeBlockCaptions+    (+    codeBlockCaptions+    ) where++import Text.Pandoc.Definition+import Text.Pandoc.Shared (normalizeSpaces)+import Data.List (isPrefixOf, stripPrefix)+import Data.Maybe (fromMaybe)+import References.Types+import Util.Options++codeBlockCaptions :: Options -> [Block] -> WS [Block]+codeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)+  = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs+codeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)+  = return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs+codeBlockCaptions _ x = return x++orderAgnostic :: Options -> [Block] -> Maybe [Block]+orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)+  | cbCaptions opts+  , Just caption <- getCodeBlockCaption ils+  , not $ null label+  , "lst" `isPrefixOf` label+  = return $ Div (label,"listing":classes, [])+      [Para caption, CodeBlock ([],classes,attrs) code] : xs+orderAgnostic _ _ = Nothing++getCodeBlockCaption :: [Inline] -> Maybe [Inline]+getCodeBlockCaption ils+  | Just caption <- [Str "Listing:",Space] `stripPrefix` normalizeSpaces ils+  = Just caption+  | Just caption <- [Str ":",Space] `stripPrefix` normalizeSpaces ils+  = Just caption+  | otherwise+  = Nothing
src/Util/Meta.hs view
@@ -1,10 +1,15 @@+{-# LANGUAGE CPP #-} module Util.Meta where -import Text.Pandoc (readMarkdown,def)+import Text.Pandoc (readMarkdown) import Text.Pandoc.Shared (stringify) import Text.Pandoc.Definition import Data.Maybe (fromMaybe)+import Data.Default +getMetaList :: (Default a) => (MetaValue -> Maybe a) -> String -> Meta -> Int -> a+getMetaList f name meta i = fromMaybe def $ lookupMeta name meta >>= getList i >>= f+ getMetaBool :: String -> Meta -> Bool getMetaBool name meta = fromMaybe False $ lookupMeta name meta >>= toBool @@ -18,7 +23,13 @@ getMetaString name meta = fromMaybe [] $ lookupMeta name meta >>= toString  toInlines :: MetaValue -> Maybe [Inline]-toInlines (MetaString s) = return $ getInlines $ readMarkdown def s+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@@ -33,7 +44,13 @@ toBlocks :: MetaValue -> Maybe [Block] toBlocks (MetaBlocks bs) = return bs toBlocks (MetaInlines ils) = return [Plain ils]-toBlocks (MetaString s) = return $ getBlocks $ readMarkdown def s+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 @@ -42,3 +59,11 @@ toString (MetaBlocks b) = Just $ stringify b toString (MetaInlines i) = Just $ stringify i toString _ = Nothing++getList :: Int -> MetaValue -> Maybe MetaValue+getList i (MetaList l) = l !!? i+  where+    list !!? index | index >= 0 && index < length list = Just $ list !! index+                   | not $ null list = Just $ last list+                   | otherwise = Nothing+getList _ x = Just x
+ src/Util/ModifyMeta.hs view
@@ -0,0 +1,77 @@+module Util.ModifyMeta+    (+    modifyMeta+    ) where++import Text.Pandoc+import Text.Pandoc.Builder+import Util.Options+import Util.Meta+import Util.Util++modifyMeta :: Options -> Meta -> Meta+modifyMeta opts meta+  | isFormat "latex" (outFormat opts)+  = setMeta "header-includes"+      (headerInc $ lookupMeta "header-includes" meta)+      meta+  | otherwise = meta+  where+    headerInc :: Maybe MetaValue -> MetaValue+    headerInc Nothing = MetaList incList+    headerInc (Just x@(MetaString _)) = MetaList $ x:incList+    headerInc (Just (MetaList x)) = MetaList $ x ++ incList+    headerInc (Just x) = x+    incList = map MetaString $+        floatnames +++        listnames  +++        [ x | x <- codelisting, not $ useListings opts] +++        lolcommand +++        [ x | x <- cleveref, useCleveref opts] +++        [ x | x <- cleverefCodelisting, useCleveref opts && not (useListings opts)] +++        []+      where+        floatnames = [+            "\\AtBeginDocument{%"+          , "\\renewcommand*\\figurename{"++metaString "figureTitle"++"}"+          , "\\renewcommand*\\tablename{"++metaString "tableTitle"++"}"+          , "}"+          ]+        listnames = [+            "\\AtBeginDocument{%"+          , "\\renewcommand*\\listfigurename{"++metaString' "lofTitle"++"}"+          , "\\renewcommand*\\listtablename{"++metaString' "lotTitle"++"}"+          , "}"+          ]+        codelisting = [+            "\\usepackage{float}"+          , "\\floatstyle{ruled}"+          , "\\newfloat{codelisting}{h}{lop}"+          , "\\floatname{codelisting}{"++metaString "listingTitle"++"}"+          ]+        lolcommand+          | useListings opts = [+              "\\newcommand*\\listoflistings\\lstlistoflistings"+            , "\\AtBeginDocument{%"+            , "\\renewcommand*{\\lstlistlistingname}{"++metaString' "lolTitle"++"}"+            , "}"+            ]+          | otherwise = ["\\newcommand*\\listoflistings{\\listof{codelisting}{"++metaString' "lolTitle"++"}}"]+        cleveref = [+            "\\usepackage{cleveref}"+          , "\\crefname{figure}" ++ prefix "figPrefix"+          , "\\crefname{table}" ++ prefix "tblPrefix"+          , "\\crefname{equation}" ++ prefix "eqnPrefix"+          , "\\crefname{listing}" ++ prefix "lstPrefix"+          ]+        cleverefCodelisting = [+            "\\makeatletter"+          , "\\crefname{codelisting}{\\cref@listing@name}{\\cref@listing@name@plural}"+          , "\\makeatother"+          ]+        toLatex = writeLaTeX def . Pandoc nullMeta . return . Plain+        metaString s = toLatex $ getMetaInlines s meta+        metaString' s = toLatex [Str $ getMetaString s meta]+        metaList s = toLatex . getMetaList toInlines s meta+        prefix s = "{" ++ metaList s 0 ++ "}" +++                   "{" ++ metaList s 1 ++ "}"
src/Util/Options.hs view
@@ -6,16 +6,21 @@  data Options = Options { useCleveref :: Bool                        , sepChapters :: Bool-                       , figPrefix   :: [Inline]-                       , eqnPrefix   :: [Inline]-                       , tblPrefix   :: [Inline]+                       , useListings :: Bool+                       , cbCaptions  :: Bool+                       , figPrefix   :: Int -> [Inline]+                       , eqnPrefix   :: Int -> [Inline]+                       , tblPrefix   :: Int -> [Inline]+                       , lstPrefix   :: Int -> [Inline]                        , chapDelim   :: [Inline]                        , rangeDelim  :: [Inline]                        , lofTitle    :: [Block]                        , lotTitle    :: [Block]+                       , lolTitle    :: [Block]                        , outFormat   :: Maybe Format                        , figureTemplate :: Template                        , tableTemplate  :: Template+                       , listingTemplate :: Template                        }  getOptions :: Meta -> Maybe Format -> Options@@ -23,14 +28,19 @@   Options {       useCleveref = getMetaBool "cref" dtv     , sepChapters = getMetaBool "chapters" dtv-    , figPrefix   = getMetaInlines "figPrefix" dtv-    , eqnPrefix   = getMetaInlines "eqnPrefix" dtv-    , tblPrefix   = getMetaInlines "tblPrefix" dtv+    , useListings = getMetaBool "listings" dtv+    , cbCaptions  = getMetaBool "codeBlockCaptions" dtv+    , figPrefix   = getMetaList toInlines "figPrefix" dtv+    , eqnPrefix   = getMetaList toInlines "eqnPrefix" dtv+    , tblPrefix   = getMetaList toInlines "tblPrefix" dtv+    , lstPrefix   = getMetaList toInlines "lstPrefix" dtv     , chapDelim   = getMetaInlines "chapDelim" dtv     , rangeDelim  = getMetaInlines "rangeDelim" dtv     , lofTitle    = getMetaBlock "lofTitle" dtv     , lotTitle    = getMetaBlock "lotTitle" dtv+    , lolTitle    = getMetaBlock "lolTitle" dtv     , outFormat   = fmt     , figureTemplate = makeTemplate dtv $ getMetaInlines "figureTemplate" dtv     , tableTemplate  = makeTemplate dtv $ getMetaInlines "tableTemplate" dtv+    , listingTemplate = makeTemplate dtv $ getMetaInlines "listingTemplate" dtv   }
src/Util/Settings.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} module Util.Settings (getSettings, defaultMeta) where  import Text.Pandoc@@ -12,23 +13,31 @@   let handler :: IOException -> IO String       handler _ = return []   yaml <- handle handler $ readFile (getMetaString "crossrefYaml" (meta <> defaultMeta))+#if MIN_VERSION_pandoc(1,14,0)+  let Pandoc dtve _ = either (error . show) id $ readMarkdown def ("---\n" ++ yaml ++ "\n---")+#else   let Pandoc dtve _ = readMarkdown def ("---\n" ++ yaml ++ "\n---")+#endif   return $ meta <> dtve <> defaultMeta  defaultMeta :: Meta defaultMeta = Meta $ M.fromList   [ ("figureTitle"    , MetaInlines [Str "Figure"])   , ("tableTitle"     , MetaInlines [Str "Table"])+  , ("listingTitle"   , MetaInlines [Str "Listing"])   , ("titleDelim"     , MetaInlines [Str ":"])   , ("chapDelim"      , MetaInlines [Str "."])   , ("rangeDelim"     , MetaInlines [Str "-"])-  , ("figPrefix"      , MetaInlines [Str "fig."])-  , ("eqnPrefix"      , MetaInlines [Str "eq."])-  , ("tblPrefix"      , MetaInlines [Str "tbl."])+  , ("figPrefix"      , MetaList [MetaInlines [Str "fig."], MetaInlines [Str "figs."]])+  , ("eqnPrefix"      , MetaList [MetaInlines [Str "eq."], MetaInlines [Str "eqns."]])+  , ("tblPrefix"      , MetaList [MetaInlines [Str "tbl."], MetaInlines [Str "tbls."]])+  , ("lstPrefix"      , MetaList [MetaInlines [Str "lst."], MetaInlines [Str "lsts."]])   , ("lofTitle"       , MetaBlocks [Header 1 nullAttr [Str "List",Space,Str "of",Space,Str "Figures"]])   , ("lotTitle"       , MetaBlocks [Header 1 nullAttr [Str "List",Space,Str "of",Space,Str "Tables"]])+  , ("lolTitle"       , MetaBlocks [Header 1 nullAttr [Str "List",Space,Str "of",Space,Str "Listings"]])   , ("figureTemplate" , MetaInlines [var "figureTitle",Space,var "i",var "titleDelim",Space,var "t"])   , ("tableTemplate"  , MetaInlines [var "tableTitle",Space,var "i",var "titleDelim",Space,var "t"])+  , ("listingTemplate", MetaInlines [var "listingTitle",Space,var "i",var "titleDelim",Space,var "t"])   , ("crossrefYaml"   , MetaString "pandoc-crossref.yaml")   ]   where var = Math DisplayMath
src/Util/Util.hs view
@@ -2,5 +2,6 @@  import Text.Pandoc.Definition -isFormat :: String -> Format -> Bool-isFormat fmt (Format f) = takeWhile (`notElem` "+-") f == fmt+isFormat :: String -> Maybe Format -> Bool+isFormat fmt (Just (Format f)) = takeWhile (`notElem` "+-") f == fmt+isFormat _ Nothing = False
test-pandoc-crossref.hs view
@@ -13,6 +13,7 @@ import qualified References.Refs import qualified References.List import qualified Util.Template+import qualified Util.CodeBlockCaptions import qualified Data.Map as M import Data.Monoid @@ -31,20 +32,32 @@         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"})      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' "fig.\160\&4-6"+        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' "eq.\160\&4-6"+        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' "tbl.\160\&4-6"+        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"      describe "References.List.listOf" $ do       it "Generates list of tables" $@@ -56,6 +69,14 @@                  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")@@ -84,6 +105,9 @@ 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) @@ -97,6 +121,23 @@ 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