pandoc-crossref 0.1.1.0 → 0.1.2.0
raw patch · 8 files changed
+128/−52 lines, 8 files
Files
- README.md +5/−1
- pandoc-crossref.cabal +2/−2
- src/References/Blocks.hs +2/−2
- src/References/Refs.hs +44/−30
- src/Util/ModifyMeta.hs +11/−7
- src/Util/Options.hs +31/−9
- src/Util/Util.hs +13/−0
- test-pandoc-crossref.hs +20/−1
README.md view
@@ -134,8 +134,10 @@ [@fig:label1;@fig:label2;...] or [@eq:label1;@eq:label2;...] or [@tbl:label1;@tbl:label2;...] or @fig:label or @eq:label or @tbl:label ``` -Reference syntax heavily relies on citation syntax. Basic reference is created by writing `@`, then basically desired label with prefix. It is also possible to reference a group of objects *of the same type*, by putting them into brackets with `;` as separator. Sequential reference numbers will be shortened, e.g. `1,2,3` will be shortened to `1-3`.+Reference syntax heavily relies on citation syntax. Basic reference is created by writing `@`, then basically desired label with prefix. It is also possible to reference a group of objects, by putting them into brackets with `;` as separator. Similar objects will be grouped in order of them appearing in citation brackets, and sequential reference numbers will be shortened, e.g. `1,2,3` will be shortened to `1-3`. +You can capitalize first reference character to get capitalized prefix, e.g. `[@Fig:label1]` will produce `Fig. ...` by default. Capitalized prefixes are derived automatically by capitalizing first letter of every word in non-capitalized prefix, unless overriden with metadata settings. See [Customization](#Customization) for more information.+ ### Lists 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.@@ -203,6 +205,8 @@ ``` They can be YAML strings as well. In that case, prefix would be the same regardless of number of references.++They can also be used with first character capitalized, i.e. `FigPrefix`, etc. In this case, these settings will override default reference capitailzation settings. ### Templates
pandoc-crossref.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: pandoc-crossref-version: 0.1.1.0+version: 0.1.2.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.1.0+ tag: v0.1.2.0 executable pandoc-crossref main-is: pandoc-crossref.hs
src/References/Blocks.hs view
@@ -52,7 +52,7 @@ return $ Table title' align widths header cells replaceBlocks opts cb@(CodeBlock (label, classes, attrs) code) | not $ null label- , "lst" `isPrefixOf` label+ , "lst:" `isPrefixOf` label , Just caption <- lookup "caption" attrs = case outFormat opts of f@@ -78,7 +78,7 @@ (Div (label,"listing":_, []) [Para caption, CodeBlock ([],classes,attrs) code]) | not $ null label- , "lst" `isPrefixOf` label+ , "lst:" `isPrefixOf` label = case outFormat opts of f --if used with listings package, return code block with caption
src/References/Refs.hs view
@@ -1,7 +1,7 @@ module References.Refs (replaceRefs) where import Text.Pandoc.Definition-import Text.Pandoc.Shared (normalizeInlines)+import Text.Pandoc.Shared (normalizeInlines, normalizeSpaces) import Control.Monad.State import Data.List import Data.Maybe@@ -17,12 +17,25 @@ replaceRefs :: Options -> [Inline] -> WS [Inline] replaceRefs opts (Cite cits _:xs)- | Just prefix <- allCitsPrefix cits- = (++ xs) `fmap` replaceRefs' prefix opts cits+ = (++ xs) `fmap` intercalate [Str ",", Space] `fmap`+ mapM replaceRefs' (groupBy eqPrefix cits) where- replaceRefs' = case outFormat opts of+ eqPrefix a b = uncurry (==) $+ (uncapitalizeFirst . getLabelPrefix . citationId) <***> (a,b)+ (<***>) = join (***)+ replaceRefs' cits'+ | Just prefix <- allCitsPrefix cits'+ = replaceRefs'' prefix opts cits'+ | otherwise = return [Cite cits' il']+ where+ il' = [Str "["]+ ++intercalate [Str ";"] (map citationToInlines cits')+ ++[Str "]"]+ citationToInlines c = normalizeSpaces $+ citationPrefix c ++ [Space, Str $ "@"++citationId c] ++ citationSuffix c+ replaceRefs'' = case outFormat opts of f | isFormat "latex" f -> replaceRefsLatex- _ -> replaceRefsOther+ _ -> replaceRefsOther replaceRefs _ x = return x -- accessors to state variables@@ -34,7 +47,7 @@ ] -- accessors to options-prefMap :: M.Map String (Options -> Int -> [Inline])+prefMap :: M.Map String (Options -> Bool -> Int -> [Inline]) prefMap = M.fromList [("fig:",figPrefix) ,("eq:" ,eqnPrefix) ,("tbl:",tblPrefix)@@ -44,21 +57,20 @@ prefixes :: [String] prefixes = M.keys accMap -getRefPrefix :: Options -> String -> Int -> [Inline]-getRefPrefix opts prefix num- | null $ refprefix num = []- | otherwise = refprefix num ++ [Str "\160"]- where refprefix = lookupUnsafe prefix prefMap opts+getRefPrefix :: Options -> String -> Bool -> Int -> [Inline]+getRefPrefix opts prefix capitalize num+ | null refprefix = []+ | otherwise = refprefix ++ [Str "\160"]+ where refprefix = lookupUnsafe prefix prefMap opts capitalize num lookupUnsafe :: Ord k => k -> M.Map k v -> v-lookupUnsafe = (fromMaybe undefined .) . M.lookup+lookupUnsafe = (fromJust .) . M.lookup allCitsPrefix :: [Citation] -> Maybe String-allCitsPrefix cits = foldl f Nothing prefixes+allCitsPrefix cits = find isCitationPrefix prefixes where- f x@(Just _) _ = x- f _ p | all (isPrefixOf p . citationId) cits = Just p- f _ _ = Nothing+ isCitationPrefix p =+ all (p `isPrefixOf`) $ map (uncapitalizeFirst . citationId) cits replaceRefsLatex :: String -> Options -> [Citation] -> WS [Inline] replaceRefsLatex prefix opts cits =@@ -67,37 +79,39 @@ texcit = RawInline (Format "tex") $ if useCleveref opts then- "\\cref{"++listLabels prefix "" "," "" cits++"}"+ cref++"{"++listLabels prefix "" "," "" cits++"}" else listLabels prefix "\\ref{" ", " "}" cits p | useCleveref opts = []- | otherwise = getRefPrefix opts prefix (length cits - 1)+ | otherwise = getRefPrefix opts prefix cap (length cits - 1)+ cap = isFirstUpper $ getLabelPrefix . citationId . head $ cits+ cref | cap = "\\Cref"+ | otherwise = "\\cref" 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++sep++p++i++s+listLabels prefix p sep s =+ intercalate sep . map ((p ++) . (++ s) . (prefix++) . getLabelWithoutPrefix . citationId) -getLabel :: String -> Citation -> Maybe String-getLabel prefix Citation{citationId=cid}- | prefix `isPrefixOf` cid = Just cid- | otherwise = Nothing+getLabelWithoutPrefix :: String -> String+getLabelWithoutPrefix = drop 1 . dropWhile (/=':') +getLabelPrefix :: String -> String+getLabelPrefix = (++ ":") . takeWhile (/=':')+ replaceRefsOther :: String -> Options -> [Citation] -> WS [Inline] replaceRefsOther prefix opts cits = do indices <- mapM (getRefIndex prefix) cits let indices' = groupBy ((==) `on` (fmap fst . fst)) (sort indices)- return $ normalizeInlines $ getRefPrefix opts prefix (length cits - 1) ++ concatMap (makeIndices opts) indices'+ cap = isFirstUpper $ getLabelPrefix . citationId . head $ cits+ return $ normalizeInlines $ getRefPrefix opts prefix cap (length cits - 1) ++ concatMap (makeIndices opts) indices' getRefIndex :: String -> Citation -> WS (Maybe (Int, Int), [Inline]) getRefIndex prefix Citation{citationId=cid,citationSuffix=suf}- | prefix `isPrefixOf` cid- = (\x -> (x,suf)) `fmap` gets (fmap refIndex . M.lookup cid . getProp prop)- | otherwise = return (Nothing, suf)+ = (\x -> (x,suf)) `fmap` gets (fmap refIndex . M.lookup lab . getProp prop) where prop = lookupUnsafe prefix accMap+ lab = prefix ++ getLabelWithoutPrefix cid makeIndices :: Options -> [(Maybe (Int, Int), [Inline])] -> [Inline] makeIndices _ s | any (isNothing . fst) s = [Strong [Str "??"]]
src/Util/ModifyMeta.hs view
@@ -59,19 +59,23 @@ | 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"+ , "\\crefname{figure}" ++ prefix figPrefix False+ , "\\crefname{table}" ++ prefix tblPrefix False+ , "\\crefname{equation}" ++ prefix eqnPrefix False+ , "\\crefname{listing}" ++ prefix lstPrefix False+ , "\\Crefname{figure}" ++ prefix figPrefix True+ , "\\Crefname{table}" ++ prefix tblPrefix True+ , "\\Crefname{equation}" ++ prefix eqnPrefix True+ , "\\Crefname{listing}" ++ prefix lstPrefix True ] cleverefCodelisting = [ "\\makeatletter" , "\\crefname{codelisting}{\\cref@listing@name}{\\cref@listing@name@plural}"+ , "\\Crefname{codelisting}{\\Cref@listing@name}{\\Cref@listing@name@plural}" , "\\makeatother" ] toLatex = writeLaTeX def . Pandoc nullMeta . return . Plain metaString s = toLatex $ getMetaInlines s meta metaString' s = toLatex [Str $ getMetaString s meta]- metaList s = toLatex . getMetaList toInlines s meta- prefix s = "{" ++ metaList s 0 ++ "}" ++- "{" ++ metaList s 1 ++ "}"+ prefix f uc = "{" ++ toLatex (f opts uc 0) ++ "}" +++ "{" ++ toLatex (f opts uc 1) ++ "}"
src/Util/Options.hs view
@@ -1,17 +1,22 @@-module Util.Options where+{-# LANGUAGE FlexibleContexts #-} +module Util.Options (Options(..), getOptions) where import Text.Pandoc.Definition import Util.Meta import Util.Template+import Util.Util (capitalizeFirst)+import Text.Pandoc.Walk+import Data.Default+-- import Control.Monad.Identity data Options = Options { useCleveref :: Bool , sepChapters :: Bool , useListings :: Bool , cbCaptions :: Bool- , figPrefix :: Int -> [Inline]- , eqnPrefix :: Int -> [Inline]- , tblPrefix :: Int -> [Inline]- , lstPrefix :: Int -> [Inline]+ , figPrefix :: Bool -> Int -> [Inline]+ , eqnPrefix :: Bool -> Int -> [Inline]+ , tblPrefix :: Bool -> Int -> [Inline]+ , lstPrefix :: Bool -> Int -> [Inline] , chapDelim :: [Inline] , rangeDelim :: [Inline] , lofTitle :: [Block]@@ -30,10 +35,10 @@ , sepChapters = getMetaBool "chapters" 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+ , figPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "figPrefix"+ , eqnPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "eqnPrefix"+ , tblPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "tblPrefix"+ , lstPrefix = tryCapitalizeM (flip (getMetaList toInlines) dtv) "lstPrefix" , chapDelim = getMetaInlines "chapDelim" dtv , rangeDelim = getMetaInlines "rangeDelim" dtv , lofTitle = getMetaBlock "lofTitle" dtv@@ -44,3 +49,20 @@ , tableTemplate = makeTemplate dtv $ getMetaInlines "tableTemplate" dtv , listingTemplate = makeTemplate dtv $ getMetaInlines "listingTemplate" dtv }++tryCapitalizeM :: (Functor m, Monad m, Walkable Inline a, Default a, Eq a) =>+ (String -> m a) -> String -> Bool -> m a+tryCapitalizeM f varname capitalize+ | capitalize = do+ res <- f (capitalizeFirst varname)+ case res of+ xs | xs == def -> f varname >>= walkM capStrFst+ | otherwise -> return xs+ | otherwise = f varname+ where+ capStrFst (Str s) = return $ Str $ capitalizeFirst s+ capStrFst x = return x++-- tryCapitalize :: (Walkable Inline a, Default a, Eq a) =>+-- (String -> a) -> String -> Bool -> a+-- tryCapitalize = ((runIdentity .) .) . tryCapitalizeM . (return .)
src/Util/Util.hs view
@@ -1,7 +1,20 @@ module Util.Util where import Text.Pandoc.Definition+import Data.Char (toUpper, toLower, isUpper) isFormat :: String -> Maybe Format -> Bool isFormat fmt (Just (Format f)) = takeWhile (`notElem` "+-") f == fmt isFormat _ Nothing = False++capitalizeFirst :: String -> String+capitalizeFirst (x:xs) = toUpper x : xs+capitalizeFirst [] = []++uncapitalizeFirst :: String -> String+uncapitalizeFirst (x:xs) = toLower x : xs+uncapitalizeFirst [] = []++isFirstUpper :: String -> Bool+isFirstUpper (x:_) = isUpper x+isFirstUpper [] = False
test-pandoc-crossref.hs view
@@ -4,6 +4,7 @@ import Text.Pandoc.Walk import Text.Pandoc.Generic import Util.Options+import Util.Util import Control.Monad.State import References.Types import Util.Settings@@ -59,6 +60,24 @@ it "References multiple listings" $ testRefs' "lst:" [1..3] [4..6] lstRefs' "lsts.\160\&4-6" + 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"+ describe "References.List.listOf" $ do it "Generates list of tables" $ testList (para $ rawInline "tex" "\\listoftables")@@ -87,7 +106,7 @@ citeGen p l = cite (mconcat $ map (cit . (p++) . show) l) mempty refGen :: String -> [Int] -> [Int] -> M.Map String RefRec-refGen p l1 l2 = M.fromList $ mconcat $ zipWith refRec'' (((p++) . show) `map` l1) l2+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=(0,i),refTitle=toList $ text tit})]