Skip to content

Commit 8520010

Browse files
argent0tarleb
authored andcommitted
Use the Figure Block constructor.
* It provides a specific representation for figures in the pandoc's AST. * It uses the `SimpleFigure` pattern synonym to replace the previous construction: [Para [Image ("",[],[]) [Str "CAP2"] ("../media/rId25.jpg","fig:")]]
1 parent c1a8289 commit 8520010

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+720
-34
lines changed

MANUAL.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3176,6 +3176,17 @@ In the `context` output format this enables the use of [Natural Tables
31763176
Natural tables allow more fine-grained global customization but come
31773177
at a performance penalty compared to extreme tables.
31783178

3179+
#### Extension: `native_figures` ####
3180+
3181+
Use pandoc's native `Figure` element for content inside `<figure>` tags, in the
3182+
case of HTML, or `figure` environments, in case of LaTeX. This, in turn, allows
3183+
some writers to produce more accurate representations of figures. It also
3184+
allows the use of the `Figure` element in filters, for custom figure output.
3185+
3186+
This extension can be enabled/disabled for the following formats:
3187+
3188+
input formats
3189+
: `latex` `html`
31793190

31803191
# Pandoc's Markdown
31813192

cabal.project

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ source-repository-package
77
type: git
88
location: https://github.com/jgm/texmath.git
99
tag: 674bcbaec03e5550f155623de6662953bd157625
10+
11+
source-repository-package
12+
type: git
13+
location: https://github.com/tarleb/pandoc-types
14+
tag: b6217365df62716366ab7dac1a7f540486bfafa2

src/Text/Pandoc/Extensions.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ data Extension =
105105
| Ext_mmd_title_block -- ^ Multimarkdown metadata block
106106
| Ext_multiline_tables -- ^ Pandoc-style multiline tables
107107
| Ext_native_divs -- ^ Use Div blocks for contents of <div> tags
108+
| Ext_native_figures -- ^ Use Figure blocks for contenst of <figure> tags.
108109
| Ext_native_spans -- ^ Use Span inlines for contents of <span>
109110
| Ext_native_numbering -- ^ Use output format's native numbering for figures and tables
110111
| Ext_ntb -- ^ ConTeXt Natural Tables
@@ -539,6 +540,7 @@ getAllExtensions f = universalExtensions <> getAll f
539540
getAll "html" = autoIdExtensions <>
540541
extensionsFromList
541542
[ Ext_native_divs
543+
, Ext_native_figures
542544
, Ext_line_blocks
543545
, Ext_native_spans
544546
, Ext_empty_paragraphs
@@ -564,6 +566,7 @@ getAllExtensions f = universalExtensions <> getAll f
564566
, Ext_raw_tex
565567
, Ext_task_lists
566568
, Ext_literate_haskell
569+
, Ext_native_figures
567570
]
568571
getAll "beamer" = getAll "latex"
569572
getAll "context" = autoIdExtensions <>

src/Text/Pandoc/Lua/Marshaling/AST.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,14 @@ typeBlock = deftype "Block"
263263
(pushAttr, \case
264264
CodeBlock attr _ -> Actual attr
265265
Div attr _ -> Actual attr
266+
Figure attr _ _ -> Actual attr
266267
Header _ attr _ -> Actual attr
267268
Table attr _ _ _ _ _ -> Actual attr
268269
_ -> Absent)
269270
(peekAttr, \case
270271
CodeBlock _ code -> Actual . flip CodeBlock code
271272
Div _ blks -> Actual . flip Div blks
273+
Figure _ capt bs -> Actual . (\attr -> Figure attr capt bs)
272274
Header lvl _ blks -> Actual . (\attr -> Header lvl attr blks)
273275
Table _ c cs h bs f -> Actual . (\attr -> Table attr c cs h bs f)
274276
_ -> const Absent)
@@ -280,9 +282,13 @@ typeBlock = deftype "Block"
280282
Table attr c cs h _ f -> Actual . (\bs -> Table attr c cs h bs f)
281283
_ -> const Absent)
282284
, possibleProperty "caption" "element caption"
283-
(pushCaption, \case {Table _ capt _ _ _ _ -> Actual capt; _ -> Absent})
285+
(pushCaption, \case
286+
Table _ capt _ _ _ _ -> Actual capt
287+
Figure _ capt _ -> Actual capt
288+
_ -> Absent)
284289
(peekCaption, \case
285290
Table attr _ cs h bs f -> Actual . (\c -> Table attr c cs h bs f)
291+
Figure attr _ bs -> Actual . (\c -> Figure attr c bs)
286292
_ -> const Absent)
287293
, possibleProperty "colspecs" "column alignments and widths"
288294
(pushPandocList pushColSpec, \case
@@ -359,6 +365,7 @@ getBlockContent = \case
359365
-- inline content
360366
BlockQuote blks -> Actual $ ContentBlocks blks
361367
Div _ blks -> Actual $ ContentBlocks blks
368+
Figure _ _ blks -> Actual $ ContentBlocks blks
362369
-- lines content
363370
LineBlock lns -> Actual $ ContentLines lns
364371
-- list items content
@@ -377,6 +384,7 @@ setBlockContent = \case
377384
-- block content
378385
BlockQuote _ -> Actual . BlockQuote . blockContent
379386
Div attr _ -> Actual . Div attr . blockContent
387+
Figure attr c _ -> Actual . Figure attr c . blockContent
380388
-- lines content
381389
LineBlock _ -> Actual . LineBlock . lineContent
382390
-- list items content

src/Text/Pandoc/Lua/Module/Pandoc.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,14 @@ blockConstructors =
244244
<#> optAttrParam
245245
=#> blockResult "Div element"
246246

247+
, defun "Figure"
248+
### liftPure3 (\capt content mattr ->
249+
Figure (fromMaybe nullAttr mattr) capt content)
250+
<#> parameter peekCaption "Caption" "caption" "figure caption"
251+
<#> parameter peekBlocksFuzzy "Blocks" "content" "figure content"
252+
<#> optAttrParam
253+
=#> blockResult "Figure element"
254+
247255
, defun "Header"
248256
### liftPure3 (\lvl content mattr ->
249257
Header lvl (fromMaybe nullAttr mattr) content)

