Skip to content

Commit

Permalink
feat(HTML): Separate authors from years
Browse files Browse the repository at this point in the history
This allows for styling based on the
 `citationMode` of the `Cite`.
 e.g. Smith (1990) (`Narrative`) vs (Smith 1990) (`Parenthetical`)
  • Loading branch information
nokome committed Mar 18, 2021
1 parent 865f976 commit 5b6abe8
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 30 deletions.
9 changes: 6 additions & 3 deletions src/__tests__/issues/673-md-cite-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ In a figure caption @bib1.
A citation that aint @bib42 in references.
`)
)
expect(dom).toHaveTextContent('In a para 1Smith and Jones, 1990.')
expect(dom).toHaveTextContent('In a figure caption 1Smith and Jones, 1990.')
// Note: the expected text content below for `1Smith and Jones1990` is actually
// in three separate spans (this allows for alternative theming and citation modes),
// not globbed together as appears to be the case here.
expect(dom).toHaveTextContent('In a para 1Smith and Jones1990.')
expect(dom).toHaveTextContent('In a figure caption 1Smith and Jones1990.')
expect(dom).toHaveTextContent('A citation that aint bib42 in references.')

dom = await toDom(
Expand Down Expand Up @@ -71,6 +74,6 @@ A citation that aint @bib42 in references.
)
)
expect(dom).toHaveTextContent(
'In a para 1Singh et al., 2022 and one that aint foo.'
'In a para 1Singh et al.2022 and one that aint foo.'
)
})
24 changes: 18 additions & 6 deletions src/codecs/html/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import { logWarnLossIfAny } from '../../log'
import { isDefined } from '../../util'
import { getThemeAssets } from '../../util/html'
import { fromFiles } from '../../util/media/fromFiles'
import { encodeCiteAuthorsYear, encodeCiteNumeric } from '../../util/references'
import {
encodeCiteAuthors,
encodeCiteNumeric,
encodeCiteYear,
} from '../../util/references'
import { truncate } from '../../util/truncate'
import * as vfile from '../../util/vfile'
import { plotlyMediaType } from '../plotly'
Expand Down Expand Up @@ -1745,12 +1749,20 @@ function encodeCite(cite: stencila.Cite, state: EncodeState): HTMLElement {
if (reference === undefined) {
contentElems = target
} else {
contentElems = [h('span', encodeCiteNumeric(reference, state.references))]
const number = encodeCiteNumeric(reference, state.references)
contentElems = [h('span', number)]

if (stencila.isCreativeWork(reference)) {
contentElems = [
...contentElems,
h('span', encodeCiteAuthorsYear(reference)),
]
const authors = encodeCiteAuthors(reference)
// For theming, always add authors span so that year span is
// always the third span (if present)
contentElems = [...contentElems, h('span', authors ?? '')]

const year = encodeCiteYear(reference)
// For theming, only add year span if a year is available
// to prevent e.g. Smith ()
if (year !== undefined)
contentElems = [...contentElems, h('span', year)]
}
}
} else {
Expand Down
62 changes: 41 additions & 21 deletions src/util/references.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,59 @@ export const encodeCiteNumeric = (
}

/**
* Create string for "author-year" type in-text citations e.g. `Smith et al (1990)`.
* Create string for "author-year" type citations within
* a citation group e.g. `Smith et al., 1990`.
*/
export const encodeCiteAuthorsYear = (work: CreativeWork): string => {
const { authors = [], datePublished } = work
let citeText = ''
const authors = encodeCiteAuthors(work) ?? ''
const year = encodeCiteYear(work)
return year !== undefined ? `${authors}, ${year}` : authors
}

if (!A.isEmpty(authors)) {
const firstAuthorName = getName(authors[0])
if (firstAuthorName.length > 0) {
citeText += firstAuthorName
if (authors.length === 2) {
const secondAuthorName = getName(authors[1])
if (secondAuthorName.length > 0) citeText += ' and ' + secondAuthorName
} else if (authors.length > 2) {
citeText += ' et al.'
}
}
}
/**
* Create string for the authors part of in-text citations.
* e.g. `Smith et al.` in `Smith et al. (1990)`.
*/
export const encodeCiteAuthors = (work: CreativeWork): string | undefined => {
const { authors = [] } = work

if (datePublished !== undefined) {
const date =
typeof datePublished === 'string' ? datePublished : datePublished.value
const publishedYear = date.split('-')[0]
citeText += `, ${publishedYear}`
}
if (A.isEmpty(authors)) return undefined

let citeText = ''
const firstAuthorName = getName(authors[0])
if (firstAuthorName.length > 0) {
citeText += firstAuthorName
if (authors.length === 2) {
const secondAuthorName = getName(authors[1])
if (secondAuthorName.length > 0) citeText += ' and ' + secondAuthorName
} else if (authors.length > 2) {
citeText += ' et al.'
}
}
return citeText
}

/**
* Get the name of a person or organization to use in an in-text citation.
*/
function getName(author: Person | Organization): string {
return isA('Person', author) &&
author.familyNames &&
author.familyNames.length > 0
? author.familyNames.join(' ').trim()
: (author.name ?? '').trim()
}

/**
* Create string for the year part on in-text citations.
* e.g. the `1990` in `Smith et al. (1990)`.
*/
export const encodeCiteYear = (work: CreativeWork): string | undefined => {
const { datePublished } = work

if (datePublished === undefined) return undefined

const date =
typeof datePublished === 'string' ? datePublished : datePublished.value
return date.split('-')[0]
}

0 comments on commit 5b6abe8

Please sign in to comment.