git.iko.soy/typeable/pandoc
on master help sign in
JATS writer: fix citations (#7018)

* JATS writer: keep code lines at 80 chars or below * JATS writer: fix citations

commit68fa43799963fff11a980d5d3959184c3d34a723 authorAlbert Krewinkel <albert@zeitkraut.de> dateMon 11 Jan 2021, 00:35 (6 years ago) parenta41cb09
6 files changed+72−241
COPYRIGHT+1−10 data/jats.csl−203 pandoc.cabal−2 src/Text/Pandoc/App.hs+2−14 src/Text/Pandoc/Writers/JATS.hs+21−12 test/command/7016.md+48
COPYRIGHT+1−10
@@ -181,7 +181,7 @@ http://github.com/paulrouget/dzslides
181181Released under the Do What the Fuck You Want To Public License.
182182
183183------------------------------------------------------------------------
184−Pandoc embeds a lua interpreter (via hslua).
184+Pandoc embeds a Lua interpreter (via hslua).
185185
186186Copyright © 1994–2020 Lua.org, PUC-Rio.
187187
@@ -203,12 +203,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
203203LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
204204OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
205205WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
206−
207−------------------------------------------------------------------------
208−The template pandoc.jats is Copyright 2013--2015 Martin Fenner,
209−released under GPL version 2 or later.
210−
211−The file data/jats.csl is derived from a csl file by Martin Fenner,
212−revised by Martin Paul Eve and then John MacFarlane.
213−"This work is licensed under a Creative Commons Attribution-ShareAlike 3.0
214−License. Originally by Martin Fenner."
data/jats.csldeleted−203
@@ -1,203 +0,0 @@
1−<?xml version="1.0" encoding="utf-8"?>
2−<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" default-locale="en-US">
3− <info>
4− <title>Journal Article Tag Suite</title>
5− <title-short>JATS</title-short>
6− <id>http://www.zotero.org/styles/journal-article-tag-suite</id>
7− <link href="https://github.com/MartinPaulEve/JATS-CSL/blob/master/jats.csl" rel="self"/>
8− <link rel="documentation" href="http://jats.nlm.nih.gov/archiving/tag-library/1.0/index.html"/>
9− <author>
10− <name>Martin Paul Eve</name>
11− <email>martin@martineve.com</email>
12− </author>
13− <category citation-format="numeric"/>
14− <category field="medicine"/>
15− <category field="biology"/>
16− <summary>Use this style to generate bibliographic data in Journal Article Tagging Suite (JATS) 1.0 XML format</summary>
17− <updated>2014-06-21T17:41:26+00:00</updated>
18− <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License. Originally by Martin Fenner.</rights>
19− </info>
20− <locale xml:lang="en">
21− <terms>
22− <term name="et-al">{{jats}}&lt;etal/&gt;{{/jats}}</term>
23− </terms>
24− </locale>
25− <macro name="citation-number">
26− <text variable="citation-number" prefix="{{jats}}id=&quot;ref-{{/jats}}" suffix="{{jats}}&quot;&gt;{{/jats}}"/>
27− </macro>
28− <macro name="author">
29− <names variable="author" delimiter=" ">
30− <name prefix="{{jats}}&lt;name&gt;{{/jats}}" suffix="{{jats}}&lt;/name&gt;{{/jats}}" name-as-sort-order="all" sort-separator=" ">
31− <name-part name="family" text-case="capitalize-first" prefix="{{jats}}&lt;surname&gt;{{/jats}}" suffix="{{jats}}&lt;/surname&gt;{{/jats}}"/>
32− <name-part name="given" text-case="capitalize-first" prefix="{{jats}}&lt;given-names&gt;{{/jats}}" suffix="{{jats}}&lt;/given-names&gt;{{/jats}}"/>
33− </name>
34− <substitute>
35− <names variable="editor"/>
36− </substitute>
37− </names>
38− </macro>
39−
40− <macro name="editor" delimiter=" ">
41− <names variable="editor" prefix="{{jats}}&lt;person-group person-group-type=&quot;editor&quot;&gt;{{/jats}}" suffix="{{jats}}&lt;/person-group&gt;{{/jats}}">
42− <name prefix="{{jats}}&lt;name&gt;{{/jats}}" suffix="{{jats}}&lt;/name&gt;{{/jats}}" name-as-sort-order="all" sort-separator=" ">
43− <name-part name="family" text-case="capitalize-first" prefix="{{jats}}&lt;surname&gt;{{/jats}}" suffix="{{jats}}&lt;/surname&gt;{{/jats}}"/>
44− <name-part name="given" text-case="capitalize-first" prefix="{{jats}}&lt;given-names&gt;{{/jats}}" suffix="{{jats}}&lt;/given-names&gt;{{/jats}}"/>
45− </name>
46− <substitute>
47− <names variable="editor"/>
48− </substitute>
49− </names>
50− </macro>
51−
52− <macro name="editor">
53− <group delimiter=": ">
54− <names variable="editor">
55− <name prefix="{{jats}}&lt;name&gt;{{/jats}}" suffix="{{jats}}&lt;/name&gt;{{/jats}}" name-as-sort-order="all" sort-separator="">
56− <name-part name="family" text-case="capitalize-first" prefix="{{jats}}&lt;surname&gt;{{/jats}}" suffix="{{jats}}&lt;/surname&gt;{{/jats}}"/>
57− <name-part name="given" text-case="capitalize-first" prefix="{{jats}}&lt;given-names&gt;{{/jats}}" suffix="{{jats}}&lt;given-names&gt;{{/jats}}"/>
58− </name>
59− </names>
60− </group>
61− </macro>
62− <macro name="title">
63− <choose>
64− <if type="book" match="any">
65− <group prefix="{{jats}}&lt;source&gt;{{/jats}}" suffix="{{jats}}&lt;/source&gt;{{/jats}}">
66− <text variable="title"/>
67− </group>
68− </if>
69− <else>
70− <group prefix="{{jats}}&lt;article-title&gt;{{/jats}}" suffix="{{jats}}&lt;/article-title&gt;{{/jats}}">
71− <text variable="title"/>
72− </group>
73− </else>
74− </choose>
75− </macro>
76− <macro name="container-title">
77− <text variable="container-title" form="short" prefix="{{jats}}&lt;source&gt;{{/jats}}" suffix="{{jats}}&lt;/source&gt;{{/jats}}"/>
78− </macro>
79− <macro name="publisher">
80− <text variable="publisher" prefix="{{jats}}&lt;publisher-name&gt;{{/jats}}" suffix="{{jats}}&lt;/publisher-name&gt;{{/jats}}"/>
81− <text variable="publisher-place" prefix="{{jats}}&lt;publisher-loc&gt;{{/jats}}" suffix="{{jats}}&lt;/publisher-loc&gt;{{/jats}}"/>
82− </macro>
83− <macro name="link">
84− <choose>
85− <if match="any" variable="DOI">
86− <group prefix="{{jats}}&lt;pub-id pub-id-type=&quot;doi&quot;&gt;{{/jats}}" suffix="{{jats}}&lt;/pub-id&gt;{{/jats}}">
87− <text variable="DOI"/>
88− </group>
89− </if>
90− </choose>
91− <choose>
92− <if match="any" variable="PMID">
93− <group prefix="{{jats}}&lt;pub-id pub-id-type=&quot;pmid&quot;&gt;{{/jats}}" suffix="{{jats}}&lt;/pub-id&gt;{{/jats}}">
94− <text variable="PMID"/>
95− </group>
96− </if>
97− </choose>
98− <choose>
99− <if variable="URL" match="any">
100− <text variable="URL" />
101− </if>
102− </choose>
103− </macro>
104− <macro name="date">
105− <choose>
106− <if type="article-journal article-magazine article-newspaper report patent book" match="any">
107− <group prefix="{{jats}}&lt;date&gt;{{/jats}}" suffix="{{jats}}&lt;/date&gt;{{/jats}}">
108− <date variable="issued">
109− <date-part name="day" form="numeric-leading-zeros" prefix="{{jats}}&lt;day&gt;{{/jats}}" suffix="{{jats}}&lt;/day&gt;{{/jats}}"/>
110− <date-part name="month" form="numeric-leading-zeros" prefix="{{jats}}&lt;month&gt;{{/jats}}" suffix="{{jats}}&lt;/month&gt;{{/jats}}"/>
111− <date-part name="year" prefix="{{jats}}&lt;year&gt;{{/jats}}" suffix="{{jats}}&lt;/year&gt;{{/jats}}"/>
112− </date>
113− </group>
114− </if>
115− <else>
116− <group prefix="{{jats}}&lt;date-in-citation content-type=&quot;access-date&quot;{{/jats}}" suffix="{{jats}}&lt;/date-in-citation&gt;{{/jats}}">
117− <date variable="accessed" prefix="{{jats}} iso-8601-date=&quot;{{/jats}}" suffix="{{jats}}&quot;&gt;{{/jats}}">
118− <date-part name="year"/>
119− <date-part name="month" form="numeric-leading-zeros" prefix="{{jats}}-{{/jats}}"/>
120− <date-part name="day" form="numeric-leading-zeros" prefix="{{jats}}-{{/jats}}"/>
121− </date>
122− <date variable="accessed">
123− <date-part name="day" prefix="{{jats}}&lt;day&gt;{{/jats}}" suffix="{{jats}}&lt;/day&gt;{{/jats}}"/>
124− <date-part name="month" form="numeric-leading-zeros" prefix="{{jats}}&lt;month&gt;{{/jats}}" suffix="{{jats}}&lt;/month&gt;{{/jats}}"/>
125− <date-part name="year" prefix="{{jats}}&lt;year&gt;{{/jats}}" suffix="{{jats}}&lt;/year&gt;{{/jats}}"/>
126− </date>
127− </group>
128− </else>
129− </choose>
130− </macro>
131− <macro name="location">
132− <choose>
133− <if type="article-journal article-magazine" match="any">
134− <text variable="volume" prefix="{{jats}}&lt;volume&gt;{{/jats}}" suffix="{{jats}}&lt;/volume&gt;{{/jats}}"/>
135− <text variable="issue" prefix="{{jats}}&lt;issue&gt;{{/jats}}" suffix="{{jats}}&lt;/issue&gt;{{/jats}}"/>
136− </if>
137− </choose>
138− <choose>
139− <if type="article-journal article-magazine article-newspaper chapter" match="any">
140− <text variable="page-first" prefix="{{jats}}&lt;fpage&gt;{{/jats}}" suffix="{{jats}}&lt;/fpage&gt;{{/jats}}"/>
141− </if>
142− </choose>
143− </macro>
144− <macro name="publication-type">
145− <group prefix="{{jats}} publication-type=&quot;{{/jats}}" suffix="{{jats}}&quot;&gt;{{/jats}}">
146− <choose>
147− <if type="article-journal article-magazine article-newspaper" match="any">
148− <text value="journal"/>
149− </if>
150− <else-if type="book" match="any">
151− <text value="book"/>
152− </else-if>
153− <else-if type="chapter" match="any">
154− <text value="bookchapter"/>
155− </else-if>
156− <else-if type="dataset" match="any">
157− <text value="dataset"/>
158− </else-if>
159− <else-if type="patent" match="any">
160− <text value="patent"/>
161− </else-if>
162− <else-if type="report" match="any">
163− <text value="report"/>
164− </else-if>
165− <else-if type="review" match="any">
166− <text value="review"/>
167− </else-if>
168− <else>
169− <text value="standard"/>
170− </else>
171− </choose>
172− </group>
173− </macro>
174− <citation collapse="citation-number">
175− <sort>
176− <key variable="citation-number"/>
177− </sort>
178− <layout delimiter=",">
179− <group prefix="{{jats}}&lt;xref ref-type=&quot;bibr&quot; rid=&quot;{{/jats}}" suffix="{{jats}}&lt;/xref&gt;{{/jats}}">
180− <text variable="citation-number" prefix="{{jats}}ref-{{/jats}}" suffix="{{jats}}&quot;&gt;{{/jats}}"/>
181− <text variable="citation-number"/>
182− </group>
183− </layout>
184− </citation>
185− <bibliography sort-separator="">
186− <layout>
187− <group prefix="{{jats}}&lt;ref {{/jats}}" suffix="{{jats}}&lt;/ref&gt;{{/jats}}">
188− <text macro="citation-number"/>
189− <group prefix="{{jats}}&lt;element-citation{{/jats}}" suffix="{{jats}}&lt;/element-citation&gt;{{/jats}}">
190− <text macro="publication-type"/>
191− <text macro="author" prefix="{{jats}}&lt;person-group person-group-type=&quot;author&quot;&gt;{{/jats}}" suffix="{{jats}}&lt;/person-group&gt;{{/jats}}"/>
192− <text macro="title" />
193− <text macro="container-title"/>
194− <text macro="editor"/>
195− <text macro="publisher"/>
196− <text macro="date"/>
197− <text macro="location"/>
198− <text macro="link"/>
199− </group>
200− </group>
201− </layout>
202− </bibliography>
203−</style>
pandoc.cabal−2
@@ -180,8 +180,6 @@ data-files:
180180 data/pandoc.List.lua
181181 -- bash completion template
182182 data/bash_completion.tpl
183− -- jats csl
184− data/jats.csl
185183 -- citeproc
186184 data/default.csl
187185 citeproc/biblatex-localization/*.lbx.strings
src/Text/Pandoc/App.hs+2−14
@@ -50,10 +50,9 @@ import Text.Pandoc.App.Opt (Opt (..), LineEnding (..), defaultOpts,
5050import Text.Pandoc.App.CommandLineOptions (parseOptions, options)
5151import Text.Pandoc.App.OutputSettings (OutputSettings (..), optToOutputSettings)
5252import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
53−import Text.Pandoc.Builder (setMeta)
5453import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
5554import Text.Pandoc.PDF (makePDF)
56−import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)
55+import Text.Pandoc.SelfContained (makeSelfContained)
5756import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
5857 headerShift, isURI, tabFilter, uriPathToPath, filterIpynbOutput,
5958 defaultUserDataDirs, tshow, findM)
@@ -190,17 +189,6 @@ convertWithOpts opts = do
190189 Nothing -> readDataFile "abbreviations"
191190 Just f -> readFileStrict f
192191
193− metadata <- if format == "jats" &&
194− isNothing (lookupMeta "csl" (optMetadata opts)) &&
195− isNothing (lookupMeta "citation-style"
196− (optMetadata opts))
197− then do
198− jatsCSL <- readDataFile "jats.csl"
199− let jatsEncoded = makeDataURI
200− ("application/xml", jatsCSL)
201− return $ setMeta "csl" jatsEncoded $ optMetadata opts
202− else return $ optMetadata opts
203−
204192 case lookupMetaString "lang" (optMetadata opts) of
205193 "" -> setTranslations $ Lang "en" "" "US" []
206194 l -> case parseBCP47 l of
@@ -286,7 +274,7 @@ convertWithOpts opts = do
286274 then fillMediaBag
287275 else return)
288276 >=> return . adjustMetadata (metadataFromFile <>)
289− >=> return . adjustMetadata (<> metadata)
277+ >=> return . adjustMetadata (<> optMetadata opts)
290278 >=> applyTransforms transforms
291279 >=> applyFilters readerOpts filters [T.unpack format]
292280 >=> maybe return extractMedia (optExtractMedia opts)
src/Text/Pandoc/Writers/JATS.hs+21−12
@@ -3,7 +3,7 @@
33{-# LANGUAGE ViewPatterns #-}
44{- |
55 Module : Text.Pandoc.Writers.JATS
6− Copyright : Copyright (C) 2017-2021 John MacFarlane
6+ Copyright : 2017-2021 John MacFarlane
77 License : GNU GPL, version 2 or above
88
99 Maintainer : John MacFarlane <jgm@berkeley.edu>
@@ -168,13 +168,15 @@ plainToPara x = x
168168-- | Convert a list of pairs of terms and definitions into a list of
169169-- JATS varlistentrys.
170170deflistItemsToJATS :: PandocMonad m
171− => WriterOptions -> [([Inline],[[Block]])] -> JATS m (Doc Text)
171+ => WriterOptions
172+ -> [([Inline],[[Block]])] -> JATS m (Doc Text)
172173deflistItemsToJATS opts items =
173174 vcat <$> mapM (uncurry (deflistItemToJATS opts)) items
174175
175176-- | Convert a term and a list of blocks into a JATS varlistentry.
176177deflistItemToJATS :: PandocMonad m
177− => WriterOptions -> [Inline] -> [[Block]] -> JATS m (Doc Text)
178+ => WriterOptions
179+ -> [Inline] -> [[Block]] -> JATS m (Doc Text)
178180deflistItemToJATS opts term defs = do
179181 term' <- inlinesToJATS opts term
180182 def' <- wrappedBlocksToJATS (not . isPara)
@@ -186,7 +188,8 @@ deflistItemToJATS opts term defs = do
186188
187189-- | Convert a list of lists of blocks to a list of JATS list items.
188190listItemsToJATS :: PandocMonad m
189− => WriterOptions -> Maybe [Text] -> [[Block]] -> JATS m (Doc Text)
191+ => WriterOptions
192+ -> Maybe [Text] -> [[Block]] -> JATS m (Doc Text)
190193listItemsToJATS opts markers items =
191194 case markers of
192195 Nothing -> vcat <$> mapM (listItemToJATS opts Nothing) items
@@ -194,12 +197,13 @@ listItemsToJATS opts markers items =
194197
195198-- | Convert a list of blocks into a JATS list item.
196199listItemToJATS :: PandocMonad m
197− => WriterOptions -> Maybe Text -> [Block] -> JATS m (Doc Text)
200+ => WriterOptions
201+ -> Maybe Text -> [Block] -> JATS m (Doc Text)
198202listItemToJATS opts mbmarker item = do
199203 contents <- wrappedBlocksToJATS (not . isParaOrList) opts
200204 (walk demoteHeaderAndRefs item)
201205 return $ inTagsIndented "list-item" $
202− maybe empty (\lbl -> inTagsSimple "label" (text $ T.unpack lbl)) mbmarker
206+ maybe empty (inTagsSimple "label" . text . T.unpack) mbmarker
203207 $$ contents
204208
205209imageMimeType :: Text -> [(Text, Text)] -> (Text, Text)
@@ -247,7 +251,9 @@ blockToJATS opts (Div (id',"section":_,kvs) (Header _lvl _ ils : xs)) = do
247251 return $ inTags True "sec" attribs $
248252 inTagsSimple "title" title' $$ contents
249253-- Bibliography reference:
250−blockToJATS opts (Div (T.stripPrefix "ref-" -> Just _,_,_) [Para lst]) =
254+blockToJATS opts (Div (ident,_,_) [Para lst]) | "ref-" `T.isPrefixOf` ident =
255+ inTags True "ref" [("id", ident)] .
256+ inTagsSimple "mixed-citation" <$>
251257 inlinesToJATS opts lst
252258blockToJATS opts (Div ("refs",_,_) xs) = do
253259 contents <- blocksToJATS opts xs
@@ -470,10 +476,13 @@ inlineToJATS _ (Link _attr [Str t] (T.stripPrefix "mailto:" -> Just email, _))
470476 | escapeURI t == email =
471477 return $ inTagsSimple "email" $ literal (escapeStringForXML email)
472478inlineToJATS opts (Link (ident,_,kvs) txt (T.uncons -> Just ('#', src), _)) = do
473− let attr = [("id", ident) | not (T.null ident)] ++
474− [("alt", stringify txt) | not (null txt)] ++
475− [("rid", src)] ++
476− [(k,v) | (k,v) <- kvs, k `elem` ["ref-type", "specific-use"]]
479+ let attr = mconcat
480+ [ [("id", ident) | not (T.null ident)]
481+ , [("alt", stringify txt) | not (null txt)]
482+ , [("rid", src)]
483+ , [(k,v) | (k,v) <- kvs, k `elem` ["ref-type", "specific-use"]]
484+ , [("ref-type", "bibr") | "ref-" `T.isPrefixOf` src]
485+ ]
477486 if null txt
478487 then return $ selfClosingTag "xref" attr
479488 else do
@@ -529,7 +538,7 @@ demoteHeaderAndRefs (Div ("refs",cls,kvs) bs) =
529538demoteHeaderAndRefs x = x
530539
531540parseDate :: Text -> Maybe Day
532−parseDate s = msum (map (\fs -> parsetimeWith fs $ T.unpack s) formats) :: Maybe Day
541+parseDate s = msum (map (`parsetimeWith` T.unpack s) formats)
533542 where parsetimeWith = parseTimeM True defaultTimeLocale
534543 formats = ["%x","%m/%d/%Y", "%D","%F", "%d %b %Y",
535544 "%e %B %Y", "%b. %e, %Y", "%B %e, %Y",
test/command/7016.mdnew file+48
@@ -0,0 +1,48 @@
1+```
2+% pandoc --citeproc --to=jats_archiving --standalone
3+---
4+csl: command/apa.csl
5+references:
6+- id: doe
7+ type: article
8+ author:
9+ - family: Doe
10+ given: Jane
11+ container-title: Proceedings of the Academy of Test Inputs
12+ doi: 10.x/nope
13+ issued: 2021
14+ title: Another article
15+...
16+Blah [@doe].
17+^D
18+<?xml version="1.0" encoding="utf-8" ?>
19+<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.2 20190208//EN"
20+ "JATS-archivearticle1.dtd">
21+<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" dtd-version="1.2" article-type="other">
22+<front>
23+<journal-meta>
24+<journal-id></journal-id>
25+<journal-title-group>
26+</journal-title-group>
27+<issn></issn>
28+<publisher>
29+<publisher-name></publisher-name>
30+</publisher>
31+</journal-meta>
32+<article-meta>
33+</article-meta>
34+</front>
35+<body>
36+<p>Blah (Doe, 2021).</p>
37+</body>
38+<back>
39+<ref-list>
40+ <ref id="ref-doe">
41+ <mixed-citation>Doe, J. (2021). Another article. <italic>Proceedings
42+ of the Academy of Test Inputs</italic>.
43+ doi:<ext-link ext-link-type="uri" xlink:href="https://doi.org/10.x/nope">10.x/nope</ext-link></mixed-citation>
44+ </ref>
45+</ref-list>
46+</back>
47+</article>
48+```