src/Text/Pandoc/Readers/HTML.hs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import Data.List.Split (splitWhen)
3535
import Data.List (foldl')
3636
import qualified Data.Map as M
3737
import Data.Maybe (fromMaybe, isJust, isNothing)
38+
import Data.Either (partitionEithers)
3839
import Data.Monoid (First (..))
3940
import qualified Data.Set as Set
4041
import Data.Text (Text)
@@ -57,7 +58,8 @@ import Text.Pandoc.Error
5758
import Text.Pandoc.Logging
5859
import Text.Pandoc.Options (
5960
Extension (Ext_epub_html_exts, Ext_empty_paragraphs, Ext_native_divs,
60-
Ext_native_spans, Ext_raw_html, Ext_line_blocks, Ext_raw_tex),
61+
Ext_native_spans, Ext_raw_html, Ext_line_blocks, Ext_raw_tex,
62+
Ext_native_figures),
6163
ReaderOptions (readerExtensions, readerStripComments),
6264
extensionEnabled)
6365
import Text.Pandoc.Parsing hiding ((<|>))
@@ -536,23 +538,40 @@ pPara = do
536538

537539
pFigure :: PandocMonad m => TagParser m Blocks
538540
pFigure = try $ do
539-
TagOpen _ _ <- pSatisfy (matchTagOpen "figure" [])
540-
skipMany pBlank
541-
let pImg = (\x -> (Just x, Nothing)) <$>
542-
(pInTag TagsOmittable "p" pImage <* skipMany pBlank)
543-
pCapt = (\x -> (Nothing, Just x)) <$> do
544-
bs <- pInTags "figcaption" block
545-
return $ blocksToInlines' $ B.toList bs
546-
pSkip = (Nothing, Nothing) <$ pSatisfy (not . matchTagClose "figure")
547-
res <- many (pImg <|> pCapt <|> pSkip)
548-
let mbimg = msum $ map fst res
549-
let mbcap = msum $ map snd res
550-
TagClose _ <- pSatisfy (matchTagClose "figure")
551-
let caption = fromMaybe mempty mbcap
552-
case B.toList <$> mbimg of
553-
Just [Image attr _ (url, tit)] ->
554-
return $ B.simpleFigureWith attr caption url tit
555-
_ -> mzero
541+
has_native_figures <-
542+
extensionEnabled Ext_native_figures <$> getOption readerExtensions
543+
if has_native_figures
544+
then pNativeFigure
545+
else try $ do
546+
TagOpen _ _ <- pSatisfy (matchTagOpen "figure" [])
547+
skipMany pBlank
548+
let pImg = (\x -> (Just x, Nothing)) <$>
549+
(pInTag TagsOmittable "p" pImage <* skipMany pBlank)
550+
pCapt = (\x -> (Nothing, Just x)) <$> do
551+
bs <- pInTags "figcaption" block
552+
return $ blocksToInlines' $ B.toList bs
553+
pSkip = (Nothing, Nothing) <$ pSatisfy (not . matchTagClose "figure")
554+
res <- many (pImg <|> pCapt <|> pSkip)
555+
-- Takes the first image and the first caption, if any, drop the rest.
556+
let mbimg = msum $ map fst res
557+
let mbcap = msum $ map snd res -- mbcap :: Maybe Inlines
558+
TagClose _ <- pSatisfy (matchTagClose "figure")
559+
let caption = fromMaybe mempty mbcap
560+
-- only process one image
561+
case B.toList <$> mbimg of
562+
Just [Image attr _ (url, tit)] ->
563+
return $ B.simpleFigureWith attr caption url tit
564+
_ -> mzero
565+
566+
pNativeFigure :: PandocMonad m => TagParser m Blocks
567+
pNativeFigure = try $ do
568+
TagOpen tag attrList <- lookAhead $ pSatisfy (matchTagOpen "figure" [])
569+
--let (ident, classes, kvs) = toAttr attr
570+
contents <- pInTags tag (many $ Left <$> pInTags "figcaption" block <|> (Right <$> block))
571+
572+
let (captions, rest) = partitionEithers contents
573+
-- I should capture the caption
574+
return $ B.figureWith (toAttr attrList) (Caption Nothing (B.toList (mconcat captions))) $ mconcat rest
556575

