@fiduswriter/document 0.1.0-alpha.1

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.
Files changed (110) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +16 -0
  3. package/jest.config.js +23 -0
  4. package/package.json +59 -0
  5. package/schema.json +1 -0
  6. package/scripts/export-schema.js +16 -0
  7. package/src/bibliography/common.js +92 -0
  8. package/src/bibliography/csl_bib.js +139 -0
  9. package/src/citations/citeproc_sys.js +42 -0
  10. package/src/citations/format.js +194 -0
  11. package/src/common/blob.js +10 -0
  12. package/src/common/file.js +25 -0
  13. package/src/common/index.js +12 -0
  14. package/src/common/network.js +79 -0
  15. package/src/common/text.js +44 -0
  16. package/src/editor/e2ee/encryptor.js +228 -0
  17. package/src/exporter/docx/citations.js +177 -0
  18. package/src/exporter/docx/comments.js +165 -0
  19. package/src/exporter/docx/footnotes.js +240 -0
  20. package/src/exporter/docx/images.js +101 -0
  21. package/src/exporter/docx/index.js +185 -0
  22. package/src/exporter/docx/lists.js +260 -0
  23. package/src/exporter/docx/math.js +46 -0
  24. package/src/exporter/docx/metadata.js +289 -0
  25. package/src/exporter/docx/rels.js +193 -0
  26. package/src/exporter/docx/render.js +941 -0
  27. package/src/exporter/docx/richtext.js +1182 -0
  28. package/src/exporter/docx/tables.js +112 -0
  29. package/src/exporter/docx/tools.js +50 -0
  30. package/src/exporter/epub/index.js +142 -0
  31. package/src/exporter/epub/templates.js +140 -0
  32. package/src/exporter/epub/tools.js +96 -0
  33. package/src/exporter/html/citations.js +121 -0
  34. package/src/exporter/html/convert.js +813 -0
  35. package/src/exporter/html/index.js +192 -0
  36. package/src/exporter/html/templates.js +34 -0
  37. package/src/exporter/html/tools.js +50 -0
  38. package/src/exporter/jats/bibliography.js +183 -0
  39. package/src/exporter/jats/citations.js +109 -0
  40. package/src/exporter/jats/convert.js +871 -0
  41. package/src/exporter/jats/index.js +92 -0
  42. package/src/exporter/jats/templates.js +35 -0
  43. package/src/exporter/jats/text.js +72 -0
  44. package/src/exporter/latex/convert.js +934 -0
  45. package/src/exporter/latex/escape_latex.js +21 -0
  46. package/src/exporter/latex/index.js +74 -0
  47. package/src/exporter/latex/readme.js +22 -0
  48. package/src/exporter/native/shrink.js +132 -0
  49. package/src/exporter/odt/citations.js +101 -0
  50. package/src/exporter/odt/footnotes.js +147 -0
  51. package/src/exporter/odt/images.js +115 -0
  52. package/src/exporter/odt/index.js +156 -0
  53. package/src/exporter/odt/math.js +57 -0
  54. package/src/exporter/odt/metadata.js +251 -0
  55. package/src/exporter/odt/render.js +806 -0
  56. package/src/exporter/odt/richtext.js +865 -0
  57. package/src/exporter/odt/styles.js +387 -0
  58. package/src/exporter/odt/track.js +68 -0
  59. package/src/exporter/pandoc/citations.js +98 -0
  60. package/src/exporter/pandoc/convert.js +1017 -0
  61. package/src/exporter/pandoc/index.js +92 -0
  62. package/src/exporter/pandoc/readme.js +8 -0
  63. package/src/exporter/pandoc/tools.js +51 -0
  64. package/src/exporter/print/index.js +177 -0
  65. package/src/exporter/tools/doc_content.js +144 -0
  66. package/src/exporter/tools/file.js +9 -0
  67. package/src/exporter/tools/json.js +73 -0
  68. package/src/exporter/tools/svg.js +29 -0
  69. package/src/exporter/tools/xml.js +531 -0
  70. package/src/exporter/tools/xml_zip.js +95 -0
  71. package/src/exporter/tools/zip.js +90 -0
  72. package/src/exporter/tools/zotero_csl.js +93 -0
  73. package/src/importer/citations.js +129 -0
  74. package/src/importer/docx/citations.js +123 -0
  75. package/src/importer/docx/convert.js +1427 -0
  76. package/src/importer/docx/helpers.js +9 -0
  77. package/src/importer/docx/omml2mathml.js +1448 -0
  78. package/src/importer/docx/parse.js +735 -0
  79. package/src/importer/native/get_images.js +76 -0
  80. package/src/importer/native/update.js +29 -0
  81. package/src/importer/odt/citations.js +87 -0
  82. package/src/importer/odt/convert.js +1855 -0
  83. package/src/importer/pandoc/convert.js +884 -0
  84. package/src/importer/pandoc/helpers.js +84 -0
  85. package/src/importer/zip_analyzer.js +102 -0
  86. package/src/index.js +1 -0
  87. package/src/mathlive/opf_includes.js +24 -0
  88. package/src/schema/common/annotate.js +76 -0
  89. package/src/schema/common/base.js +118 -0
  90. package/src/schema/common/citation.js +62 -0
  91. package/src/schema/common/equation.js +31 -0
  92. package/src/schema/common/figure.js +190 -0
  93. package/src/schema/common/heading.js +43 -0
  94. package/src/schema/common/index.js +40 -0
  95. package/src/schema/common/list.js +95 -0
  96. package/src/schema/common/reference.js +100 -0
  97. package/src/schema/common/table.js +103 -0
  98. package/src/schema/common/track.js +190 -0
  99. package/src/schema/const.js +58 -0
  100. package/src/schema/convert.js +1272 -0
  101. package/src/schema/document/content.js +187 -0
  102. package/src/schema/document/index.js +117 -0
  103. package/src/schema/document/structure.js +452 -0
  104. package/src/schema/export.js +21 -0
  105. package/src/schema/footnotes.js +126 -0
  106. package/src/schema/footnotes_convert.js +31 -0
  107. package/src/schema/i18n.js +595 -0
  108. package/src/schema/index.js +5 -0
  109. package/src/schema/mini_json.js +61 -0
  110. package/src/schema/text.js +22 -0
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Helper functions for creating Zotero-compatible citation data.
3
+ * Uses CSLExporter from biblatex-csl-converter to convert Fidus Writer's
4
+ * internal BibLaTeX format to CSL-JSON.
5
+ */
6
+
7
+ import {CSLExporter} from "biblatex-csl-converter"
8
+
9
+ /**
10
+ * Generate a random citation ID similar to Zotero's format.
11
+ * Zotero uses 8-10 character alphanumeric IDs.
12
+ */
13
+ function generateCitationId() {
14
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
15
+ let id = ""
16
+ for (let i = 0; i < 8; i++) {
17
+ id += chars.charAt(Math.floor(Math.random() * chars.length))
18
+ }
19
+ return id
20
+ }
21
+
22
+ /**
23
+ * Convert bibliography entries to CSL-JSON format.
24
+ * @param {Object} bibDB - The bibliography database
25
+ * @param {Array} ids - Array of entry IDs to convert
26
+ * @returns {Object} Object mapping IDs to CSL-JSON entries
27
+ */
28
+ function convertToCSL(bibDB, ids) {
29
+ const exporter = new CSLExporter(bibDB.db, ids)
30
+ return exporter.parse()
31
+ }
32
+
33
+ /**
34
+ * Create a Zotero citation JSON object.
35
+ * @param {Array} references - Array of {id, prefix?, locator?} from citation node
36
+ * @param {Object} bibDB - Bibliography database
37
+ * @param {string} formattedCitation - Pre-formatted citation text from citeproc
38
+ * @param {string} citationId - Optional citation ID (generated if not provided)
39
+ * @returns {Object} Zotero citation JSON object
40
+ */
41
+ export function createZoteroCitation(
42
+ references,
43
+ bibDB,
44
+ formattedCitation,
45
+ citationId = null
46
+ ) {
47
+ const citationID = citationId || generateCitationId()
48
+
49
+ // Get the IDs of all referenced items
50
+ const ids = references.map(ref => ref.id)
51
+
52
+ // Convert to CSL-JSON
53
+ const _cslData = convertToCSL(bibDB, ids)
54
+ const citationItems = references
55
+ .map(ref => {
56
+ const entry = bibDB.db[ref.id]
57
+
58
+ if (!entry) {
59
+ return null
60
+ }
61
+ const citationKey = entry.entry_key || String(ref.id)
62
+ const item = {
63
+ id: ref.id,
64
+ uris: [],
65
+ itemData: {
66
+ ...ref.item,
67
+ id: citationKey
68
+ }
69
+ }
70
+
71
+ if (ref.locator) {
72
+ item.locator = ref.locator
73
+ }
74
+
75
+ if (ref.prefix) {
76
+ item.prefix = ref.prefix
77
+ }
78
+
79
+ return item
80
+ })
81
+ .filter(item => item !== null)
82
+
83
+ return {
84
+ citationID,
85
+ properties: {
86
+ formattedCitation,
87
+ plainCitation: formattedCitation,
88
+ noteIndex: 0
89
+ },
90
+ citationItems,
91
+ schema: "https://github.com/citation-style-language/schema/raw/master/csl-citation.json"
92
+ }
93
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Shared citation utilities for DOCX and ODT importers.
3
+ *
4
+ * Converts a CitationResult (from DocxCitationsParser or OdtCitationsParser
5
+ * static methods) plus a BibDB (entries) into a Fidus Writer citation node,
6
+ * and merges the new BibDB entries into the document bibliography.
7
+ *
8
+ * The `bibliography` object passed in is mutated in place: new entries are
9
+ * appended with sequential numeric string keys ("1", "2", …).
10
+ */
11
+
12
+ /**
13
+ * Given a BibDB returned by a static Citations parser call and the current
14
+ * document bibliography, add every entry that is not yet present (matched by
15
+ * entry_key) and return a mapping from entry_key → bibliography key string.
16
+ *
17
+ * @param {Object} entries BibDB (Record<number, EntryObject>) from parser
18
+ * @param {Object} bibliography Fidus Writer bibliography (mutated in place)
19
+ * @returns {Object} Map of entry_key → bibKey string
20
+ */
21
+ function mergeBibEntries(entries, bibliography, bibDB) {
22
+ const keyMap = {}
23
+
24
+ for (const entry of Object.values(entries)) {
25
+ if (!entry || !entry.entry_key) {
26
+ continue
27
+ }
28
+ const entryKey = entry.entry_key
29
+
30
+ // Check whether this entry_key is already in the bibliography.
31
+ const existing = Object.entries(bibliography).find(
32
+ ([, bibEntry]) => bibEntry && bibEntry.entry_key === entryKey
33
+ )
34
+
35
+ if (existing) {
36
+ keyMap[entryKey] = existing[0]
37
+ } else {
38
+ if (bibDB && Object.keys(entry.fields).length === 0) {
39
+ // Jabref citations don't contain any fields. Look up values in bibDB instead
40
+ const bibEntry = Object.values(bibDB.db).find(
41
+ bibEntry => bibEntry && bibEntry.entry_key === entryKey
42
+ )
43
+ if (bibEntry) {
44
+ entry.fields = JSON.parse(JSON.stringify(bibEntry.fields))
45
+ entry.bib_type = bibEntry.bib_type
46
+ }
47
+ }
48
+ // TODO: add for jabref citations - according to entry_key import from user
49
+ // library if useExternalDB is true
50
+ const bibKey = String(Object.keys(bibliography).length + 1)
51
+ bibliography[bibKey] = entry
52
+ keyMap[entryKey] = bibKey
53
+ }
54
+ }
55
+
56
+ return keyMap
57
+ }
58
+
59
+ /**
60
+ * Convert a CitationResult from a static DocxCitationsParser or
61
+ * OdtCitationsParser call into a Fidus Writer citation node.
62
+ *
63
+ * The `bibliography` object is mutated in place to include any new entries.
64
+ *
65
+ * Each item in `metadata` (when `retrieveMetadata` was true) may carry:
66
+ * - id : entry_key string identifying which entry this item refers to
67
+ * - prefix : citation prefix text
68
+ * - suffix : citation suffix / locator text (used as `locator`)
69
+ * - locator : explicit locator string (preferred over suffix when present)
70
+ * - authorOnly : boolean – render author name only (maps to "textcite")
71
+ * - suppressAuthor : boolean – suppress author name (ignored, maps to default)
72
+ * - authorYear : boolean – render author name and year (maps to "textcite")
73
+ *
74
+ * `format` on the returned citation node matches the Fidus Writer citation schema:
75
+ * - "textcite" when authorOnly or authorYear is set on the (single) item (biblatex \textcite)
76
+ * - "autocite" otherwise, including when suppressAuthor is set (biblatex \autocite)
77
+ *
78
+ * @param {Object} result CitationResult from a static parser method
79
+ * @param {Object} bibliography Fidus Writer bibliography (mutated in place)
80
+ * @returns {Object|null} ProseMirror citation node or null
81
+ */
82
+ export function citationResultToNode(result, bibliography, bibDB = false) {
83
+ if (!result || !result.isCitation || !result.entries) {
84
+ return null
85
+ }
86
+ const entries = result.entries
87
+ const metadata = result.metadata || []
88
+
89
+ if (Object.keys(entries).length === 0) {
90
+ return null
91
+ }
92
+ const keyMap = mergeBibEntries(entries, bibliography, bibDB)
93
+ // Build the references array from entries.
94
+ //
95
+ const references = Object.entries(entries).map(([_entryId, entry]) => {
96
+ const entryKey = entry.entry_key
97
+ const entryMetadata = metadata.find(meta => meta.entry_key === entryKey)
98
+ return {
99
+ id: keyMap[entryKey],
100
+ prefix: entryMetadata?.prefix || "",
101
+ locator: entryMetadata?.locator || entryMetadata?.suffix || ""
102
+ }
103
+ })
104
+
105
+ if (references.length === 0) {
106
+ return null
107
+ }
108
+
109
+ // Determine citation format from the first item's metadata flags.
110
+ // "textcite" corresponds to biblatex's \textcite (author-in-text / authorYear).
111
+ // Even authorOnly comes through as "textcite" since it's a similar concept.
112
+ // Everything else, including suppressAuthor, falls back to "autocite".
113
+ // TODO: When an authorOnly citation is followed directly by a suppressAuthor
114
+ // citation, this would display the same as a single authorYear citation and
115
+ // should be treated as such.
116
+ const format =
117
+ metadata.length === 1 &&
118
+ (metadata[0].authorOnly || metadata[0].authorYear)
119
+ ? "textcite"
120
+ : "autocite"
121
+
122
+ return {
123
+ type: "citation",
124
+ attrs: {
125
+ format,
126
+ references
127
+ }
128
+ }
129
+ }
@@ -0,0 +1,123 @@
1
+ import {DocxCitationsParser} from "biblatex-csl-converter"
2
+ import {citationResultToNode} from "../citations.js"
3
+
4
+ /**
5
+ * Check whether a field instruction string belongs to a citation.
6
+ * Uses DocxCitationsParser.fieldCitation() with retrieve=false so no BibDB
7
+ * is allocated for the check.
8
+ *
9
+ * @param {string} instrText - Concatenated w:instrText content
10
+ * @returns {boolean}
11
+ */
12
+ export function isDocxCitationField(instrText) {
13
+ if (!instrText) {
14
+ return false
15
+ }
16
+ return DocxCitationsParser.fieldCitation(instrText, false).isCitation
17
+ }
18
+
19
+ /**
20
+ * Check whether a field instruction string belongs to a bibliography region
21
+ * (Zotero ZOTERO_BIBL, Word native BIBLIOGRAPHY, EN.REFLIST, etc.).
22
+ * Uses DocxCitationsParser.fieldBibliography() with the accumulated
23
+ * instruction text between begin and separate markers.
24
+ *
25
+ * @param {string} instrText - Concatenated w:instrText content
26
+ * @returns {boolean}
27
+ */
28
+ export function isDocxBibliographyField(instrText) {
29
+ if (!instrText) {
30
+ return false
31
+ }
32
+
33
+ return DocxCitationsParser.fieldBibliography(instrText).isBibliography
34
+ }
35
+
36
+ /**
37
+ * Check whether a w:sdt node contains a citation (Mendeley v3, Citavi).
38
+ * Uses DocxCitationsParser.sdtCitation() with retrieve=false.
39
+ *
40
+ * @param {Object} sdtNode - The parsed w:sdt XMLElement node
41
+ * @returns {boolean}
42
+ */
43
+ export function isDocxSdtCitation(sdtNode) {
44
+ if (!sdtNode) {
45
+ return false
46
+ }
47
+ return DocxCitationsParser.sdtCitation(sdtNode.outerXML, false).isCitation
48
+ }
49
+
50
+ /**
51
+ * Check whether a w:sdt node is a bibliography rendering region
52
+ * (Mendeley v3 bibliography, Citavi bibliography).
53
+ * Uses DocxCitationsParser.sdtBibliography().
54
+ *
55
+ * @param {Object} sdtNode - The parsed w:sdt XMLElement node
56
+ * @returns {boolean}
57
+ */
58
+ export function isDocxSdtBibliography(sdtNode) {
59
+ if (!sdtNode) {
60
+ return false
61
+ }
62
+ return DocxCitationsParser.sdtBibliography(sdtNode.outerXML).isBibliography
63
+ }
64
+
65
+ /**
66
+ * Parse a citation from a DOCX field instruction and add any new bibliography
67
+ * entries into `bibliography`.
68
+ *
69
+ * Handles all field-based citation managers: Zotero, Mendeley Desktop
70
+ * (legacy), EndNote (both inline and fldData forms), Citavi (older ADDIN
71
+ * form), and Word native (requires sourcesXml).
72
+ *
73
+ * @param {string} instrText - Concatenated w:instrText for this field
74
+ * @param {string|null} fldData - Base64 content of w:fldData (EndNote),
75
+ * or null/undefined if absent
76
+ * @param {string|null} sourcesXml - Content of customXml/item1.xml (required
77
+ * only for Word-native citations)
78
+ * @param {Object} bibliography - Fidus Writer bibliography (mutated)
79
+ * @returns {Object|null} ProseMirror citation node or null
80
+ */
81
+ export function parseDocxFieldCitation(
82
+ instrText,
83
+ fldData,
84
+ sourcesXml,
85
+ bibliography
86
+ ) {
87
+ if (!instrText) {
88
+ return null
89
+ }
90
+ const options = sourcesXml ? {sourcesXml} : {}
91
+ const result = DocxCitationsParser.fieldCitation(
92
+ instrText,
93
+ true, // retrieve
94
+ true, // retrieveMetadata
95
+ true, // extractWordNative
96
+ fldData || undefined,
97
+ options
98
+ )
99
+ const node = citationResultToNode(result, bibliography)
100
+ return node
101
+ }
102
+
103
+ /**
104
+ * Parse a citation from a DOCX structured document tag (w:sdt) and add any
105
+ * new bibliography entries into `bibliography`.
106
+ *
107
+ * Handles Mendeley Cite v3 and Citavi (modern SDT form).
108
+ *
109
+ * @param {Object} sdtNode - The parsed w:sdt XMLElement node
110
+ * @param {Object} bibliography - Fidus Writer bibliography (mutated)
111
+ * @returns {Object|null} ProseMirror citation node or null
112
+ */
113
+ export function parseDocxSdtCitation(sdtNode, bibliography) {
114
+ if (!sdtNode) {
115
+ return null
116
+ }
117
+ const result = DocxCitationsParser.sdtCitation(
118
+ sdtNode.outerXML,
119
+ true, // retrieve
120
+ true // retrieveMetadata
121
+ )
122
+ return citationResultToNode(result, bibliography)
123
+ }