git.iko.soy/typeable/pandoc
on master help sign in
JATS writer: move Table handling to separate module

This makes it easier to split the module into smaller parts.

commit94c9028819415a874b2469890de44108a98f8c48 authorAlbert Krewinkel <albert@zeitkraut.de> dateFri 13 Nov 2020, 10:44 (6 years ago) parentc9ada73
4 files changed+146−68
pandoc.cabal+2 src/Text/Pandoc/Writers/JATS.hs+17−68 src/Text/Pandoc/Writers/JATS/Table.hs+81 src/Text/Pandoc/Writers/JATS/Types.hs+46
pandoc.cabal+2
@@ -629,6 +629,8 @@ library
629629 Text.Pandoc.Readers.Metadata,
630630 Text.Pandoc.Readers.Roff,
631631 Text.Pandoc.Writers.Docx.StyleMap,
632+ Text.Pandoc.Writers.JATS.Table,
633+ Text.Pandoc.Writers.JATS.Types,
632634 Text.Pandoc.Writers.Roff,
633635 Text.Pandoc.Writers.Powerpoint.Presentation,
634636 Text.Pandoc.Writers.Powerpoint.Output,
src/Text/Pandoc/Writers/JATS.hs+17−68
@@ -40,26 +40,14 @@ import Text.DocLayout
4040import Text.Pandoc.Shared
4141import Text.Pandoc.Templates (renderTemplate)
4242import Text.DocTemplates (Context(..), Val(..))
43+import Text.Pandoc.Writers.JATS.Table (tableToJATS)
44+import Text.Pandoc.Writers.JATS.Types
4345import Text.Pandoc.Writers.Math
4446import Text.Pandoc.Writers.Shared
4547import Text.Pandoc.XML
4648import Text.TeXMath
4749import qualified Text.XML.Light as Xml
4850
49−-- | JATS tag set variant
50−data JATSTagSet
51− = TagSetArchiving -- ^ Archiving and Interchange Tag Set
52− | TagSetPublishing -- ^ Journal Publishing Tag Set
53− | TagSetArticleAuthoring -- ^ Article Authoring Tag Set
54− deriving (Eq)
55−
56−-- | Internal state used by the writer.
57−newtype JATSState = JATSState
58− { jatsNotes :: [(Int, Doc Text)] }
59−
60−-- | JATS writer type
61−type JATS a = StateT JATSState (ReaderT JATSTagSet a)
62−
6351-- | Convert a @'Pandoc'@ document to JATS (Archiving and Interchange
6452-- Tag Set.)
6553writeJatsArchiving :: PandocMonad m => WriterOptions -> Pandoc -> m Text
@@ -83,9 +71,14 @@ writeJATS = writeJatsArchiving
8371-- | Convert a @'Pandoc'@ document to JATS.
8472writeJats :: PandocMonad m => JATSTagSet -> WriterOptions -> Pandoc -> m Text
8573writeJats tagSet opts d =
86− runReaderT (evalStateT (docToJATS opts d)
87− (JATSState{ jatsNotes = [] }))
88− tagSet
74+ runReaderT (evalStateT (docToJATS opts d) initialState)
75+ environment
76+ where initialState = JATSState { jatsNotes = [] }
77+ environment = JATSEnv
78+ { jatsTagSet = tagSet
79+ , jatsInlinesWriter = inlinesToJATS
80+ , jatsBlockWriter = blockToJATS
81+ }
8982
9083-- | Convert Pandoc document to string in JATS format.
9184docToJATS :: PandocMonad m => WriterOptions -> Pandoc -> JATS m Text
@@ -110,7 +103,7 @@ docToJATS opts (Pandoc meta blocks) = do
110103 main <- fromBlocks bodyblocks
111104 notes <- gets (reverse . map snd . jatsNotes)
112105 backs <- fromBlocks backblocks
113− tagSet <- ask
106+ tagSet <- asks jatsTagSet
114107 -- In the "Article Authoring" tag set, occurrence of fn-group elements
115108 -- is restricted to table footers. Footnotes have to be placed inline.
116109 let fns = if null notes || tagSet == TagSetArticleAuthoring
@@ -311,7 +304,7 @@ blockToJATS opts (Para lst) =
311304blockToJATS opts (LineBlock lns) =
312305 blockToJATS opts $ linesToPara lns
313306blockToJATS opts (BlockQuote blocks) = do
314− tagSet <- ask
307+ tagSet <- asks jatsTagSet
315308 let blocksToJats' = if tagSet == TagSetArticleAuthoring
316309 then wrappedBlocksToJATS (not . isPara)
317310 else blocksToJATS
@@ -326,7 +319,7 @@ blockToJATS opts (BulletList lst) =
326319 listItemsToJATS opts Nothing lst
327320blockToJATS _ (OrderedList _ []) = return empty
328321blockToJATS opts (OrderedList (start, numstyle, delimstyle) items) = do
329− tagSet <- ask
322+ tagSet <- asks jatsTagSet
330323 let listType =
331324 -- The Article Authoring tag set doesn't allow a more specific
332325 -- @list-type@ attribute than "order".
@@ -356,52 +349,8 @@ blockToJATS _ b@(RawBlock f str)
356349 report $ BlockNotRendered b
357350 return empty
358351blockToJATS _ HorizontalRule = return empty -- not semantic
359−blockToJATS opts (Table _ blkCapt specs th tb tf) =
360− case toLegacyTable blkCapt specs th tb tf of
361− ([], aligns, widths, headers, rows) -> captionlessTable aligns widths headers rows
362− (caption, aligns, widths, headers, rows) -> do
363− captionDoc <- inTagsIndented "caption" <$> blockToJATS opts (Para caption)
364− tbl <- captionlessTable aligns widths headers rows
365− return $ inTags True "table-wrap" [] $ captionDoc $$ tbl
366− where
367− captionlessTable aligns widths headers rows = do
368− let percent w = tshow (truncate (100*w) :: Integer) <> "*"
369− let coltags = vcat $ zipWith (\w al -> selfClosingTag "col"
370− ([("width", percent w) | w > 0] ++
371− [("align", alignmentToText al)])) widths aligns
372− thead <- if all null headers
373− then return empty
374− else inTagsIndented "thead" <$> tableRowToJATS opts True headers
375− tbody <- inTagsIndented "tbody" . vcat <$>
376− mapM (tableRowToJATS opts False) rows
377− return $ inTags True "table" [] $ coltags $$ thead $$ tbody
378−
379−alignmentToText :: Alignment -> Text
380−alignmentToText alignment = case alignment of
381− AlignLeft -> "left"
382− AlignRight -> "right"
383− AlignCenter -> "center"
384− AlignDefault -> "left"
385−
386−tableRowToJATS :: PandocMonad m
387− => WriterOptions
388− -> Bool
389− -> [[Block]]
390− -> JATS m (Doc Text)
391−tableRowToJATS opts isHeader cols =
392− inTagsIndented "tr" . vcat <$> mapM (tableItemToJATS opts isHeader) cols
393−
394−tableItemToJATS :: PandocMonad m
395− => WriterOptions
396− -> Bool
397− -> [Block]
398− -> JATS m (Doc Text)
399−tableItemToJATS opts isHeader [Plain item] =
400− inTags False (if isHeader then "th" else "td") [] <$>
401− inlinesToJATS opts item
402−tableItemToJATS opts isHeader item =
403− inTags False (if isHeader then "th" else "td") [] . vcat <$>
404− mapM (blockToJATS opts) item
352+blockToJATS opts (Table attr blkCapt specs th tb tf) =
353+ tableToJATS opts attr blkCapt specs th tb tf
405354
406355-- | Convert a list of inline elements to JATS.
407356inlinesToJATS :: PandocMonad m => WriterOptions -> [Inline] -> JATS m (Doc Text)
@@ -458,7 +407,7 @@ inlineToJATS opts SoftBreak
458407 | writerWrapText opts == WrapPreserve = return cr
459408 | otherwise = return space
460409inlineToJATS opts (Note contents) = do
461− tagSet <- ask
410+ tagSet <- asks jatsTagSet
462411 -- Footnotes must occur inline when using the Article Authoring tag set.
463412 if tagSet == TagSetArticleAuthoring
464413 then inTagsIndented "fn" <$> wrappedBlocksToJATS (not . isPara) opts contents
@@ -504,7 +453,7 @@ inlineToJATS _ (Math t str) = do
504453 let rawtex = text "<![CDATA[" <> literal str <> text "]]>"
505454 let texMath = inTagsSimple "tex-math" rawtex
506455
507− tagSet <- ask
456+ tagSet <- asks jatsTagSet
508457 return . inTagsSimple tagtype $
509458 case res of
510459 Right r -> let mathMl = text (Xml.ppcElement conf $ fixNS r)
src/Text/Pandoc/Writers/JATS/Table.hsnew file+81
@@ -0,0 +1,81 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+{- |
3+ Module : Text.Pandoc.Writers.JATS.Table
4+ Copyright : © 2020 Albert Krewinkel
5+ License : GNU GPL, version 2 or above
6+
7+ Maintainer : Albert Krewinkel <tarleb@zeitkraut.de>
8+ Stability : alpha
9+ Portability : portable
10+
11+Conversion of 'Pandoc' tables to JATS XML.
12+-}
13+module Text.Pandoc.Writers.JATS.Table
14+ ( tableToJATS
15+ ) where
16+import Control.Monad.Reader (asks)
17+import Data.Text (Text)
18+import Text.Pandoc.Class.PandocMonad (PandocMonad)
19+import Text.Pandoc.Definition
20+import Text.Pandoc.Options (WriterOptions)
21+import Text.DocLayout (Doc, empty, vcat, ($$))
22+import Text.Pandoc.Shared (tshow)
23+import Text.Pandoc.Writers.JATS.Types
24+import Text.Pandoc.Writers.Shared (toLegacyTable)
25+import Text.Pandoc.XML (inTags, inTagsIndented, selfClosingTag)
26+
27+
28+tableToJATS :: PandocMonad m
29+ => WriterOptions
30+ -> Attr -> Caption -> [ColSpec] -> TableHead
31+ -> [TableBody] -> TableFoot
32+ -> JATS m (Doc Text)
33+tableToJATS opts _attr blkCapt specs th tb tf = do
34+ blockToJATS <- asks jatsBlockWriter
35+ case toLegacyTable blkCapt specs th tb tf of
36+ ([], aligns, widths, headers, rows) -> captionlessTable aligns widths headers rows
37+ (caption, aligns, widths, headers, rows) -> do
38+ captionDoc <- inTagsIndented "caption" <$> blockToJATS opts (Para caption)
39+ tbl <- captionlessTable aligns widths headers rows
40+ return $ inTags True "table-wrap" [] $ captionDoc $$ tbl
41+ where
42+ captionlessTable aligns widths headers rows = do
43+ let percent w = tshow (truncate (100*w) :: Integer) <> "*"
44+ let coltags = vcat $ zipWith (\w al -> selfClosingTag "col"
45+ ([("width", percent w) | w > 0] ++
46+ [("align", alignmentToText al)])) widths aligns
47+ thead <- if all null headers
48+ then return empty
49+ else inTagsIndented "thead" <$> tableRowToJATS opts True headers
50+ tbody <- inTagsIndented "tbody" . vcat <$>
51+ mapM (tableRowToJATS opts False) rows
52+ return $ inTags True "table" [] $ coltags $$ thead $$ tbody
53+
54+alignmentToText :: Alignment -> Text
55+alignmentToText alignment = case alignment of
56+ AlignLeft -> "left"
57+ AlignRight -> "right"
58+ AlignCenter -> "center"
59+ AlignDefault -> "left"
60+
61+tableRowToJATS :: PandocMonad m
62+ => WriterOptions
63+ -> Bool
64+ -> [[Block]]
65+ -> JATS m (Doc Text)
66+tableRowToJATS opts isHeader cols =
67+ inTagsIndented "tr" . vcat <$> mapM (tableItemToJATS opts isHeader) cols
68+
69+tableItemToJATS :: PandocMonad m
70+ => WriterOptions
71+ -> Bool
72+ -> [Block]
73+ -> JATS m (Doc Text)
74+tableItemToJATS opts isHeader [Plain item] = do
75+ inlinesToJATS <- asks jatsInlinesWriter
76+ inTags False (if isHeader then "th" else "td") [] <$>
77+ inlinesToJATS opts item
78+tableItemToJATS opts isHeader item = do
79+ blockToJATS <- asks jatsBlockWriter
80+ inTags False (if isHeader then "th" else "td") [] . vcat <$>
81+ mapM (blockToJATS opts) item
src/Text/Pandoc/Writers/JATS/Types.hsnew file+46
@@ -0,0 +1,46 @@
1+{- |
2+ Module : Text.Pandoc.Writers.JATS.Types
3+ Copyright : Copyright (C) 2017-2020 John MacFarlane
4+ License : GNU GPL, version 2 or above
5+
6+ Maintainer : John MacFarlane <jgm@berkeley.edu>
7+ Stability : alpha
8+ Portability : portable
9+
10+Types for pandoc's JATS writer.
11+-}
12+module Text.Pandoc.Writers.JATS.Types
13+ ( JATS
14+ , JATSEnv (..)
15+ , JATSState (..)
16+ , JATSTagSet (..)
17+ )
18+where
19+
20+import Control.Monad.Reader (ReaderT)
21+import Control.Monad.State (StateT)
22+import Data.Text (Text)
23+import Text.DocLayout (Doc)
24+import Text.Pandoc.Definition (Block, Inline)
25+import Text.Pandoc.Options (WriterOptions)
26+
27+-- | JATS tag set variant
28+data JATSTagSet
29+ = TagSetArchiving -- ^ Archiving and Interchange Tag Set
30+ | TagSetPublishing -- ^ Journal Publishing Tag Set
31+ | TagSetArticleAuthoring -- ^ Article Authoring Tag Set
32+ deriving (Eq)
33+
34+-- | Internal state used by the writer.
35+newtype JATSState = JATSState
36+ { jatsNotes :: [(Int, Doc Text)]
37+ }
38+
39+data JATSEnv m = JATSEnv
40+ { jatsTagSet :: JATSTagSet
41+ , jatsInlinesWriter :: WriterOptions -> [Inline] -> JATS m (Doc Text)
42+ , jatsBlockWriter :: WriterOptions -> Block -> JATS m (Doc Text)
43+ }
44+
45+-- | JATS writer type
46+type JATS m = StateT JATSState (ReaderT (JATSEnv m) m)