git.iko.soy/typeable/pandoc
on master help sign in
JATS writer: wrap elements with p when needed.

The JATS spec restricts contents of certain elements (fn, list-item); this patch wraps elements that can't go in these contexts inside p elements with specific-use "wrapper", so the documents will conform. Closes #5570.

commit550d949b9eb5ee82d6c77ec40374de3602ba54aa authorJohn MacFarlane <jgm@berkeley.edu> dateTue 11 Jun 2019, 10:36 (7 years ago) parent3febd81
2 files changed+64−18
src/Text/Pandoc/Writers/JATS.hs+43−5 test/writer.jats+21−13
src/Text/Pandoc/Writers/JATS.hs+43−5
@@ -27,6 +27,7 @@ import Text.Pandoc.Definition
2727import Text.Pandoc.Highlighting (languages, languagesByExtension)
2828import Text.Pandoc.Logging
2929import Text.Pandoc.MIME (getMimeType)
30+import Text.Pandoc.Walk (walk)
3031import Text.Pandoc.Options
3132import Text.Pandoc.Pretty
3233import Text.Pandoc.Shared
@@ -111,7 +112,22 @@ elementToJATS opts lvl (Sec _ _num (id',_,kvs) title elements) = do
111112
112113-- | Convert a list of Pandoc blocks to JATS.
113114blocksToJATS :: PandocMonad m => WriterOptions -> [Block] -> JATS m Doc
114−blocksToJATS opts = fmap vcat . mapM (blockToJATS opts)
115+blocksToJATS = wrappedBlocksToJATS (const False)
116+
117+wrappedBlocksToJATS :: PandocMonad m
118+ => (Block -> Bool)
119+ -> WriterOptions
120+ -> [Block]
121+ -> JATS m Doc
122+wrappedBlocksToJATS needsWrap opts =
123+ fmap vcat . mapM wrappedBlockToJATS
124+ where
125+ wrappedBlockToJATS b = do
126+ inner <- blockToJATS opts b
127+ return $
128+ if needsWrap b
129+ then inTags True "p" [("specific-use","wrapper")] inner
130+ else inner
115131
116132-- | Auxiliary function to convert Plain block to Para.
117133plainToPara :: Block -> Block
@@ -130,7 +146,9 @@ deflistItemToJATS :: PandocMonad m
130146 => WriterOptions -> [Inline] -> [[Block]] -> JATS m Doc
131147deflistItemToJATS opts term defs = do
132148 term' <- inlinesToJATS opts term
133− def' <- blocksToJATS opts $ concatMap (map plainToPara) defs
149+ def' <- wrappedBlocksToJATS (not . isPara)
150+ opts $ concatMap (walk demoteHeaderAndRefs .
151+ map plainToPara) defs
134152 return $ inTagsIndented "def-item" $
135153 inTagsSimple "term" term' $$
136154 inTagsIndented "def" def'
@@ -147,7 +165,8 @@ listItemsToJATS opts markers items =
147165listItemToJATS :: PandocMonad m
148166 => WriterOptions -> Maybe String -> [Block] -> JATS m Doc
149167listItemToJATS opts mbmarker item = do
150− contents <- blocksToJATS opts item
168+ contents <- wrappedBlocksToJATS (not . isParaOrList) opts
169+ (walk demoteHeaderAndRefs item)
151170 return $ inTagsIndented "list-item" $
152171 maybe empty (\lbl -> inTagsSimple "label" (text lbl)) mbmarker
153172 $$ contents
@@ -377,13 +396,13 @@ inlineToJATS opts SoftBreak
377396 | writerWrapText opts == WrapPreserve = return cr
378397 | otherwise = return space
379398inlineToJATS opts (Note contents) = do
380− -- TODO technically only <p> tags are allowed inside
381399 notes <- gets jatsNotes
382400 let notenum = case notes of
383401 (n, _):_ -> n + 1
384402 [] -> 1
385403 thenote <- inTags True "fn" [("id","fn" ++ show notenum)]
386− <$> blocksToJATS opts contents
404+ <$> wrappedBlocksToJATS (not . isPara) opts
405+ (walk demoteHeaderAndRefs contents)
387406 modify $ \st -> st{ jatsNotes = (notenum, thenote) : notes }
388407 return $ inTags False "xref" [("ref-type", "fn"),
389408 ("rid", "fn" ++ show notenum)]
@@ -466,3 +485,22 @@ inlineToJATS _ (Image (ident,_,kvs) _ (src, tit)) = do
466485 "xlink:href", "xlink:role", "xlink:show",
467486 "xlink:type"]]
468487 return $ selfClosingTag "inline-graphic" attr
488+
489+isParaOrList :: Block -> Bool
490+isParaOrList Para{} = True
491+isParaOrList Plain{} = True
492+isParaOrList BulletList{} = True
493+isParaOrList OrderedList{} = True
494+isParaOrList DefinitionList{} = True
495+isParaOrList _ = False
496+
497+isPara :: Block -> Bool
498+isPara Para{} = True
499+isPara Plain{} = True
500+isPara _ = False
501+
502+demoteHeaderAndRefs :: Block -> Block
503+demoteHeaderAndRefs (Header _ _ ils) = Para ils
504+demoteHeaderAndRefs (Div ("refs",cls,kvs) bs) =
505+ Div ("",cls,kvs) bs
506+demoteHeaderAndRefs x = x
test/writer.jats+21−13
@@ -498,10 +498,14 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
498498 <term><italic>orange</italic></term>
499499 <def>
500500 <p>orange fruit</p>
501− <preformat>{ orange code block }</preformat>
502− <disp-quote>
503− <p>orange block quote</p>
504− </disp-quote>
501+ <p specific-use="wrapper">
502+ <preformat>{ orange code block }</preformat>
503+ </p>
504+ <p specific-use="wrapper">
505+ <disp-quote>
506+ <p>orange block quote</p>
507+ </disp-quote>
508+ </p>
505509 </def>
506510 </def-item>
507511 </def-list>
@@ -552,14 +556,16 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
552556 <term>orange</term>
553557 <def>
554558 <p>orange fruit</p>
555− <list list-type="order">
556− <list-item>
557− <p>sublist</p>
558− </list-item>
559− <list-item>
560− <p>sublist</p>
561− </list-item>
562− </list>
559+ <p specific-use="wrapper">
560+ <list list-type="order">
561+ <list-item>
562+ <p>sublist</p>
563+ </list-item>
564+ <list-item>
565+ <p>sublist</p>
566+ </list-item>
567+ </list>
568+ </p>
563569 </def>
564570 </def-item>
565571 </def-list>
@@ -870,7 +876,9 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
870876 <p>Here’s the long note. This one contains multiple blocks.</p>
871877 <p>Subsequent blocks are indented to show that they belong to the footnote
872878 (as with list items).</p>
873− <preformat> { &lt;code&gt; }</preformat>
879+ <p specific-use="wrapper">
880+ <preformat> { &lt;code&gt; }</preformat>
881+ </p>
874882 <p>If you want, you can indent every line, but you can also be lazy and
875883 just indent the first line of each block.</p>
876884 </fn>