@@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
18
18
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
19
-}
20
20
21
- {-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts #-}
21
+ {-# LANGUAGE Rank2Types, OverloadedStrings, FlexibleContexts, LambdaCase #-}
22
22
23
23
module Text.Pandoc.CrossRef.References.Blocks.Subfigures where
24
24
@@ -35,10 +35,11 @@ import Data.Maybe
35
35
import Text.Pandoc.Walk (walk )
36
36
import Lens.Micro
37
37
import Lens.Micro.Mtl
38
+ import Text.Pandoc.Shared (blocksToInlines )
38
39
39
40
import Text.Pandoc.CrossRef.References.Types
40
41
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 )
42
43
import Text.Pandoc.CrossRef.Util.Options
43
44
import Text.Pandoc.CrossRef.Util.Template
44
45
import Text.Pandoc.CrossRef.Util.Util
@@ -47,7 +48,10 @@ runSubfigures :: Attr -> [Block] -> [Inline] -> WS (ReplacedResult Block)
47
48
runSubfigures (label, cls, attrs) images caption = do
48
49
opts <- ask
49
50
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
51
55
opts' = opts
52
56
{ figureTemplate = subfigureChildTemplate opts
53
57
, customLabel = \ r i -> customLabel opts (" sub" <> r) i
@@ -77,32 +81,33 @@ runSubfigures (label, cls, attrs) images caption = do
77
81
(M. map (\ v -> v{refIndex = refIndex lastRef, refSubfigure = Just $ refIndex v})
78
82
$ st^. imgRefs)
79
83
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
91
97
where
92
98
removeFootnotes = walk removeFootnote
93
99
removeFootnote Note {} = Str " "
94
100
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
100
106
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
102
108
| 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"
106
111
getWidth (Image (_id, _class, as) _ _)
107
112
= Just $ maybe 0 percToDouble $ lookup " width" as
108
113
getWidth _ = Nothing
@@ -118,34 +123,42 @@ runSubfigures (label, cls, attrs) images caption = do
118
123
| Right (perc, " %" ) <- T. double percs
119
124
= perc/ 100.0
120
125
| otherwise = error " Only percent allowed in subfigure width!"
121
- blkToRow :: Block -> [[ Block ] ]
126
+ blkToRow :: Block -> [Block ]
122
127
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]]
126
132
inlToCell _ = Nothing
127
133
setW as = (" width" , " 100%" ): filter ((/= " width" ) . fst ) as
128
134
129
135
replaceSubfigs :: [Inline ] -> WS (ReplacedResult [Inline ])
130
136
replaceSubfigs = (replaceNoRecurse . concat ) <=< mapM replaceSubfig
131
137
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
+
132
151
replaceSubfig :: Inline -> WS [Inline ]
133
- replaceSubfig x@ (Image (label,cls,attrs) alt (src, tit) )
152
+ replaceSubfig x@ (Image (label,cls,attrs) alt tgt )
134
153
= do
135
154
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
139
156
idxStr <- replaceAttr label' (lookup " label" attrs) alt imgRefs
157
+ let alt' = applyTemplate idxStr alt $ figureTemplate opts
140
158
case outFormat opts of
141
159
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]
149
162
replaceSubfig x = return [x]
150
163
151
164
latexSubFigure :: Inline -> T. Text -> [Inline ]
@@ -168,6 +181,12 @@ latexSubFigure (Image (_, cls, attrs) alt (src, title)) label =
168
181
]
169
182
latexSubFigure x _ = [x]
170
183
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
+
171
190
simpleTable :: [Alignment ] -> [ColWidth ] -> [[[Block ]]] -> Block
172
191
simpleTable align width bod = Table nullAttr noCaption (zip align width)
173
192
noTableHead [mkBody bod] noTableFoot
@@ -178,3 +197,22 @@ simpleTable align width bod = Table nullAttr noCaption (zip align width)
178
197
noCaption = Caption Nothing mempty
179
198
noTableHead = TableHead nullAttr []
180
199
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
0 commit comments