diff --git a/CHANGELOG.md b/CHANGELOG.md
index f72b6dd..bde57bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,8 +15,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The Playground demos (release, main build, and WordPress.org Preview) open on a demo page with copy-ready samples of every accepted input format, an empty Bibliography block to paste them into, brief notes on the key features, and three example bibliographies (Chicago notes-bibliography with Cite / Export, APA 7, IEEE). The Welcome Guide no longer covers the page. The page is defined once in `playground/demo-content.json` and `playground/demo-content.php`, and `npm run playground:build` writes it into every Blueprint.
+### Changed
+
+- The nine citation styles and their locales are rewritten in full from each style manual:
+ - Chicago notes-bibliography and author-date (17th ed.);
+ - APA 7;
+ - MLA 9;
+ - Harvard (Cite Them Right);
+ - IEEE;
+ - Vancouver (*Citing Medicine*);
+ - OSCOLA;
+ - ABNT NBR 6023.
+
+ The earlier files were about 2 KB stand-ins. They initialized every given name and dropped volume, issue, pages, editors, translators, editions, and access dates. Every manual's author-list rules now apply: "and" or "&", "et al." thresholds, and APA's 21+ ellipsis. So do its journal, chapter, webpage, thesis, report, conference-paper, and preprint forms.
+
+ The en-US, en-GB, and pt-BR locales now carry month names, quotation marks, and role terms. pt-BR was an English copy, so ABNT printed "and" and "accessed"; it is now written in Portuguese. Harvard now uses British conventions.
+
+ The styles are still written for Borges and licensed GPL-2.0-or-later, not copied from the CC BY-SA CSL repository. `docs/csl-styles.md` lists each source and the few deliberate deviations.
+
+ Existing bibliographies keep their saved text until an entry is added or edited or the style is changed.
+
### Fixed
+- Organization authors (CSL `literal` names, such as "Open Research Alliance") no longer vanish from formatted entries.
+- An entry after one shortened to "et al." no longer loses the "and" before its last author. Each entry is now formatted on its own.
- A bibliography block no longer opens as invalid ("Attempt Block Recovery") when an editor using a different language from the one who saved it opens the post. `save()` used to write the Cite / Export labels ("Cite / Export", "Copy citation", "Copied", "RIS", "CSL-JSON", "BibTeX", "BibLaTeX") and the "Link to publication" link label into post content in the saving editor's language. The editor checks saved markup against `save()` in the *current* editor's language, so the two did not match. Saved markup is now the same in every language: the panel labels are stored in English and translated for visitors on the server as the block renders (`includes/frontend-labels.php`, a `render_block` filter), so they are translated without JavaScript and the view script loads no `wp-i18n`, and a link whose citation has no title or container title carries no `aria-label`, so screen readers announce its visible URL. Existing posts still validate in any language, because the new deprecation reads the labels back from the saved markup. The exception is blocks saved in the oldest markup shapes (before the biblioentry role was removed) that contain a linked URL in a citation with no title or container title: those still validate only in the language they were saved in, as before. They switch to the new markup the next time they are saved. The PHP port of `save()` (`includes/save-markup.php`) matches.
- In all 19 bundled translations, seven strings were compiled as "Add citations" even though they mean something else: "Copy citation", "Copy citation: %s", "Copied citation.", "Edit citation: %s", "Delete citation: %s", "Added 1 citation.", and "Added 1 citation. %s". These were stale fuzzy matches, and `wp i18n make-mo` compiles fuzzy entries. The translations are cleared so these strings fall back to English, and the `.mo` files are rebuilt.
- Pasting a whole reference-manager `.bib` export no longer loses or misreads records:
diff --git a/README.md b/README.md
index a012a06..9814406 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,7 @@ Borges is a static-output block: formatted bibliography HTML, JSON-LD, and COinS
| Metric | Value |
|---|---|
-| First-party PHP | ~1,978 LOC main plugin file; ~6,428 LOC total with `includes/` |
+| First-party PHP | ~2,064 LOC main plugin file; ~6,514 LOC total with `includes/` |
| JS source (`src/`) | ~9,956 LOC |
| Frontend runtime shipped to visitors | `view.js` ~1.4 KB + `style-index.css` ~2.9 KB, no script dependencies, enqueued only when the block is present |
| Installed footprint | ~1.9 MB (`vendor/` ~792 KB, translations 724 KB, build assets ~324 KB) |
diff --git a/SPEC.md b/SPEC.md
index 2191b2d..9c82853 100644
--- a/SPEC.md
+++ b/SPEC.md
@@ -482,7 +482,7 @@ These handle:
- `plugin-doi`: DOI string → CSL-JSON fallback support when direct CrossRef fetch is unavailable
- `plugin-bibtex`: BibTeX string → CSL-JSON
-Formatted bibliography strings are generated locally through `citeproc-php` using plugin-owned GPL-compatible CSL style and locale fixtures. Do not bundle the official CSL style or locale repositories in the WordPress.org release package.
+Formatted bibliography strings are generated locally through `citeproc-php` using plugin-owned GPL-2.0-or-later CSL styles and locales, written from each style manual's rules (see `docs/csl-styles.md`). Do not bundle the official CSL style or locale repositories in the WordPress.org release package.
---
diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt
index a0ca6ad..f8200af 100644
--- a/THIRD-PARTY-NOTICES.txt
+++ b/THIRD-PARTY-NOTICES.txt
@@ -7,6 +7,6 @@ Borges Bibliography Builder is licensed GPL-2.0-or-later. The release package in
- `myclabs/php-enum` — MIT License — https://github.com/myclabs/php-enum
- `@citation-js/core`, `@citation-js/plugin-doi`, and `@citation-js/plugin-bibtex` are used at build time/editor runtime through the bundled editor script and are MIT licensed — https://citation.js.org/
-The Composer path packages named `citation-style-language/styles` and `citation-style-language/locales` in this repository are **not** the official CSL project packages. They contain project-authored, minimal CSL style and locale fixtures licensed GPL-2.0-or-later for this plugin. They are included so the WordPress.org release does not bundle the official CC BY-SA CSL style or locale repositories.
+The Composer path packages named `citation-style-language/styles` and `citation-style-language/locales` in this repository are **not** the official CSL project packages. They contain CSL styles and locales written for this plugin from the style manuals' own rules (see docs/csl-styles.md), licensed GPL-2.0-or-later. They are included so the WordPress.org release does not bundle the official CC BY-SA CSL style or locale repositories.
The source tree and release package must not include dependencies or files licensed only as CPAL-1.0, AGPL-1.0, or CC-BY-SA-3.0.
diff --git a/bibliography-builder.php b/bibliography-builder.php
index 25e50ca..c617a8a 100644
--- a/bibliography-builder.php
+++ b/bibliography-builder.php
@@ -232,7 +232,7 @@ function bibliography_builder_get_formatter_style_definitions() {
),
'harvard' => array(
'template' => 'harvard1',
- 'locale' => 'en-US',
+ 'locale' => 'en-GB',
'family' => 'author-date',
),
'ieee' => array(
@@ -1112,6 +1112,27 @@ function bibliography_builder_normalize_formatted_text( $text, $style ) {
$text = preg_replace( '/\bp\.\s+p{1,2}\.\s+/u', 'p. ', $text );
}
+ // citeproc-php puts a space between a name and a label whose prefix is
+ // ", " ("Lindqvist , eds."); a space before a comma is never wanted.
+ $text = str_replace( ' ,', ',', $text );
+
+ // American styles put commas and periods inside closing quotes. citeproc-php
+ // only does so for an element's own suffix, not for a group delimiter
+ // (“Title”, in IEEE).
+ if ( isset( $style['locale'] ) && 'en-US' === $style['locale'] ) {
+ $text = str_replace( array( '”,', '”.' ), array( ',”', '.”' ), $text );
+ }
+
+ // citeproc-php initializes only capitalized parts of a hyphenated given
+ // name, so "Ji-woo" comes out "J.- woo". Initialize the second part too.
+ $text = preg_replace_callback(
+ '/(\p{Lu})(\.?)- (\p{Ll})\p{Ll}*/u',
+ static function ( $parts ) {
+ return $parts[1] . $parts[2] . '-' . mb_strtoupper( $parts[3], 'UTF-8' ) . $parts[2];
+ },
+ $text
+ );
+
return str_replace( 'and et al.', 'et al.', $text );
}
@@ -1169,6 +1190,63 @@ function bibliography_builder_extract_citeproc_entries( $html, $style ) {
return $entries;
}
+/**
+ * Adapt a CSL-JSON item to what citeproc-php 2.7 can render.
+ *
+ * - Literal names (organizations, one-name authors): citeproc-php renders a
+ * name only from its `family` part, so `{ "literal": "Open Research
+ * Alliance" }` would vanish. As a family-only name it prints whole, never
+ * inverted or initialized.
+ * - `page-first`: citeproc-php does not derive it from `page`, and OSCOLA
+ * cites a journal article by its first page.
+ *
+ * @param array $item CSL-JSON item.
+ * @return array
+ */
+function bibliography_builder_prepare_csl_for_formatter( $item ) {
+ $name_variables = array(
+ 'author',
+ 'collection-editor',
+ 'composer',
+ 'container-author',
+ 'director',
+ 'editor',
+ 'editorial-director',
+ 'illustrator',
+ 'interviewer',
+ 'original-author',
+ 'recipient',
+ 'reviewed-author',
+ 'translator',
+ );
+
+ foreach ( $name_variables as $variable ) {
+ if ( empty( $item[ $variable ] ) || ! is_array( $item[ $variable ] ) ) {
+ continue;
+ }
+
+ foreach ( $item[ $variable ] as $position => $name ) {
+ $is_literal = is_array( $name ) && empty( $name['family'] )
+ && isset( $name['literal'] ) && is_string( $name['literal'] );
+ $literal = $is_literal ? trim( $name['literal'] ) : '';
+
+ if ( '' !== $literal ) {
+ $item[ $variable ][ $position ] = array( 'family' => $literal );
+ }
+ }
+ }
+
+ if ( empty( $item['page-first'] ) && isset( $item['page'] ) && is_scalar( $item['page'] ) ) {
+ $first = trim( preg_split( '/[-\x{2013}\x{2014},&]/u', (string) $item['page'] )[0] );
+
+ if ( '' !== $first ) {
+ $item['page-first'] = $first;
+ }
+ }
+
+ return $item;
+}
+
/**
* Format CSL-JSON items as plain-text bibliography entries.
*
@@ -1216,7 +1294,7 @@ function bibliography_builder_format_csl_items( $csl_items, $style_key ) {
$prepared_items = array();
foreach ( array_values( $csl_items ) as $index => $item ) {
- $item_array = is_array( $item ) ? $item : array();
+ $item_array = bibliography_builder_prepare_csl_for_formatter( is_array( $item ) ? $item : array() );
$item_array['id'] = 'bibliography-builder-format-' . $index;
$prepared_items[] = $item_array;
}
@@ -1246,9 +1324,17 @@ function bibliography_builder_format_csl_items( $csl_items, $style_key ) {
),
);
+ // One formatter per entry: citeproc-php keeps per-render state on its
+ // parsed name elements (once one entry is cut to "et al.", later entries
+ // in the same render lose their "and"), and no style here needs
+ // cross-entry context such as disambiguation or author substitution.
try {
- $formatter = new \Seboettg\CiteProc\CiteProc( $style_xml, $style['locale'], $markup_extension );
- $html = $formatter->render( $items_for_formatter, 'bibliography' );
+ $html = '';
+
+ foreach ( $items_for_formatter as $item_for_formatter ) {
+ $formatter = new \Seboettg\CiteProc\CiteProc( $style_xml, $style['locale'], $markup_extension );
+ $html .= $formatter->render( array( $item_for_formatter ), 'bibliography' );
+ }
} catch ( Throwable $error ) {
return new WP_Error(
'bibliography_builder_formatter_failed',
diff --git a/docs/csl-styles.md b/docs/csl-styles.md
new file mode 100644
index 0000000..42b0f69
--- /dev/null
+++ b/docs/csl-styles.md
@@ -0,0 +1,84 @@
+# Bundled citation styles
+
+Borges formats bibliographies with `citeproc-php` against nine CSL styles and three locales that live in this repository:
+
+- styles: `packages/citation-style-language-styles/`
+- locales: `packages/citation-style-language-locales/`
+
+## Why they are project-authored
+
+The CSL project's official styles and locales are licensed CC BY-SA 3.0, which is not GPL-compatible. WordPress.org requires GPL-compatible code and assets, so Borges must not bundle them (see `THIRD-PARTY-NOTICES.txt` and `SPEC.md`).
+
+Instead, every style here was written for Borges from its style manual's own rules, and is licensed GPL-2.0-or-later. Style rules themselves are not copyrightable. The official CSL files were not used as a source.
+
+Earlier releases shipped about 2 KB stand-ins. Those initialized every given name, dropped volume, issue and pages, and ignored editors, translators, editions and access dates. The locales had no month names or quotation marks, and pt-BR was a copy of English.
+
+## Styles
+
+| Key | File | Source | Notes |
+| --- | --- | --- | --- |
+| `chicago-notes-bibliography` | `chicago-notes-bibliography.csl` | Chicago Manual of Style, 17th ed., ch. 14 (bibliography entries) | First author inverted, "and" before the last name, 11+ authors cut to 7 + "et al." |
+| `chicago-author-date` | `chicago-author-date.csl` | Chicago Manual of Style, 17th ed., ch. 15 | Year after the author; journal form `27 (2): 97–111` |
+| `apa-7` | `apa.csl` | APA Publication Manual, 7th ed., ch. 9–10 | Initials, `&`, up to 20 authors, 21+ as the first 19, "…", and the last; no publisher place |
+| `mla-9` | `modern-language-association.csl` | MLA Handbook, 9th ed., ch. 5 | 3+ authors as "First, et al."; MLA month abbreviations (June, July, Sept.) |
+| `harvard` | `harvard1.csl` | Cite Them Right, 12th ed. | en-GB; initials without spaces, 4+ authors "et al.", `(eds)`, `edn`, single quotes, "Available at: … (Accessed: …)" |
+| `ieee` | `ieee.csl` | IEEE Reference Guide (2023) | Initials first; 7+ authors as first + "et al."; `doi:` form; "[Online]. Available:" |
+| `vancouver` | `vancouver.csl` | NLM *Citing Medicine*, 2nd ed. (ICMJE) | `Green S`; 7+ authors as 6 + "et al."; `2020 Apr;27(2):97-111`; "[Internet] … [cited …]" |
+| `oscola` | `oscola.csl` | OSCOLA, 4th ed. (bibliography) | en-GB; `Alvarez MI`, 4+ "and others"; `(2020) 27 Journal 97`; `Smith v Jones [2019] UKSC 12`; no final full stop |
+| `abnt` | `abnt.csl` | ABNT NBR 6023:2018 | pt-BR; SURNAMES in capitals, `;` between authors, 4+ "et al."; `3. ed.`, `(org.)`, `In:`, `[S. l.]`, `[s. d.]`, "Disponível em: … Acesso em: …" |
+
+Deviations shared by every style, all forced by how the block stores and renders entries:
+
+- **Titles keep their stored capitalization.** APA's sentence case is not applied, and neither is ABNT's capitalized first word for title-first entries. The block re-applies italics by finding the stored title text in the formatted entry, so a case-transformed title would lose its italics.
+- **URLs and DOIs stay linkable.** The block links `https://` URLs up to the next space. So OSCOLA prints URLs without angle brackets, and ABNT prints DOIs as `https://doi.org/` links.
+- **No Chicago 3-em dash for repeated authors.** It depends on list order, and the block sorts entries itself, after formatting.
+- **No citation numbers.** Numeric styles number with the list element.
+- **Journal titles print as stored.** They are not abbreviated (IEEE, Vancouver).
+
+## Writing or changing a style
+
+Follow these conventions. Each one works around citeproc-php 2.7 behavior (see `docs/external-eccentricities.md`):
+
+1. **Suffix each part with `.` or `,` inside a space-delimited group.** citeproc-php moves punctuation inside a closing quote, and drops a doubled period ("eds.."), only for an element's own suffix, and only when it is exactly `.`, `,` or `;`. It never does this for a group delimiter.
+2. **Use ` ` before the names for role phrases.** A `` placed before a name loses its trailing space ("Translated byHelen").
+3. **Choose creators explicitly when later conditions test them.** After ``, citeproc-php treats the substituted variable as absent in every later ``, so an edited book lost its title. Substitution is safe only when no later condition tests the substituted variable.
+4. **Wrap the children of a nested `` in a delimited ``.** A `` inside another branch joins its children with no delimiter ("15.Available").
+5. **Omit `page-range-format` for en-dash styles.** Any `page-range-format` makes citeproc-php join the range with a hyphen, while none gives a full en-dash range ("97–111"). Vancouver (`minimal`) and ABNT (`expanded`) set one because they want hyphens.
+6. **Use explicit `` children.** Never use `form="text"` dates. See the "localized dates" entry.
+7. **Keep sort keys in separate `sort-*` macros.** The `` blocks exist for the PHP/JS sort-coordination tests (`tests/phpunit/SortCoordinationTest.php`). Rendering a display macro as a sort key corrupts its name state, so the "and" disappears.
+
+The formatter (`bibliography_builder_format_csl_items()`) also adapts input and output:
+
+- **Per-entry rendering.** Each entry is rendered with its own formatter, because citeproc-php keeps name state across entries: once one entry is cut to "et al.", later entries lose their "and".
+- **`bibliography_builder_prepare_csl_for_formatter()`**:
+ - maps `{ "literal": … }` names to family-only names, because citeproc-php drops names without a family part;
+ - derives `page-first`, for OSCOLA.
+- **`bibliography_builder_normalize_formatted_text()`**:
+ - removes the space citeproc-php puts before a label's comma;
+ - fully initializes hyphenated given names ("J.-W.", not "J.- woo");
+ - moves commas and periods inside closing quotes for `en-US` styles.
+
+## Testing
+
+`tests/phpunit/CslStyleGoldenTest.php` renders `tests/fixtures/csl-styles/items.json` in every style and compares the result with `tests/fixtures/csl-styles/.txt`.
+
+The corpus covers:
+
+- books with one or two authors, a translator, and editors only;
+- a chapter;
+- journal articles with 1, 3, 8 and 22 authors;
+- a magazine and a newspaper article;
+- webpages with and without a date;
+- a thesis, a report, a conference paper and a preprint;
+- an entry with no author and no date;
+- a case and a statute.
+
+After an intended change:
+
+```sh
+BORGES_WRITE_STYLE_GOLDENS=1 composer test:php -- --filter CslStyleGolden
+```
+
+Then review the golden diff against the manual.
+
+The same test fails when `vendor/citation-style-language/` is out of date with `packages/`. The formatter reads the vendor copy, so run `composer install` after editing a style.
diff --git a/docs/current-metrics.md b/docs/current-metrics.md
index 3d65414..7675248 100644
--- a/docs/current-metrics.md
+++ b/docs/current-metrics.md
@@ -11,8 +11,8 @@ Source and LOC figures last verified: **2026-09-25** against the locale-independ
| Metric | Value | Re-derivation command |
|---|---|---|
-| Main plugin file (`bibliography-builder.php`) | **1,978** | `wc -l bibliography-builder.php` |
-| All first-party PHP (excl. vendor, tests, scripts, playground, packages, output, node_modules, generated `build/`) | **6,428** | `find . -name '*.php' -not -path './vendor/*' -not -path './node_modules/*' -not -path './tests/*' -not -path './packages/*' -not -path './scripts/*' -not -path './playground/*' -not -path './output/*' -not -path './build/*' -print0 \| xargs -0 wc -l \| tail -1` |
+| Main plugin file (`bibliography-builder.php`) | **2,064** | `wc -l bibliography-builder.php` |
+| All first-party PHP (excl. vendor, tests, scripts, playground, packages, output, node_modules, generated `build/`) | **6,514** | `find . -name '*.php' -not -path './vendor/*' -not -path './node_modules/*' -not -path './tests/*' -not -path './packages/*' -not -path './scripts/*' -not -path './playground/*' -not -path './output/*' -not -path './build/*' -print0 \| xargs -0 wc -l \| tail -1` |
| JS source (`src/`, excl. `*.test.js`) | **9,956** | `find ./src -name '*.js' -not -name '*.test.js' -print0 \| xargs -0 wc -l \| tail -1` |
| Shipped frontend runtime (`build/view.js`, minified) | **1,449 bytes** | `npm run build` then `wc -c < build/view.js` |
diff --git a/docs/external-eccentricities.md b/docs/external-eccentricities.md
index 75b942e..9596261 100644
--- a/docs/external-eccentricities.md
+++ b/docs/external-eccentricities.md
@@ -44,6 +44,26 @@ check across every bundled style). Three styles had regressed to the localized
form and dropped the year: `chicago-notes-bibliography`, `oscola`,
`modern-language-association`.
+## citeproc-php 2.7: rendering quirks the bundled styles work around
+
+Found while writing full styles to replace the minimal ones (2026-09). Each one was reproduced against `seboettg/citeproc-php` 2.7.1 source. The style-side conventions are in `docs/csl-styles.md`; the formatter-side fixes are in `bibliography_builder_format_csl_items()` and its helpers.
+
+| Symptom | Cause in citeproc-php | Workaround |
+| --- | --- | --- |
+| Organization authors (`{ "literal": … }`) vanish | `Name::getNamesString()` returns "" for a name without `family` | `bibliography_builder_prepare_csl_for_formatter()` maps literal to family-only |
+| Entries after an "et al." entry lose their "and" | `Name` keeps `$etAl` (and `$and`) set across the items of one render | One `CiteProc` instance per entry |
+| "and" missing when a display macro is also a `` key | Rendering a sort key leaves the shared `Name` object in sort mode | Separate `sort-*` macros |
+| "Lindqvist , eds." | `Names::appendLabel()` adds a space unless the trimmed prefix is in its punctuation list, and "," is not | Formatter removes " ," |
+| "Translated byHelen" | A label rendered before names is trimmed, and its suffix space is lost | `` followed by `` |
+| “Title”. and “Title”, | Punctuation moves inside the quote only for an element suffix that is exactly `.`, `,` or `;` | Suffix each part; formatter moves `,` and `.` inside quotes for en-US |
+| Title missing from an edited book | A variable used by `` counts as absent in later `` tests | Choose the creator explicitly |
+| "15.Available" | A nested `` joins its children without the parent group's delimiter | Wrap the branch children in a delimited `` |
+| Page ranges with "-" | Any `page-range-format` returns `"$from-$to"`; none returns an en dash | Omit it where an en dash is wanted |
+| "J.- woo" | `StringHelper::initializeBySpaceOrHyphen()` keeps a lowercase part after a hyphen as a particle | Formatter initializes it ("J.-W.") |
+| `page-first` empty | Not derived from `page` | Derived in `bibliography_builder_prepare_csl_for_formatter()` |
+
+These are upstream behaviors, not Borges bugs. The literal-name and cross-entry state issues are worth reporting upstream (pkp/citeproc-php) if they are still present in a newer release.
+
## Build: the formatter renders from `vendor/`, not `packages/`
The PHP formatter (`bibliography_builder_format_csl_items`) loads style XML from
diff --git a/docs/supported-input-style-matrix.md b/docs/supported-input-style-matrix.md
index dbaa092..f34f8d3 100644
--- a/docs/supported-input-style-matrix.md
+++ b/docs/supported-input-style-matrix.md
@@ -93,7 +93,7 @@ This avoids overpromising broad multilingual BibTeX support.
## Selectable bibliography styles
-These are style outputs, not raw-input parsing promises.
+These are style outputs, not raw-input parsing promises. Each style is written for Borges from its manual; see [`docs/csl-styles.md`](./csl-styles.md) for sources and deviations.
### Enabled now
diff --git a/packages/citation-style-language-locales/locales-en-GB.xml b/packages/citation-style-language-locales/locales-en-GB.xml
index 5372341..34d8551 100644
--- a/packages/citation-style-language-locales/locales-en-GB.xml
+++ b/packages/citation-style-language-locales/locales-en-GB.xml
@@ -1,19 +1,163 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‘
+ ’
+ “
+ ”
+ accessed
and
+ &
+ and others
+ anonymous
+ anon.
+ at
+ available at
+ by
+ circa
+ c.
+ cited
et al.
- n.d.
+ forthcoming
+ from
+ ibid.
+ in
+ in press
+ internet
+ no date
+ n.d.
+ online
+ presented at the
+ retrieved
+ version
+ –
+
+ th
+ st
+ nd
+ rd
+ th
+ th
+ th
+
+ first
+ second
+ third
+ fourth
+ fifth
+ sixth
+ seventh
+ eighth
+ ninth
+ tenth
+
+ book books
+ chapter chapters
+ column columns
+ figure figures
+ folio folios
+ number numbers
+ line lines
+ note notes
+ page pages
+ paragraph paragraphs
+ part parts
+ section sections
+ volume volumes
+ edition editions
+
+ chap. chaps.
+ fig. figs.
+ no. nos.
+ l. ll.
+ n. nn.
+ p. pp.
+ para. paras.
+ pt. pts.
+ sec. secs.
+ vol. vols.
+ ed. eds.
+
+ § §§
+ ¶ ¶¶
+
+ director directors
editor editors
- ed. eds.
+ editor editors
+ illustrator illustrators
translator translators
+ editor and translator editors and translators
+
+ dir. dirs.
+ ed. eds.
+ ed. eds.
+ ill. ills.
trans. trans.
- p. pp.
- vol. vols.
- no. nos.
- in
- accessed
- available at
+ ed. and trans. eds. and trans.
+
+ by
+ directed by
+ edited by
+ edited by
+ illustrated by
+ interview by
+ to
+ by
+ translated by
+ edited and translated by
+
+ dir. by
+ ed. by
+ ed. by
+ illus. by
+ trans. by
+ ed. and trans. by
+
+ January
+ February
+ March
+ April
+ May
+ June
+ July
+ August
+ September
+ October
+ November
+ December
+
+ Jan
+ Feb
+ Mar
+ Apr
+ May
+ Jun
+ Jul
+ Aug
+ Sep
+ Oct
+ Nov
+ Dec
+
+ Spring
+ Summer
+ Autumn
+ Winter
diff --git a/packages/citation-style-language-locales/locales-en-US.xml b/packages/citation-style-language-locales/locales-en-US.xml
index 5372341..2b3efde 100644
--- a/packages/citation-style-language-locales/locales-en-US.xml
+++ b/packages/citation-style-language-locales/locales-en-US.xml
@@ -1,19 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
+ “
+ ”
+ ‘
+ ’
+ accessed
and
+ &
+ and others
+ anonymous
+ anon.
+ at
+ available at
+ by
+ circa
+ c.
+ cited
et al.
- n.d.
+ forthcoming
+ from
+ ibid.
+ in
+ in press
+ internet
+ no date
+ n.d.
+ online
+ presented at the
+ retrieved
+ version
+ –
+
+ th
+ st
+ nd
+ rd
+ th
+ th
+ th
+
+ first
+ second
+ third
+ fourth
+ fifth
+ sixth
+ seventh
+ eighth
+ ninth
+ tenth
+
+ book books
+ chapter chapters
+ column columns
+ figure figures
+ folio folios
+ number numbers
+ line lines
+ note notes
+ page pages
+ paragraph paragraphs
+ part parts
+ section sections
+ volume volumes
+ edition editions
+
+ chap. chaps.
+ fig. figs.
+ no. nos.
+ l. ll.
+ n. nn.
+ p. pp.
+ para. paras.
+ pt. pts.
+ sec. secs.
+ vol. vols.
+ ed. eds.
+
+ § §§
+ ¶ ¶¶
+
+ director directors
editor editors
- ed. eds.
+ editor editors
+ illustrator illustrators
translator translators
+ editor and translator editors and translators
+
+ dir. dirs.
+ ed. eds.
+ ed. eds.
+ ill. ills.
trans. trans.
- p. pp.
- vol. vols.
- no. nos.
- in
- accessed
- available at
+ ed. and trans. eds. and trans.
+
+ by
+ directed by
+ edited by
+ edited by
+ illustrated by
+ interview by
+ to
+ by
+ translated by
+ edited and translated by
+
+ dir. by
+ ed. by
+ ed. by
+ illus. by
+ trans. by
+ ed. and trans. by
+
+ January
+ February
+ March
+ April
+ May
+ June
+ July
+ August
+ September
+ October
+ November
+ December
+
+ Jan.
+ Feb.
+ Mar.
+ Apr.
+ May
+ Jun.
+ Jul.
+ Aug.
+ Sep.
+ Oct.
+ Nov.
+ Dec.
+
+ Spring
+ Summer
+ Autumn
+ Winter
diff --git a/packages/citation-style-language-locales/locales-pt-BR.xml b/packages/citation-style-language-locales/locales-pt-BR.xml
index 5372341..078f903 100644
--- a/packages/citation-style-language-locales/locales-pt-BR.xml
+++ b/packages/citation-style-language-locales/locales-pt-BR.xml
@@ -1,19 +1,154 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
- and
+ “
+ ”
+ ‘
+ ’
+ acesso em
+ e
+ &
+ e outros
+ anônimo
+ anôn.
+ em
+ disponível em
+ por
+ cerca de
+ ca.
+ citado
et al.
- n.d.
- editor editors
- ed. eds.
- translator translators
- trans. trans.
- p. pp.
- vol. vols.
- no. nos.
+ no prelo
+ de
+ ibid.
in
- accessed
- available at
+ no prelo
+ internet
+ sem data
+ s. d.
+ online
+ apresentado em
+ recuperado
+ versão
+ -
+
+ º
+ primeira
+ segunda
+ terceira
+ quarta
+ quinta
+ sexta
+ sétima
+ oitava
+ nona
+ décima
+
+ livro livros
+ capítulo capítulos
+ figura figuras
+ número números
+ linha linhas
+ nota notas
+ página páginas
+ parágrafo parágrafos
+ parte partes
+ seção seções
+ volume volumes
+ edição edições
+
+ cap. caps.
+ fig. figs.
+ n. n.
+ l. l.
+ n. n.
+ p. p.
+ par. par.
+ pt. pts.
+ seç. seç.
+ v. v.
+ ed. ed.
+
+ § §§
+ ¶ ¶¶
+
+ diretor diretores
+ organizador organizadores
+ editor editores
+ ilustrador ilustradores
+ tradutor tradutores
+ organizador e tradutor organizadores e tradutores
+
+ dir. dirs.
+ org. org.
+ ed. ed.
+ il. il.
+ trad. trad.
+ org. e trad. org. e trad.
+
+ por
+ dirigido por
+ organizado por
+ editado por
+ ilustrado por
+ entrevista de
+ para
+ por
+ tradução de
+ organizado e traduzido por
+
+ dir.
+ org.
+ ed.
+ il.
+ trad.
+ org. e trad.
+
+ janeiro
+ fevereiro
+ março
+ abril
+ maio
+ junho
+ julho
+ agosto
+ setembro
+ outubro
+ novembro
+ dezembro
+
+ jan.
+ fev.
+ mar.
+ abr.
+ maio
+ jun.
+ jul.
+ ago.
+ set.
+ out.
+ nov.
+ dez.
+
+ primavera
+ verão
+ outono
+ inverno
diff --git a/packages/citation-style-language-styles/abnt.csl b/packages/citation-style-language-styles/abnt.csl
index 8c0cfc1..a7a46b4 100644
--- a/packages/citation-style-language-styles/abnt.csl
+++ b/packages/citation-style-language-styles/abnt.csl
@@ -1,22 +1,285 @@
-
diff --git a/packages/citation-style-language-styles/apa.csl b/packages/citation-style-language-styles/apa.csl
index 8c0cfc1..615934d 100644
--- a/packages/citation-style-language-styles/apa.csl
+++ b/packages/citation-style-language-styles/apa.csl
@@ -1,22 +1,258 @@
-
diff --git a/packages/citation-style-language-styles/chicago-author-date.csl b/packages/citation-style-language-styles/chicago-author-date.csl
index 8c0cfc1..0d8743d 100644
--- a/packages/citation-style-language-styles/chicago-author-date.csl
+++ b/packages/citation-style-language-styles/chicago-author-date.csl
@@ -1,22 +1,253 @@
-
diff --git a/packages/citation-style-language-styles/chicago-notes-bibliography.csl b/packages/citation-style-language-styles/chicago-notes-bibliography.csl
index 7bccf0d..064af31 100644
--- a/packages/citation-style-language-styles/chicago-notes-bibliography.csl
+++ b/packages/citation-style-language-styles/chicago-notes-bibliography.csl
@@ -1,21 +1,293 @@
-
diff --git a/packages/citation-style-language-styles/harvard1.csl b/packages/citation-style-language-styles/harvard1.csl
index 8c0cfc1..7f69f97 100644
--- a/packages/citation-style-language-styles/harvard1.csl
+++ b/packages/citation-style-language-styles/harvard1.csl
@@ -1,22 +1,278 @@
-
diff --git a/packages/citation-style-language-styles/ieee.csl b/packages/citation-style-language-styles/ieee.csl
index f25f2a5..d3d0741 100644
--- a/packages/citation-style-language-styles/ieee.csl
+++ b/packages/citation-style-language-styles/ieee.csl
@@ -1,20 +1,272 @@
-
diff --git a/packages/citation-style-language-styles/modern-language-association.csl b/packages/citation-style-language-styles/modern-language-association.csl
index 7bccf0d..c248ef4 100644
--- a/packages/citation-style-language-styles/modern-language-association.csl
+++ b/packages/citation-style-language-styles/modern-language-association.csl
@@ -1,21 +1,237 @@
-
diff --git a/packages/citation-style-language-styles/oscola.csl b/packages/citation-style-language-styles/oscola.csl
index 7bccf0d..2112827 100644
--- a/packages/citation-style-language-styles/oscola.csl
+++ b/packages/citation-style-language-styles/oscola.csl
@@ -1,21 +1,253 @@
-
diff --git a/packages/citation-style-language-styles/vancouver.csl b/packages/citation-style-language-styles/vancouver.csl
index f25f2a5..c2a56f4 100644
--- a/packages/citation-style-language-styles/vancouver.csl
+++ b/packages/citation-style-language-styles/vancouver.csl
@@ -1,20 +1,252 @@
-
diff --git a/tests/fixtures/csl-styles/abnt.txt b/tests/fixtures/csl-styles/abnt.txt
new file mode 100644
index 0000000..b97dc20
--- /dev/null
+++ b/tests/fixtures/csl-styles/abnt.txt
@@ -0,0 +1,20 @@
+book-one-author ALVAREZ, Marta Inés. The Architecture of Small Libraries. 3. ed. Chicago: Northfield University Press, 2019.
+book-two-authors BECKER, Thomas J.; NAKAMURA, Yuki. Reading Machines: Catalogues, Indexes, and the Order of Knowledge. New York: Harbor House, 2021.
+book-translated FERREIRA, João Paulo. The Garden of Forking Paths. Tradução de Helen Wright. London: Meridian Books, 2015.
+book-edited OKAFOR, Chidi; LINDQVIST, Anna (org.). Essays on Classification. Oxford: Delta Academic, 2018.
+chapter DUBOIS, Claire. Indexing the Infinite. In: OKAFOR, Chidi; LINDQVIST, Anna (org.). Essays on Classification. Oxford: Delta Academic, 2018. p. 45-67.
+article-one-author GREEN, Samuel. Metadata Drift in Institutional Repositories. Journal of Library Systems, v. 27, n. 2, p. 97-111, abr. 2020. DOI: https://doi.org/10.1234/jls.2020.0027.
+article-three-authors HUGHES, Rebecca; IQBAL, Omar; JENSEN, Lars. Citation Styles as Data. Scholarly Communication Review, v. 12, n. 4, p. 301-322, 2022. DOI: https://doi.org/10.5555/scr.12.4.301.
+article-eight-authors KIM, Ji-woo et al. A Shared Corpus of Reference Metadata. Data in Brief, v. 41, p. 107-118, 2023.
+article-twenty-two-authors ABBOTT, A. et al. Large Collaborations and Author Lists. Physical Review Letters, v. 130, n. 5, p. 051801, 2023. DOI: https://doi.org/10.1103/example.130.051801.
+article-magazine TANAKA, Emi. The Return of the Card Catalogue. The Atlantic Review, 15 mar. 2021. Disponível em: https://example.com/magazine/card-catalogue.
+article-newspaper USMAN, Bola. City Library Opens New Wing. The Daily Courier, 2 nov. 2022.
+webpage-organization OPEN RESEARCH ALLIANCE. Guide to Persistent Identifiers. Open Research Alliance, 10 jan. 2024. Disponível em: https://example.org/guides/pids. Acesso em: 3 jun. 2025.
+webpage-no-date About the Collection. Museum of Printed Books, [s. d.]. Disponível em: https://example.org/about. Acesso em: 14 fev. 2025.
+thesis VARGA, Dóra. Authority Control in Multilingual Catalogues. 2017. PhD diss. – University of Toronto, Toronto, 2017.
+report NATIONAL LIBRARY COUNCIL. State of Open Metadata. Washington, DC: National Library Council, 2020. (NLC-2020-4).
+paper-conference WEBER, Jonas; XU, Li. Fast Deduplication of Bibliographic Records. In: Proceedings of the Conference on Digital Libraries. New York: ACM, 2019. p. 210-219. DOI: https://doi.org/10.1145/0000000.0000001.
+preprint YOUNG, Grace; ZHAO, Wei. Learning Citation Formats from Examples. arXiv, 2024. Preprint. DOI: https://doi.org/10.48550/arXiv.2401.01234.
+book-no-author-no-date A Handbook of Bookbinding. Boston: Guild Press, [s. d.].
+legal-case Smith v Jones. UKSC 12, 2019.
+legislation Copyright, Designs and Patents Act. 1988.
diff --git a/tests/fixtures/csl-styles/apa-7.txt b/tests/fixtures/csl-styles/apa-7.txt
new file mode 100644
index 0000000..f612c03
--- /dev/null
+++ b/tests/fixtures/csl-styles/apa-7.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez, M. I. (2019). The Architecture of Small Libraries (3rd ed.). Northfield University Press.
+book-two-authors Becker, T. J., & Nakamura, Y. (2021). Reading Machines: Catalogues, Indexes, and the Order of Knowledge. Harbor House.
+book-translated Ferreira, J. P. (2015). The Garden of Forking Paths (H. Wright, Trans.). Meridian Books.
+book-edited Okafor, C., & Lindqvist, A. (Eds.). (2018). Essays on Classification. Delta Academic.
+chapter Dubois, C. (2018). Indexing the Infinite. In C. Okafor & A. Lindqvist (Eds.), Essays on Classification (pp. 45–67). Delta Academic.
+article-one-author Green, S. (2020). Metadata Drift in Institutional Repositories. Journal of Library Systems, 27(2), 97–111. https://doi.org/10.1234/jls.2020.0027
+article-three-authors Hughes, R., Iqbal, O., & Jensen, L. (2022). Citation Styles as Data. Scholarly Communication Review, 12(4), 301–322. https://doi.org/10.5555/scr.12.4.301
+article-eight-authors Kim, J.-W., Lopez, A., Moreau, P., Novak, P., Osei, K., Park, M., Quinn, A., & Rossi, M. (2023). A Shared Corpus of Reference Metadata. Data in Brief, 41, 107–118.
+article-twenty-two-authors Abbott, A., Baker, B., Clark, C., Davis, D., Evans, E., Foster, F., Gray, G., Hall, H., Irwin, I., Jones, J., King, K., Lewis, L., Moore, M., Nash, N., Owen, O., Price, P., Quill, Q., Reed, R., Stone, S., … Vance, V. (2023). Large Collaborations and Author Lists. Physical Review Letters, 130(5), 051801. https://doi.org/10.1103/example.130.051801
+article-magazine Tanaka, E. (2021, March 15). The Return of the Card Catalogue. The Atlantic Review. https://example.com/magazine/card-catalogue
+article-newspaper Usman, B. (2022, November 2). City Library Opens New Wing. The Daily Courier.
+webpage-organization Open Research Alliance. (2024, January 10). Guide to Persistent Identifiers. Open Research Alliance. https://example.org/guides/pids
+webpage-no-date About the Collection. (n.d.). Museum of Printed Books. Retrieved February 14, 2025, from https://example.org/about
+thesis Varga, D. (2017). Authority Control in Multilingual Catalogues [PhD diss., University of Toronto].
+report National Library Council. (2020). State of Open Metadata (Report No. NLC-2020-4). National Library Council.
+paper-conference Weber, J., & Xu, L. (2019). Fast Deduplication of Bibliographic Records. In Proceedings of the Conference on Digital Libraries (pp. 210–219). ACM. https://doi.org/10.1145/0000000.0000001
+preprint Young, G., & Zhao, W. (2024). Learning Citation Formats from Examples (arXiv:2401.01234). arXiv. https://doi.org/10.48550/arXiv.2401.01234
+book-no-author-no-date A Handbook of Bookbinding. (n.d.). Guild Press.
+legal-case Smith v Jones. (2019). UKSC 12.
+legislation Copyright, Designs and Patents Act. (1988).
diff --git a/tests/fixtures/csl-styles/chicago-author-date.txt b/tests/fixtures/csl-styles/chicago-author-date.txt
new file mode 100644
index 0000000..6ea5b46
--- /dev/null
+++ b/tests/fixtures/csl-styles/chicago-author-date.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez, Marta Inés. 2019. The Architecture of Small Libraries. 3rd ed. Chicago: Northfield University Press.
+book-two-authors Becker, Thomas J., and Yuki Nakamura. 2021. Reading Machines: Catalogues, Indexes, and the Order of Knowledge. New York: Harbor House.
+book-translated Ferreira, João Paulo. 2015. The Garden of Forking Paths. Translated by Helen Wright. London: Meridian Books.
+book-edited Okafor, Chidi, and Anna Lindqvist, eds. 2018. Essays on Classification. Oxford: Delta Academic.
+chapter Dubois, Claire. 2018. “Indexing the Infinite.” In Essays on Classification, edited by Chidi Okafor and Anna Lindqvist, 45–67. Oxford: Delta Academic.
+article-one-author Green, Samuel. 2020. “Metadata Drift in Institutional Repositories.” Journal of Library Systems 27 (2): 97–111. https://doi.org/10.1234/jls.2020.0027.
+article-three-authors Hughes, Rebecca, Omar Iqbal, and Lars Jensen. 2022. “Citation Styles as Data.” Scholarly Communication Review 12 (4): 301–322. https://doi.org/10.5555/scr.12.4.301.
+article-eight-authors Kim, Ji-woo, Ana Lopez, Paul Moreau, Petra Novak, Kwame Osei, Min Park, Aoife Quinn, and Marco Rossi. 2023. “A Shared Corpus of Reference Metadata.” Data in Brief 41: 107–118.
+article-twenty-two-authors Abbott, A., B. Baker, C. Clark, D. Davis, E. Evans, F. Foster, G. Gray, et al. 2023. “Large Collaborations and Author Lists.” Physical Review Letters 130 (5): 051801. https://doi.org/10.1103/example.130.051801.
+article-magazine Tanaka, Emi. 2021. “The Return of the Card Catalogue.” The Atlantic Review, March 15, 2021. https://example.com/magazine/card-catalogue.
+article-newspaper Usman, Bola. 2022. “City Library Opens New Wing.” The Daily Courier, November 2, 2022.
+webpage-organization Open Research Alliance. 2024. “Guide to Persistent Identifiers.” Open Research Alliance. January 10, 2024. https://example.org/guides/pids.
+webpage-no-date “About the Collection.” n.d. Museum of Printed Books. Accessed February 14, 2025. https://example.org/about.
+thesis Varga, Dóra. 2017. “Authority Control in Multilingual Catalogues.” PhD diss., University of Toronto.
+report National Library Council. 2020. State of Open Metadata. NLC-2020-4. Washington, DC: National Library Council.
+paper-conference Weber, Jonas, and Li Xu. 2019. “Fast Deduplication of Bibliographic Records.” In Proceedings of the Conference on Digital Libraries, 210–219. New York: ACM. https://doi.org/10.1145/0000000.0000001.
+preprint Young, Grace, and Wei Zhao. 2024. “Learning Citation Formats from Examples.” Preprint, arXiv. https://doi.org/10.48550/arXiv.2401.01234.
+book-no-author-no-date A Handbook of Bookbinding. n.d. Boston: Guild Press.
+legal-case Smith v Jones. 2019. UKSC 12.
+legislation Copyright, Designs and Patents Act. 1988.
diff --git a/tests/fixtures/csl-styles/chicago-notes-bibliography.txt b/tests/fixtures/csl-styles/chicago-notes-bibliography.txt
new file mode 100644
index 0000000..21ea04a
--- /dev/null
+++ b/tests/fixtures/csl-styles/chicago-notes-bibliography.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez, Marta Inés. The Architecture of Small Libraries. 3rd ed. Chicago: Northfield University Press, 2019.
+book-two-authors Becker, Thomas J., and Yuki Nakamura. Reading Machines: Catalogues, Indexes, and the Order of Knowledge. New York: Harbor House, 2021.
+book-translated Ferreira, João Paulo. The Garden of Forking Paths. Translated by Helen Wright. London: Meridian Books, 2015.
+book-edited Okafor, Chidi, and Anna Lindqvist, eds. Essays on Classification. Oxford: Delta Academic, 2018.
+chapter Dubois, Claire. “Indexing the Infinite.” In Essays on Classification, edited by Chidi Okafor and Anna Lindqvist, 45–67. Oxford: Delta Academic, 2018.
+article-one-author Green, Samuel. “Metadata Drift in Institutional Repositories.” Journal of Library Systems 27, no. 2 (April 2020): 97–111. https://doi.org/10.1234/jls.2020.0027.
+article-three-authors Hughes, Rebecca, Omar Iqbal, and Lars Jensen. “Citation Styles as Data.” Scholarly Communication Review 12, no. 4 (2022): 301–322. https://doi.org/10.5555/scr.12.4.301.
+article-eight-authors Kim, Ji-woo, Ana Lopez, Paul Moreau, Petra Novak, Kwame Osei, Min Park, Aoife Quinn, and Marco Rossi. “A Shared Corpus of Reference Metadata.” Data in Brief 41 (2023): 107–118.
+article-twenty-two-authors Abbott, A., B. Baker, C. Clark, D. Davis, E. Evans, F. Foster, G. Gray, et al. “Large Collaborations and Author Lists.” Physical Review Letters 130, no. 5 (2023): 051801. https://doi.org/10.1103/example.130.051801.
+article-magazine Tanaka, Emi. “The Return of the Card Catalogue.” The Atlantic Review, March 15, 2021. https://example.com/magazine/card-catalogue.
+article-newspaper Usman, Bola. “City Library Opens New Wing.” The Daily Courier, November 2, 2022.
+webpage-organization Open Research Alliance. “Guide to Persistent Identifiers.” Open Research Alliance. January 10, 2024. https://example.org/guides/pids.
+webpage-no-date “About the Collection.” Museum of Printed Books. Accessed February 14, 2025. https://example.org/about.
+thesis Varga, Dóra. “Authority Control in Multilingual Catalogues.” PhD diss., University of Toronto, 2017.
+report National Library Council. State of Open Metadata. NLC-2020-4. Washington, DC: National Library Council, 2020.
+paper-conference Weber, Jonas, and Li Xu. “Fast Deduplication of Bibliographic Records.” In Proceedings of the Conference on Digital Libraries, 210–219. New York: ACM, 2019. https://doi.org/10.1145/0000000.0000001.
+preprint Young, Grace, and Wei Zhao. “Learning Citation Formats from Examples.” Preprint, arXiv, 2024. https://doi.org/10.48550/arXiv.2401.01234.
+book-no-author-no-date A Handbook of Bookbinding. Boston: Guild Press, n.d.
+legal-case Smith v Jones. UKSC 12 (2019).
+legislation Copyright, Designs and Patents Act. 1988.
diff --git a/tests/fixtures/csl-styles/harvard.txt b/tests/fixtures/csl-styles/harvard.txt
new file mode 100644
index 0000000..9c64143
--- /dev/null
+++ b/tests/fixtures/csl-styles/harvard.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez, M.I. (2019) The Architecture of Small Libraries. 3rd edn. Chicago: Northfield University Press.
+book-two-authors Becker, T.J. and Nakamura, Y. (2021) Reading Machines: Catalogues, Indexes, and the Order of Knowledge. New York: Harbor House.
+book-translated Ferreira, J.P. (2015) The Garden of Forking Paths. Translated by H. Wright. London: Meridian Books.
+book-edited Okafor, C. and Lindqvist, A. (eds) (2018) Essays on Classification. Oxford: Delta Academic.
+chapter Dubois, C. (2018) ‘Indexing the Infinite’, in Okafor, C. and Lindqvist, A. (eds) Essays on Classification. Oxford: Delta Academic, pp. 45–67.
+article-one-author Green, S. (2020) ‘Metadata Drift in Institutional Repositories’, Journal of Library Systems, 27(2), pp. 97–111. Available at: https://doi.org/10.1234/jls.2020.0027.
+article-three-authors Hughes, R., Iqbal, O. and Jensen, L. (2022) ‘Citation Styles as Data’, Scholarly Communication Review, 12(4), pp. 301–322. Available at: https://doi.org/10.5555/scr.12.4.301.
+article-eight-authors Kim, J.-W. et al. (2023) ‘A Shared Corpus of Reference Metadata’, Data in Brief, 41, pp. 107–118.
+article-twenty-two-authors Abbott, A. et al. (2023) ‘Large Collaborations and Author Lists’, Physical Review Letters, 130(5), p. 051801. Available at: https://doi.org/10.1103/example.130.051801.
+article-magazine Tanaka, E. (2021) ‘The Return of the Card Catalogue’, The Atlantic Review, 15 March. Available at: https://example.com/magazine/card-catalogue.
+article-newspaper Usman, B. (2022) ‘City Library Opens New Wing’, The Daily Courier, 2 November.
+webpage-organization Open Research Alliance (2024) Guide to Persistent Identifiers. Available at: https://example.org/guides/pids (Accessed: 3 June 2025).
+webpage-no-date About the Collection (no date) Available at: https://example.org/about (Accessed: 14 February 2025).
+thesis Varga, D. (2017) Authority Control in Multilingual Catalogues. PhD diss. University of Toronto.
+report National Library Council (2020) State of Open Metadata. NLC-2020-4. Washington, DC: National Library Council.
+paper-conference Weber, J. and Xu, L. (2019) ‘Fast Deduplication of Bibliographic Records’, in Proceedings of the Conference on Digital Libraries. New York: ACM, pp. 210–219. Available at: https://doi.org/10.1145/0000000.0000001.
+preprint Young, G. and Zhao, W. (2024) ‘Learning Citation Formats from Examples’. arXiv [Preprint]. Available at: https://doi.org/10.48550/arXiv.2401.01234.
+book-no-author-no-date A Handbook of Bookbinding (no date) Boston: Guild Press.
+legal-case Smith v Jones (2019) UKSC 12.
+legislation Copyright, Designs and Patents Act (1988).
diff --git a/tests/fixtures/csl-styles/ieee.txt b/tests/fixtures/csl-styles/ieee.txt
new file mode 100644
index 0000000..0ec6c1a
--- /dev/null
+++ b/tests/fixtures/csl-styles/ieee.txt
@@ -0,0 +1,20 @@
+book-one-author M. I. Alvarez, The Architecture of Small Libraries, 3rd ed. Chicago: Northfield University Press, 2019.
+book-two-authors T. J. Becker and Y. Nakamura, Reading Machines: Catalogues, Indexes, and the Order of Knowledge. New York: Harbor House, 2021.
+book-translated J. P. Ferreira, The Garden of Forking Paths, H. Wright, Trans. London: Meridian Books, 2015.
+book-edited C. Okafor and A. Lindqvist, Eds., Essays on Classification. Oxford: Delta Academic, 2018.
+chapter C. Dubois, “Indexing the Infinite,” in Essays on Classification, C. Okafor and A. Lindqvist, Eds. Oxford: Delta Academic, 2018, pp. 45–67.
+article-one-author S. Green, “Metadata Drift in Institutional Repositories,” Journal of Library Systems, vol. 27, no. 2, pp. 97–111, Apr. 2020, doi: 10.1234/jls.2020.0027.
+article-three-authors R. Hughes, O. Iqbal, and L. Jensen, “Citation Styles as Data,” Scholarly Communication Review, vol. 12, no. 4, pp. 301–322, 2022, doi: 10.5555/scr.12.4.301.
+article-eight-authors J.-W. Kim et al., “A Shared Corpus of Reference Metadata,” Data in Brief, vol. 41, pp. 107–118, 2023.
+article-twenty-two-authors A. Abbott et al., “Large Collaborations and Author Lists,” Physical Review Letters, vol. 130, no. 5, p. 051801, 2023, doi: 10.1103/example.130.051801.
+article-magazine E. Tanaka, “The Return of the Card Catalogue,” The Atlantic Review, Mar. 15, 2021. [Online]. Available: https://example.com/magazine/card-catalogue
+article-newspaper B. Usman, “City Library Opens New Wing,” The Daily Courier, Nov. 2, 2022.
+webpage-organization Open Research Alliance. “Guide to Persistent Identifiers.” Open Research Alliance. Accessed: June 3, 2025. [Online]. Available: https://example.org/guides/pids
+webpage-no-date “About the Collection.” Museum of Printed Books. Accessed: Feb. 14, 2025. [Online]. Available: https://example.org/about
+thesis D. Varga, “Authority Control in Multilingual Catalogues,” PhD diss., University of Toronto, Toronto, 2017.
+report National Library Council, “State of Open Metadata,” National Library Council, Washington, DC, Rep. NLC-2020-4, 2020.
+paper-conference J. Weber and L. Xu, “Fast Deduplication of Bibliographic Records,” in Proceedings of the Conference on Digital Libraries, New York: ACM, 2019, pp. 210–219, doi: 10.1145/0000000.0000001.
+preprint G. Young and W. Zhao, “Learning Citation Formats from Examples,” arXiv:2401.01234, 2024, doi: 10.48550/arXiv.2401.01234.
+book-no-author-no-date A Handbook of Bookbinding. Boston: Guild Press, n.d.
+legal-case Smith v Jones, UKSC 12, 2019.
+legislation Copyright, Designs and Patents Act, 1988.
diff --git a/tests/fixtures/csl-styles/items.json b/tests/fixtures/csl-styles/items.json
new file mode 100644
index 0000000..60fb837
--- /dev/null
+++ b/tests/fixtures/csl-styles/items.json
@@ -0,0 +1,248 @@
+[
+ {
+ "id": "book-one-author",
+ "type": "book",
+ "title": "The Architecture of Small Libraries",
+ "author": [{ "family": "Alvarez", "given": "Marta Inés" }],
+ "edition": "3",
+ "publisher": "Northfield University Press",
+ "publisher-place": "Chicago",
+ "issued": { "date-parts": [[2019]] }
+ },
+ {
+ "id": "book-two-authors",
+ "type": "book",
+ "title": "Reading Machines: Catalogues, Indexes, and the Order of Knowledge",
+ "author": [
+ { "family": "Becker", "given": "Thomas J." },
+ { "family": "Nakamura", "given": "Yuki" }
+ ],
+ "publisher": "Harbor House",
+ "publisher-place": "New York",
+ "issued": { "date-parts": [[2021]] }
+ },
+ {
+ "id": "book-translated",
+ "type": "book",
+ "title": "The Garden of Forking Paths",
+ "author": [{ "family": "Ferreira", "given": "João Paulo" }],
+ "translator": [{ "family": "Wright", "given": "Helen" }],
+ "publisher": "Meridian Books",
+ "publisher-place": "London",
+ "issued": { "date-parts": [[2015]] }
+ },
+ {
+ "id": "book-edited",
+ "type": "book",
+ "title": "Essays on Classification",
+ "editor": [
+ { "family": "Okafor", "given": "Chidi" },
+ { "family": "Lindqvist", "given": "Anna" }
+ ],
+ "publisher": "Delta Academic",
+ "publisher-place": "Oxford",
+ "issued": { "date-parts": [[2018]] }
+ },
+ {
+ "id": "chapter",
+ "type": "chapter",
+ "title": "Indexing the Infinite",
+ "author": [{ "family": "Dubois", "given": "Claire" }],
+ "container-title": "Essays on Classification",
+ "editor": [
+ { "family": "Okafor", "given": "Chidi" },
+ { "family": "Lindqvist", "given": "Anna" }
+ ],
+ "page": "45-67",
+ "publisher": "Delta Academic",
+ "publisher-place": "Oxford",
+ "issued": { "date-parts": [[2018]] }
+ },
+ {
+ "id": "article-one-author",
+ "type": "article-journal",
+ "title": "Metadata Drift in Institutional Repositories",
+ "author": [{ "family": "Green", "given": "Samuel" }],
+ "container-title": "Journal of Library Systems",
+ "volume": "27",
+ "issue": "2",
+ "page": "97-111",
+ "DOI": "10.1234/jls.2020.0027",
+ "issued": { "date-parts": [[2020, 4]] }
+ },
+ {
+ "id": "article-three-authors",
+ "type": "article-journal",
+ "title": "Citation Styles as Data",
+ "author": [
+ { "family": "Hughes", "given": "Rebecca" },
+ { "family": "Iqbal", "given": "Omar" },
+ { "family": "Jensen", "given": "Lars" }
+ ],
+ "container-title": "Scholarly Communication Review",
+ "volume": "12",
+ "issue": "4",
+ "page": "301-322",
+ "DOI": "10.5555/scr.12.4.301",
+ "issued": { "date-parts": [[2022]] }
+ },
+ {
+ "id": "article-eight-authors",
+ "type": "article-journal",
+ "title": "A Shared Corpus of Reference Metadata",
+ "author": [
+ { "family": "Kim", "given": "Ji-woo" },
+ { "family": "Lopez", "given": "Ana" },
+ { "family": "Moreau", "given": "Paul" },
+ { "family": "Novak", "given": "Petra" },
+ { "family": "Osei", "given": "Kwame" },
+ { "family": "Park", "given": "Min" },
+ { "family": "Quinn", "given": "Aoife" },
+ { "family": "Rossi", "given": "Marco" }
+ ],
+ "container-title": "Data in Brief",
+ "volume": "41",
+ "page": "107-118",
+ "issued": { "date-parts": [[2023]] }
+ },
+ {
+ "id": "article-twenty-two-authors",
+ "type": "article-journal",
+ "title": "Large Collaborations and Author Lists",
+ "author": [
+ { "family": "Abbott", "given": "A." },
+ { "family": "Baker", "given": "B." },
+ { "family": "Clark", "given": "C." },
+ { "family": "Davis", "given": "D." },
+ { "family": "Evans", "given": "E." },
+ { "family": "Foster", "given": "F." },
+ { "family": "Gray", "given": "G." },
+ { "family": "Hall", "given": "H." },
+ { "family": "Irwin", "given": "I." },
+ { "family": "Jones", "given": "J." },
+ { "family": "King", "given": "K." },
+ { "family": "Lewis", "given": "L." },
+ { "family": "Moore", "given": "M." },
+ { "family": "Nash", "given": "N." },
+ { "family": "Owen", "given": "O." },
+ { "family": "Price", "given": "P." },
+ { "family": "Quill", "given": "Q." },
+ { "family": "Reed", "given": "R." },
+ { "family": "Stone", "given": "S." },
+ { "family": "Turner", "given": "T." },
+ { "family": "Upton", "given": "U." },
+ { "family": "Vance", "given": "V." }
+ ],
+ "container-title": "Physical Review Letters",
+ "volume": "130",
+ "issue": "5",
+ "page": "051801",
+ "DOI": "10.1103/example.130.051801",
+ "issued": { "date-parts": [[2023]] }
+ },
+ {
+ "id": "article-magazine",
+ "type": "article-magazine",
+ "title": "The Return of the Card Catalogue",
+ "author": [{ "family": "Tanaka", "given": "Emi" }],
+ "container-title": "The Atlantic Review",
+ "issued": { "date-parts": [[2021, 3, 15]] },
+ "URL": "https://example.com/magazine/card-catalogue"
+ },
+ {
+ "id": "article-newspaper",
+ "type": "article-newspaper",
+ "title": "City Library Opens New Wing",
+ "author": [{ "family": "Usman", "given": "Bola" }],
+ "container-title": "The Daily Courier",
+ "issued": { "date-parts": [[2022, 11, 2]] }
+ },
+ {
+ "id": "webpage-organization",
+ "type": "webpage",
+ "title": "Guide to Persistent Identifiers",
+ "author": [{ "literal": "Open Research Alliance" }],
+ "container-title": "Open Research Alliance",
+ "issued": { "date-parts": [[2024, 1, 10]] },
+ "accessed": { "date-parts": [[2025, 6, 3]] },
+ "URL": "https://example.org/guides/pids"
+ },
+ {
+ "id": "webpage-no-date",
+ "type": "webpage",
+ "title": "About the Collection",
+ "container-title": "Museum of Printed Books",
+ "accessed": { "date-parts": [[2025, 2, 14]] },
+ "URL": "https://example.org/about"
+ },
+ {
+ "id": "thesis",
+ "type": "thesis",
+ "title": "Authority Control in Multilingual Catalogues",
+ "author": [{ "family": "Varga", "given": "Dóra" }],
+ "genre": "PhD diss.",
+ "publisher": "University of Toronto",
+ "publisher-place": "Toronto",
+ "issued": { "date-parts": [[2017]] }
+ },
+ {
+ "id": "report",
+ "type": "report",
+ "title": "State of Open Metadata",
+ "author": [{ "literal": "National Library Council" }],
+ "number": "NLC-2020-4",
+ "publisher": "National Library Council",
+ "publisher-place": "Washington, DC",
+ "issued": { "date-parts": [[2020]] }
+ },
+ {
+ "id": "paper-conference",
+ "type": "paper-conference",
+ "title": "Fast Deduplication of Bibliographic Records",
+ "author": [
+ { "family": "Weber", "given": "Jonas" },
+ { "family": "Xu", "given": "Li" }
+ ],
+ "container-title": "Proceedings of the Conference on Digital Libraries",
+ "page": "210-219",
+ "publisher": "ACM",
+ "publisher-place": "New York",
+ "DOI": "10.1145/0000000.0000001",
+ "issued": { "date-parts": [[2019]] }
+ },
+ {
+ "id": "preprint",
+ "type": "article",
+ "title": "Learning Citation Formats from Examples",
+ "author": [
+ { "family": "Young", "given": "Grace" },
+ { "family": "Zhao", "given": "Wei" }
+ ],
+ "publisher": "arXiv",
+ "number": "2401.01234",
+ "DOI": "10.48550/arXiv.2401.01234",
+ "issued": { "date-parts": [[2024]] }
+ },
+ {
+ "id": "book-no-author-no-date",
+ "type": "book",
+ "title": "A Handbook of Bookbinding",
+ "publisher": "Guild Press",
+ "publisher-place": "Boston"
+ },
+ {
+ "id": "legal-case",
+ "type": "legal_case",
+ "title": "Smith v Jones",
+ "container-title": "UKSC",
+ "number": "12",
+ "issued": { "date-parts": [[2019]] },
+ "authority": "Supreme Court"
+ },
+ {
+ "id": "legislation",
+ "type": "legislation",
+ "title": "Copyright, Designs and Patents Act",
+ "issued": { "date-parts": [[1988]] }
+ }
+]
diff --git a/tests/fixtures/csl-styles/mla-9.txt b/tests/fixtures/csl-styles/mla-9.txt
new file mode 100644
index 0000000..4d4a7ad
--- /dev/null
+++ b/tests/fixtures/csl-styles/mla-9.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez, Marta Inés. The Architecture of Small Libraries. 3rd ed., Northfield University Press, 2019.
+book-two-authors Becker, Thomas J., and Yuki Nakamura. Reading Machines: Catalogues, Indexes, and the Order of Knowledge. Harbor House, 2021.
+book-translated Ferreira, João Paulo. The Garden of Forking Paths. Translated by Helen Wright, Meridian Books, 2015.
+book-edited Okafor, Chidi, and Anna Lindqvist, editors. Essays on Classification. Delta Academic, 2018.
+chapter Dubois, Claire. “Indexing the Infinite.” Essays on Classification, edited by Chidi Okafor and Anna Lindqvist, Delta Academic, 2018, pp. 45–67.
+article-one-author Green, Samuel. “Metadata Drift in Institutional Repositories.” Journal of Library Systems, vol. 27, no. 2, Apr. 2020, pp. 97–111, https://doi.org/10.1234/jls.2020.0027.
+article-three-authors Hughes, Rebecca, et al. “Citation Styles as Data.” Scholarly Communication Review, vol. 12, no. 4, 2022, pp. 301–322, https://doi.org/10.5555/scr.12.4.301.
+article-eight-authors Kim, Ji-woo, et al. “A Shared Corpus of Reference Metadata.” Data in Brief, vol. 41, 2023, pp. 107–118.
+article-twenty-two-authors Abbott, A., et al. “Large Collaborations and Author Lists.” Physical Review Letters, vol. 130, no. 5, 2023, p. 051801, https://doi.org/10.1103/example.130.051801.
+article-magazine Tanaka, Emi. “The Return of the Card Catalogue.” The Atlantic Review, 15 Mar. 2021, https://example.com/magazine/card-catalogue.
+article-newspaper Usman, Bola. “City Library Opens New Wing.” The Daily Courier, 2 Nov. 2022.
+webpage-organization Open Research Alliance. “Guide to Persistent Identifiers.” Open Research Alliance, 10 Jan. 2024, https://example.org/guides/pids.
+webpage-no-date “About the Collection.” Museum of Printed Books, https://example.org/about. Accessed 14 Feb. 2025.
+thesis Varga, Dóra. Authority Control in Multilingual Catalogues. 2017. University of Toronto, PhD diss.
+report National Library Council. State of Open Metadata. National Library Council, 2020.
+paper-conference Weber, Jonas, and Li Xu. “Fast Deduplication of Bibliographic Records.” Proceedings of the Conference on Digital Libraries, ACM, 2019, pp. 210–219, https://doi.org/10.1145/0000000.0000001.
+preprint Young, Grace, and Wei Zhao. “Learning Citation Formats from Examples.” arXiv, 2024, https://doi.org/10.48550/arXiv.2401.01234.
+book-no-author-no-date A Handbook of Bookbinding. Guild Press.
+legal-case Smith v Jones. UKSC 12, 2019.
+legislation Copyright, Designs and Patents Act. 1988.
diff --git a/tests/fixtures/csl-styles/oscola.txt b/tests/fixtures/csl-styles/oscola.txt
new file mode 100644
index 0000000..083856a
--- /dev/null
+++ b/tests/fixtures/csl-styles/oscola.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez MI, The Architecture of Small Libraries (3rd edn, Northfield University Press 2019)
+book-two-authors Becker TJ and Nakamura Y, Reading Machines: Catalogues, Indexes, and the Order of Knowledge (Harbor House 2021)
+book-translated Ferreira JP, The Garden of Forking Paths (Helen Wright tr, Meridian Books 2015)
+book-edited Okafor C and Lindqvist A (eds), Essays on Classification (Delta Academic 2018)
+chapter Dubois C, ‘Indexing the Infinite’ in Chidi Okafor and Anna Lindqvist (eds), Essays on Classification (Delta Academic 2018)
+article-one-author Green S, ‘Metadata Drift in Institutional Repositories’ (2020) 27 Journal of Library Systems 97
+article-three-authors Hughes R, Iqbal O and Jensen L, ‘Citation Styles as Data’ (2022) 12 Scholarly Communication Review 301
+article-eight-authors Kim J-W and others, ‘A Shared Corpus of Reference Metadata’ (2023) 41 Data in Brief 107
+article-twenty-two-authors Abbott A and others, ‘Large Collaborations and Author Lists’ (2023) 130 Physical Review Letters 051801
+article-magazine Tanaka E, ‘The Return of the Card Catalogue’ The Atlantic Review (15 March 2021) https://example.com/magazine/card-catalogue
+article-newspaper Usman B, ‘City Library Opens New Wing’ The Daily Courier (2 November 2022)
+webpage-organization Open Research Alliance, ‘Guide to Persistent Identifiers’ (Open Research Alliance, 10 January 2024) https://example.org/guides/pids accessed 3 June 2025
+webpage-no-date ‘About the Collection’ (Museum of Printed Books) https://example.org/about accessed 14 February 2025
+thesis Varga D, ‘Authority Control in Multilingual Catalogues’ (PhD diss., University of Toronto 2017)
+report National Library Council, State of Open Metadata (National Library Council 2020)
+paper-conference Weber J and Xu L, ‘Fast Deduplication of Bibliographic Records’ (Proceedings of the Conference on Digital Libraries, ACM 2019) https://doi.org/10.1145/0000000.0000001
+preprint Young G and Zhao W, ‘Learning Citation Formats from Examples’ (arXiv 2024) https://doi.org/10.48550/arXiv.2401.01234
+book-no-author-no-date A Handbook of Bookbinding (Guild Press)
+legal-case Smith v Jones [2019] UKSC 12
+legislation Copyright, Designs and Patents Act 1988
diff --git a/tests/fixtures/csl-styles/vancouver.txt b/tests/fixtures/csl-styles/vancouver.txt
new file mode 100644
index 0000000..aedefee
--- /dev/null
+++ b/tests/fixtures/csl-styles/vancouver.txt
@@ -0,0 +1,20 @@
+book-one-author Alvarez MI. The Architecture of Small Libraries. 3rd ed. Chicago: Northfield University Press; 2019.
+book-two-authors Becker TJ, Nakamura Y. Reading Machines: Catalogues, Indexes, and the Order of Knowledge. New York: Harbor House; 2021.
+book-translated Ferreira JP. The Garden of Forking Paths. Wright H, translator. London: Meridian Books; 2015.
+book-edited Okafor C, Lindqvist A, editors. Essays on Classification. Oxford: Delta Academic; 2018.
+chapter Dubois C. Indexing the Infinite. In: Okafor C, Lindqvist A, editors. Essays on Classification. Oxford: Delta Academic; 2018. p. 45-67.
+article-one-author Green S. Metadata Drift in Institutional Repositories. Journal of Library Systems. 2020 Apr;27(2):97-111. doi:10.1234/jls.2020.0027
+article-three-authors Hughes R, Iqbal O, Jensen L. Citation Styles as Data. Scholarly Communication Review. 2022;12(4):301-22. doi:10.5555/scr.12.4.301
+article-eight-authors Kim J-W, Lopez A, Moreau P, Novak P, Osei K, Park M, et al. A Shared Corpus of Reference Metadata. Data in Brief. 2023;41:107-18.
+article-twenty-two-authors Abbott A, Baker B, Clark C, Davis D, Evans E, Foster F, et al. Large Collaborations and Author Lists. Physical Review Letters. 2023;130(5):051801. doi:10.1103/example.130.051801
+article-magazine Tanaka E. The Return of the Card Catalogue. The Atlantic Review [Internet]. 2021 Mar 15. Available from: https://example.com/magazine/card-catalogue
+article-newspaper Usman B. City Library Opens New Wing. The Daily Courier. 2022 Nov 2.
+webpage-organization Open Research Alliance. Guide to Persistent Identifiers [Internet]. Open Research Alliance; 2024 Jan 10 [cited 2025 Jun 3]. Available from: https://example.org/guides/pids
+webpage-no-date About the Collection [Internet]. Museum of Printed Books [cited 2025 Feb 14]. Available from: https://example.org/about
+thesis Varga D. Authority Control in Multilingual Catalogues [PhD diss.]. Toronto: University of Toronto; 2017.
+report National Library Council. State of Open Metadata. Washington, DC: National Library Council; 2020. Report No.: NLC-2020-4.
+paper-conference Weber J, Xu L. Fast Deduplication of Bibliographic Records. In: Proceedings of the Conference on Digital Libraries. New York: ACM; 2019. p. 210-9. doi:10.1145/0000000.0000001
+preprint Young G, Zhao W. Learning Citation Formats from Examples [Preprint]. arXiv; 2024. doi:10.48550/arXiv.2401.01234
+book-no-author-no-date A Handbook of Bookbinding. Boston: Guild Press; [date unknown].
+legal-case Smith v Jones. UKSC 12. 2019.
+legislation Copyright, Designs and Patents Act. 1988.
diff --git a/tests/phpunit/CslStyleGoldenTest.php b/tests/phpunit/CslStyleGoldenTest.php
new file mode 100644
index 0000000..6aa3f35
--- /dev/null
+++ b/tests/phpunit/CslStyleGoldenTest.php
@@ -0,0 +1,85 @@
+.txt holds the reviewed output, one
+ * `idtext` line per item.
+ *
+ * After an intended style change, rewrite the goldens and review the diff
+ * against the style manual:
+ *
+ * BORGES_WRITE_STYLE_GOLDENS=1 composer test:php -- --filter CslStyleGolden
+ *
+ * @package BibliographyBuilder
+ */
+
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\TestCase;
+
+final class CslStyleGoldenTest extends TestCase {
+
+ private static function fixture_dir() {
+ return dirname( __DIR__ ) . '/fixtures/csl-styles';
+ }
+
+ public static function styleProvider() {
+ $cases = array();
+
+ foreach ( array_keys( bibliography_builder_get_formatter_style_definitions() ) as $style_key ) {
+ $cases[ $style_key ] = array( $style_key );
+ }
+
+ return $cases;
+ }
+
+ protected function setUp(): void {
+ if ( ! class_exists( '\\Seboettg\\CiteProc\\CiteProc' ) || ! class_exists( 'DOMDocument' ) ) {
+ $this->markTestSkipped( 'citeproc-php and DOM are required.' );
+ }
+ }
+
+ #[DataProvider( 'styleProvider' )]
+ public function test_style_renders_the_reviewed_output( $style_key ) {
+ $items = json_decode( file_get_contents( self::fixture_dir() . '/items.json' ), true );
+ $formatted = bibliography_builder_format_csl_items( $items, $style_key );
+
+ $this->assertIsArray( $formatted, $style_key . ' failed to format' );
+
+ $lines = array();
+ foreach ( $items as $index => $item ) {
+ $lines[] = $item['id'] . "\t" . $formatted[ $index ];
+ }
+ $actual = implode( "\n", $lines ) . "\n";
+ $golden = self::fixture_dir() . '/' . $style_key . '.txt';
+
+ if ( getenv( 'BORGES_WRITE_STYLE_GOLDENS' ) ) {
+ file_put_contents( $golden, $actual );
+ }
+
+ $this->assertFileExists( $golden );
+ $this->assertSame( file_get_contents( $golden ), $actual );
+ }
+
+ /**
+ * The formatter reads vendor/citation-style-language/, a Composer copy of
+ * packages/. A stale copy once hid a style regression; fail on any drift.
+ */
+ public function test_installed_styles_and_locales_match_their_source() {
+ $root = dirname( __DIR__, 2 );
+ $dirs = array(
+ 'packages/citation-style-language-styles' => 'vendor/citation-style-language/styles',
+ 'packages/citation-style-language-locales' => 'vendor/citation-style-language/locales',
+ );
+
+ foreach ( $dirs as $source => $installed ) {
+ foreach ( glob( $root . '/' . $source . '/*.{csl,xml,json}', GLOB_BRACE ) as $file ) {
+ $copy = $root . '/' . $installed . '/' . basename( $file );
+ $this->assertFileExists( $copy, 'run composer install: ' . $copy . ' is missing' );
+ $this->assertFileEquals( $file, $copy, 'run composer install: ' . basename( $file ) . ' is stale in ' . $installed );
+ }
+ }
+ }
+}
diff --git a/tests/phpunit/FormatterAdaptationTest.php b/tests/phpunit/FormatterAdaptationTest.php
new file mode 100644
index 0000000..c4866de
--- /dev/null
+++ b/tests/phpunit/FormatterAdaptationTest.php
@@ -0,0 +1,137 @@
+ array(
+ array( 'literal' => ' Open Research Alliance ' ),
+ array(
+ 'family' => 'Green',
+ 'given' => 'Samuel',
+ ),
+ ),
+ 'editor' => array( array( 'literal' => 'Board' ) ),
+ )
+ );
+
+ $this->assertSame( array( 'family' => 'Open Research Alliance' ), $item['author'][0] );
+ $this->assertSame(
+ array(
+ 'family' => 'Green',
+ 'given' => 'Samuel',
+ ),
+ $item['author'][1]
+ );
+ $this->assertSame( array( 'family' => 'Board' ), $item['editor'][0] );
+ }
+
+ public function test_blank_literal_names_are_left_alone() {
+ $item = bibliography_builder_prepare_csl_for_formatter(
+ array( 'author' => array( array( 'literal' => ' ' ) ) )
+ );
+
+ $this->assertSame( array( array( 'literal' => ' ' ) ), $item['author'] );
+ }
+
+ public function test_page_first_is_derived_from_the_page_range() {
+ $this->assertSame( '97', bibliography_builder_prepare_csl_for_formatter( array( 'page' => '97-111' ) )['page-first'] );
+ $this->assertSame( '301', bibliography_builder_prepare_csl_for_formatter( array( 'page' => "301\u{2013}322" ) )['page-first'] );
+ $this->assertSame( 'e1234', bibliography_builder_prepare_csl_for_formatter( array( 'page' => 'e1234' ) )['page-first'] );
+ $this->assertSame(
+ '5',
+ bibliography_builder_prepare_csl_for_formatter(
+ array(
+ 'page' => '97-111',
+ 'page-first' => '5',
+ )
+ )['page-first']
+ );
+ $this->assertArrayNotHasKey( 'page-first', bibliography_builder_prepare_csl_for_formatter( array( 'title' => 'x' ) ) );
+ }
+
+ public function test_space_before_a_label_comma_is_removed() {
+ $style = array( 'family' => 'notes' );
+
+ $this->assertSame(
+ 'Okafor, Chidi, and Anna Lindqvist, eds.',
+ bibliography_builder_normalize_formatted_text( 'Okafor, Chidi, and Anna Lindqvist , eds.', $style )
+ );
+ }
+
+ public function test_hyphenated_given_names_are_fully_initialized() {
+ $style = array( 'family' => 'author-date' );
+
+ $this->assertSame( 'Kim, J.-W., Lopez, A.', bibliography_builder_normalize_formatted_text( 'Kim, J.- woo, Lopez, A.', $style ) );
+ $this->assertSame( 'Kim J-W, Lopez A', bibliography_builder_normalize_formatted_text( 'Kim J- woo, Lopez A', $style ) );
+ $this->assertSame( 'Jean-Paul Sartre', bibliography_builder_normalize_formatted_text( 'Jean-Paul Sartre', $style ) );
+ }
+
+ public function test_american_styles_move_commas_and_periods_inside_quotes() {
+ $us = array(
+ 'family' => 'numeric',
+ 'locale' => 'en-US',
+ );
+ $gb = array(
+ 'family' => 'notes',
+ 'locale' => 'en-GB',
+ );
+
+ $this->assertSame( "S. Green, \u{201C}Title,\u{201D} Journal.", bibliography_builder_normalize_formatted_text( "S. Green, \u{201C}Title\u{201D}, Journal.", $us ) );
+ $this->assertSame( "\u{2018}Title\u{2019}, Journal", bibliography_builder_normalize_formatted_text( "\u{2018}Title\u{2019}, Journal", $gb ) );
+ }
+
+ public function test_each_entry_is_rendered_on_its_own() {
+ if ( ! class_exists( '\\Seboettg\\CiteProc\\CiteProc' ) || ! class_exists( 'DOMDocument' ) ) {
+ $this->markTestSkipped( 'citeproc-php and DOM are required.' );
+ }
+
+ $many = array();
+ $names = array( 'Ann', 'Bea', 'Cal', 'Dee', 'Eve', 'Fay', 'Gus', 'Hal', 'Ida', 'Jay', 'Kit', 'Lee' );
+ foreach ( $names as $given ) {
+ $many[] = array(
+ 'family' => 'Author',
+ 'given' => $given,
+ );
+ }
+
+ $formatted = bibliography_builder_format_csl_items(
+ array(
+ array(
+ 'type' => 'book',
+ 'title' => 'First',
+ 'author' => $many,
+ ),
+ array(
+ 'type' => 'book',
+ 'title' => 'Second',
+ 'author' => array(
+ array(
+ 'family' => 'Weber',
+ 'given' => 'Jonas',
+ ),
+ array(
+ 'family' => 'Xu',
+ 'given' => 'Li',
+ ),
+ ),
+ ),
+ ),
+ 'chicago-notes-bibliography'
+ );
+
+ // An "et al." entry must not strip the "and" from the entries after it.
+ $this->assertStringContainsString( 'et al.', $formatted[0] );
+ $this->assertStringStartsWith( 'Weber, Jonas, and Li Xu.', $formatted[1] );
+ }
+}