Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CRediT roles to JATS #10153

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
- Cezary Drożak
- Chandrahas77
- Charanjit Singh
- Charles Tapley Hoyt
- Charlotte Koch
- Chris Black
- Christian Conkle
Expand Down Expand Up @@ -197,6 +198,7 @@
- Jeroen de Haas
- Jerry Sky
- Jesse Rosenthal
- Jez Cope
- Joe Hermaszewski
- Joe Hillenbrand
- John KetzerX
Expand Down
11 changes: 11 additions & 0 deletions data/templates/article.jats_publishing
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ $elseif(author.name)$
$else$
<string-name>$author$</string-name>
$endif$
$for(author.roles)$
$if(it.credit)$
<role vocab="credit"$if(it.degree)$ degree-contribution="$it.degree$"$endif$
vocab-identifier="https://credit.niso.org/"
vocab-term-identifier="https://credit.niso.org/contributor-roles/$it.credit$/"
vocab-term="$it.credit-name$"
>$if(it.name)$$it.name$$else$$it.credit-name$$endif$</role>
$elseif(it.name)$
<role>$it.name$</role>
$endif$
$endfor$
$if(author.email)$
<email>$author.email$</email>
$endif$
Expand Down
81 changes: 81 additions & 0 deletions doc/jats.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,85 @@ Metadata Values
set it used, as affiliation links are not allowed in that
schema.

`roles`
: a list of dictionaries describing the author's role(s).
Each role is added as an [`<role>`] element to
the author's [`<contrib>`] element. The following examples
illustrate:

An ad-hoc role:

```yaml
roles:
- name: Dolphin Catcher
```

A role specified with CRediT.

```yaml
roles:
- credit: writing-review-editing
```

The `credit-name` is automatically looked up from
the CRediT taxonomy, but you can also specify it
yourself:

```yaml
roles:
- credit: writing-review-editing
credit-name: Writing – review & editing
```

A role specified with CRediT, including an
optional degree of contribution. Note that
specifying the degree only is allowed when
using CRediT roles and not ad-hoc roles.

```yaml
roles:
- credit: writing-review-editing
degree: Lead
```

A role specified with CRediT with a label override,
useful for internationalization:

```yaml
roles:
- credit: writing-review-editing
name: Escrita – revisão e edição
```

The value for `credit` and `credit-name`
must be from one of the 14 terms from the
Contribution Role Taxonomy (CRediT):

| `credit` | `credit-name` |
|--------------------------|----------------------------|
| `conceptualization` | Conceptualization |
| `data-curation` | Data curation |
| `formal-analysis` | Formal analysis |
| `funding-acquisition` | Funding acquisition |
| `investigation` | Investigation |
| `methodology` | Methodology |
| `project-administration` | Project administration |
| `resources` | Resources |
| `software` | Software |
| `supervision` | Supervision |
| `validation` | Validation |
| `visualization` | Visualization |
| `writing-original-draft` | Writing – original draft |
| `writing-review-editing` | Writing – review & editing |

JATS suggests in [`<degree-contribution>`] to use one of
the following three values when specifying the degree of
contribution:

1. `Lead`
2. `Equal`
3. `Supporting`

`equal-contrib`
: boolean attribute used to mark authors who contributed
equally to the work. The
Expand Down Expand Up @@ -483,3 +562,5 @@ Required metadata values:
[`<institution-wrap>`]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/institution-wrap.html
[`<institution>`]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/institution.html
[`<pub-date>`]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/pub-date.html
[`<role>`]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/element/role.html
[`<degree-contribution>`]: https://jats.nlm.nih.gov/publishing/tag-library/1.2/attribute/degree-contribution.html
53 changes: 51 additions & 2 deletions src/Text/Pandoc/Writers/JATS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Control.Monad.Reader
import Control.Monad.State
import Data.Generics (everywhere, mkT)
import qualified Data.Map as M
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Maybe (fromMaybe, listToMaybe, isNothing)
import Data.Time (toGregorian, Day, parseTimeM, defaultTimeLocale, formatTime)
import qualified Data.Text as T
import Data.Text (Text)
Expand All @@ -43,7 +43,7 @@ import Text.DocLayout
import Text.Pandoc.Shared
import Text.Pandoc.URI
import Text.Pandoc.Templates (renderTemplate)
import Text.DocTemplates (Context(..), Val(..))
import Text.DocTemplates (Context(..), Val(..), toVal)
import Text.Pandoc.Writers.JATS.References (referencesToJATS)
import Text.Pandoc.Writers.JATS.Table (tableToJATS)
import Text.Pandoc.Writers.JATS.Types
Expand All @@ -54,6 +54,54 @@ import Text.TeXMath
import qualified Text.Pandoc.Writers.AnnotatedTable as Ann
import qualified Text.XML.Light as Xml

-- | Default human-readable names for roles in the Contributor Role
-- Taxonomy (CRediT). This is useful for generating JATS that annotate
-- contributor roles
creditNames :: M.Map Text Text
creditNames = M.fromList [
("conceptualization", "Conceptualization"),
("data-curation", "Data curation"),
("formal-analysis", "Formal analysis"),
("funding-acquisition", "Funding acquisition"),
("investigation", "Investigation"),
("methodology", "Methodology"),
("project-administration", "Project administration"),
("resources", "Resources"),
("software", "Software"),
("supervision", "Supervision"),
("validation", "Validation"),
("visualization", "Visualization"),
("writing-original-draft", "Writing – original draft"),
("writing-review-editing", "Writing – review & editing")]

-- | Ensure every role with a `credit` key also has a `credit-name`,
-- using a default value if necessary
addCreditNames :: Context Text -> Context Text
addCreditNames context =
case getField "author" context of
-- If there is an "authors" key, then we replace the existing value
-- with one we mutate by running the addCreditNamesToAuthor helper
-- function on each
Just (ListVal authors) ->
resetField "author" (map addCreditNamesToAuthor authors) context
-- If there is no "authors" key in the context, then we don't have to do
-- anything, and just return the context as is
_ -> context
where
addCreditNamesToAuthor :: Val Text -> Val Text
addCreditNamesToAuthor val = fromMaybe val $ do
MapVal authorCtx <- pure val
ListVal roles <- getField "roles" authorCtx
return $ toVal $ resetField "roles" (map addCreditNameToRole roles) authorCtx

addCreditNameToRole :: Val Text -> Val Text
addCreditNameToRole val = fromMaybe val $ do
MapVal roleCtx <- pure val
guard $ isNothing (getField "credit-name" roleCtx :: Maybe (Val Text))
creditId <- getField "credit" roleCtx
creditName <- M.lookup creditId creditNames
return $ toVal $ resetField "credit-name" creditName roleCtx

-- | Convert a @'Pandoc'@ document to JATS (Archiving and Interchange
-- Tag Set.)
writeJatsArchiving :: PandocMonad m => WriterOptions -> Pandoc -> m Text
Expand Down Expand Up @@ -159,6 +207,7 @@ docToJATS opts (Pandoc meta blocks') = do
(lookupMetaInlines "title" meta)
let context = defField "body" main
$ defField "back" back
$ addCreditNames
$ resetField "title" title'
$ resetField "date" date
$ defField "mathml" (case writerHTMLMathMethod opts of
Expand Down
Loading