Skip to content

Commit e8e9546

Browse files
committed
Updates for pandoc 3.0 and bump version
1 parent 05730bf commit e8e9546

File tree

27 files changed

+1048
-420
lines changed

27 files changed

+1048
-420
lines changed

cabal.project

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ package pandoc
55
ghc-options: -j +RTS -A64m -RTS
66
package pandoc-crossref
77
ghc-options: -j +RTS -A64m -RTS
8+
tests: True
9+
benchmarks: True

lib-internal/Text/Pandoc/CrossRef/References/Blocks.hs

+16-18
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,13 @@ import Text.Pandoc.CrossRef.References.Blocks.Subfigures
3737
import Text.Pandoc.CrossRef.References.Blocks.Table
3838
import Text.Pandoc.CrossRef.References.Blocks.Util
3939
import Text.Pandoc.CrossRef.References.Monad
40-
import Text.Pandoc.CrossRef.References.Types
4140
import Text.Pandoc.CrossRef.Util.Options
42-
import Text.Pandoc.CrossRef.Util.Template
4341
import Text.Pandoc.CrossRef.Util.Util
4442

4543
replaceAll :: (Data a) => a -> WS a
4644
replaceAll x = do
4745
opts <- ask
4846
x & runReplace (mkRR replaceBlock
49-
`extRR` replaceInline
5047
`extRR` replaceInlineMany
5148
)
5249
. runSplitMath opts
@@ -58,12 +55,25 @@ replaceAll x = do
5855
= everywhere (mkT splitMath)
5956
| otherwise = id
6057

