postext-citeproc 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Postext contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # postext-citeproc
2
+
3
+ Citation formatting for [Postext](https://postext.dev): the citations a Postext document writes in Pandoc's syntax (`[@garcia2020, p. 33]`, `@garcia2020`) are formatted in a CSL style — APA, Chicago, MLA, IEEE, Vancouver, ISO 690, GB/T 7714, OSCOLA… — and the bibliography is built from the document's references.
4
+
5
+ ```ts
6
+ import 'postext-citeproc/register';
7
+ import { buildDocument } from 'postext';
8
+
9
+ const doc = buildDocument({ markdown }, { citations: { style: 'ieee' } });
10
+ ```
11
+
12
+ `postext-citeproc/register` registers the engine with every bundled style and locale. To load it only when a document cites, hand Postext a loader instead (its layout worker calls it before such a build):
13
+
14
+ ```ts
15
+ import { setCitationEngineLoader } from 'postext';
16
+ setCitationEngineLoader(() => import('postext-citeproc/register'));
17
+ ```
18
+
19
+ ## What is bundled
20
+
21
+ - **Styles** (`citations.style`): `apa`, `chicago-author-date`, `harvard-cite-them-right`, `iso690-author-date-en`, `iso690-author-date-es`, `china-national-standard-gb-t-7714-2015-author-date`, `modern-language-association`, `ieee`, `elsevier-vancouver`, `american-medical-association`, `nature`, `iso690-numeric-en`, `china-national-standard-gb-t-7714-2015-numeric`, `chicago-notes-bibliography`, `oscola`, `china-national-standard-gb-t-7714-2015-note`. Any other CSL style can be passed whole (`citations.style: 'custom'`, `citations.customStyle: '<style …>'`).
22
+ - **Locales**: en-US, en-GB, es-ES, fr-FR, de-DE, it-IT, pt-PT, pt-BR, ca-AD, nl-NL, zh-CN, zh-TW.
23
+ - `postext-citeproc/catalog`: the style list alone (names, citation system, fields), for a picker that should not load the engine.
24
+
25
+ ## Licences
26
+
27
+ This package is MIT. It depends on [citeproc-js](https://github.com/Juris-M/citeproc-js), © Frank Bennett, used under the Common Public Attribution License 1.0 (it is dual-licensed CPAL 1.0 / AGPL 1.0). The bundled styles and locales are from the [Citation Style Language](https://citationstyles.org/) project, CC BY-SA 3.0. See `THIRD_PARTY_LICENSES.md`.
@@ -0,0 +1,21 @@
1
+ # Third-party licences
2
+
3
+ ## citeproc-js
4
+
5
+ postext-citeproc depends on citeproc-js (npm package `citeproc`), a dependency installed alongside it, not copied into this package.
6
+
7
+ - Copyright © 2009–2024 Frank Bennett and contributors.
8
+ - Licence: Common Public Attribution License 1.0 (CPAL-1.0), at the licensee's choice of CPAL-1.0 or AGPL-1.0. This package uses it under CPAL-1.0.
9
+ - Source: https://github.com/Juris-M/citeproc-js
10
+
11
+ Attribution (CPAL Exhibit B): "Citations are formatted with citeproc-js (Frank Bennett, CPAL 1.0)". Hosts that show citation settings should display this line, as the Postext Sandbox does in its Citations section.
12
+
13
+ ## Citation Style Language styles and locales
14
+
15
+ The files under `csl/` (embedded in `dist/generated/`) are from the Citation Style Language project:
16
+
17
+ - Styles: https://github.com/citation-style-language/styles
18
+ - Locales: https://github.com/citation-style-language/locales
19
+ - Licence: Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0), https://creativecommons.org/licenses/by-sa/3.0/
20
+
21
+ Each style file names its authors and contributors in its `<info>` block. They are distributed unmodified.
@@ -0,0 +1,2 @@
1
+ import '../register';
2
+ //# sourceMappingURL=build.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/build.test.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC"}
@@ -0,0 +1,162 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { buildBundle, buildDocument, renderToHtml } from 'postext';
3
+ import '../register';
4
+ // Deterministic text measurement stub (no DOM in the node test env).
5
+ class StubCtx {
6
+ font = '';
7
+ measureText(s) {
8
+ return { width: s.length * 7 };
9
+ }
10
+ }
11
+ globalThis.OffscreenCanvas = class {
12
+ getContext() {
13
+ return new StubCtx();
14
+ }
15
+ };
16
+ const pt = (value) => ({ value, unit: 'pt' });
17
+ const config = {
18
+ page: { width: pt(400), height: pt(600), margins: { top: pt(20), bottom: pt(20), left: pt(20), right: pt(20) } },
19
+ layout: { layoutType: 'single' },
20
+ };
21
+ const FRONT = `---
22
+ references:
23
+ - id: garcia2020
24
+ type: book
25
+ author: [{family: García, given: Ana}]
26
+ title: Tipografía y lectura
27
+ issued: 2020
28
+ publisher: Trea
29
+ language: es
30
+ - id: lopez2019
31
+ type: article-journal
32
+ author: ["López, Luis", "Ruiz, Eva"]
33
+ title: Leer en pantalla
34
+ container-title: Revista de Letras
35
+ volume: 12
36
+ issue: 3
37
+ page: 45-67
38
+ issued: 2019-05-03
39
+ DOI: 10.1000/xyz
40
+ language: es
41
+ ---
42
+ `;
43
+ /** The text of the document's lines, block by block (bibliography blocks
44
+ * flagged), with links. */
45
+ function lines(doc) {
46
+ return doc.blocks.map((b) => b.lines.map((l) => (l.segments ?? []).map((s) => s.text).join('')).join(' '));
47
+ }
48
+ function hrefs(doc) {
49
+ return [...new Set(doc.blocks.flatMap((b) => b.lines.flatMap((l) => (l.segments ?? []).map((s) => s.href).filter((h) => !!h))))];
50
+ }
51
+ const entries = (doc) => doc.blocks.filter((b) => b.bibEntry).map((b) => b.bibEntry);
52
+ describe('author-date (APA)', () => {
53
+ const doc = buildDocument({ markdown: `${FRONT}# Uno\n\nAs [see @garcia2020, p. 33; @lopez2019] show, @garcia2020 [p. 4] says it.\n` }, config);
54
+ it('formats parenthetical and narrative citations', () => {
55
+ const text = lines(doc).join('\n');
56
+ expect(text).toContain('(see García, 2020, p. 33; López & Ruiz, 2019)');
57
+ expect(text).toContain('García (2020, p. 4) says it.');
58
+ });
59
+ it('appends the bibliography with its title, entries as anchors', () => {
60
+ expect(entries(doc)).toEqual(['garcia2020', 'lopez2019']);
61
+ expect(lines(doc).some((l) => l === 'References')).toBe(true);
62
+ expect(doc.anchors.map((a) => a.id)).toEqual(expect.arrayContaining(['ref-garcia2020', 'ref-lopez2019']));
63
+ });
64
+ it('links each citation to its entry, and the DOI to its URL', () => {
65
+ expect(hrefs(doc)).toEqual(expect.arrayContaining(['#ref-garcia2020', 'https://doi.org/10.1000/xyz']));
66
+ const html = renderToHtml(doc);
67
+ expect(html).toContain('href="#pt-a-ref-garcia2020"');
68
+ expect(html).toContain('id="pt-a-ref-garcia2020"');
69
+ });
70
+ });
71
+ describe('numbered styles', () => {
72
+ const md = `${FRONT}# One\n\nFirst [@lopez2019], then [@garcia2020; @lopez2019, p. 50].\n\n# Works cited\n\n:::bibliography{title=""}\n`;
73
+ it('IEEE as the style writes it, with a label column', () => {
74
+ const doc = buildDocument({ markdown: md }, { ...config, citations: { style: 'ieee' } });
75
+ const text = lines(doc).join('\n');
76
+ expect(text).toContain('First [1], then [1, p. 50], [2].');
77
+ expect(lines(doc).filter((_, i) => doc.blocks[i].bibEntry)[0]).toMatch(/^\[1\] L\. López and E\. Ruiz/);
78
+ expect(lines(doc)).not.toContain('References');
79
+ });
80
+ it('a marker of the configuration’s own: superscript ranges', () => {
81
+ const doc = buildDocument({ markdown: md }, { ...config, citations: { style: 'ieee', marker: 'superscript' } });
82
+ const sups = doc.blocks.flatMap((b) => b.lines.flatMap((l) => (l.segments ?? []).filter((s) => s.script === 'sup').map((s) => s.text)));
83
+ expect(sups.join('')).toBe('11,2');
84
+ });
85
+ it('GB/T 7714 in Chinese: superscript bracket, 等 and type codes', () => {
86
+ const zh = `---\nreferences:\n - {id: zhang, type: book, language: zh-CN, author: [张三, 李四, 王五, 赵六], title: 排版学, issued: 2018, publisher: 商务印书馆, publisher-place: 北京}\n---\n# 一\n\n见[@zhang]。\n`;
87
+ const doc = buildDocument({ markdown: zh }, { ...config, locale: 'zh-Hans', citations: { style: 'china-national-standard-gb-t-7714-2015-numeric' } });
88
+ const sups = doc.blocks.flatMap((b) => b.lines.flatMap((l) => (l.segments ?? []).filter((s) => s.script === 'sup').map((s) => s.text)));
89
+ expect(sups.join('')).toContain('[1]');
90
+ expect(lines(doc).join('\n')).toContain('张三, 李四, 王五, 等. 排版学[M]');
91
+ expect(lines(doc)).toContain('参考文献');
92
+ });
93
+ });
94
+ describe('note styles', () => {
95
+ it('Chicago notes: each citation becomes a footnote', () => {
96
+ const doc = buildDocument({ markdown: `${FRONT}# One\n\nA claim [@garcia2020, p. 33]. Another [@garcia2020, p. 34].\n` }, { ...config, citations: { style: 'chicago-notes-bibliography' } });
97
+ const markers = doc.blocks.flatMap((b) => b.lines.flatMap((l) => (l.segments ?? []).filter((s) => s.footnoteId !== undefined).map((s) => s.text)));
98
+ expect(markers).toEqual(['1', '2']);
99
+ const notes = doc.blocks.filter((b) => b.footnoteNote !== undefined).map((b) => b.lines.map((l) => (l.segments ?? []).map((s) => s.text).join('')).join(' '));
100
+ expect(notes[0]).toContain('García, Tipografía y lectura');
101
+ expect(notes[1]).toContain('34');
102
+ });
103
+ });
104
+ describe('references written in the text', () => {
105
+ it('reads BibTeX from a :::references block, and nocite', () => {
106
+ const md = `---\nnocite: "@knuth81"\n---\n# One\n\nSee [@lamport94].\n\n:::references{format=bibtex}\n@book{lamport94, author={Leslie Lamport}, title={LaTeX: A Document Preparation System}, publisher={Addison-Wesley}, year=1994}\n@article{knuth81, author={Knuth, Donald E. and Plass, Michael F.}, title={Breaking paragraphs into lines}, journal={Software: Practice and Experience}, year=1981, volume=11, pages={1119--1184}}\n:::\n`;
107
+ const doc = buildDocument({ markdown: md }, config);
108
+ expect(lines(doc).join('\n')).toContain('See (Lamport, 1994).');
109
+ expect(entries(doc)).toEqual(['knuth81', 'lamport94']);
110
+ });
111
+ it('prints a citation as written when the book has no reference for it', () => {
112
+ const doc = buildDocument({ markdown: '# One\n\nWrite to @maria or see [@x].\n' }, config);
113
+ expect(lines(doc).join('\n')).toContain('Write to @maria or see [@x].');
114
+ expect(entries(doc)).toEqual([]);
115
+ });
116
+ });
117
+ describe('books', () => {
118
+ it('numbers through the book and lists every work after the last chapter', () => {
119
+ const docs = buildBundle({
120
+ chapters: [
121
+ { markdown: `${FRONT}# One\n\nFirst [@lopez2019].\n` },
122
+ { markdown: `# Two\n\nThen [@garcia2020] and [@lopez2019].\n` },
123
+ ],
124
+ config: { ...config, citations: { style: 'ieee' } },
125
+ resources: [],
126
+ });
127
+ expect(lines(docs[1]).join('\n')).toContain('Then [2] and [1].');
128
+ expect(entries(docs[0])).toEqual([]);
129
+ expect(entries(docs[1])).toEqual(['lopez2019', 'garcia2020']);
130
+ });
131
+ it('per-chapter bibliographies list each chapter’s works', () => {
132
+ const docs = buildBundle({
133
+ chapters: [
134
+ { markdown: `${FRONT}# One\n\nFirst [@lopez2019].\n` },
135
+ { markdown: `# Two\n\nThen [@garcia2020].\n` },
136
+ ],
137
+ config: { ...config, citations: { bibliography: { scope: 'chapter' } } },
138
+ resources: [],
139
+ });
140
+ expect(entries(docs[0])).toEqual(['lopez2019']);
141
+ expect(entries(docs[1])).toEqual(['garcia2020']);
142
+ });
143
+ });
144
+ describe('Chinese in vertical text (#277)', () => {
145
+ const zh = `---\nreferences:\n - {id: zhang, type: book, language: zh-CN, author: [张三, 李四, 王五, 赵六], title: 排版学, issued: 2018, publisher: 商务印书馆, publisher-place: 北京}\n - {id: knuth, type: book, language: en, author: ["Knuth, Donald E."], title: The TeXbook, issued: 1984, publisher: Addison-Wesley}\n---\n# 第一章\n\n竖排的书也引用文献[@zhang, 页 12],西文文献亦然[@knuth]。\n`;
146
+ const vertical = { ...config, locale: 'zh-Hans', layout: { layoutType: 'single', writingMode: 'vertical-rl' } };
147
+ it('a numbered style in corner brackets, upright in the column', () => {
148
+ const doc = buildDocument({ markdown: zh }, { ...vertical, citations: { style: 'china-national-standard-gb-t-7714-2015-numeric', marker: 'corner', bibliography: { groupByLanguage: true } } });
149
+ const text = lines(doc).join('\n');
150
+ expect(text).toContain('〔1〕12');
151
+ expect(text).toContain('〔2〕');
152
+ expect(entries(doc)).toEqual(['zhang', 'knuth']);
153
+ expect(doc.pages[0].flow).toBeDefined();
154
+ });
155
+ it('a note style set as 夹注 inside the line', () => {
156
+ const doc = buildDocument({ markdown: zh }, { ...vertical, citations: { style: 'china-national-standard-gb-t-7714-2015-note', notes: 'warichu' } });
157
+ const warichu = doc.blocks.flatMap((b) => b.lines.flatMap((l) => (l.segments ?? []).filter((s) => s.warichu)));
158
+ expect(warichu.length).toBeGreaterThan(0);
159
+ expect(doc.blocks.some((b) => b.footnoteNote !== undefined)).toBe(false);
160
+ });
161
+ });
162
+ //# sourceMappingURL=build.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.test.js","sourceRoot":"","sources":["../../src/__tests__/build.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAwC,MAAM,SAAS,CAAC;AACzG,OAAO,aAAa,CAAC;AAErB,qEAAqE;AACrE,MAAM,OAAO;IACX,IAAI,GAAG,EAAE,CAAC;IACV,WAAW,CAAC,CAAS;QACnB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACjC,CAAC;CACF;AACA,UAAsD,CAAC,eAAe,GAAG;IACxE,UAAU;QACR,OAAO,IAAI,OAAO,EAAE,CAAC;IACvB,CAAC;CACF,CAAC;AAEF,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAa,EAAE,CAAC,CAAC;AAC/D,MAAM,MAAM,GAAkB;IAC5B,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IAChH,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE;CACjC,CAAC;AAEF,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBb,CAAC;AAEF;4BAC4B;AAC5B,SAAS,KAAK,CAAC,GAAgB;IAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7G,CAAC;AACD,SAAS,KAAK,CAAC,GAAgB;IAC7B,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChJ,CAAC;AACD,MAAM,OAAO,GAAG,CAAC,GAAgB,EAAY,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAS,CAAC,CAAC;AAE7G,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,sFAAsF,EAAE,EAAE,MAAM,CAAC,CAAC;IAEhJ,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,+CAA+C,CAAC,CAAC;QACxE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,OAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC;QACvG,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,EAAE,GAAG,GAAG,KAAK,qHAAqH,CAAC;IAEzI,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACzF,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACzG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;QAChH,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,EAAE,GAAG,qLAAqL,CAAC;QACjM,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,gDAAgD,EAAE,EAAE,CAAC,CAAC;QACtJ,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,wEAAwE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,CAAC,CAAC;QAC7L,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnJ,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9J,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,EAAE,GAAG,oaAAoa,CAAC;QAChb,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,yCAAyC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC3F,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACxE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,IAAI,GAAG,WAAW,CAAC;YACvB,QAAQ,EAAE;gBACR,EAAE,QAAQ,EAAE,GAAG,KAAK,gCAAgC,EAAE;gBACtD,EAAE,QAAQ,EAAE,iDAAiD,EAAE;aAChE;YACD,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACnD,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAClE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,IAAI,GAAG,WAAW,CAAC;YACvB,QAAQ,EAAE;gBACR,EAAE,QAAQ,EAAE,GAAG,KAAK,gCAAgC,EAAE;gBACtD,EAAE,QAAQ,EAAE,gCAAgC,EAAE;aAC/C;YACD,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE;YACxE,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,MAAM,EAAE,GAAG,0VAA0V,CAAC;IACtW,MAAM,QAAQ,GAAkB,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,CAAC;IAE/H,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,gDAAgD,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAChM,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,6CAA6C,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QACpJ,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC/G,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=engine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/engine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { createCiteprocEngine, LOCALES, parseBibtex, pickLocale, STYLES, STYLE_CATALOG } from '../index';
3
+ const engine = createCiteprocEngine({ styles: STYLES, locales: LOCALES });
4
+ const items = [
5
+ { id: 'garcia2020', type: 'book', author: [{ family: 'García', given: 'Ana' }], title: 'Tipografía y lectura', issued: { 'date-parts': [[2020]] }, publisher: 'Trea', 'publisher-place': 'Gijón', language: 'es' },
6
+ { id: 'lopez2019', type: 'article-journal', author: [{ family: 'López', given: 'Luis' }, { family: 'Ruiz', given: 'Eva' }], title: 'Leer en pantalla', 'container-title': 'Revista de Letras', volume: '12', issue: '3', page: '45-67', issued: { 'date-parts': [[2019]] }, DOI: '10.1000/xyz', language: 'es' },
7
+ { id: 'zhang2018', type: 'book', language: 'zh-CN', author: [{ family: '张三' }, { family: '李四' }, { family: '王五' }, { family: '赵六' }], title: '排版学', issued: { 'date-parts': [[2018]] }, publisher: '商务印书馆', 'publisher-place': '北京' },
8
+ ];
9
+ describe('the bundled catalog', () => {
10
+ it('ships every style it lists, and the locales', () => {
11
+ expect(engine.styles().map((s) => s.id)).toEqual(STYLE_CATALOG.map((s) => s.id));
12
+ for (const tag of ['en-US', 'es-ES', 'fr-FR', 'de-DE', 'zh-CN', 'zh-TW'])
13
+ expect(LOCALES[tag]).toBeDefined();
14
+ expect(pickLocale(LOCALES, 'es')).toBe('es-ES');
15
+ expect(pickLocale(LOCALES, 'zh-Hant')).toBe('zh-TW');
16
+ expect(pickLocale(LOCALES, 'zz')).toBe('en-US');
17
+ });
18
+ });
19
+ describe('formatting', () => {
20
+ it('APA: parenthetical with a locator, narrative, author suppressed', () => {
21
+ const p = engine.createProcessor({ style: 'apa', locale: 'es-ES', items });
22
+ expect(p.kind).toBe('in-text');
23
+ expect(p.numeric).toBe(false);
24
+ const out = p.cite([
25
+ { mode: 'parenthetical', items: [{ id: 'garcia2020', locator: '33', label: 'page' }, { id: 'lopez2019' }] },
26
+ { mode: 'narrative', items: [{ id: 'garcia2020' }] },
27
+ { mode: 'parenthetical', items: [{ id: 'lopez2019', suppressAuthor: true }] },
28
+ ]);
29
+ expect(out[0]).toBe('(García, 2020, p. 33; López &#38; Ruiz, 2019)');
30
+ expect(out[1]).toBe('García (2020)');
31
+ expect(out[2]).toBe('(2019)');
32
+ const bib = p.bibliography();
33
+ expect(bib.hangingIndent).toBe(true);
34
+ expect(bib.entries.map((e) => e.id)).toEqual(['garcia2020', 'lopez2019']);
35
+ expect(bib.entries[0].html).toContain('<i>Tipografía y lectura</i>');
36
+ expect(bib.entries[1].html).toContain('<a href="https://doi.org/10.1000/xyz">');
37
+ });
38
+ it('IEEE: numbers in citation order, a label column, narrative authors', () => {
39
+ const p = engine.createProcessor({ style: 'ieee', locale: 'en-US', items });
40
+ expect(p.numeric).toBe(true);
41
+ const out = p.cite([
42
+ { mode: 'parenthetical', items: [{ id: 'lopez2019' }] },
43
+ { mode: 'narrative', items: [{ id: 'garcia2020' }] },
44
+ ]);
45
+ expect(out).toEqual(['[1]', 'García [2]']);
46
+ expect([...p.citationNumbers()]).toEqual([['lopez2019', 1], ['garcia2020', 2]]);
47
+ const bib = p.bibliography();
48
+ expect(bib.labelColumn).toBe(true);
49
+ expect(bib.entries.map((e) => e.label)).toEqual(['[1]', '[2]']);
50
+ });
51
+ it('GB/T 7714: superscript numbers, type codes, 等 for a Chinese work', () => {
52
+ const p = engine.createProcessor({ style: 'china-national-standard-gb-t-7714-2015-numeric', locale: 'zh-CN', items });
53
+ const out = p.cite([{ mode: 'parenthetical', items: [{ id: 'zhang2018' }, { id: 'lopez2019' }] }, { mode: 'narrative', items: [{ id: 'zhang2018' }] }]);
54
+ expect(out[0]).toBe('<sup>[1,2]</sup>');
55
+ expect(out[1]).toBe('张三等<sup>[1]</sup>');
56
+ const bib = p.bibliography();
57
+ expect(bib.entries[0].html).toContain('张三, 李四, 王五, 等. 排版学[M]');
58
+ expect(bib.entries[1].html).toContain('[J/OL]');
59
+ });
60
+ it('Chicago notes: a note style, with uncited works in the bibliography', () => {
61
+ const p = engine.createProcessor({ style: 'chicago-notes-bibliography', locale: 'en-US', items });
62
+ expect(p.kind).toBe('note');
63
+ const out = p.cite([
64
+ { mode: 'parenthetical', noteIndex: 1, items: [{ id: 'garcia2020', locator: '33', label: 'page' }] },
65
+ { mode: 'parenthetical', noteIndex: 2, items: [{ id: 'garcia2020', locator: '34', label: 'page' }] },
66
+ ]);
67
+ expect(out[0]).toContain('García, <i>Tipografía y lectura</i>');
68
+ // Chicago 18 repeats a short form where earlier editions wrote ibid.
69
+ expect(out[1]).toBe('García, <i>Tipografía y lectura</i>, 34.');
70
+ const bib = p.bibliography(['garcia2020', 'zhang2018']);
71
+ expect(bib.entries.map((e) => e.id)).toEqual(['garcia2020', 'zhang2018']);
72
+ });
73
+ it('OSCOLA: ibid. for the same work in the next note', () => {
74
+ const p = engine.createProcessor({ style: 'oscola', locale: 'en-GB', items });
75
+ const out = p.cite([
76
+ { mode: 'parenthetical', noteIndex: 1, items: [{ id: 'garcia2020', locator: '33', label: 'page' }] },
77
+ { mode: 'parenthetical', noteIndex: 2, items: [{ id: 'garcia2020', locator: '34', label: 'page' }] },
78
+ ]);
79
+ expect(out[1]).toMatch(/^[Ii]bid 34/);
80
+ });
81
+ it('accepts a whole CSL style and ignores unknown keys', () => {
82
+ const p = engine.createProcessor({ style: STYLES.nature, locale: 'en-US', items });
83
+ expect(p.cite([{ mode: 'parenthetical', items: [{ id: 'nope' }, { id: 'garcia2020' }] }])).toEqual(['<sup>1</sup>']);
84
+ });
85
+ });
86
+ describe('BibTeX', () => {
87
+ it('reads entries, names, accents, dashes and macros', () => {
88
+ const issues = [];
89
+ const out = parseBibtex(String.raw `
90
+ @string{rl = "Revista de Letras"}
91
+ % a comment
92
+ @article{lopez2019, author = {L{\'o}pez, Luis and Ruiz, Eva}, title = {Leer en {P}antalla},
93
+ journal = rl # " (Madrid)", year = 2019, volume = {12}, number = 3, pages = {45--67}, doi = {https://doi.org/10.1000/xyz}}
94
+ @book{zhang2018, author = {张三 and 李四}, title = {排版学}, publisher = {商务印书馆}, address = {北京}, year = {2018}, langid = {chinese}}
95
+ @inproceedings{knuth81, author = {Donald E. Knuth and Ludwig van Beethoven and {World Health Organization}},
96
+ title = "Breaking paragraphs into lines", booktitle = {Software}, year = {1981}, month = nov, url = {https://x.org/a_b}}
97
+ @phdthesis{t, author = {Ruiz, Jr., Eva}, title = {Tesis}, school = {UNED}, date = {2021-05-03}}
98
+ `, issues);
99
+ expect(issues).toEqual([]);
100
+ expect(out[0]).toMatchObject({ id: 'lopez2019', type: 'article-journal', title: 'Leer en Pantalla', 'container-title': 'Revista de Letras (Madrid)', issue: '3', page: '45–67', DOI: '10.1000/xyz', issued: { 'date-parts': [[2019]] } });
101
+ expect(out[0].author).toEqual([{ family: 'López', given: 'Luis' }, { family: 'Ruiz', given: 'Eva' }]);
102
+ expect(out[1]).toMatchObject({ type: 'book', language: 'zh-CN', 'publisher-place': '北京', author: [{ family: '张三' }, { family: '李四' }] });
103
+ expect(out[2].author).toEqual([
104
+ { family: 'Knuth', given: 'Donald E.' },
105
+ { family: 'Beethoven', given: 'Ludwig', 'non-dropping-particle': 'van' },
106
+ { literal: 'World Health Organization' },
107
+ ]);
108
+ expect(out[2]).toMatchObject({ type: 'paper-conference', issued: { 'date-parts': [[1981, 11]] }, URL: 'https://x.org/a_b' });
109
+ expect(out[3]).toMatchObject({ type: 'thesis', publisher: 'UNED', genre: 'PhD thesis', issued: { 'date-parts': [[2021, 5, 3]] } });
110
+ expect(out[3].author).toEqual([{ family: 'Ruiz', given: 'Eva', suffix: 'Jr.' }]);
111
+ });
112
+ });
113
+ //# sourceMappingURL=engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.test.js","sourceRoot":"","sources":["../../src/__tests__/engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { CitationStyleInfo } from 'postext';
2
+ /** The bundled styles, in the order a picker lists them: by citation
3
+ * system, then by name. Ids are the CSL repository's file names. */
4
+ export declare const STYLE_CATALOG: readonly CitationStyleInfo[];
5
+ /** The CSL locales bundled, as a picker lists them. */
6
+ export declare const LOCALE_TAGS: readonly string[];
7
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;qEACqE;AACrE,eAAO,MAAM,aAAa,EAAE,SAAS,iBAAiB,EAiBrD,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAAiH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** The bundled styles, in the order a picker lists them: by citation
2
+ * system, then by name. Ids are the CSL repository's file names. */
3
+ export const STYLE_CATALOG = [
4
+ { id: 'apa', title: 'American Psychological Association 7th edition', short: 'APA 7', format: 'author-date', fields: 'psychology, education, social sciences' },
5
+ { id: 'chicago-author-date', title: 'Chicago Manual of Style 18th edition (author-date)', short: 'Chicago (author-date)', format: 'author-date', fields: 'sciences, social sciences' },
6
+ { id: 'harvard-cite-them-right', title: 'Cite Them Right 12th edition — Harvard', short: 'Harvard', format: 'author-date', fields: 'general, UK universities' },
7
+ { id: 'iso690-author-date-en', title: 'ISO-690 (author-date, English)', short: 'ISO 690 (author-date)', format: 'author-date', fields: 'general, standards' },
8
+ { id: 'iso690-author-date-es', title: 'ISO-690 (autor-fecha, español)', short: 'ISO 690 (autor-fecha)', format: 'author-date', fields: 'general, Spanish universities' },
9
+ { id: 'china-national-standard-gb-t-7714-2015-author-date', title: 'China National Standard GB/T 7714-2015 (author-date)', short: 'GB/T 7714 (著者-出版年)', format: 'author-date', fields: 'Chinese journals and theses' },
10
+ { id: 'modern-language-association', title: 'Modern Language Association 9th edition', short: 'MLA 9', format: 'author', fields: 'literature, languages, humanities' },
11
+ { id: 'ieee', title: 'IEEE', short: 'IEEE', format: 'numeric', fields: 'engineering, computer science' },
12
+ { id: 'elsevier-vancouver', title: 'Vancouver (Elsevier)', short: 'Vancouver', format: 'numeric', fields: 'medicine, health sciences' },
13
+ { id: 'american-medical-association', title: 'American Medical Association 11th edition', short: 'AMA', format: 'numeric', fields: 'medicine' },
14
+ { id: 'nature', title: 'Nature', short: 'Nature', format: 'numeric', fields: 'natural sciences' },
15
+ { id: 'iso690-numeric-en', title: 'ISO-690 (numeric, English)', short: 'ISO 690 (numeric)', format: 'numeric', fields: 'general, standards' },
16
+ { id: 'china-national-standard-gb-t-7714-2015-numeric', title: 'China National Standard GB/T 7714-2015 (numeric)', short: 'GB/T 7714 (顺序编码)', format: 'numeric', fields: 'Chinese journals and theses' },
17
+ { id: 'chicago-notes-bibliography', title: 'Chicago Manual of Style 18th edition (notes and bibliography)', short: 'Chicago (notes)', format: 'note', fields: 'history, humanities' },
18
+ { id: 'oscola', title: 'OSCOLA (Oxford University Standard for Citation of Legal Authorities)', short: 'OSCOLA', format: 'note', fields: 'law' },
19
+ { id: 'china-national-standard-gb-t-7714-2015-note', title: 'China National Standard GB/T 7714-2015 (note)', short: 'GB/T 7714 (注释)', format: 'note', fields: 'Chinese humanities' },
20
+ ];
21
+ /** The CSL locales bundled, as a picker lists them. */
22
+ export const LOCALE_TAGS = ['en-US', 'en-GB', 'es-ES', 'fr-FR', 'de-DE', 'it-IT', 'pt-PT', 'pt-BR', 'ca-AD', 'nl-NL', 'zh-CN', 'zh-TW'];
23
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { CitationEngine } from 'postext';
2
+ /** The XML of the styles and locales an engine can use. */
3
+ export interface CslSources {
4
+ /** Style id → CSL XML. */
5
+ styles: Readonly<Record<string, string>>;
6
+ /** Locale (`en-US`, `zh-CN`…) → CSL locale XML. */
7
+ locales: Readonly<Record<string, string>>;
8
+ }
9
+ /** The locale of `wanted` the sources hold: the tag itself, the first one
10
+ * of its language (`es` → `es-ES`, `zh-Hant` → `zh-TW`), else `en-US`. */
11
+ export declare function pickLocale(locales: Readonly<Record<string, string>>, wanted: string | undefined): string;
12
+ /** A citation engine over citeproc-js and the given CSL sources. */
13
+ export declare function createCiteprocEngine(sources: CslSources): CitationEngine;
14
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,cAAc,EAMf,MAAM,SAAS,CAAC;AAIjB,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACzB,0BAA0B;IAC1B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,mDAAmD;IACnD,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C;AAED;2EAC2E;AAC3E,wBAAgB,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CASxG;AAyBD,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,GAAG,cAAc,CAsFxE"}
package/dist/engine.js ADDED
@@ -0,0 +1,132 @@
1
+ import CSL from 'citeproc';
2
+ import { parseBibtex } from 'postext';
3
+ import { STYLE_CATALOG } from './catalog';
4
+ /** The locale of `wanted` the sources hold: the tag itself, the first one
5
+ * of its language (`es` → `es-ES`, `zh-Hant` → `zh-TW`), else `en-US`. */
6
+ export function pickLocale(locales, wanted) {
7
+ const tag = (wanted ?? 'en-US').replace(/_/g, '-');
8
+ if (locales[tag])
9
+ return tag;
10
+ const lower = tag.toLowerCase();
11
+ if (lower.startsWith('zh'))
12
+ return /hant|tw|hk|mo/.test(lower) ? 'zh-TW' : 'zh-CN';
13
+ if (lower === 'pt-br')
14
+ return 'pt-BR';
15
+ const lang = lower.split('-')[0];
16
+ const hit = Object.keys(locales).find((k) => k.toLowerCase().split('-')[0] === lang);
17
+ return hit ?? 'en-US';
18
+ }
19
+ const CJK = /[\p{sc=Han}\p{sc=Hiragana}\p{sc=Katakana}\p{sc=Hangul}]/u;
20
+ function escapeHtml(s) {
21
+ return s.replace(/&/g, '&#38;').replace(/</g, '&#60;').replace(/>/g, '&#62;');
22
+ }
23
+ /** The authors of a work as a sentence names them, for a numbered style
24
+ * that prints none: "García", "García and Ruiz", "García et al.", "张三等". */
25
+ function narrativeAuthors(item, and, etAl) {
26
+ const names = (item?.author ?? item?.editor ?? []);
27
+ if (names.length === 0)
28
+ return '';
29
+ const nameOf = (n) => n.literal ?? [n['non-dropping-particle'], n.family].filter(Boolean).join(' ');
30
+ const first = nameOf(names[0]);
31
+ const cjk = CJK.test(first);
32
+ if (names.length === 1)
33
+ return first;
34
+ if (names.length === 2)
35
+ return cjk ? `${first}、${nameOf(names[1])}` : `${first} ${and} ${nameOf(names[1])}`;
36
+ return cjk ? `${first}等` : `${first} ${etAl}`;
37
+ }
38
+ function numericStyle(xml) {
39
+ return /citation-format="numeric"/.test(xml) || /<citation[\s\S]*variable="citation-number"[\s\S]*<\/citation>/.test(xml);
40
+ }
41
+ /** A citation engine over citeproc-js and the given CSL sources. */
42
+ export function createCiteprocEngine(sources) {
43
+ return {
44
+ styles: () => STYLE_CATALOG.filter((s) => sources.styles[s.id] !== undefined),
45
+ parseBibtex: (source) => parseBibtex(source),
46
+ createProcessor(options) {
47
+ const xml = options.style.trimStart().startsWith('<') ? options.style : (sources.styles[options.style] ?? sources.styles.apa);
48
+ const items = new Map(options.items.map((i) => [i.id, i]));
49
+ const locale = pickLocale(sources.locales, options.locale);
50
+ const sys = {
51
+ retrieveLocale: (lang) => sources.locales[pickLocale(sources.locales, lang)] ?? sources.locales['en-US'],
52
+ retrieveItem: (id) => items.get(id),
53
+ };
54
+ const engine = new CSL.Engine(sys, xml, locale, true);
55
+ engine.opt.development_extensions.wrap_url_and_doi = true;
56
+ engine.setOutputFormat('html');
57
+ const kind = engine.opt.class === 'note' ? 'note' : 'in-text';
58
+ const numeric = numericStyle(xml);
59
+ const and = engine.getTerm('and') || 'and';
60
+ const etAl = engine.getTerm('et-al') || 'et al.';
61
+ let cited = [];
62
+ return {
63
+ kind,
64
+ numeric,
65
+ cite(clusters) {
66
+ const known = clusters.map((c) => ({ ...c, items: c.items.filter((it) => items.has(it.id)) }));
67
+ const citations = known.map((c, index) => ({
68
+ citationID: `c${index}`,
69
+ citationItems: c.items.map((it) => ({
70
+ id: it.id,
71
+ ...(it.locator ? { locator: it.locator, label: it.label ?? 'page' } : {}),
72
+ ...(it.prefix ? { prefix: escapeHtml(it.prefix) } : {}),
73
+ ...(it.suffix ? { suffix: escapeHtml(it.suffix) } : {}),
74
+ ...(it.suppressAuthor ? { 'suppress-author': true } : {}),
75
+ })),
76
+ properties: {
77
+ noteIndex: c.noteIndex ?? 0,
78
+ // An author-date or author-page style writes "García (2020)"
79
+ // itself; a numbered or a note style does not.
80
+ ...(c.mode === 'narrative' && kind === 'in-text' && !numeric ? { mode: 'composite' } : {}),
81
+ },
82
+ }));
83
+ const withItems = citations.filter((c) => c.citationItems.length > 0);
84
+ const out = withItems.length > 0 ? engine.rebuildProcessorState(withItems, 'html') : [];
85
+ const byId = new Map(out.map(([id, , html]) => [id, html]));
86
+ cited = [...new Set(known.flatMap((c) => c.items.map((it) => it.id)))];
87
+ return known.map((c, index) => {
88
+ const html = byId.get(`c${index}`) ?? '';
89
+ if (c.mode === 'narrative' && kind === 'in-text' && numeric && c.items.length > 0) {
90
+ const who = c.items.map((it) => narrativeAuthors(items.get(it.id), and, etAl)).filter(Boolean).join('; ');
91
+ const glue = /^<sup>/.test(html) || CJK.test(who) ? '' : ' ';
92
+ return who ? `${escapeHtml(who)}${glue}${html}` : html;
93
+ }
94
+ return html.replace(/\[?NO_PRINTED_FORM\]?\s*/g, '');
95
+ });
96
+ },
97
+ bibliography(ids) {
98
+ const uncited = (ids ?? []).filter((id) => items.has(id) && !cited.includes(id));
99
+ if (uncited.length > 0)
100
+ engine.updateUncitedItems(uncited);
101
+ const result = engine.makeBibliography();
102
+ if (!result)
103
+ return { entries: [], hangingIndent: false, labelColumn: false, entrySpacing: 0 };
104
+ const [meta, html] = result;
105
+ const wanted = ids ? new Set(ids) : undefined;
106
+ const entries = [];
107
+ meta.entry_ids.forEach((group, i) => {
108
+ const id = group[0];
109
+ if (wanted && !wanted.has(id))
110
+ return;
111
+ const raw = html[i] ?? '';
112
+ const label = /<div class="csl-left-margin">([\s\S]*?)<\/div>/.exec(raw)?.[1]?.trim();
113
+ const body = /<div class="csl-right-inline">([\s\S]*?)<\/div>\s*<\/div>\s*$/.exec(raw)?.[1]
114
+ ?? /<div class="csl-entry">([\s\S]*?)<\/div>\s*$/.exec(raw)?.[1]
115
+ ?? raw;
116
+ entries.push({ id, html: body.replace(/\s+/g, ' ').trim(), ...(label ? { label } : {}) });
117
+ });
118
+ return {
119
+ entries,
120
+ hangingIndent: Boolean(meta.hangingindent),
121
+ labelColumn: Boolean(meta['second-field-align']),
122
+ entrySpacing: meta.entryspacing ?? 0,
123
+ };
124
+ },
125
+ citationNumbers() {
126
+ return new Map(Object.values(engine.registry.registry).map((r) => [r.id, r.seq]));
127
+ },
128
+ };
129
+ },
130
+ };
131
+ }
132
+ //# sourceMappingURL=engine.js.map