@kedataindo/docflow-plugins 0.0.103 → 0.0.104

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.
@@ -36,6 +36,7 @@ __export(citations_exports, {
36
36
  DEFAULT_CSL_STYLE: () => DEFAULT_CSL_STYLE,
37
37
  buildCitationNodes: () => buildCitationNodes,
38
38
  nextCitationId: () => nextCitationId,
39
+ resolveCslStyles: () => resolveCslStyles,
39
40
  sanitizeCiteprocHtml: () => sanitizeCiteprocHtml
40
41
  });
41
42
  module.exports = __toCommonJS(citations_exports);
@@ -958,6 +959,19 @@ var DEFAULT_CSL_STYLE = "chicago-notes-bibliography";
958
959
  var CSL_LOCALE_EN_US = localesEnUS_default;
959
960
 
960
961
  // src/citeEngine.ts
962
+ function resolveCslStyles(extra) {
963
+ const merged = { ...CSL_STYLES };
964
+ for (const style of extra ?? []) {
965
+ const id = typeof style?.id === "string" ? style.id.trim() : "";
966
+ if (!id || typeof style?.xml !== "string" || style.xml.trim() === "") {
967
+ throw new Error(
968
+ `resolveCslStyles: every style needs a non-empty id and CSL xml (got id=${JSON.stringify(style?.id)}, xml=${style?.xml === void 0 ? "undefined" : `${typeof style.xml === "string" ? style.xml.length : typeof style.xml} chars`})`
969
+ );
970
+ }
971
+ merged[id] = { ...style, id };
972
+ }
973
+ return merged;
974
+ }
961
975
  var clusterSeq = 0;
