@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
package/jest.config.js ADDED
@@ -0,0 +1,23 @@
1
+ export default {
2
+ rootDir: ".",
3
+ testEnvironment: "node",
4
+ transform: {},
5
+ moduleDirectories: ["node_modules"],
6
+ moduleNameMapper: {
7
+ "^downloadjs$": "<rootDir>/test/exporter/mocks/downloadjs.js",
8
+ "^mathlive$": "<rootDir>/test/exporter/mocks/mathlive.js",
9
+ "^mathml2omml$": "<rootDir>/test/exporter/mocks/mathml2omml.js",
10
+ "^@vivliostyle/print$": "<rootDir>/test/exporter/mocks/vivliostyle.js",
11
+ "^pretty$": "<rootDir>/test/exporter/mocks/pretty.js",
12
+ "^biblatex-csl-converter$": "<rootDir>/test/exporter/mocks/biblatex-csl-converter.js",
13
+ "^jszip$": "<rootDir>/test/importer/mocks/jszip.js",
14
+ "^mathml-to-latex$": "<rootDir>/test/importer/mocks/mathml-to-latex.js",
15
+ "^@fiduswriter/document/common$": "<rootDir>/test/exporter/mocks/common.js",
16
+ "^@fiduswriter/document/citations/format$": "<rootDir>/test/exporter/mocks/citations-format.js",
17
+ "^@fiduswriter/document/bibliography/csl_bib$": "<rootDir>/test/exporter/mocks/csl-bib-schema.js",
18
+ "^@fiduswriter/document/mathlive/opf_includes$": "<rootDir>/test/exporter/mocks/empty-module.js"
19
+ },
20
+ testMatch: ["<rootDir>/test/**/*.test.js"],
21
+ setupFiles: ["<rootDir>/test/setup.js"],
22
+ moduleFileExtensions: ["js", "mjs", "json"]
23
+ }
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@fiduswriter/document",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Fidus Writer document schema, importers and exporters",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "ssh://git@codeberg.org/fiduswriter/fiduswriter-document.git"
8
+ },
9
+ "license": "AGPL-3.0",
10
+ "author": "Johannes Wilm",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": "./src/index.js",
14
+ "./schema": "./src/schema/index.js",
15
+ "./schema/*": "./src/schema/*",
16
+ "./importer/*": "./src/importer/*",
17
+ "./exporter/*": "./src/exporter/*",
18
+ "./citations/*": "./src/citations/*",
19
+ "./bibliography/*": "./src/bibliography/*",
20
+ "./common": "./src/common/index.js",
21
+ "./common/*": "./src/common/*"
22
+ },
23
+ "main": "jest.config.js",
24
+ "directories": {
25
+ "test": "test"
26
+ },
27
+ "files": [
28
+ "src/",
29
+ "scripts/",
30
+ "schema.json",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "scripts": {
35
+ "build-schema": "node scripts/export-schema.js",
36
+ "prepare": "node scripts/export-schema.js",
37
+ "prepublishOnly": "node scripts/export-schema.js",
38
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.config.js"
39
+ },
40
+ "dependencies": {
41
+ "biblatex-csl-converter": "^3.0.0",
42
+ "downloadjs": "^1.4.7",
43
+ "fast-deep-equal": "^3.1.3",
44
+ "fast-xml-parser": "^4.5.0",
45
+ "jszip": "^3.10.1",
46
+ "mathlive": "^0.104.0",
47
+ "mathml-to-latex": "^1.4.3",
48
+ "mathml2omml": "^0.5.0",
49
+ "orderedmap": "^2.1.1",
50
+ "pretty": "^2.0.0",
51
+ "prosemirror-model": "^1.25.0",
52
+ "prosemirror-schema-basic": "^1.2.4",
53
+ "prosemirror-tables": "^1.6.4",
54
+ "@vivliostyle/print": "^2.42.0"
55
+ },
56
+ "devDependencies": {
57
+ "jest": "^29.7.0"
58
+ }
59
+ }
package/schema.json ADDED
@@ -0,0 +1 @@
1
+ {"nodes":{"doc":{"content":"title part*","selectable":false,"allowGapCursor":false,"attrs":{"documentstyle":{"default":""},"tracked":{"default":false},"citationstyle":{"default":"apa"},"citationstyles":{"default":["american-anthropological-association","apa","chicago-author-date","chicago-note-bibliography","harvard-cite-them-right","modern-language-association","nature","oxford-university-press-humsoc"]},"language":{"default":"en-US"},"languages":{"default":["af-ZA","sq-AL","ar","ast","be","br","bg","ca","ca-ES-Valencia","zh-CN","da","nl","en-AU","en-CA","en-NZ","en-ZA","en-GB","en-US","eo","fr","gl","de-DE","de-AU","de-CH","el","he","is","it","ja","km","lt","ml","nb-NO","nn-NO","fa","pl","pt-BR","pt-PT","ro","ru","tr","sr-SP-Cy","sr-SP-Lt","sk","sl","es","sv","ta","tl","uk"]},"papersize":{"default":"A4"},"papersizes":{"default":["A4","US Letter"]},"footnote_marks":{"default":["strong","em","link"]},"footnote_elements":{"default":["paragraph","heading1","heading2","heading3","heading4","heading5","heading6","figure","ordered_list","bullet_list","horizontal_rule","equation","citation","cross_reference","blockquote","table"]},"bibliography_header":{"default":{}},"template":{"default":""},"import_id":{"default":""},"copyright":{"default":{"holder":false,"year":false,"freeToRead":true,"licenses":[]}},"code_categories":{"default":{"listing":{"counter":0,"enabled":true},"example":{"counter":0,"enabled":true},"snippet":{"counter":0,"enabled":false},"tutorial":{"counter":0,"enabled":false},"exercise":{"counter":0,"enabled":false},"exercise_solution":{"counter":0,"enabled":false}}},"code_languages":{"default":["javascript","python","java","cpp","c","csharp","php","ruby","go","rust","swift","kotlin","typescript","html","css","sql","bash","shell","r","matlab","scala","perl","lua","haskell","xml","json","yaml","markdown"]},"id_types":{"default":[]}},"parseDOM":[{"tag":"div.doc"}]},"richtext_part":{"content":"block+","group":"part","marks":"annotation track","isolating":true,"attrs":{"title":{"default":""},"id":{"default":""},"locking":{"default":false},"language":{"default":false},"optional":{"default":false},"hidden":{"default":false},"help":{"default":false},"initial":{"default":false},"deleted":{"default":false},"elements":{"default":["paragraph","heading1","heading2","heading3","heading4","heading5","heading6","code_block","figure","ordered_list","bullet_list","horizontal_rule","equation","citation","cross_reference","blockquote","footnote","table"]},"marks":{"default":["strong","em","link","anchor","sup","sub","code"]},"metadata":{"default":false}},"parseDOM":[{"tag":"div.doc-richtext"}]},"heading_part":{"content":"heading","group":"part","marks":"annotation track","isolating":true,"attrs":{"title":{"default":""},"id":{"default":""},"locking":{"default":false},"language":{"default":false},"optional":{"default":false},"hidden":{"default":false},"help":{"default":false},"initial":{"default":false},"deleted":{"default":false},"elements":{"default":["heading1"]},"marks":{"default":["strong","em","link","anchor","sup","sub","code"]},"metadata":{"default":false}},"parseDOM":[{"tag":"div.doc-heading"}]},"contributors_part":{"content":"contributor*","group":"part","marks":"annotation track","isolating":true,"attrs":{"title":{"default":""},"id":{"default":""},"locking":{"default":false},"language":{"default":false},"optional":{"default":false},"hidden":{"default":false},"help":{"default":false},"initial":{"default":false},"deleted":{"default":false},"item_title":{"default":"Contributor"},"metadata":{"default":false}},"parseDOM":[{"tag":"div.doc-contributors"}]},"tags_part":{"content":"tag*","group":"part","marks":"annotation track","isolating":true,"attrs":{"title":{"default":""},"id":{"default":""},"locking":{"default":false},"language":{"default":false},"optional":{"default":false},"hidden":{"default":false},"help":{"default":false},"initial":{"default":false},"deleted":{"default":false},"item_title":{"default":"Tag"},"metadata":{"default":false}},"parseDOM":[{"tag":"div.doc-tags"}]},"table_part":{"content":"table","group":"part","marks":"annotation track","isolating":true,"attrs":{"title":{"default":""},"id":{"default":""},"locking":{"default":false},"language":{"default":false},"optional":{"default":false},"hidden":{"default":false},"help":{"default":false},"initial":{"default":false},"deleted":{"default":false},"elements":{"default":["paragraph","heading1","heading2","heading3","heading4","heading5","heading6","code_block","figure","ordered_list","bullet_list","horizontal_rule","equation","citation","blockquote","footnote"]},"marks":{"default":["strong","em","link","anchor","sup","sub","code"]}},"parseDOM":[{"tag":"div.doc-table"}]},"table_of_contents":{"group":"part","marks":"annotation track","defining":true,"parseDOM":[{"tag":"div.table-of-contents"}],"attrs":{"title":{"default":"Table of Contents"},"id":{"default":"toc"},"optional":{"default":false},"hidden":{"default":false}}},"separator_part":{"marks":"annotation track","group":"part","defining":true,"attrs":{"id":{"default":"separator"}},"parseDOM":[{"tag":"hr.doc-separator_part"}]},"title":{"content":"text*","marks":"annotation track","group":"fixedpart","defining":true,"isolating":true,"attrs":{"id":{"default":"title"}},"parseDOM":[{"tag":"div.doc-title"}]},"contributor":{"inline":true,"draggable":true,"attrs":{"firstname":{"default":false},"lastname":{"default":false},"email":{"default":false},"institution":{"default":false},"id_type":{"default":false},"id_value":{"default":false}},"parseDOM":[{"tag":"span.contributor"}]},"tag":{"inline":true,"draggable":true,"attrs":{"tag":{"default":""}},"parseDOM":[{"tag":"span.tag"}]},"paragraph":{"group":"block","content":"inline*","attrs":{"track":{"default":[]}},"parseDOM":[{"tag":"p"}]},"blockquote":{"content":"block+","group":"block","attrs":{"track":{"default":[]}},"marks":"annotation","defining":true,"parseDOM":[{"tag":"blockquote"}]},"horizontal_rule":{"group":"block","attrs":{"track":{"default":[]}},"parseDOM":[{"tag":"hr"}]},"figure":{"inline":false,"allowGapCursor":false,"selectable":true,"group":"block","attrs":{"category":{"default":"none"},"caption":{"default":false},"id":{"default":false},"track":{"default":[]},"aligned":{"default":"center"},"width":{"default":"100"}},"content":"figure_caption image|figure_caption figure_equation|image figure_caption|figure_equation figure_caption","parseDOM":[{"tag":"figure"}]},"image":{"selectable":false,"draggable":false,"attrs":{"image":{"default":false}},"parseDOM":[{"tag":"img"}]},"figure_equation":{"selectable":false,"draggable":false,"attrs":{"equation":{"default":false}},"parseDOM":[{"tag":"div.figure-equation[data-equation]"}]},"figure_caption":{"isolating":true,"defining":true,"content":"inline*","parseDOM":[{"tag":"figcaption span.text"}]},"heading1":{"group":"block heading","content":"inline*","marks":"_","defining":true,"attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"h1"}]},"heading2":{"group":"block heading","content":"inline*","marks":"_","defining":true,"attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"h2"}]},"heading3":{"group":"block heading","content":"inline*","marks":"_","defining":true,"attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"h3"}]},"heading4":{"group":"block heading","content":"inline*","marks":"_","defining":true,"attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"h4"}]},"heading5":{"group":"block heading","content":"inline*","marks":"_","defining":true,"attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"h5"}]},"heading6":{"group":"block heading","content":"inline*","marks":"_","defining":true,"attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"h6"}]},"code_block":{"content":"text*","marks":"_","group":"block","code":true,"defining":true,"attrs":{"track":{"default":[]},"language":{"default":""},"category":{"default":""},"title":{"default":""},"id":{"default":""}},"parseDOM":[{"tag":"pre","preserveWhitespace":"full"}]},"text":{"group":"inline"},"hard_break":{"inline":true,"group":"inline","selectable":false,"parseDOM":[{"tag":"br"}]},"citation":{"inline":true,"group":"inline","attrs":{"format":{"default":"autocite"},"references":{"default":[]}},"parseDOM":[{"tag":"span.citation"}]},"equation":{"inline":true,"group":"inline","attrs":{"equation":{"default":""}},"parseDOM":[{"tag":"span.equation"}]},"cross_reference":{"inline":true,"group":"inline","attrs":{"id":{"default":false},"title":{"default":null}},"parseDOM":[{"tag":"span.cross-reference[data-id][data-title]"}]},"footnote":{"inline":true,"group":"inline","attrs":{"footnote":{"default":[{"type":"paragraph"}]}},"parseDOM":[{"tag":"span.footnote-marker[data-footnote]"}]},"ordered_list":{"group":"block","content":"list_item+","attrs":{"id":{"default":false},"order":{"default":1},"track":{"default":[]}},"parseDOM":[{"tag":"ol"}]},"bullet_list":{"group":"block","content":"list_item+","attrs":{"id":{"default":false},"track":{"default":[]}},"parseDOM":[{"tag":"ul"}]},"list_item":{"content":"block+","marks":"annotation","attrs":{"track":{"default":[]}},"parseDOM":[{"tag":"li"}],"defining":true},"table":{"inline":false,"group":"block","tableRole":"table","attrs":{"id":{"default":false},"track":{"default":[]},"width":{"default":"100"},"aligned":{"default":"center"},"layout":{"default":"fixed"},"category":{"default":"none"},"caption":{"default":false}},"content":"table_caption table_body","parseDOM":[{"tag":"table"}]},"table_caption":{"content":"inline*","parseDOM":[{"tag":"caption span.text"}]},"table_body":{"content":"table_row+","tableRole":"table","isolating":true,"parseDOM":[{"tag":"tbody"}]},"table_row":{"content":"(table_cell | table_header)+","tableRole":"row","parseDOM":[{"tag":"tr"}]},"table_cell":{"marks":"annotation","content":"block+","attrs":{"colspan":{"default":1,"validate":"number"},"rowspan":{"default":1,"validate":"number"},"colwidth":{"default":null}},"tableRole":"cell","isolating":true,"parseDOM":[{"tag":"td"}]},"table_header":{"marks":"annotation","content":"block+","attrs":{"colspan":{"default":1,"validate":"number"},"rowspan":{"default":1,"validate":"number"},"colwidth":{"default":null}},"tableRole":"header_cell","isolating":true,"parseDOM":[{"tag":"th"}]}},"marks":{"em":{"parseDOM":[{"tag":"i"},{"tag":"em"},{"style":"font-style=italic"},{"style":"font-style=normal"}]},"strong":{"parseDOM":[{"tag":"strong"},{"tag":"b"},{"style":"font-weight=400"},{"style":"font-weight"}]},"link":{"attrs":{"href":{},"title":{"default":""}},"inclusive":false,"parseDOM":[{"tag":"a[href]"}]},"underline":{"parseDOM":[{"tag":"span.underline"}]},"sup":{"parseDOM":[{"tag":"sup"}],"excludes":"sub"},"sub":{"parseDOM":[{"tag":"sub"}],"excludes":"sup"},"code":{"parseDOM":[{"tag":"code"}],"excludes":"strong em underline link sup sub"},"comment":{"attrs":{"id":{"default":false}},"inclusive":false,"excludes":"","group":"annotation","parseDOM":[{"tag":"span.comment[data-id]"}]},"annotation_tag":{"attrs":{"type":{"default":""},"key":{"default":""},"value":{"default":""}},"inclusive":false,"excludes":"","group":"annotation","parseDOM":[{"tag":"span.annotation-tag[data-type]"}]},"anchor":{"attrs":{"id":{"default":false}},"inclusive":false,"group":"annotation","parseDOM":[{"tag":"span.anchor[data-id]"}]},"deletion":{"attrs":{"user":{"default":0},"username":{"default":""},"date":{"default":0}},"inclusive":false,"group":"track","parseDOM":[{"tag":"span.deletion"}]},"insertion":{"attrs":{"user":{"default":0},"username":{"default":""},"date":{"default":0},"approved":{"default":true}},"inclusive":false,"group":"track","parseDOM":[{"tag":"span.insertion"},{"tag":"span.approved-insertion"}]},"format_change":{"attrs":{"user":{"default":0},"username":{"default":""},"date":{"default":0},"before":{"default":[]},"after":{"default":[]}},"inclusive":false,"group":"track","parseDOM":[{"tag":"span.format-change"}]}}}
@@ -0,0 +1,16 @@
1
+ // Generate a JSON serialization of the Fidus Writer document schema.
2
+ // This script is run by the package's prepare/prepublishOnly scripts.
3
+ import {writeFileSync} from "node:fs"
4
+ import {dirname, join} from "node:path"
5
+ import {fileURLToPath} from "node:url"
6
+
7
+ import {SchemaExport} from "../src/schema/export.js"
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url))
10
+ const outPath = join(__dirname, "..", "schema.json")
11
+
12
+ const exporter = new SchemaExport()
13
+ const json = exporter.init()
14
+
15
+ writeFileSync(outPath, json)
16
+ console.log(`Wrote schema.json (${json.length} bytes)`)
@@ -0,0 +1,92 @@
1
+ export const text = {
2
+ group: "inline"
3
+ }
4
+
5
+ export const literal = {
6
+ content: "inline*",
7
+ marks: "_",
8
+ parseDOM: [{tag: "div.literal"}],
9
+ toDOM() {
10
+ return [
11
+ "div",
12
+ {
13
+ class: "literal"
14
+ },
15
+ 0
16
+ ]
17
+ }
18
+ }
19
+
20
+ export const variable = {
21
+ inline: true,
22
+ group: "inline",
23
+ attrs: {
24
+ variable: {default: ""}
25
+ },
26
+ parseDOM: [
27
+ {
28
+ tag: "span[data-variable]",
29
+ getAttrs(dom) {
30
+ return {
31
+ variable: dom.getAttribute("data-variable")
32
+ }
33
+ }
34
+ }
35
+ ],
36
+ toDOM(node) {
37
+ return [
38
+ "span",
39
+ {"data-variable": node.attrs.variable},
40
+ node.attrs.variable
41
+ ]
42
+ }
43
+ }
44
+
45
+ export const sup = {
46
+ parseDOM: [
47
+ {tag: "sup"},
48
+ {style: "vertical-align", getAttrs: value => value == "super" && null}
49
+ ],
50
+ toDOM() {
51
+ return ["sup"]
52
+ }
53
+ }
54
+
55
+ export const sub = {
56
+ parseDOM: [
57
+ {tag: "sub"},
58
+ {style: "vertical-align", getAttrs: value => value == "sub" && null}
59
+ ],
60
+ toDOM() {
61
+ return ["sub"]
62
+ }
63
+ }
64
+
65
+ export const smallcaps = {
66
+ parseDOM: [
67
+ {tag: "span.smallcaps"},
68
+ {
69
+ style: "font-variant",
70
+ getAttrs: value => value == "small-caps" && null
71
+ }
72
+ ],
73
+ toDOM() {
74
+ return ["span", {class: "smallcaps"}]
75
+ }
76
+ }
77
+
78
+ //Currently unsupported
79
+
80
+ export const url = {
81
+ parseDOM: [{tag: "span.url"}],
82
+ toDOM() {
83
+ return ["span", {class: "url"}]
84
+ }
85
+ }
86
+
87
+ export const enquote = {
88
+ parseDOM: [{tag: "span.enquote"}],
89
+ toDOM() {
90
+ return ["span", {class: "enquote"}]
91
+ }
92
+ }
@@ -0,0 +1,139 @@
1
+ import {Schema} from "prosemirror-model"
2
+ import {marks} from "prosemirror-schema-basic"
3
+ import {smallcaps, sub, sup, text} from "./common.js"
4
+
5
+ const doc = {content: "cslbib"}
6
+
7
+ const cslbib = {
8
+ content: "cslentry*",
9
+ parseDOM: [{tag: "div.csl-bib-body"}],
10
+ toDOM(_node) {
11
+ return [
12
+ "div",
13
+ {
14
+ class: "csl-bib-body"
15
+ },
16
+ 0
17
+ ]
18
+ }
19
+ }
20
+
21
+ const cslentry = {
22
+ content: "block*",
23
+ parseDOM: [{tag: "div.csl-entry"}],
24
+ toDOM(_node) {
25
+ return [
26
+ "div",
27
+ {
28
+ class: "csl-entry"
29
+ },
30
+ 0
31
+ ]
32
+ }
33
+ }
34
+
35
+ // This block doesn't actually appear in the HTML output, but because the schema
36
+ // system doesn't allow for the mixing of inline and block content, it "imagines"
37
+ // that this block exists. This---rather than other blocks---is chosen, because
38
+ // it's the first in the list.
39
+ const cslinline = {
40
+ group: "block",
41
+ content: "text*",
42
+ marks: "_",
43
+ parseDOM: [{tag: "div.csl-inline"}],
44
+ toDOM(_node) {
45
+ return [
46
+ "div",
47
+ {
48
+ class: "csl-inline"
49
+ },
50
+ 0
51
+ ]
52
+ }
53
+ }
54
+
55
+ const cslblock = {
56
+ group: "block",
57
+ content: "text*",
58
+ marks: "_",
59
+ parseDOM: [{tag: "div.csl-block"}],
60
+ toDOM(_node) {
61
+ return [
62
+ "div",
63
+ {
64
+ class: "csl-block"
65
+ },
66
+ 0
67
+ ]
68
+ }
69
+ }
70
+
71
+ const cslleftmargin = {
72
+ group: "block",
73
+ content: "text*",
74
+ marks: "_",
75
+ parseDOM: [{tag: "div.csl-left-margin"}],
76
+ toDOM(_node) {
77
+ return [
78
+ "div",
79
+ {
80
+ class: "csl-left-margin"
81
+ },
82
+ 0
83
+ ]
84
+ }
85
+ }
86
+
87
+ const cslrightinline = {
88
+ group: "block",
89
+ content: "text*",
90
+ marks: "_",
91
+ parseDOM: [{tag: "div.csl-right-inline"}],
92
+ toDOM(_node) {
93
+ return [
94
+ "div",
95
+ {
96
+ class: "csl-right-inline"
97
+ },
98
+ 0
99
+ ]
100
+ }
101
+ }
102
+
103
+ const cslindent = {
104
+ group: "block",
105
+ content: "text*",
106
+ marks: "_",
107
+ parseDOM: [{tag: "div.csl-indent"}],
108
+ toDOM(_node) {
109
+ return [
110
+ "div",
111
+ {
112
+ class: "csl-indent"
113
+ },
114
+ 0
115
+ ]
116
+ }
117
+ }
118
+
119
+ // A schema to express the citeproc HTML bibliography output
120
+ export const cslBibSchema = new Schema({
121
+ nodes: {
122
+ doc,
123
+ cslbib,
124
+ cslentry,
125
+ cslinline,
126
+ cslblock,
127
+ cslleftmargin,
128
+ cslrightinline,
129
+ cslindent,
130
+ text
131
+ },
132
+ marks: {
133
+ em: marks.em,
134
+ strong: marks.strong,
135
+ smallcaps,
136
+ sup,
137
+ sub
138
+ }
139
+ })
@@ -0,0 +1,42 @@
1
+ /* Connects Fidus Writer citation system with citeproc */
2
+ import {CSLExporter} from "biblatex-csl-converter"
3
+
4
+ export class citeprocSys {
5
+ constructor(bibDB) {
6
+ this.bibDB = bibDB
7
+ this.abbreviations = {
8
+ default: {}
9
+ }
10
+ this.abbrevsname = "default"
11
+ // We cache values retrieved once.
12
+ this.items = {}
13
+ this.missingItems = []
14
+ }
15
+
16
+ retrieveItem(id) {
17
+ if (!this.items[id]) {
18
+ if (this.bibDB.db[id]) {
19
+ const cslGetter = new CSLExporter(this.bibDB.db, [id])
20
+ const cslOutput = cslGetter.parse()
21
+ Object.assign(this.items, cslOutput)
22
+ } else {
23
+ this.missingItems.push(id)
24
+ this.items[id] = {author: [{literal: ""}], type: "article", id}
25
+ }
26
+ }
27
+ return this.items[id]
28
+ }
29
+
30
+ getAbbreviation(_dummy, obj, _jurisdiction, vartype, key) {
31
+ try {
32
+ if (this.abbreviations[this.abbrevsname][vartype][key]) {
33
+ obj["default"][vartype][key] =
34
+ this.abbreviations[this.abbrevsname][vartype][key]
35
+ } else {
36
+ obj["default"][vartype][key] = ""
37
+ }
38
+ } catch (_error) {
39
+ // There is breakage here that needs investigating.
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,194 @@
1
+ import {escapeText} from "../common/index.js"
2
+ import {citeprocSys} from "./citeproc_sys.js"
3
+ /*
4
+ * Use CSL and bibDB to format all citations for the given prosemirror json citation nodes
5
+ */
6
+
7
+ export class FormatCitations {
8
+ constructor(
9
+ csl,
10
+ allCitationInfos,
11
+ citationStyle,
12
+ bibliographyHeader,
13
+ bibDB,
14
+ synchronous = false,
15
+ lang = "en-US"
16
+ ) {
17
+ this.csl = csl
18
+ this.allCitationInfos = allCitationInfos
19
+ this.citationStyle = citationStyle
20
+ this.bibliographyHeader = bibliographyHeader
21
+ this.bibDB = bibDB
22
+ this.synchronous = synchronous
23
+ this.lang = lang
24
+ }
25
+
26
+ init() {
27
+ this.bibliography = false
28
+ this.citations = []
29
+ this.bibFormats = []
30
+ this.citationTexts = []
31
+ this.citationType = ""
32
+ this.formatAllCitations()
33
+ return this.getFormattedCitations()
34
+ }
35
+
36
+ formatAllCitations() {
37
+ this.allCitationInfos.forEach(cInfo => {
38
+ this.bibFormats.push(cInfo.format)
39
+ this.citations.push({
40
+ citationItems: cInfo.references,
41
+ properties: {
42
+ noteIndex: this.bibFormats.length
43
+ }
44
+ })
45
+ })
46
+ }
47
+
48
+ get bibHTML() {
49
+ if (!this.bibliography || !this.bibliography[0].entry_ids.length) {
50
+ return ""
51
+ }
52
+ const bib = this.bibliography,
53
+ bibHTML = bib[0].bibstart + bib[1].join("") + bib[0].bibend
54
+ return `<h1 class="doc-bibliography-header">${escapeText(this.bibliographyHeader)}</h1>${bibHTML}`
55
+ }
56
+
57
+ // CSS
58
+ get bibCSS() {
59
+ if (!this.bibliography || !this.bibliography[0].entry_ids.length) {
60
+ return ""
61
+ }
62
+ const bibInfo = this.bibliography[0]
63
+ let css = "\n"
64
+ css += `.csl-entry {padding-bottom: ${bibInfo.entryspacing + 1}em;}\n`
65
+ css += `.csl-bib-body {line-height: ${bibInfo.linespacing};}\n`
66
+ if (bibInfo.hangingindent) {
67
+ css += `
68
+ .csl-entry {
69
+ text-indent: -0.5in;
70
+ padding-left: 0.5in;
71
+ }\n`
72
+ } else if (bibInfo["second-field-align"] === "margin") {
73
+ css += `
74
+ .csl-left-margin {
75
+ text-indent: -${bibInfo.maxoffset}ch;
76
+ width: ${bibInfo.maxoffset}ch;
77
+ }
78
+ `
79
+ } else if (bibInfo["second-field-align"] === "flush") {
80
+ css += `
81
+ .csl-left-margin {
82
+ width: ${bibInfo.maxoffset}ch;
83
+ }
84
+ `
85
+ }
86
+ return css
87
+ }
88
+
89
+ reloadCitations(missingItems) {
90
+ // Not all citations could be found in the database.
91
+ // Reload the database if possible, but don't cycle if no new matches are found.
92
+ if (!this.bibDB.getDB) {
93
+ return Promise.resolve()
94
+ }
95
+
96
+ return this.bibDB.getDB().then(() => {
97
+ if (missingItems.some(item => this.bibDB.db.hasOwnProperty(item))) {
98
+ return this.init()
99
+ } else {
100
+ return Promise.resolve()
101
+ }
102
+ })
103
+ }
104
+
105
+ getFormattedCitations() {
106
+ const citeprocConnector = new citeprocSys(this.bibDB)
107
+ if (this.synchronous) {
108
+ const citeprocInstance = this.csl.getEngineSync(
109
+ citeprocConnector,
110
+ this.citationStyle,
111
+ this.lang
112
+ )
113
+ if (!citeprocInstance) {
114
+ return false
115
+ }
116
+ this.process(citeprocInstance)
117
+ return true
118
+ } else {
119
+ return this.csl
120
+ .getEngine(citeprocConnector, this.citationStyle, this.lang)
121
+ .then(citeprocInstance => {
122
+ this.process(citeprocInstance)
123
+ if (citeprocConnector.missingItems.length > 0) {
124
+ return this.reloadCitations(
125
+ citeprocConnector.missingItems
126
+ )
127
+ } else {
128
+ return Promise.resolve()
129
+ }
130
+ })
131
+ }
132
+ }
133
+
134
+ process(citeprocInstance) {
135
+ const allIds = []
136
+ this.citations.forEach(cit =>
137
+ cit.citationItems.forEach(item => allIds.push(String(item.id)))
138
+ )
139
+ citeprocInstance.updateItems(allIds)
140
+
141
+ const inText = citeprocInstance.cslXml.dataObj.attrs.class === "in-text"
142
+ const len = this.citations.length
143
+ for (let i = 0; i < len; i++) {
144
+ const citation = this.citations[i],
145
+ citationTexts = citeprocInstance.appendCitationCluster(
146
+ citation,
147
+ true
148
+ )
149
+ if (inText && "textcite" == this.bibFormats[i]) {
150
+ const items = citation.citationItems
151
+ let newCiteText = ""
152
+
153
+ for (let j = 0; j < items.length; j++) {
154
+ const onlyNameOption = [
155
+ {
156
+ id: items[j].id,
157
+ "author-only": 1
158
+ }
159
+ ]
160
+
161
+ const onlyDateOption = [
162
+ {
163
+ id: items[j].id,
164
+ "suppress-author": 1
165
+ }
166
+ ]
167
+
168
+ if (items[j].locator) {
169
+ onlyDateOption[0].locator = items[j].locator
170
+ }
171
+
172
+ if (items[j].prefix) {
173
+ onlyDateOption[0].prefix = items[j].prefix
174
+ }
175
+
176
+ if (0 < j) {
177
+ newCiteText +=
178
+ citeprocInstance.citation.opt.layout_delimiter ||
179
+ "; "
180
+ }
181
+ newCiteText += `${citeprocInstance.makeCitationCluster(onlyNameOption)} ${citeprocInstance.makeCitationCluster(onlyDateOption)}`
182
+ }
183
+ citationTexts.find(citationText => citationText[0] === i)[1] =
184
+ newCiteText
185
+ }
186
+ citationTexts.forEach(
187
+ ([index, citationText]) =>
188
+ (this.citationTexts[index] = citationText)
189
+ )
190
+ }
191
+ this.citationType = citeprocInstance.cslXml.dataObj.attrs.class
192
+ this.bibliography = citeprocInstance.makeBibliography()
193
+ }
194
+ }
@@ -0,0 +1,10 @@
1
+ export const convertDataURIToBlob = dataURI => {
2
+ const byteString = atob(dataURI.split(",")[1])
3
+ const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]
4
+ const ab = new ArrayBuffer(byteString.length)
5
+ const ia = new Uint8Array(ab)
6
+ for (let i = 0; i < byteString.length; i++) {
7
+ ia[i] = byteString.charCodeAt(i)
8
+ }
9
+ return new Blob([ab], {type: mimeString})
10
+ }
@@ -0,0 +1,25 @@
1
+ import {escapeText} from "./text.js"
2
+
3
+ export const shortFileTitle = (title, path) => {
4
+ if (!path.length || path.endsWith("/")) {
5
+ return escapeText(title || gettext("Untitled"))
6
+ }
7
+ return escapeText(path.split("/").pop())
8
+ }
9
+
10
+ export const longFilePath = (title, path, prefix = "") => {
11
+ if (!path.length) {
12
+ path = "/"
13
+ }
14
+ if (path.endsWith("/")) {
15
+ path += title.replace(/\//g, "") || gettext("Untitled")
16
+ }
17
+ if (prefix.length) {
18
+ const pathParts = path.split("/")
19
+ const fileName = pathParts.pop()
20
+ pathParts.push(prefix + fileName)
21
+ path = pathParts.join("/")
22
+ }
23
+
24
+ return path
25
+ }
@@ -0,0 +1,12 @@
1
+ export {escapeText, unescapeText, noSpaceTmp} from "./text.js"
2
+ export {convertDataURIToBlob} from "./blob.js"
3
+ export {shortFileTitle, longFilePath} from "./file.js"
4
+ export {get, post, postJson} from "./network.js"
5
+
6
+ export const addAlert = (type, message) => {
7
+ if (typeof console !== "undefined") {
8
+ console.log(`[@fiduswriter/document alert][${type}] ${message}`)
9
+ }
10
+ }
11
+
12
+ export const deactivateWait = () => {}