557576
pCodeBlock :: PandocMonad m => TagParser m Blocks
558577
pCodeBlock = try $ do

src/Text/Pandoc/Readers/LaTeX.hs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import Data.Maybe (fromMaybe, maybeToList)
3232
import qualified Data.Set as Set
3333
import Data.Text (Text)
3434
import qualified Data.Text as T
35+
import Data.Either (partitionEithers)
3536
import Skylighting (defaultSyntaxMap)
3637
import System.FilePath (addExtension, replaceExtension, takeExtension)
3738
import Text.Collate.Lang (renderLang)
@@ -935,8 +936,8 @@ environments = M.union (tableEnvironments blocks inline) $
935936
, ("letter", env "letter" letterContents)
936937
, ("minipage", env "minipage" $
937938
skipopts *> spaces *> optional braced *> spaces *> blocks)
938-
, ("figure", env "figure" $ skipopts *> figure)
939-
, ("subfigure", env "subfigure" $ skipopts *> tok *> figure)
939+
, ("figure", env "figure" $ skipopts *> Text.Pandoc.Readers.LaTeX.figure)
940+
, ("subfigure", env "subfigure" $ skipopts *> tok *> Text.Pandoc.Readers.LaTeX.figure)
940941
, ("center", divWith ("", ["center"], []) <$> env "center" blocks)
941942
, ("quote", blockQuote <$> env "quote" blocks)
942943
, ("quotation", blockQuote <$> env "quotation" blocks)
@@ -1089,9 +1090,33 @@ letterContents = do
10891090
return $ addr <> bs -- sig added by \closing
10901091

10911092
figure :: PandocMonad m => LP m Blocks
1092-
figure = try $ do
1093+
figure = do
1094+
has_native_figures <-
1095+
extensionEnabled Ext_native_figures <$> getOption readerExtensions
1096+
if has_native_figures
1097+
then nativeFigure
1098+
else try $ do
1099+
resetCaption
1100+
blocks >>= addImageCaption
1101+
1102+
nativeFigure :: PandocMonad m => LP m Blocks
1103+
nativeFigure = try $ do
10931104
resetCaption
1094-
blocks >>= addImageCaption
1105+
innerContent <- many $ try (Left <$> label) <|> (Right <$> block)
1106+
let content = walk go $ mconcat $ snd $ partitionEithers innerContent
1107+
labelResult <- sLastLabel <$> getState
1108+
let attr = case labelResult of
1109+
Just lab -> (lab, [], [])
1110+
_ -> nullAttr
1111+
captResult <- sCaption <$> getState
1112+
case captResult of
1113+
Nothing -> return $ B.figureWith attr (Caption Nothing []) content
1114+
Just capt -> return $ B.figureWith attr (B.caption Nothing $ B.plain capt) content
1115+
1116+
where
1117+
-- Remove the `Image` caption b.c. it's on the `Figure`
1118+
go (Para [Image attr _ target]) = Plain [Image attr [] target]
1119+
go x = x
10951120

10961121
addImageCaption :: PandocMonad m => Blocks -> LP m Blocks
10971122
addImageCaption = walkM go

src/Text/Pandoc/Shared.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,7 @@ blockToInlines (Table _ _ _ (TableHead _ hbd) bodies (TableFoot _ fbd)) =
921921
unTableBodies = concatMap unTableBody
922922
blockToInlines (Div _ blks) = blocksToInlines' blks
923923
blockToInlines Null = mempty
924+
blockToInlines (Figure _ _ body) = blocksToInlines' body
924925

925926
blocksToInlinesWithSep :: Inlines -> [Block] -> Inlines
926927
blocksToInlinesWithSep sep =

src/Text/Pandoc/Writers/AsciiDoc.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ blockToAsciiDoc opts (Header level (ident,_,_) inlines) = do
186186
return $ identifier $$
187187
nowrap (text (replicate (level + 1) '=') <> space <> contents) <>
188188
blankline
189-
189+
blockToAsciiDoc opts (Figure attr _ body) = blockToAsciiDoc opts $ Div attr body
190190
blockToAsciiDoc _ (CodeBlock (_,classes,_) str) = return $ flush (
191191
if null classes
192192
then "...." $$ literal str $$ "...."

src/Text/Pandoc/Writers/ConTeXt.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ blockToConTeXt (Table _ blkCapt specs thead tbody tfoot) = do
267267
then "location=none"
268268
else "title=" <> braces captionText
269269
) $$ body $$ "\\stopplacetable" <> blankline
270+
blockToConTeXt (Figure attr _ body) = blockToConTeXt $ Div attr body
270271

271272
tableToConTeXt :: PandocMonad m
272273
=> Tabl -> Doc Text -> [Doc Text] -> WM m (Doc Text)

0 commit comments

Comments
 (0)