962
976
  function nextCitationId() {
963
977
  clusterSeq += 1;
@@ -970,21 +984,28 @@ function sanitizeCiteprocHtml(html) {
970
984
  var CiteEngine = class {
971
985
  sources = /* @__PURE__ */ new Map();
972
986
  style;
987
+ /** Bundled styles + whatever the host injected (issue #180). */
988
+ styles;
973
989
  clusters = /* @__PURE__ */ new Map();
974
990
  order = [];
975
991
  rendered = /* @__PURE__ */ new Map();
976
992
  bibliography = [];
977
993
  listeners = /* @__PURE__ */ new Set();
978
994
  constructor(options = {}) {
979
- this.style = options.style && CSL_STYLES[options.style] ? options.style : DEFAULT_CSL_STYLE;
995
+ this.styles = resolveCslStyles(options.styles);
996
+ this.style = options.style && this.styles[options.style] ? options.style : DEFAULT_CSL_STYLE;
980
997
  this.updateSources(options.sources ?? [], false);
981
998
  }
982
999
  getStyle() {
983
1000
  return this.style;
984
1001
  }
1002
+ /** Every style this engine can render with, bundled + host-injected. */
1003
+ getAvailableStyles() {
1004
+ return Object.values(this.styles).sort((a, b) => a.id.localeCompare(b.id));
1005
+ }
985
1006
  /** 'note' styles (Chicago notes-bib) cite via footnotes; 'in-text' cite inline. */
986
1007
  isNoteStyle() {
987
- return CSL_STYLES[this.style]?.category === "note";
1008
+ return this.styles[this.style]?.category === "note";
988
1009
  }
989
1010
  getSource(id) {
990
1011
  return this.sources.get(id);
@@ -1001,7 +1022,7 @@ var CiteEngine = class {
1001
1022
  }
1002
1023
  /** Live style switch: reload the CSL, recompute everything, repaint (6A-7). */
1003
1024
  setStyle(styleId) {
1004
- if (!CSL_STYLES[styleId] || styleId === this.style) return;
1025
+ if (!this.styles[styleId] || styleId === this.style) return;
1005
1026
  this.style = styleId;
1006
1027
  this.recompute();
1007
1028
  this.emitChange();
@@ -1054,7 +1075,7 @@ var CiteEngine = class {
1054
1075
  * any edit — the same derived-view pattern used for pagination/collab.
1055
1076
  */
1056
1077
  recompute() {
1057
- const styleInfo = CSL_STYLES[this.style];
1078
+ const styleInfo = this.styles[this.style];
1058
1079
  const engine = new import_citeproc.default.Engine(
1059
1080
  {
1060
1081
  retrieveLocale: () => CSL_LOCALE_EN_US,
@@ -1134,5 +1155,6 @@ function buildCitationNodes(engine, attrs) {
1134
1155
  DEFAULT_CSL_STYLE,
1135
1156
  buildCitationNodes,
1136
1157
  nextCitationId,
1158
+ resolveCslStyles,
1137
1159
  sanitizeCiteprocHtml
1138
1160
  });
@@ -1,5 +1,18 @@
1
- import { CslItemData } from '@kedataindo/docflow-core';
1
+ import { CslItemData, CslStyleInfo } from '@kedataindo/docflow-core';
2
+ export { CslStyleInfo } from '@kedataindo/docflow-core';
2
3
 
4
+ /**
5
+ * Merge the bundled styles with the ones a host injected (issue #180) — the
6
+ * single place that decides what this engine can render with.
7
+ *
8
+ * Bundled styles stay available unless the host overrides one by id, so a host
9
+ * that passes nothing (or an empty array) behaves exactly as before and nothing
10
+ * has to be fetched at runtime for the defaults to work offline.
11
+ *
12
+ * A malformed entry fails loudly here rather than inside citeproc, where the
13
+ * error would arrive as an empty citation with no clue which style caused it.
14
+ */
15
+ declare function resolveCslStyles(extra?: CslStyleInfo[]): Record<string, CslStyleInfo>;
3
16
  type CitationMode = 'normal' | 'author-only' | 'suppress-author';
4
17
  /**
5
18
  * Structured citation attributes stored on citation/footnote nodes. Nodes
@@ -17,6 +30,14 @@ interface CitationAttrs {
17
30
  interface CiteEngineOptions {
18
31
  sources?: CslItemData[];
19
32
  style?: string;
33
+ /**
34
+ * Extra CSL styles for this engine (issue #180). A style whose `id` matches a
35
+ * bundled one **overrides** it; every other id is added alongside the four
36
+ * defaults. Omitting this keeps the previous behaviour exactly (offline
37
+ * bundled styles), and an unknown `style` id always falls back to
38
+ * `DEFAULT_CSL_STYLE` instead of throwing.
39
+ */
40
+ styles?: CslStyleInfo[];
20
41
  }
21
42
  interface CitationCluster {
22
43
  citationId: string;
@@ -39,6 +60,8 @@ declare function sanitizeCiteprocHtml(html: string): string;
39
60
  declare class CiteEngine {
40
61
  private sources;
41
62
  private style;
63
+ /** Bundled styles + whatever the host injected (issue #180). */
64
+ private styles;
42
65
  private clusters;
43
66
  private order;
44
67
  private rendered;
@@ -46,6 +69,8 @@ declare class CiteEngine {
46
69
  private listeners;
47
70
  constructor(options?: CiteEngineOptions);
48
71
  getStyle(): string;
72
+ /** Every style this engine can render with, bundled + host-injected. */
73
+ getAvailableStyles(): CslStyleInfo[];
49
74
  /** 'note' styles (Chicago notes-bib) cite via footnotes; 'in-text' cite inline. */
50
75
  isNoteStyle(): boolean;
51
76
  getSource(id: string): CslItemData | undefined;
@@ -112,22 +137,17 @@ declare function buildCitationNodes(engine: CiteEngine, attrs: {
112
137
  locator?: string;
113
138
  }): CitationNodeSpec;
114
139
 
115
- interface CslStyleInfo {
116
- id: string;
117
- name: string;
118
- /** 'note' styles render citations as footnotes; 'in-text' render inline. */
119
- category: 'note' | 'in-text';
120
- xml: string;
121
- }
122
140
  /**
123
141
  * CSL styles bundled with the citation engine. Bundling (instead of runtime
124
142
  * fetch) keeps the editor standalone/offline-capable — the same guarantee the
125
- * embedded source snapshot provides (see phase-6 plan §2 decision 5).
143
+ * embedded source snapshot provides (see phase-6 plan §2 decision 5). These are
144
+ * the *default* set: a host can add or override styles through
145
+ * `CitationPort.styles` / `CiteEngineOptions.styles` (see `resolveCslStyles`).
126
146
  */
127
147
  declare const CSL_STYLES: Record<string, CslStyleInfo>;
128
148
  declare const DEFAULT_CSL_STYLE = "chicago-notes-bibliography";
129
149
  /** The single bundled locale. Multi-locale rendering is deferred (phase 6 §7). */
130
150
  declare const CSL_LOCALE_EN_US: string;
131
151
 
132
- export { CSL_LOCALE_EN_US, CSL_STYLES, CiteEngine, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, sanitizeCiteprocHtml };
133
- export type { CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, CslStyleInfo };
152
+ export { CSL_LOCALE_EN_US, CSL_STYLES, CiteEngine, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, resolveCslStyles, sanitizeCiteprocHtml };
153
+ export type { CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions };
@@ -1,5 +1,18 @@
1
- import { CslItemData } from '@kedataindo/docflow-core';
1
+ import { CslItemData, CslStyleInfo } from '@kedataindo/docflow-core';
2
+ export { CslStyleInfo } from '@kedataindo/docflow-core';
2
3
 
4
+ /**
5
+ * Merge the bundled styles with the ones a host injected (issue #180) — the
6
+ * single place that decides what this engine can render with.
7
+ *
8
+ * Bundled styles stay available unless the host overrides one by id, so a host
9
+ * that passes nothing (or an empty array) behaves exactly as before and nothing
10
+ * has to be fetched at runtime for the defaults to work offline.
11
+ *
12
+ * A malformed entry fails loudly here rather than inside citeproc, where the
13
+ * error would arrive as an empty citation with no clue which style caused it.
14
+ */
15
+ declare function resolveCslStyles(extra?: CslStyleInfo[]): Record<string, CslStyleInfo>;
3
16
  type CitationMode = 'normal' | 'author-only' | 'suppress-author';
4
17
  /**
5
18
  * Structured citation attributes stored on citation/footnote nodes. Nodes
@@ -17,6 +30,14 @@ interface CitationAttrs {
17
30
  interface CiteEngineOptions {
18
31
  sources?: CslItemData[];
19
32
  style?: string;
33
+ /**
34
+ * Extra CSL styles for this engine (issue #180). A style whose `id` matches a
35
+ * bundled one **overrides** it; every other id is added alongside the four
36
+ * defaults. Omitting this keeps the previous behaviour exactly (offline
37
+ * bundled styles), and an unknown `style` id always falls back to
38
+ * `DEFAULT_CSL_STYLE` instead of throwing.
39
+ */
40
+ styles?: CslStyleInfo[];
20
41
  }
21
42
  interface CitationCluster {
22
43
  citationId: string;
@@ -39,6 +60,8 @@ declare function sanitizeCiteprocHtml(html: string): string;
39
60
  declare class CiteEngine {
40
61
  private sources;
41
62
  private style;
63
+ /** Bundled styles + whatever the host injected (issue #180). */
64
+ private styles;
42
65
  private clusters;
43
66
  private order;
44
67
  private rendered;
@@ -46,6 +69,8 @@ declare class CiteEngine {
46
69
  private listeners;
47
70
  constructor(options?: CiteEngineOptions);
48
71
  getStyle(): string;
72
+ /** Every style this engine can render with, bundled + host-injected. */
73
+ getAvailableStyles(): CslStyleInfo[];
49
74
  /** 'note' styles (Chicago notes-bib) cite via footnotes; 'in-text' cite inline. */
50
75
  isNoteStyle(): boolean;
51
76
  getSource(id: string): CslItemData | undefined;
@@ -112,22 +137,17 @@ declare function buildCitationNodes(engine: CiteEngine, attrs: {
112
137
  locator?: string;
113
138
  }): CitationNodeSpec;
114
139
 
115
- interface CslStyleInfo {
116
- id: string;
117
- name: string;
118
- /** 'note' styles render citations as footnotes; 'in-text' render inline. */
119
- category: 'note' | 'in-text';
120
- xml: string;
121
- }
122
140
  /**
123
141
  * CSL styles bundled with the citation engine. Bundling (instead of runtime
124
142
  * fetch) keeps the editor standalone/offline-capable — the same guarantee the
125
- * embedded source snapshot provides (see phase-6 plan §2 decision 5).
143
+ * embedded source snapshot provides (see phase-6 plan §2 decision 5). These are
144
+ * the *default* set: a host can add or override styles through
145
+ * `CitationPort.styles` / `CiteEngineOptions.styles` (see `resolveCslStyles`).
126
146
  */
127
147
  declare const CSL_STYLES: Record<string, CslStyleInfo>;
128
148
  declare const DEFAULT_CSL_STYLE = "chicago-notes-bibliography";
129
149
  /** The single bundled locale. Multi-locale rendering is deferred (phase 6 §7). */
130
150
  declare const CSL_LOCALE_EN_US: string;
131
151
 
132
- export { CSL_LOCALE_EN_US, CSL_STYLES, CiteEngine, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, sanitizeCiteprocHtml };
133
- export type { CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, CslStyleInfo };
152
+ export { CSL_LOCALE_EN_US, CSL_STYLES, CiteEngine, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, resolveCslStyles, sanitizeCiteprocHtml };
153
+ export type { CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions };
package/dist/citations.js CHANGED
@@ -916,6 +916,19 @@ var DEFAULT_CSL_STYLE = "chicago-notes-bibliography";
916
916
  var CSL_LOCALE_EN_US = localesEnUS_default;
917
917
 
918
918
  // src/citeEngine.ts
919
+ function resolveCslStyles(extra) {
920
+ const merged = { ...CSL_STYLES };
921
+ for (const style of extra ?? []) {
922
+ const id = typeof style?.id === "string" ? style.id.trim() : "";
923
+ if (!id || typeof style?.xml !== "string" || style.xml.trim() === "") {
924
+ throw new Error(
925
+ `resolveCslStyles: every style needs a non-empty id and CSL xml (got id=${JSON.stringify(style?.id)}, xml=${style?.xml === void 0 ? "undefined" : `${typeof style.xml === "string" ? style.xml.length : typeof style.xml} chars`})`
926
+ );
927
+ }
928
+ merged[id] = { ...style, id };
929
+ }
930
+ return merged;
931
+ }
919
932
  var clusterSeq = 0;
920
933
  function nextCitationId() {
921
934
  clusterSeq += 1;
@@ -928,21 +941,28 @@ function sanitizeCiteprocHtml(html) {
928
941
  var CiteEngine = class {
929
942
  sources = /* @__PURE__ */ new Map();
930
943
  style;
944
+ /** Bundled styles + whatever the host injected (issue #180). */
945
+ styles;
931
946
  clusters = /* @__PURE__ */ new Map();
932
947
  order = [];
933
948
  rendered = /* @__PURE__ */ new Map();
934
949
  bibliography = [];
935
950
  listeners = /* @__PURE__ */ new Set();
936
951
  constructor(options = {}) {
937
- this.style = options.style && CSL_STYLES[options.style] ? options.style : DEFAULT_CSL_STYLE;
952
+ this.styles = resolveCslStyles(options.styles);
953
+ this.style = options.style && this.styles[options.style] ? options.style : DEFAULT_CSL_STYLE;
938
954
  this.updateSources(options.sources ?? [], false);
939
955
  }
940
956
  getStyle() {
941
957
  return this.style;
942
958
  }
959
+ /** Every style this engine can render with, bundled + host-injected. */
960
+ getAvailableStyles() {
961
+ return Object.values(this.styles).sort((a, b) => a.id.localeCompare(b.id));
962
+ }
943
963
  /** 'note' styles (Chicago notes-bib) cite via footnotes; 'in-text' cite inline. */
944
964
  isNoteStyle() {
945
- return CSL_STYLES[this.style]?.category === "note";
965
+ return this.styles[this.style]?.category === "note";
946
966
  }
947
967
  getSource(id) {
948
968
  return this.sources.get(id);
@@ -959,7 +979,7 @@ var CiteEngine = class {
959
979
  }
960
980
  /** Live style switch: reload the CSL, recompute everything, repaint (6A-7). */
961
981
  setStyle(styleId) {
962
- if (!CSL_STYLES[styleId] || styleId === this.style) return;
982
+ if (!this.styles[styleId] || styleId === this.style) return;
963
983
  this.style = styleId;
964
984
  this.recompute();
965
985
  this.emitChange();
@@ -1012,7 +1032,7 @@ var CiteEngine = class {
1012
1032
  * any edit — the same derived-view pattern used for pagination/collab.
1013
1033
  */
1014
1034
  recompute() {
1015
- const styleInfo = CSL_STYLES[this.style];
1035
+ const styleInfo = this.styles[this.style];
1016
1036
  const engine = new CSL.Engine(
1017
1037
  {
1018
1038
  retrieveLocale: () => CSL_LOCALE_EN_US,
@@ -1091,5 +1111,6 @@ export {
1091
1111
  DEFAULT_CSL_STYLE,
1092
1112
  buildCitationNodes,
1093
1113
  nextCitationId,
1114
+ resolveCslStyles,
1094
1115
  sanitizeCiteprocHtml
1095
1116
  };
package/dist/index.cjs CHANGED
@@ -93,6 +93,7 @@ __export(index_exports, {
93
93
  registerSlashCommands: () => registerSlashCommands,
94
94
  rejectAllSuggestions: () => rejectAllSuggestions,
95
95
  rejectSuggestion: () => rejectSuggestion,
96
+ resolveCslStyles: () => resolveCslStyles,
96
97
  sanitizeCiteprocHtml: () => sanitizeCiteprocHtml,
97
98
  scrollEditorToPos: () => scrollEditorToPos,
98
99
  setDocumentMode: () => setDocumentMode,
@@ -1970,6 +1971,19 @@ var DEFAULT_CSL_STYLE = "chicago-notes-bibliography";
1970
1971
  var CSL_LOCALE_EN_US = localesEnUS_default;
1971
1972
 
1972
1973
  // src/citeEngine.ts
1974
+ function resolveCslStyles(extra) {
1975
+ const merged = { ...CSL_STYLES };
1976
+ for (const style of extra ?? []) {
1977
+ const id = typeof style?.id === "string" ? style.id.trim() : "";
1978
+ if (!id || typeof style?.xml !== "string" || style.xml.trim() === "") {
1979
+ throw new Error(
1980
+ `resolveCslStyles: every style needs a non-empty id and CSL xml (got id=${JSON.stringify(style?.id)}, xml=${style?.xml === void 0 ? "undefined" : `${typeof style.xml === "string" ? style.xml.length : typeof style.xml} chars`})`
1981
+ );
1982
+ }
1983
+ merged[id] = { ...style, id };
1984
+ }
1985
+ return merged;
1986
+ }
1973
1987
  var clusterSeq = 0;
1974
1988
  function nextCitationId() {
1975
1989
  clusterSeq += 1;
@@ -1982,21 +1996,28 @@ function sanitizeCiteprocHtml(html) {
1982
1996
  var CiteEngine = class {
1983
1997
  sources = /* @__PURE__ */ new Map();
1984
1998
  style;
1999
+ /** Bundled styles + whatever the host injected (issue #180). */
2000
+ styles;
1985
2001
  clusters = /* @__PURE__ */ new Map();
1986
2002
  order = [];
1987
2003
  rendered = /* @__PURE__ */ new Map();
1988
2004
  bibliography = [];
1989
2005
  listeners = /* @__PURE__ */ new Set();
1990
2006
  constructor(options = {}) {
1991
- this.style = options.style && CSL_STYLES[options.style] ? options.style : DEFAULT_CSL_STYLE;
2007
+ this.styles = resolveCslStyles(options.styles);
2008
+ this.style = options.style && this.styles[options.style] ? options.style : DEFAULT_CSL_STYLE;
1992
2009
  this.updateSources(options.sources ?? [], false);
1993
2010
  }
1994
2011
  getStyle() {
1995
2012
  return this.style;
1996
2013
  }
2014
+ /** Every style this engine can render with, bundled + host-injected. */
2015
+ getAvailableStyles() {
2016
+ return Object.values(this.styles).sort((a, b) => a.id.localeCompare(b.id));
2017
+ }
1997
2018
  /** 'note' styles (Chicago notes-bib) cite via footnotes; 'in-text' cite inline. */
1998
2019
  isNoteStyle() {
1999
- return CSL_STYLES[this.style]?.category === "note";
2020
+ return this.styles[this.style]?.category === "note";
2000
2021
  }
2001
2022
  getSource(id) {
2002
2023
  return this.sources.get(id);
@@ -2013,7 +2034,7 @@ var CiteEngine = class {
2013
2034
  }
2014
2035
  /** Live style switch: reload the CSL, recompute everything, repaint (6A-7). */
2015
2036
  setStyle(styleId) {
2016
- if (!CSL_STYLES[styleId] || styleId === this.style) return;
2037
+ if (!this.styles[styleId] || styleId === this.style) return;
2017
2038
  this.style = styleId;
2018
2039
  this.recompute();
2019
2040
  this.emitChange();
@@ -2066,7 +2087,7 @@ var CiteEngine = class {
2066
2087
  * any edit — the same derived-view pattern used for pagination/collab.
2067
2088
  */
2068
2089
  recompute() {
2069
- const styleInfo = CSL_STYLES[this.style];
2090
+ const styleInfo = this.styles[this.style];
2070
2091
  const engine = new import_citeproc.default.Engine(
2071
2092
  {
2072
2093
  retrieveLocale: () => CSL_LOCALE_EN_US,
@@ -2461,7 +2482,7 @@ var citationPlugin = (0, import_docflow_core18.definePlugin)({
2461
2482
  const citation = port?.citation;
2462
2483
  if (!citation) return;
2463
2484
  const sources = typeof citation.sources === "function" ? citation.sources() : citation.sources;
2464
- const engine = new CiteEngine({ sources, style: citation.style });
2485
+ const engine = new CiteEngine({ sources, style: citation.style, styles: citation.styles });
2465
2486
  editor.storage.citationEngine.engine = engine;
2466
2487
  },
2467
2488
  onDestroy(editor) {
@@ -4266,6 +4287,7 @@ var defaultPlugins = [
4266
4287
  registerSlashCommands,
4267
4288
  rejectAllSuggestions,
4268
4289
  rejectSuggestion,
4290
+ resolveCslStyles,
4269
4291
  sanitizeCiteprocHtml,
4270
4292
  scrollEditorToPos,
4271
4293
  setDocumentMode,
package/dist/index.d.cts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as _kedata_indonesia_docflow_core from '@kedataindo/docflow-core';
2
2
  import { AIAction, DocsEditorPlugin, DocumentMode } from '@kedataindo/docflow-core';
3
- export { DocsEditorPlugin, FontFamilyExtension, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
3
+ export { CslStyleInfo, DocsEditorPlugin, FontFamilyExtension, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
4
4
  import { Node, Editor, Extension, Mark } from '@tiptap/core';
5
5
  import { CiteEngine } from './citations.cjs';
6
- export { CSL_LOCALE_EN_US, CSL_STYLES, CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, CslStyleInfo, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, sanitizeCiteprocHtml } from './citations.cjs';
6
+ export { CSL_LOCALE_EN_US, CSL_STYLES, CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, resolveCslStyles, sanitizeCiteprocHtml } from './citations.cjs';
7
7
  import { PluginKey } from '@tiptap/pm/state';
8
8
  import { Fragment } from '@tiptap/pm/model';
9
9
  import { EditorView } from '@tiptap/pm/view';
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as _kedata_indonesia_docflow_core from '@kedataindo/docflow-core';
2
2
  import { AIAction, DocsEditorPlugin, DocumentMode } from '@kedataindo/docflow-core';
3
- export { DocsEditorPlugin, FontFamilyExtension, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
3
+ export { CslStyleInfo, DocsEditorPlugin, FontFamilyExtension, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
4
4
  import { Node, Editor, Extension, Mark } from '@tiptap/core';
5
5
  import { CiteEngine } from './citations.js';
6
- export { CSL_LOCALE_EN_US, CSL_STYLES, CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, CslStyleInfo, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, sanitizeCiteprocHtml } from './citations.js';
6
+ export { CSL_LOCALE_EN_US, CSL_STYLES, CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, resolveCslStyles, sanitizeCiteprocHtml } from './citations.js';
7
7
  import { PluginKey } from '@tiptap/pm/state';
8
8
  import { Fragment } from '@tiptap/pm/model';
9
9
  import { EditorView } from '@tiptap/pm/view';
package/dist/index.js CHANGED
@@ -1860,6 +1860,19 @@ var DEFAULT_CSL_STYLE = "chicago-notes-bibliography";
1860
1860
  var CSL_LOCALE_EN_US = localesEnUS_default;
1861
1861
 
1862
1862
  // src/citeEngine.ts
1863
+ function resolveCslStyles(extra) {
1864
+ const merged = { ...CSL_STYLES };
1865
+ for (const style of extra ?? []) {
1866
+ const id = typeof style?.id === "string" ? style.id.trim() : "";
1867
+ if (!id || typeof style?.xml !== "string" || style.xml.trim() === "") {
1868
+ throw new Error(
1869
+ `resolveCslStyles: every style needs a non-empty id and CSL xml (got id=${JSON.stringify(style?.id)}, xml=${style?.xml === void 0 ? "undefined" : `${typeof style.xml === "string" ? style.xml.length : typeof style.xml} chars`})`
1870
+ );
1871
+ }
1872
+ merged[id] = { ...style, id };
1873
+ }
1874
+ return merged;
1875
+ }
1863
1876
  var clusterSeq = 0;
1864
1877
  function nextCitationId() {
1865
1878
  clusterSeq += 1;
@@ -1872,21 +1885,28 @@ function sanitizeCiteprocHtml(html) {
1872
1885
  var CiteEngine = class {
1873
1886
  sources = /* @__PURE__ */ new Map();
1874
1887
  style;
1888
+ /** Bundled styles + whatever the host injected (issue #180). */
1889
+ styles;
1875
1890
  clusters = /* @__PURE__ */ new Map();
1876
1891
  order = [];
1877
1892
  rendered = /* @__PURE__ */ new Map();
1878
1893
  bibliography = [];
1879
1894
  listeners = /* @__PURE__ */ new Set();
1880
1895
  constructor(options = {}) {
1881
- this.style = options.style && CSL_STYLES[options.style] ? options.style : DEFAULT_CSL_STYLE;
1896
+ this.styles = resolveCslStyles(options.styles);
1897
+ this.style = options.style && this.styles[options.style] ? options.style : DEFAULT_CSL_STYLE;
1882
1898
  this.updateSources(options.sources ?? [], false);
1883
1899
  }
1884
1900
  getStyle() {
1885
1901
  return this.style;
1886
1902
  }
1903
+ /** Every style this engine can render with, bundled + host-injected. */
1904
+ getAvailableStyles() {
1905
+ return Object.values(this.styles).sort((a, b) => a.id.localeCompare(b.id));
1906
+ }
1887
1907
  /** 'note' styles (Chicago notes-bib) cite via footnotes; 'in-text' cite inline. */
1888
1908
  isNoteStyle() {
1889
- return CSL_STYLES[this.style]?.category === "note";
1909
+ return this.styles[this.style]?.category === "note";
1890
1910
  }
1891
1911
  getSource(id) {
1892
1912
  return this.sources.get(id);
@@ -1903,7 +1923,7 @@ var CiteEngine = class {
1903
1923
  }
1904
1924
  /** Live style switch: reload the CSL, recompute everything, repaint (6A-7). */
1905
1925
  setStyle(styleId) {
1906
- if (!CSL_STYLES[styleId] || styleId === this.style) return;
1926
+ if (!this.styles[styleId] || styleId === this.style) return;
1907
1927
  this.style = styleId;
1908
1928
  this.recompute();
1909
1929
  this.emitChange();
@@ -1956,7 +1976,7 @@ var CiteEngine = class {
1956
1976
  * any edit — the same derived-view pattern used for pagination/collab.
1957
1977
  */
1958
1978
  recompute() {
1959
- const styleInfo = CSL_STYLES[this.style];
1979
+ const styleInfo = this.styles[this.style];
1960
1980
  const engine = new CSL.Engine(
1961
1981
  {
1962
1982
  retrieveLocale: () => CSL_LOCALE_EN_US,
@@ -2351,7 +2371,7 @@ var citationPlugin = definePlugin18({
2351
2371
  const citation = port?.citation;
2352
2372
  if (!citation) return;
2353
2373
  const sources = typeof citation.sources === "function" ? citation.sources() : citation.sources;
2354
- const engine = new CiteEngine({ sources, style: citation.style });
2374
+ const engine = new CiteEngine({ sources, style: citation.style, styles: citation.styles });
2355
2375
  editor.storage.citationEngine.engine = engine;
2356
2376
  },
2357
2377
  onDestroy(editor) {
@@ -4155,6 +4175,7 @@ export {
4155
4175
  registerSlashCommands,
4156
4176
  rejectAllSuggestions,
4157
4177
  rejectSuggestion,
4178
+ resolveCslStyles,
4158
4179
  sanitizeCiteprocHtml,
4159
4180
  scrollEditorToPos,
4160
4181
  setDocumentMode,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kedataindo/docflow-plugins",
3
3
  "license": "Apache-2.0",
4
- "version": "0.0.103",
4
+ "version": "0.0.104",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -32,7 +32,7 @@
32
32
  "@tiptap/pm": "^2.27.3",
33
33
  "citeproc": "^2.4.63",
34
34
  "tiptap-markdown": "0.8.10",
35
- "@kedataindo/docflow-core": "0.0.96"
35
+ "@kedataindo/docflow-core": "0.0.97"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@tiptap/core": "^2.11.0",