@kedataindo/docflow-plugins 0.0.34 → 0.0.36

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.
@@ -1112,85 +1112,6 @@ var CiteEngine = class {
1112
1112
  }
1113
1113
  };
1114
1114
 
1115
- // src/citation.ts
1116
- var import_core2 = require("@tiptap/core");
1117
- var import_docflow_core = require("@kedataindo/docflow-core");
1118
-
1119
- // src/bibliography.ts
1120
- var import_core = require("@tiptap/core");
1121
- function getEngine(editor) {
1122
- const storage = editor.storage.citation;
1123
- return storage?.engine ?? null;
1124
- }
1125
- var BibliographyNode = import_core.Node.create({
1126
- name: "bibliography",
1127
- group: "block",
1128
- selectable: true,
1129
- draggable: true,
1130
- atom: true,
1131
- parseHTML() {
1132
- return [{ tag: 'div[data-node-type="bibliography"]' }];
1133
- },
1134
- renderHTML({ HTMLAttributes }) {
1135
- return [
1136
- "div",
1137
- (0, import_core.mergeAttributes)(HTMLAttributes, {
1138
- "data-node-type": "bibliography",
1139
- class: "docs-bibliography"
1140
- })
1141
- ];
1142
- },
1143
- // Return type cast to `any` to bypass TipTap's strict NodeViewRenderer typing
1144
- // (same pattern as FootnoteNode).
1145
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1146
- addNodeView() {
1147
- return (props) => {
1148
- const editor = props.editor;
1149
- const dom = document.createElement("div");
1150
- dom.className = "docs-bibliography";
1151
- dom.setAttribute("data-node-type", "bibliography");
1152
- const render = () => {
1153
- const engine2 = getEngine(editor);
1154
- const items = engine2?.getBibliography() ?? [];
1155
- dom.innerHTML = "";
1156
- if (items.length === 0) {
1157
- const placeholder = document.createElement("p");
1158
- placeholder.className = "docs-bibliography__empty";
1159
- placeholder.textContent = "Bibliography";
1160
- dom.appendChild(placeholder);
1161
- return;
1162
- }
1163
- const heading = document.createElement("h2");
1164
- heading.className = "docs-bibliography__heading";
1165
- heading.textContent = "Bibliography";
1166
- dom.appendChild(heading);
1167
- const list = document.createElement("div");
1168
- list.className = "docs-bibliography__entries";
1169
- for (const item of items) {
1170
- const entry = document.createElement("p");
1171
- entry.className = "docs-bibliography__entry";
1172
- entry.innerHTML = item;
1173
- list.appendChild(entry);
1174
- }
1175
- dom.appendChild(list);
1176
- };
1177
- render();
1178
- const engine = getEngine(editor);
1179
- const unsubscribe = engine?.onChange(render);
1180
- return {
1181
- dom,
1182
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1183
- update(updatedNode) {
1184
- return updatedNode?.type?.name === "bibliography";
1185
- },
1186
- destroy() {
1187
- unsubscribe?.();
1188
- }
1189
- };
1190
- };
1191
- }
1192
- });
1193
-
1194
1115
  // src/citationNodeSpec.ts
1195
1116
  function buildCitationNodes(engine, attrs) {
1196
1117
  const citationId = nextCitationId();
@@ -1205,247 +1126,6 @@ function buildCitationNodes(engine, attrs) {
1205
1126
  attrs: { citationId, sourceId: attrs.sourceId, locator: attrs.locator ?? "" }
1206
1127
  };
1207
1128
  }