58+
extractCaption :: Block -> Maybe [Inline]
59+
extractCaption = \case
60+
Para caption -> Just caption
61+
Div (_, dcls, _) [Para caption] | "caption" `elem` dcls -> Just caption
62+
_ -> Nothing
63+
6164
replaceBlock :: Block -> WS (ReplacedResult Block)
6265
replaceBlock (Header n attr text') = runHeader n attr text'
63-
replaceBlock (Div attr@(label, _, _) images)
66+
replaceBlock (Figure attr@(label, _, _) caption content)
67+
| "fig:" `T.isPrefixOf` label
68+
= runFigure False attr caption content
69+
replaceBlock (Div attr@(label, _, _) content)
6470
| "fig:" `T.isPrefixOf` label
65-
, Para caption <- last images
66-
= runSubfigures attr images caption
71+
, Just caption <- extractCaption $ last content
72+
= case init content of
73+
[Figure ("", [], []) _ content'] -- nested figure due to implicit_figures...
74+
-> runFigure False attr (Caption Nothing [Para caption]) content'
75+
[x] -> runFigure False attr (Caption Nothing [Para caption]) [x]
76+
xs -> runSubfigures attr xs caption
6777
replaceBlock (Div attr@(label, _, _) [Table tattr (Caption short (btitle:rest)) colspec header cells foot])
6878
| not $ null $ blocksToInlines [btitle]
6979
, "tbl:" `T.isPrefixOf` label
@@ -103,18 +113,6 @@ replaceInlineMany (Span spanAttr@(label,clss,attrs) [Math DisplayMath eq]:xs) =
103113
else noReplaceRecurse
104114
replaceInlineMany _ = noReplaceRecurse
105115

106-
replaceInline :: Inline -> WS (ReplacedResult Inline)
107-
replaceInline (Image (label,cls,attrs) alt img@(_, tit))
108-
| "fig:" `T.isPrefixOf` label && "fig:" `T.isPrefixOf` tit
109-
= do
110-
opts <- ask
111-
idxStr <- replaceAttr (Right label) (lookup "label" attrs) alt imgRefs
112-
let alt' = case outFormat opts of
113-
f | isLatexFormat f -> alt
114-
_ -> applyTemplate idxStr alt $ figureTemplate opts
115-
replaceNoRecurse $ Image (label,cls,setLabel opts idxStr attrs) alt' img
116-
replaceInline _ = noReplaceRecurse
117-
118116
divBlocks :: Block -> Block
119117
divBlocks (Table tattr (Caption short (btitle:rest)) colspec header cells foot)
120118
| not $ null title

lib-internal/Text/Pandoc/CrossRef/References/Blocks/Subfigures.hs

+76-38
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1818
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1919
-}
2020

21-
{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}
21+
{-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts, LambdaCase #-}
2222

2323
module Text.Pandoc.CrossRef.References.Blocks.Subfigures where
2424

@@ -35,10 +35,11 @@ import Data.Maybe
3535
import Text.Pandoc.Walk (walk)
3636
import Lens.Micro
3737
import Lens.Micro.Mtl
38+
import Text.Pandoc.Shared (blocksToInlines)
3839

3940
import Text.Pandoc.CrossRef.References.Types
4041
import Text.Pandoc.CrossRef.References.Monad
41-
import Text.Pandoc.CrossRef.References.Blocks.Util (setLabel, replaceAttr, mkCaption)
42+
import Text.Pandoc.CrossRef.References.Blocks.Util (setLabel, replaceAttr, walkReplaceInlines)
4243
import Text.Pandoc.CrossRef.Util.Options
4344
import Text.Pandoc.CrossRef.Util.Template
4445
import Text.Pandoc.CrossRef.Util.Util
@@ -47,7 +48,10 @@ runSubfigures :: Attr -> [Block] -> [Inline] -> WS (ReplacedResult Block)
4748
runSubfigures (label, cls, attrs) images caption = do
4849
opts <- ask
4950
idxStr <- replaceAttr (Right label) (lookup "label" attrs) caption imgRefs
50-
let (cont, st) = flip runState def $ flip runReaderT opts' $ runWS $ runReplace (mkRR $ replaceSubfigs) $ init images
51+
let (cont, st) = flip runState def $ flip runReaderT opts' $ runWS $ runReplace (mkRR replaceSubfigs `extRR` doFigure) $ images
52+
doFigure :: Block -> WS (ReplacedResult Block)
53+
doFigure (Figure attr caption' content) = runFigure True attr caption' content
54+
doFigure _ = noReplaceRecurse
5155
opts' = opts
5256
{ figureTemplate = subfigureChildTemplate opts
5357
, customLabel = \r i -> customLabel opts ("sub"<>r) i
@@ -77,32 +81,33 @@ runSubfigures (label, cls, attrs) images caption = do
7781
(M.map (\v -> v{refIndex = refIndex lastRef, refSubfigure = Just $ refIndex v})
7882
$ st^.imgRefs)
7983
case outFormat opts of
80-
f | isLatexFormat f ->
81-
replaceNoRecurse $ Div nullAttr $
82-
[ RawBlock (Format "latex") "\\begin{pandoccrossrefsubfigures}" ]
83-
<> cont <>
84-
[ Para [RawInline (Format "latex") "\\caption["
85-
, Span nullAttr (removeFootnotes caption)
86-
, RawInline (Format "latex") "]"
87-
, Span nullAttr caption]
88-
, RawBlock (Format "latex") $ mkLaTeXLabel label
89-
, RawBlock (Format "latex") "\\end{pandoccrossrefsubfigures}"]
90-
_ -> replaceNoRecurse $ Div (label, "subfigures":cls, setLabel opts idxStr attrs) $ toTable opts cont capt
84+
f | isLatexFormat f ->
85+
replaceNoRecurse $ Div nullAttr $
86+
[ RawBlock (Format "latex") "\\begin{pandoccrossrefsubfigures}" ]
87+
<> cont <>
88+
[ Para [RawInline (Format "latex") "\\caption["
89+
, Span nullAttr (removeFootnotes caption)
90+
, RawInline (Format "latex") "]"
91+
, Span nullAttr caption]
92+
, RawBlock (Format "latex") $ mkLaTeXLabel label
93+
, RawBlock (Format "latex") "\\end{pandoccrossrefsubfigures}"]
94+
_ -> replaceNoRecurse
95+
$ Figure (label, "subfigures":cls, setLabel opts idxStr attrs) (Caption Nothing [Para capt])
96+
$ toTable opts cont
9197
where
9298
removeFootnotes = walk removeFootnote
9399
removeFootnote Note{} = Str ""
94100
removeFootnote x = x
95-
toTable :: Options ->[Block] -> [Inline] -> [Block]
96-
toTable opts blks capt
97-
| subfigGrid opts = [ simpleTable align (map ColWidth widths) (map blkToRow blks)
98-
, mkCaption opts "Image Caption" capt]
99-
| otherwise = blks <> [mkCaption opts "Image Caption" capt]
101+
toTable :: Options -> [Block] -> [Block]
102+
toTable opts blks
103+
| isLatexFormat $ outFormat opts = concatMap imagesToFigures blks
104+
| subfigGrid opts = [simpleTable align (map ColWidth widths) (map (fmap pure . blkToRow) blks)]
105+
| otherwise = blks
100106
where
101-
align | Para ils:_ <- blks = replicate (length $ mapMaybe getWidth ils) AlignCenter
107+
align | b:_ <- blks = let ils = blocksToInlines [b] in replicate (length $ mapMaybe getWidth ils) AlignCenter
102108
| otherwise = error "Misformatted subfigures block"
103-
widths | Para ils:_ <- blks
104-
= fixZeros $ mapMaybe getWidth ils
105-
| otherwise = error "Misformatted subfigures block"
109+
widths | b:_ <- blks = let ils = blocksToInlines [b] in fixZeros $ mapMaybe getWidth ils
110+
| otherwise = error "Misformatted subfigures block"
106111
getWidth (Image (_id, _class, as) _ _)
107112
= Just $ maybe 0 percToDouble $ lookup "width" as
108113
getWidth _ = Nothing
@@ -118,34 +123,42 @@ runSubfigures (label, cls, attrs) images caption = do
118123
| Right (perc, "%") <- T.double percs
119124
= perc/100.0
120125
| otherwise = error "Only percent allowed in subfigure width!"
121-
blkToRow :: Block -> [[Block]]
126+
blkToRow :: Block -> [Block]
122127
blkToRow (Para inls) = mapMaybe inlToCell inls
123-
blkToRow x = [[x]]
124-
inlToCell :: Inline -> Maybe [Block]
125-
inlToCell (Image (id', cs, as) txt tgt) = Just [Para [Image (id', cs, setW as) txt tgt]]
128+
blkToRow x = [x]
129+
inlToCell :: Inline -> Maybe Block
130+
inlToCell (Image (id', cs, as) txt tgt) = Just $
131+
Figure (id', cs, as) (Caption Nothing [Para txt]) [Plain [Image ("", cs, setW as) txt tgt]]
126132
inlToCell _ = Nothing
127133
setW as = ("width", "100%"):filter ((/="width") . fst) as
128134

129135
replaceSubfigs :: [Inline] -> WS (ReplacedResult [Inline])
130136
replaceSubfigs = (replaceNoRecurse . concat) <=< mapM replaceSubfig
131137

138+
imagesToFigures :: Block -> [Block]
139+
imagesToFigures = \case
140+
x@Figure{} -> [x]
141+
Para xs -> mapMaybe imageToFigure xs
142+
Plain xs -> mapMaybe imageToFigure xs
143+
_ -> []
144+
145+
imageToFigure :: Inline -> Maybe Block
146+
imageToFigure = \case
147+
Image (label,cls,attrs) alt tgt -> Just $ Figure (label, cls, attrs) (Caption Nothing [Para alt])
148+
[Plain [Image ("",cls,attrs) alt tgt]]
149+
_ -> Nothing
150+
132151
replaceSubfig :: Inline -> WS [Inline]
133-
replaceSubfig x@(Image (label,cls,attrs) alt (src, tit))
152+
replaceSubfig x@(Image (label,cls,attrs) alt tgt)
134153
= do
135154
opts <- ask
136-
let label' | "fig:" `T.isPrefixOf` label = Right label
137-
| T.null label = Left "fig"
138-
| otherwise = Right $ "fig:" <> label
155+
let label' = normalizeLabel label
139156
idxStr <- replaceAttr label' (lookup "label" attrs) alt imgRefs
157+
let alt' = applyTemplate idxStr alt $ figureTemplate opts
140158
case outFormat opts of
141159
f | isLatexFormat f ->
142-
return $ latexSubFigure x label
143-
_ ->
144-
let alt' = applyTemplate idxStr alt $ figureTemplate opts
145-
tit' | "nocaption" `elem` cls = fromMaybe tit $ T.stripPrefix "fig:" tit
146-
| "fig:" `T.isPrefixOf` tit = tit
147-
| otherwise = "fig:" <> tit
148-
in return [Image (label, cls, setLabel opts idxStr attrs) alt' (src, tit')]
160+
pure $ latexSubFigure x label
161+
_ -> return [Image (label, cls, setLabel opts idxStr attrs) alt' tgt]
149162
replaceSubfig x = return [x]
150163

151164
latexSubFigure :: Inline -> T.Text -> [Inline]
@@ -168,6 +181,12 @@ latexSubFigure (Image (_, cls, attrs) alt (src, title)) label =
168181
]
169182
latexSubFigure x _ = [x]
170183

184+
normalizeLabel :: T.Text -> Either T.Text T.Text
185+
normalizeLabel label
186+
| "fig:" `T.isPrefixOf` label = Right label
187+
| T.null label = Left "fig"
188+
| otherwise = Right $ "fig:" <> label
189+
171190
simpleTable :: [Alignment] -> [ColWidth] -> [[[Block]]] -> Block
172191
simpleTable align width bod = Table nullAttr noCaption (zip align width)
173192
noTableHead [mkBody bod] noTableFoot
@@ -178,3 +197,22 @@ simpleTable align width bod = Table nullAttr noCaption (zip align width)
178197
noCaption = Caption Nothing mempty
179198
noTableHead = TableHead nullAttr []
180199
noTableFoot = TableFoot nullAttr []
200+
201+
runFigure :: Bool -> Attr -> Caption -> [Block] -> WS (ReplacedResult Block)
202+
runFigure subFigure (label, cls, fattrs) (Caption short (btitle : rest)) content = do
203+
opts <- ask
204+
let label' = normalizeLabel label
205+
let title = blocksToInlines [btitle]
206+
attrs = fromMaybe fattrs $ case blocksToInlines content of
207+
[Image (_, _, as) _ _] -> Just as
208+
_ -> Nothing
209+
idxStr <- replaceAttr label' (lookup "label" attrs) title imgRefs
210+
let title' = case outFormat opts of
211+
f | isLatexFormat f -> title
212+
_ -> applyTemplate idxStr title $ figureTemplate opts
213+
caption' = Caption short (walkReplaceInlines title' title btitle:rest)
214+
replaceNoRecurse $
215+
if subFigure && isLatexFormat (outFormat opts)
216+
then Plain $ latexSubFigure (head $ blocksToInlines content) label
217+
else Figure (label,cls,setLabel opts idxStr attrs) caption' content
218+
runFigure _ _ _ _ = noReplaceNoRecurse

lib-internal/Text/Pandoc/CrossRef/Util/CodeBlockCaptions.hs

+12-7
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1818
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1919
-}
2020

21-
{-# LANGUAGE OverloadedStrings #-}
21+
{-# LANGUAGE OverloadedStrings, LambdaCase #-}
2222
module Text.Pandoc.CrossRef.Util.CodeBlockCaptions
2323
(
2424
mkCodeBlockCaptions
2525
) where
2626

27+
import Control.Monad.Reader (ask)
2728
import Data.List (stripPrefix)
2829
import Data.Maybe (fromMaybe)
2930
import qualified Data.Text as T
@@ -32,12 +33,16 @@ import Text.Pandoc.CrossRef.Util.Options
3233
import Text.Pandoc.CrossRef.Util.Util
3334
import Text.Pandoc.Definition
3435

35-
mkCodeBlockCaptions :: Options -> [Block] -> WS [Block]
36-
mkCodeBlockCaptions opts x@(cb@(CodeBlock _ _):p@(Para _):xs)
37-
= return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
38-
mkCodeBlockCaptions opts x@(p@(Para _):cb@(CodeBlock _ _):xs)
39-
= return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
40-
mkCodeBlockCaptions _ x = return x
36+
mkCodeBlockCaptions :: [Block] -> WS [Block]
37+
mkCodeBlockCaptions = \case
38+
x@(cb@CodeBlock{}:p@Para{}:xs) -> go x p cb xs
39+
x@(p@Para{}:cb@CodeBlock{}:xs) -> go x p cb xs
40+
x -> pure x
41+
where
42+
go :: [Block] -> Block -> Block -> [Block] -> WS [Block]
43+
go x p cb xs = do
44+
opts <- ask
45+
return $ fromMaybe x $ orderAgnostic opts $ p:cb:xs
4146

4247
orderAgnostic :: Options -> [Block] -> Maybe [Block]
4348
orderAgnostic opts (Para ils:CodeBlock (label,classes,attrs) code:xs)

lib/Text/Pandoc/CrossRef.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ crossRefBlocks blocks = do
109109
opts <- R.asks creOptions
110110
let
111111
doWalk =
112-
bottomUpM (mkCodeBlockCaptions opts) blocks
112+
bottomUpM mkCodeBlockCaptions blocks
113113
>>= replaceAll
114114
>>= bottomUpM replaceRefs
115115
>>= bottomUpM listOf

package.yaml

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: pandoc-crossref
2-
version: '0.3.14.0'
2+
version: '0.3.15.0'
33
synopsis: Pandoc filter for cross-references
44
description: pandoc-crossref is a pandoc filter for numbering figures, equations,
55
tables and cross-references to them.
@@ -20,8 +20,8 @@ data-files:
2020
dependencies:
2121
- base >=4.11 && <5
2222
- text >=1.2.2 && <2.1
23-
- pandoc >=2.18 && < 2.20
24-
- pandoc-types >=1.22.2 && <1.23
23+
- pandoc >=3.0 && < 3.1
24+
- pandoc-types
2525
library:
2626
source-dirs: lib
2727
ghc-options: -Wall
@@ -112,6 +112,8 @@ tests:
112112
- hspec >=2.4.4 && <3
113113
- directory >=1 && <1.4
114114
- filepath >=1.1 && <1.5
115+
build-tools:
116+
- pandoc-cli:pandoc
115117
benchmarks:
116118
simple:
117119
main: bench-simple.hs

0 commit comments

Comments
 (0)