diff --git a/README.md b/README.md
index 6a6e675b6..a73c449fc 100644
--- a/README.md
+++ b/README.md
@@ -130,16 +130,18 @@ Extensions provide styling, and potentially interactivity, for node types that d
-| Name | Description |
-| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [cite](./themes/cite) | Provides styling for in-text citations (i.e. `Cite` and `CiteGroup` nodes) and bibliographies (i.e. `CreativeWork` nodes in the `references` property of another `CreativeWork`). |
-| [cite-apa](./themes/cite-apa) | Provides styling for in-text citations and bibliographies in accordance with the [American Psychological Association (APA) style](https://en.wikipedia.org/wiki/APA_style). |
-| [cite-mla](./themes/cite-mla) | Provides styling for in-text citations and bibliographies in accordance with the [Modern Language Association (MLA) style](https://style.mla.org/). |
-| [code](./themes/code) | Provides syntax highlighting for `CodeFragment` and `CodeBlock` nodes using [Prism](https://prismjs.com/). Will not style executable node types like `CodeExpression` and `CodeChunk` which are styled by the base Stencila Web Components. |
-| [math](./themes/math) | Provides styling of math nodes using MathJax fonts and styles. Use this if there is any likely to be math content, i.e. `MathFragment` and/or `MathBlock` nodes, in documents that your theme targets. |
-| [organization](./themes/organization) | Provides styling of `Organization` nodes e.g the `authors` of an article, or affiliations for each `author` in it's `authors` list. |
-| [pages](./themes/pages) | Provides a [`@media print` CSS at-rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@page) to modify properties when printing a document e.g. to PDF. |
-| [person](./themes/person) | Provides styling of `Person` nodes e.g the `authors` of an article, or authors for each `citation` in it's `references`. |
+| Name | Description |
+| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cite](./themes/cite) | Provides styling for in-text citations (i.e. `Cite` and `CiteGroup` nodes) and bibliographies (i.e. `CreativeWork` nodes in the `references` property of another `CreativeWork`). |
+| [cite-apa](./themes/cite-apa) | Provides styling for in-text citations and bibliographies in accordance with the [American Psychological Association (APA) style](https://en.wikipedia.org/wiki/APA_style). |
+| [cite-author-year](./themes/cite-author-year) | CSS styles to support author-year in-text citations as used in citation styles such as APA, Chicago and MLA. |
+| [cite-mla](./themes/cite-mla) | Provides styling for in-text citations and bibliographies in accordance with the [Modern Language Association (MLA) style](https://style.mla.org/). |
+| [cite-numeric](./themes/cite-numeric) | CSS styles to support numeric in-text citations (e.g. Vancouver, IEEE citation styles). |
+| [code](./themes/code) | Provides syntax highlighting for `CodeFragment` and `CodeBlock` nodes using [Prism](https://prismjs.com/). Will not style executable node types like `CodeExpression` and `CodeChunk` which are styled by the base Stencila Web Components. |
+| [math](./themes/math) | Provides styling of math nodes using MathJax fonts and styles. Use this if there is any likely to be math content, i.e. `MathFragment` and/or `MathBlock` nodes, in documents that your theme targets. |
+| [organization](./themes/organization) | Provides styling of `Organization` nodes e.g the `authors` of an article, or affiliations for each `author` in it's `authors` list. |
+| [pages](./themes/pages) | Provides a [`@media print` CSS at-rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@page) to modify properties when printing a document e.g. to PDF. |
+| [person](./themes/person) | Provides styling of `Person` nodes e.g the `authors` of an article, or authors for each `citation` in it's `references`. |
@@ -438,15 +440,15 @@ Several utility functions are provided in the [`util`](./src/util) module for tr
### ready(func)
Register a function to be executed when the DOM is fully loaded.
-**Kind**: global function
+**Kind**: global function
**Detail**: Use this to wrap calls to the DOM selection and manipulation functions
-to be sure that the DOM is ready before working on it.
+to be sure that the DOM is ready before working on it.
| Param | Type | Description |
| --- | --- | --- |
| func | function | Function to register |
-**Example**
+**Example**
```js
ready(() => {
// Use other DOM manipulation functions here
@@ -457,23 +459,23 @@ ready(() => {
### first([elem], selector) ⇒ Element \| null
Select the first element matching a CSS selector.
-**Kind**: global function
-**Returns**: Element \| null - An `Element` or `null` if no match
+**Kind**: global function
+**Returns**: Element \| null - An `Element` or `null` if no match
**Detail**: This function provides a short hand for `querySelector` but
also allowing for the use of semantic selectors.
-You can use it for the whole document, or scoped to a particular element.
+You can use it for the whole document, or scoped to a particular element.
| Param | Type | Description |
| --- | --- | --- |
| [elem] | Element | The element to query (defaults to the `window.document`) |
| selector | string | The selector to match |
-**Example** *(Select the first element from the document matching selector)*
+**Example** *(Select the first element from the document matching selector)*
```js
first(':--CodeChunk')
```
-**Example** *(Select the first element within an element matching the selector)*
+**Example** *(Select the first element within an element matching the selector)*
```js
first(elem, ':--author')
@@ -483,23 +485,23 @@ first(elem, ':--author')
### select([elem], selector) ⇒ Array.<Element>
Select all elements matching a CSS selector.
-**Kind**: global function
-**Returns**: Array.<Element> - An array of elements
+**Kind**: global function
+**Returns**: Array.<Element> - An array of elements
**Detail**: Provides a short hand for using `querySelectorAll` but
also allowing for the use of semantic selectors. You can use it for
-the whole document, or scoped to a particular element.
+the whole document, or scoped to a particular element.
| Param | Type | Description |
| --- | --- | --- |
| [elem] | Element | The element to query (defaults to the `window.document`) |
| selector | string | The selector to match |
-**Example** *(Select all elements from the document matching selector)*
+**Example** *(Select all elements from the document matching selector)*
```js
select(':--CodeChunk')
```
-**Example** *(Select all elements within an element matching the selector)*
+**Example** *(Select all elements within an element matching the selector)*
```js
select(elem, ':--author')
@@ -509,12 +511,12 @@ select(elem, ':--author')
### create([spec], [attributes], ...children) ⇒ Element
Create a new element.
-**Kind**: global function
+**Kind**: global function
**Detail**: This function allows creation of new elements using either
(a) a HTML (or SVG) string (b) a CSS selector like string, or (c) an `Element`.
CSS selectors are a convenient way to create elements with attributes,
particularly Microdata elements. They can be prone to syntax errors however.
-Alternatively, the second argument can be an object of attribute name:value pairs.
+Alternatively, the second argument can be an object of attribute name:value pairs.
| Param | Type | Description |
| --- | --- | --- |
@@ -522,14 +524,14 @@ Alternatively, the second argument can be an object of attribute name:value pair
| [attributes] | object \| undefined \| null \| boolean \| number \| string \| Element | Attributes for the element. |
| ...children | undefined \| null \| boolean \| number \| string \| Element | Child nodes to to add as text content or elements. |
-**Example** *(Create a <figure> with id, class and itemtype attributes)*
+**Example** *(Create a <figure> with id, class and itemtype attributes)*
```js
create('figure #fig1 .fig :--Figure')
//
```
-**Example** *(As above but using an object to specify attributes)*
+**Example** *(As above but using an object to specify attributes)*
```js
create('figure', {
@@ -539,7 +541,7 @@ create('figure', {
itemtype: translate(':--Figure')
})
```
-**Example** *(Create a Person with a name property)*
+**Example** *(Create a Person with a name property)*
```js
create(':--Person', create('span :--name', 'John Doe'))
@@ -547,7 +549,7 @@ create(':--Person', create('span :--name', 'John Doe'))
// John Doe
//
```
-**Example** *(Create a link around an SVG image)*
+**Example** *(Create a link around an SVG image)*
```js
create('a', {href: 'https://example.com'}, create(imageSVG))
@@ -560,31 +562,31 @@ create('a', {href: 'https://example.com'}, create(imageSVG))
### tag(target, [value]) ⇒ string \| Element
Get or set the tag name of an element.
-**Kind**: global function
+**Kind**: global function
**Returns**: string \| Element - The lowercase tag name when getting,
- a new element when setting.
+ a new element when setting.
**Detail**: Caution must be used when setting the tag. This function
does not actually change the tag of the element (that is not possible)
but instead returns a new `Element` that is a clone of the original apart
from having the new tag name. Use the `replace` function where necessary
-in association with this function.
+in association with this function.
| Param | Type | Description |
| --- | --- | --- |
| target | Element | The element to get or set the tag |
| [value] | string | The value of the tag (when setting) |
-**Example** *(Get the tag name as a lowercase string)*
+**Example** *(Get the tag name as a lowercase string)*
```js
tag(elem) // "h3"
```
-**Example** *(Setting the tag actually returns a new element)*
+**Example** *(Setting the tag actually returns a new element)*
```js
tag(tag(elem, 'h2')) // "h2"
```
-**Example** *(Change the tag name of an element)*
+**Example** *(Change the tag name of an element)*
```js
replace(elem, tag(elem, 'h2'))
@@ -594,8 +596,8 @@ replace(elem, tag(elem, 'h2'))
### attrs(target, [attributes]) ⇒ object \| undefined
Get or set the attributes of an element
-**Kind**: global function
-**Returns**: object \| undefined - The attributes of the element when getting, `undefined` when setting
+**Kind**: global function
+**Returns**: object \| undefined - The attributes of the element when getting, `undefined` when setting
| Param | Type | Description |
| --- | --- | --- |
@@ -607,8 +609,8 @@ Get or set the attributes of an element
### attr(target, name, [value]) ⇒ string \| null
Get or set the value of an attribute on an element.
-**Kind**: global function
-**Returns**: string \| null - a `string` if the attribute exists, `null` if does not exist, or when setting
+**Kind**: global function
+**Returns**: string \| null - a `string` if the attribute exists, `null` if does not exist, or when setting
| Param | Type | Description |
| --- | --- | --- |
@@ -616,12 +618,12 @@ Get or set the value of an attribute on an element.
| name | string | The name of the attribute |
| [value] | string | The value of the attribute (when setting) |
-**Example** *(Set an attribute value)*
+**Example** *(Set an attribute value)*
```js
attr(elem, "attr", "value")
```
-**Example** *(Get an attribute)*
+**Example** *(Get an attribute)*
```js
attr(elem, "attr") // "value"
@@ -631,21 +633,21 @@ attr(elem, "attr") // "value"
### text(target, [value]) ⇒ string \| null \| undefined
Get or set the text content of an element.
-**Kind**: global function
+**Kind**: global function
**Returns**: string \| null \| undefined - `null` if there is no text content,
- `undefined` when setting
+ `undefined` when setting
| Param | Type | Description |
| --- | --- | --- |
| target | Element | The element to get or set the text content |
| [value] | string | The value of the text content (when setting) |
-**Example** *(Set the text content)*
+**Example** *(Set the text content)*
```js
text(elem, "text content")
```
-**Example** *(Get the text content)*
+**Example** *(Get the text content)*
```js
text(elem) // "text content"
@@ -655,7 +657,7 @@ text(elem) // "text content"
### append(target, ...elems)
Append new child elements to an element.
-**Kind**: global function
+**Kind**: global function
| Param | Type | Description |
| --- | --- | --- |
@@ -667,10 +669,10 @@ Append new child elements to an element.
### prepend(target, ...elems)
Prepend new child elements to an element.
-**Kind**: global function
+**Kind**: global function
**Detail**: When called with multiple elements to prepend
will maintain the order of those elements (at the top
-of the target element).
+of the target element).
| Param | Type | Description |
| --- | --- | --- |
@@ -682,7 +684,7 @@ of the target element).
### before(target, ...elems)
Insert new elements before an element.
-**Kind**: global function
+**Kind**: global function
| Param | Type | Description |
| --- | --- | --- |
@@ -694,7 +696,7 @@ Insert new elements before an element.
### after(target, ...elems)
Insert new elements after an element.
-**Kind**: global function
+**Kind**: global function
| Param | Type | Description |
| --- | --- | --- |
@@ -706,7 +708,7 @@ Insert new elements after an element.
### replace(target, ...elems)
Replace an element with a new element.
-**Kind**: global function
+**Kind**: global function
| Param | Type | Description |
| --- | --- | --- |
@@ -718,17 +720,17 @@ Replace an element with a new element.
### wrap(target, elem)
Wrap an element with a new element.
-**Kind**: global function
+**Kind**: global function
**Detail**: This function can be useful if you need
to create a container element to more easily style
-a type of element.
+a type of element.
| Param | Description |
| --- | --- |
| target | The element to wrap |
| elem | The element to wrap it in |
-**Example** *(Wrap all figure captions in a <div>)*
+**Example** *(Wrap all figure captions in a <div>)*
```js
select(':--Figure :--caption')
diff --git a/src/extensions/cite-apa/styles.css b/src/extensions/cite-apa/styles.css
index e4add9dc9..3a35e87b8 100644
--- a/src/extensions/cite-apa/styles.css
+++ b/src/extensions/cite-apa/styles.css
@@ -1,34 +1,9 @@
-/*
-In-text citations
+/*
+Author-year style in-text citations
See https://en.wikipedia.org/wiki/APA_style#In-text_citations
*/
-:--CiteGroup {
- &::before {
- content: '(';
- }
-
- &::after {
- content: ')';
- }
-
- :--Cite {
- &:not(:last-child)::after {
- content: ';\00a0';
- order: 100;
- }
- }
-}
-
-/* Hide numeric citation format */
-:--Cite > a > :first-child {
- display: none;
-}
-
-/* Ensure that at least one citation format is visible */
-:--Cite > a > :only-child {
- display: inline;
-}
+@import '../cite-author-year/styles.css';
/*
Reference list
diff --git a/src/extensions/cite-author-year/README.md b/src/extensions/cite-author-year/README.md
new file mode 100644
index 000000000..050dacee0
--- /dev/null
+++ b/src/extensions/cite-author-year/README.md
@@ -0,0 +1,3 @@
+# Author-year in-text citations extension
+
+CSS styles to support author-year in-text citations as used in citation styles such as APA, Chicago and MLA.
diff --git a/src/extensions/cite-author-year/styles.css b/src/extensions/cite-author-year/styles.css
new file mode 100644
index 000000000..0cd63607b
--- /dev/null
+++ b/src/extensions/cite-author-year/styles.css
@@ -0,0 +1,42 @@
+/* Parentheses around CiteGroup elements with semicolon between Cite items */
+:--CiteGroup {
+ &::before {
+ content: '(';
+ }
+
+ &::after {
+ content: ')';
+ }
+
+ :--Cite {
+ &:not(:last-child)::after {
+ content: ';\00a0';
+ order: 100;
+ }
+ }
+}
+
+/* Parentheses around orphan Cite elements */
+:not(:--CiteGroup) > :--Cite {
+ &::before {
+ content: '(';
+ }
+ &::after {
+ content: ')';
+ }
+}
+
+/* Hide numeric citation content */
+:--Cite > a > :first-child {
+ display: none;
+}
+
+/* Show author-year citation content */
+:--Cite > a > :last-child {
+ display: inline;
+}
+
+/* Ensure that at least some content is visible */
+:--Cite > a > :only-child {
+ display: inline;
+}
diff --git a/src/extensions/cite-mla/styles.css b/src/extensions/cite-mla/styles.css
index a9b8decf2..f131e8c36 100644
--- a/src/extensions/cite-mla/styles.css
+++ b/src/extensions/cite-mla/styles.css
@@ -1,3 +1,8 @@
+/*
+Author-year style in-text citations
+*/
+@import '../cite-author-year/styles.css';
+
@import '../cite/styles.css';
:--references :--citation {
diff --git a/src/extensions/cite-numeric/styles.css b/src/extensions/cite-numeric/styles.css
index 394a9647c..0f6d3c3d7 100644
--- a/src/extensions/cite-numeric/styles.css
+++ b/src/extensions/cite-numeric/styles.css
@@ -1,3 +1,4 @@
+/* Square brackets around CiteGroup elements with commas between Cite items */
:--CiteGroup {
&::before {
content: '[';
@@ -15,6 +16,7 @@
}
}
+/* Square brackets around orphan Cite elements */
:not(:--CiteGroup) > :--Cite {
&::before {
content: '[';
@@ -24,17 +26,17 @@
}
}
-/* Show numeric citation format */
+/* Show numeric citation content */
:--Cite > a > :first-child {
display: inline;
}
-/* Hide author-date citation format */
+/* Hide author-date citation content */
:--Cite > a > :last-child {
display: none;
}
-/* Ensure that at least one citation format is visible */
+/* Ensure that at least some content is visible */
:--Cite > a > :only-child {
display: inline;
}