1208
-
1209
- // src/citation.ts
1210
- function getCitationEngine(editor) {
1211
- return editor.storage.citation ? editor.storage.citation.engine ?? null : null;
1212
- }
1213
- var CitationEngineExtension = import_core2.Extension.create({
1214
- name: "citation",
1215
- addStorage() {
1216
- return {
1217
- engine: null
1218
- };
1219
- },
1220
- /**
1221
- * Keep the engine's cluster registry in sync with the document: walk the
1222
- * PM doc after every update, collect citation nodes AND citation-backed
1223
- * footnotes in document order, and hand them to the engine. The engine
1224
- * recomputes only when the ordered signature changed, so plain typing
1225
- * costs one cheap walk and no citeproc work.
1226
- */
1227
- onUpdate() {
1228
- const editor = this.editor;
1229
- const engine = getCitationEngine(editor);
1230
- if (!engine) return;
1231
- {
1232
- const seen = /* @__PURE__ */ new Set();
1233
- const repairs = [];
1234
- editor.state.doc.descendants((node, pos) => {
1235
- if (node.type.name === "citation" || node.type.name === "footnote" && node.attrs.sourceId) {
1236
- const id = node.attrs.citationId;
1237
- if (id) {
1238
- if (seen.has(id)) {
1239
- repairs.push({ pos, attrs: { ...node.attrs } });
1240
- } else {
1241
- seen.add(id);
1242
- }
1243
- }
1244
- }
1245
- return true;
1246
- });
1247
- if (repairs.length > 0) {
1248
- const tr = editor.state.tr;
1249
- for (const { pos, attrs } of repairs) {
1250
- tr.setNodeMarkup(pos, void 0, { ...attrs, citationId: nextCitationId() });
1251
- }
1252
- editor.view.dispatch(tr);
1253
- return;
1254
- }
1255
- }
1256
- const ordered = [];
1257
- editor.state.doc.descendants((node, pos) => {
1258
- if (node.type.name === "citation" || node.type.name === "footnote" && node.attrs.sourceId) {
1259
- ordered.push({
1260
- citationId: node.attrs.citationId ?? `anon-${pos}`,
1261
- attrs: {
1262
- sourceId: node.attrs.sourceId ?? null,
1263
- locator: node.attrs.locator || "",
1264
- label: node.attrs.label || "page",
1265
- mode: node.attrs.mode || "normal",
1266
- prefix: node.attrs.prefix || "",
1267
- suffix: node.attrs.suffix || ""
1268
- }
1269
- });
1270
- }
1271
- return true;
1272
- });
1273
- const changed = engine.syncCitations(ordered);
1274
- if (changed) {
1275
- const port = editor.storage.editorContext;
1276
- port?.citation?.onSourcesChange?.(engine.getCitedSourceIds());
1277
- }
1278
- }
1279
- });
1280
- var CitationNode = import_core2.Node.create({
1281
- name: "citation",
1282
- group: "inline",
1283
- inline: true,
1284
- selectable: true,
1285
- draggable: false,
1286
- atom: true,
1287
- addAttributes() {
1288
- return {
1289
- citationId: {
1290
- default: null,
1291
- parseHTML: (el) => el.getAttribute("data-citation-id"),
1292
- renderHTML: (attrs) => ({ "data-citation-id": attrs.citationId })
1293
- },
1294
- sourceId: {
1295
- default: null,
1296
- parseHTML: (el) => el.getAttribute("data-citation-source-id"),
1297
- renderHTML: (attrs) => ({ "data-citation-source-id": attrs.sourceId })
1298
- },
1299
- locator: {
1300
- default: "",
1301
- parseHTML: (el) => el.getAttribute("data-citation-locator") ?? "",
1302
- renderHTML: (attrs) => ({ "data-citation-locator": attrs.locator })
1303
- },
1304
- label: {
1305
- default: "page",
1306
- parseHTML: (el) => el.getAttribute("data-citation-label") ?? "page",
1307
- renderHTML: (attrs) => ({ "data-citation-label": attrs.label })
1308
- },
1309
- mode: {
1310
- default: "normal",
1311
- parseHTML: (el) => el.getAttribute("data-citation-mode") ?? "normal",
1312
- renderHTML: (attrs) => ({ "data-citation-mode": attrs.mode })
1313
- },
1314
- prefix: { default: "" },
1315
- suffix: { default: "" }
1316
- };
1317
- },
1318
- parseHTML() {
1319
- return [{ tag: 'span[data-node-type="citation"]' }];
1320
- },
1321
- renderHTML({ HTMLAttributes }) {
1322
- return [
1323
- "span",
1324
- (0, import_core2.mergeAttributes)(HTMLAttributes, {
1325
- "data-node-type": "citation",
1326
- class: "docs-citation"
1327
- }),
1328
- ""
1329
- ];
1330
- },
1331
- // Return type cast to `any` to bypass TipTap's strict NodeViewRenderer typing
1332
- // (same pattern as FootnoteNode).
1333
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1334
- addNodeView() {
1335
- return (props) => {
1336
- const editor = props.editor;
1337
- const node = props.node ?? props;
1338
- const dom = document.createElement("span");
1339
- dom.className = "docs-citation";
1340
- dom.setAttribute("data-node-type", "citation");
1341
- const render = () => {
1342
- const engine2 = getCitationEngine(editor);
1343
- const citationId = node.attrs.citationId;
1344
- const text = engine2 && citationId ? engine2.renderCluster(citationId) : "";
1345
- if (text) {
1346
- dom.innerHTML = text;
1347
- dom.classList.remove("docs-citation--missing");
1348
- } else {
1349
- dom.textContent = "[?]";
1350
- dom.classList.add("docs-citation--missing");
1351
- }
1352
- dom.setAttribute("data-citation-id", String(node.attrs.citationId ?? ""));
1353
- dom.setAttribute("data-citation-source-id", String(node.attrs.sourceId ?? ""));
1354
- };
1355
- render();
1356
- const engine = getCitationEngine(editor);
1357
- const unsubscribe = engine?.onChange(render);
1358
- return {
1359
- dom,
1360
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1361
- update(updatedNode) {
1362
- if (updatedNode?.type?.name !== "citation") return false;
1363
- try {
1364
- Object.assign(node.attrs, updatedNode.attrs);
1365
- render();
1366
- } catch {
1367
- }
1368
- return true;
1369
- },
1370
- destroy() {
1371
- unsubscribe?.();
1372
- }
1373
- };
1374
- };
1375
- }
1376
- });
1377
- function insertCitationWithSource(editor, engine, attrs) {
1378
- const spec = buildCitationNodes(engine, attrs);
1379
- if (spec.type === "footnote" && !editor.schema.nodes["footnote"]) return false;
1380
- return editor.chain().focus().insertContent({ type: spec.type, attrs: spec.attrs }).run();
1381
- }
1382
- var citationPlugin = (0, import_docflow_core.definePlugin)({
1383
- id: "citation",
1384
- tiptapExtensions: [CitationEngineExtension, CitationNode, BibliographyNode],
1385
- toolbar: [{ id: "insert-citation", label: "Citation", action: "insertCitation", iconComponent: "Quote" }],
1386
- slashCommands: [
1387
- { name: "Citation", command: "insertCitation" },
1388
- { name: "Bibliography", command: "insertBibliography" }
1389
- ],
1390
- commands: {
1391
- /**
1392
- * Insert a citation. Programmatic path: pass { sourceId, locator? }.
1393
- * Interactive path: ask the host for a source via the injected
1394
- * onSourceRequest picker (async — insertion happens on resolve, the
1395
- * command contract stays synchronous, same as imagePlugin).
1396
- */
1397
- insertCitation: (editor, ...args) => {
1398
- const engine = getCitationEngine(editor);
1399
- if (!engine) {
1400
- console.warn("[citation] no citation engine \u2014 inject the CitationPort to enable citations");
1401
- return false;
1402
- }
1403
- const options = args[0];
1404
- if (options?.sourceId) {
1405
- return insertCitationWithSource(editor, engine, { sourceId: options.sourceId, locator: options.locator });
1406
- }
1407
- const port = editor.storage.editorContext;
1408
- const request = port?.citation?.onSourceRequest;
1409
- if (!request) return false;
1410
- void request().then((sourceId) => {
1411
- if (sourceId) insertCitationWithSource(editor, engine, { sourceId });
1412
- });
1413
- return true;
1414
- },
1415
- /** Insert the auto-rendered bibliography (one per document). */
1416
- insertBibliography: (editor) => {
1417
- let exists = false;
1418
- editor.state.doc.descendants((node) => {
1419
- if (node.type.name === "bibliography") exists = true;
1420
- return !exists;
1421
- });
1422
- if (exists) return false;
1423
- return editor.chain().focus().insertContent({ type: "bibliography" }).run();
1424
- },
1425
- /** Live style switch — reformats every citation + bibliography (6A-7). */
1426
- setCitationStyle: (editor, ...args) => {
1427
- const engine = getCitationEngine(editor);
1428
- const styleId = args[0];
1429
- if (!engine || !styleId) return false;
1430
- engine.setStyle(styleId);
1431
- return true;
1432
- }
1433
- },
1434
- hooks: {
1435
- onInit(editor) {
1436
- const port = editor.storage.editorContext;
1437
- const citation = port?.citation;
1438
- if (!citation) return;
1439
- const sources = typeof citation.sources === "function" ? citation.sources() : citation.sources;
1440
- const engine = new CiteEngine({ sources, style: citation.style });
1441
- editor.storage.citation.engine = engine;
1442
- },
1443
- onDestroy(editor) {
1444
- ;
1445
- editor.storage.citation.engine = null;
1446
- }
1447
- }
1448
- });
1449
1129
  // Annotate the CommonJS export names for ESM import in node:
1450
1130
  0 && (module.exports = {
1451
1131
  CSL_LOCALE_EN_US,