@fiduswriter/document 0.1.0-alpha.3 → 0.1.0-alpha.4
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/README.md +22 -1
- package/dist/bibliography/common.d.ts +92 -0
- package/dist/bibliography/common.d.ts.map +1 -0
- package/dist/bibliography/common.js +85 -0
- package/dist/bibliography/common.js.map +1 -0
- package/dist/bibliography/csl_bib.d.ts +3 -0
- package/dist/bibliography/csl_bib.d.ts.map +1 -0
- package/dist/bibliography/csl_bib.js +131 -0
- package/dist/bibliography/csl_bib.js.map +1 -0
- package/dist/citations/citeproc_sys.d.ts +13 -0
- package/dist/citations/citeproc_sys.d.ts.map +1 -0
- package/dist/citations/citeproc_sys.js +43 -0
- package/dist/citations/citeproc_sys.js.map +1 -0
- package/dist/citations/format.d.ts +23 -0
- package/dist/citations/format.d.ts.map +1 -0
- package/dist/citations/format.js +161 -0
- package/dist/citations/format.js.map +1 -0
- package/dist/editor/e2ee/encryptor.d.ts +123 -0
- package/dist/editor/e2ee/encryptor.d.ts.map +1 -0
- package/dist/editor/e2ee/encryptor.js +201 -0
- package/dist/editor/e2ee/encryptor.js.map +1 -0
- package/dist/exporter/docx/citations.d.ts +21 -0
- package/dist/exporter/docx/citations.d.ts.map +1 -0
- package/dist/exporter/docx/citations.js +154 -0
- package/dist/exporter/docx/citations.js.map +1 -0
- package/dist/exporter/docx/comments.d.ts +18 -0
- package/dist/exporter/docx/comments.d.ts.map +1 -0
- package/dist/exporter/docx/comments.js +137 -0
- package/dist/exporter/docx/comments.js.map +1 -0
- package/dist/exporter/docx/footnotes.d.ts +42 -0
- package/dist/exporter/docx/footnotes.d.ts.map +1 -0
- package/dist/exporter/docx/footnotes.js +182 -0
- package/dist/exporter/docx/footnotes.js.map +1 -0
- package/dist/exporter/docx/images.d.ts +14 -0
- package/dist/exporter/docx/images.d.ts.map +1 -0
- package/dist/exporter/docx/images.js +86 -0
- package/dist/exporter/docx/images.js.map +1 -0
- package/dist/exporter/docx/index.d.ts +22 -0
- package/dist/exporter/docx/index.d.ts.map +1 -0
- package/dist/exporter/docx/index.js +107 -0
- package/dist/exporter/docx/index.js.map +1 -0
- package/dist/exporter/docx/lists.d.ts +33 -0
- package/dist/exporter/docx/lists.d.ts.map +1 -0
- package/dist/exporter/docx/lists.js +229 -0
- package/dist/exporter/docx/lists.js.map +1 -0
- package/dist/exporter/docx/math.d.ts +13 -0
- package/dist/exporter/docx/math.d.ts.map +1 -0
- package/dist/exporter/docx/math.js +42 -0
- package/dist/exporter/docx/math.js.map +1 -0
- package/dist/exporter/docx/metadata.d.ts +14 -0
- package/dist/exporter/docx/metadata.d.ts.map +1 -0
- package/dist/exporter/docx/metadata.js +239 -0
- package/dist/exporter/docx/metadata.js.map +1 -0
- package/dist/exporter/docx/rels.d.ts +25 -0
- package/dist/exporter/docx/rels.d.ts.map +1 -0
- package/dist/exporter/docx/rels.js +168 -0
- package/dist/exporter/docx/rels.js.map +1 -0
- package/dist/exporter/docx/render.d.ts +20 -0
- package/dist/exporter/docx/render.d.ts.map +1 -0
- package/dist/exporter/docx/render.js +774 -0
- package/dist/exporter/docx/render.js.map +1 -0
- package/dist/exporter/docx/richtext.d.ts +25 -0
- package/dist/exporter/docx/richtext.d.ts.map +1 -0
- package/dist/exporter/docx/richtext.js +1052 -0
- package/dist/exporter/docx/richtext.js.map +1 -0
- package/dist/exporter/docx/tables.d.ts +14 -0
- package/dist/exporter/docx/tables.d.ts.map +1 -0
- package/dist/exporter/docx/tables.js +109 -0
- package/dist/exporter/docx/tables.js.map +1 -0
- package/dist/exporter/docx/tools.d.ts +3 -0
- package/dist/exporter/docx/tools.d.ts.map +1 -0
- package/dist/exporter/docx/tools.js +48 -0
- package/dist/exporter/docx/tools.js.map +1 -0
- package/dist/exporter/epub/index.d.ts +11 -0
- package/dist/exporter/epub/index.d.ts.map +1 -0
- package/dist/exporter/epub/index.js +102 -0
- package/dist/exporter/epub/index.js.map +1 -0
- package/dist/exporter/epub/templates.d.ts +32 -0
- package/dist/exporter/epub/templates.d.ts.map +1 -0
- package/dist/exporter/epub/templates.js +95 -0
- package/dist/exporter/epub/templates.js.map +1 -0
- package/dist/exporter/epub/tools.d.ts +5 -0
- package/dist/exporter/epub/tools.d.ts.map +1 -0
- package/dist/exporter/epub/tools.js +81 -0
- package/dist/exporter/epub/tools.js.map +1 -0
- package/dist/exporter/html/citations.d.ts +27 -0
- package/dist/exporter/html/citations.d.ts.map +1 -0
- package/dist/exporter/html/citations.js +91 -0
- package/dist/exporter/html/citations.js.map +1 -0
- package/dist/exporter/html/convert.d.ts +100 -0
- package/dist/exporter/html/convert.d.ts.map +1 -0
- package/dist/exporter/html/convert.js +718 -0
- package/dist/exporter/html/convert.js.map +1 -0
- package/dist/exporter/html/index.d.ts +61 -0
- package/dist/exporter/html/index.d.ts.map +1 -0
- package/dist/exporter/html/index.js +134 -0
- package/dist/exporter/html/index.js.map +1 -0
- package/dist/exporter/html/templates.d.ts +10 -0
- package/dist/exporter/html/templates.d.ts.map +1 -0
- package/dist/exporter/html/templates.js +21 -0
- package/dist/exporter/html/templates.js.map +1 -0
- package/dist/exporter/html/tools.d.ts +2 -0
- package/dist/exporter/html/tools.d.ts.map +1 -0
- package/dist/exporter/html/tools.js +49 -0
- package/dist/exporter/html/tools.js.map +1 -0
- package/dist/exporter/jats/bibliography.d.ts +2 -0
- package/dist/exporter/jats/bibliography.d.ts.map +1 -0
- package/dist/exporter/jats/bibliography.js +153 -0
- package/dist/exporter/jats/bibliography.js.map +1 -0
- package/dist/exporter/jats/citations.d.ts +14 -0
- package/dist/exporter/jats/citations.d.ts.map +1 -0
- package/dist/exporter/jats/citations.js +83 -0
- package/dist/exporter/jats/citations.js.map +1 -0
- package/dist/exporter/jats/convert.d.ts +45 -0
- package/dist/exporter/jats/convert.d.ts.map +1 -0
- package/dist/exporter/jats/convert.js +799 -0
- package/dist/exporter/jats/convert.js.map +1 -0
- package/dist/exporter/jats/index.d.ts +19 -0
- package/dist/exporter/jats/index.d.ts.map +1 -0
- package/dist/exporter/jats/index.js +66 -0
- package/dist/exporter/jats/index.js.map +1 -0
- package/dist/exporter/jats/templates.d.ts +16 -0
- package/dist/exporter/jats/templates.d.ts.map +1 -0
- package/dist/exporter/jats/templates.js +25 -0
- package/dist/exporter/jats/templates.js.map +1 -0
- package/dist/exporter/jats/text.d.ts +3 -0
- package/dist/exporter/jats/text.d.ts.map +1 -0
- package/dist/exporter/jats/text.js +72 -0
- package/dist/exporter/jats/text.js.map +1 -0
- package/dist/exporter/latex/convert.d.ts +27 -0
- package/dist/exporter/latex/convert.d.ts.map +1 -0
- package/dist/exporter/latex/convert.js +865 -0
- package/dist/exporter/latex/convert.js.map +1 -0
- package/dist/exporter/latex/escape_latex.d.ts +2 -0
- package/dist/exporter/latex/escape_latex.d.ts.map +1 -0
- package/dist/exporter/latex/escape_latex.js +20 -0
- package/dist/exporter/latex/escape_latex.js.map +1 -0
- package/dist/exporter/latex/index.d.ts +23 -0
- package/dist/exporter/latex/index.d.ts.map +1 -0
- package/dist/exporter/latex/index.js +57 -0
- package/dist/exporter/latex/index.js.map +1 -0
- package/dist/exporter/latex/readme.d.ts +2 -0
- package/dist/exporter/latex/readme.d.ts.map +1 -0
- package/dist/exporter/latex/readme.js +23 -0
- package/dist/exporter/latex/readme.js.map +1 -0
- package/dist/exporter/native/shrink.d.ts +21 -0
- package/dist/exporter/native/shrink.d.ts.map +1 -0
- package/dist/exporter/native/shrink.js +115 -0
- package/dist/exporter/native/shrink.js.map +1 -0
- package/dist/exporter/odt/citations.d.ts +18 -0
- package/dist/exporter/odt/citations.d.ts.map +1 -0
- package/dist/exporter/odt/citations.js +87 -0
- package/dist/exporter/odt/citations.js.map +1 -0
- package/dist/exporter/odt/footnotes.d.ts +25 -0
- package/dist/exporter/odt/footnotes.d.ts.map +1 -0
- package/dist/exporter/odt/footnotes.js +112 -0
- package/dist/exporter/odt/footnotes.js.map +1 -0
- package/dist/exporter/odt/images.d.ts +13 -0
- package/dist/exporter/odt/images.d.ts.map +1 -0
- package/dist/exporter/odt/images.js +98 -0
- package/dist/exporter/odt/images.js.map +1 -0
- package/dist/exporter/odt/index.d.ts +23 -0
- package/dist/exporter/odt/index.d.ts.map +1 -0
- package/dist/exporter/odt/index.js +99 -0
- package/dist/exporter/odt/index.js.map +1 -0
- package/dist/exporter/odt/math.d.ts +13 -0
- package/dist/exporter/odt/math.d.ts.map +1 -0
- package/dist/exporter/odt/math.js +48 -0
- package/dist/exporter/odt/math.js.map +1 -0
- package/dist/exporter/odt/metadata.d.ts +14 -0
- package/dist/exporter/odt/metadata.d.ts.map +1 -0
- package/dist/exporter/odt/metadata.js +203 -0
- package/dist/exporter/odt/metadata.js.map +1 -0
- package/dist/exporter/odt/render.d.ts +24 -0
- package/dist/exporter/odt/render.d.ts.map +1 -0
- package/dist/exporter/odt/render.js +644 -0
- package/dist/exporter/odt/render.js.map +1 -0
- package/dist/exporter/odt/richtext.d.ts +22 -0
- package/dist/exporter/odt/richtext.d.ts.map +1 -0
- package/dist/exporter/odt/richtext.js +728 -0
- package/dist/exporter/odt/richtext.js.map +1 -0
- package/dist/exporter/odt/styles.d.ts +33 -0
- package/dist/exporter/odt/styles.d.ts.map +1 -0
- package/dist/exporter/odt/styles.js +348 -0
- package/dist/exporter/odt/styles.js.map +1 -0
- package/dist/exporter/odt/track.d.ts +11 -0
- package/dist/exporter/odt/track.d.ts.map +1 -0
- package/dist/exporter/odt/track.js +59 -0
- package/dist/exporter/odt/track.js.map +1 -0
- package/dist/exporter/pandoc/citations.d.ts +17 -0
- package/dist/exporter/pandoc/citations.d.ts.map +1 -0
- package/dist/exporter/pandoc/citations.js +85 -0
- package/dist/exporter/pandoc/citations.js.map +1 -0
- package/dist/exporter/pandoc/convert.d.ts +38 -0
- package/dist/exporter/pandoc/convert.d.ts.map +1 -0
- package/dist/exporter/pandoc/convert.js +881 -0
- package/dist/exporter/pandoc/convert.js.map +1 -0
- package/dist/exporter/pandoc/index.d.ts +38 -0
- package/dist/exporter/pandoc/index.d.ts.map +1 -0
- package/dist/exporter/pandoc/index.js +67 -0
- package/dist/exporter/pandoc/index.js.map +1 -0
- package/dist/exporter/pandoc/readme.d.ts +2 -0
- package/dist/exporter/pandoc/readme.d.ts.map +1 -0
- package/dist/exporter/pandoc/readme.js +9 -0
- package/dist/exporter/pandoc/readme.js.map +1 -0
- package/dist/exporter/pandoc/tools.d.ts +6 -0
- package/dist/exporter/pandoc/tools.d.ts.map +1 -0
- package/dist/exporter/pandoc/tools.js +52 -0
- package/dist/exporter/pandoc/tools.js.map +1 -0
- package/dist/exporter/print/index.d.ts +9 -0
- package/dist/exporter/print/index.d.ts.map +1 -0
- package/dist/exporter/print/index.js +140 -0
- package/dist/exporter/print/index.js.map +1 -0
- package/dist/exporter/tools/doc_content.d.ts +7 -0
- package/dist/exporter/tools/doc_content.d.ts.map +1 -0
- package/dist/exporter/tools/doc_content.js +129 -0
- package/dist/exporter/tools/doc_content.js.map +1 -0
- package/dist/exporter/tools/file.d.ts +2 -0
- package/dist/exporter/tools/file.d.ts.map +1 -0
- package/dist/exporter/tools/file.js +10 -0
- package/dist/exporter/tools/file.js.map +1 -0
- package/dist/exporter/tools/json.d.ts +7 -0
- package/dist/exporter/tools/json.d.ts.map +1 -0
- package/dist/exporter/tools/json.js +82 -0
- package/dist/exporter/tools/json.js.map +1 -0
- package/dist/exporter/tools/svg.d.ts +2 -0
- package/dist/exporter/tools/svg.d.ts.map +1 -0
- package/dist/exporter/tools/svg.js +26 -0
- package/dist/exporter/tools/svg.js.map +1 -0
- package/dist/exporter/tools/xml.d.ts +41 -0
- package/dist/exporter/tools/xml.d.ts.map +1 -0
- package/dist/exporter/tools/xml.js +440 -0
- package/dist/exporter/tools/xml.js.map +1 -0
- package/dist/exporter/tools/xml_zip.d.ts +20 -0
- package/dist/exporter/tools/xml_zip.d.ts.map +1 -0
- package/dist/exporter/tools/xml_zip.js +86 -0
- package/dist/exporter/tools/xml_zip.js.map +1 -0
- package/dist/exporter/tools/zip.d.ts +21 -0
- package/dist/exporter/tools/zip.d.ts.map +1 -0
- package/dist/exporter/tools/zip.js +71 -0
- package/dist/exporter/tools/zip.js.map +1 -0
- package/dist/exporter/tools/zotero_csl.d.ts +10 -0
- package/dist/exporter/tools/zotero_csl.d.ts.map +1 -0
- package/dist/exporter/tools/zotero_csl.js +78 -0
- package/dist/exporter/tools/zotero_csl.js.map +1 -0
- package/dist/importer/citations.d.ts +25 -0
- package/dist/importer/citations.d.ts.map +1 -0
- package/dist/importer/citations.js +116 -0
- package/dist/importer/citations.js.map +1 -0
- package/dist/importer/docx/citations.d.ts +65 -0
- package/dist/importer/docx/citations.d.ts.map +1 -0
- package/dist/importer/docx/citations.js +106 -0
- package/dist/importer/docx/citations.js.map +1 -0
- package/dist/importer/docx/convert.d.ts +228 -0
- package/dist/importer/docx/convert.d.ts.map +1 -0
- package/dist/importer/docx/convert.js +1226 -0
- package/dist/importer/docx/convert.js.map +1 -0
- package/dist/importer/docx/helpers.d.ts +2 -0
- package/dist/importer/docx/helpers.d.ts.map +1 -0
- package/dist/importer/docx/helpers.js +10 -0
- package/dist/importer/docx/helpers.js.map +1 -0
- package/dist/importer/docx/omml2mathml.d.ts +7 -0
- package/dist/importer/docx/omml2mathml.d.ts.map +1 -0
- package/dist/importer/docx/omml2mathml.js +1239 -0
- package/dist/importer/docx/omml2mathml.js.map +1 -0
- package/dist/importer/docx/parse.d.ts +205 -0
- package/dist/importer/docx/parse.d.ts.map +1 -0
- package/dist/importer/docx/parse.js +663 -0
- package/dist/importer/docx/parse.js.map +1 -0
- package/dist/importer/native/get_images.d.ts +11 -0
- package/dist/importer/native/get_images.d.ts.map +1 -0
- package/dist/importer/native/get_images.js +64 -0
- package/dist/importer/native/get_images.js.map +1 -0
- package/dist/importer/native/update.d.ts +6 -0
- package/dist/importer/native/update.d.ts.map +1 -0
- package/dist/importer/native/update.js +26 -0
- package/dist/importer/native/update.js.map +1 -0
- package/dist/importer/odt/citations.d.ts +47 -0
- package/dist/importer/odt/citations.d.ts.map +1 -0
- package/dist/importer/odt/citations.js +79 -0
- package/dist/importer/odt/citations.js.map +1 -0
- package/dist/importer/odt/convert.d.ts +330 -0
- package/dist/importer/odt/convert.d.ts.map +1 -0
- package/dist/importer/odt/convert.js +1506 -0
- package/dist/importer/odt/convert.js.map +1 -0
- package/dist/importer/pandoc/convert.d.ts +84 -0
- package/dist/importer/pandoc/convert.d.ts.map +1 -0
- package/dist/importer/pandoc/convert.js +777 -0
- package/dist/importer/pandoc/convert.js.map +1 -0
- package/dist/importer/pandoc/helpers.d.ts +4 -0
- package/dist/importer/pandoc/helpers.d.ts.map +1 -0
- package/dist/importer/pandoc/helpers.js +75 -0
- package/dist/importer/pandoc/helpers.js.map +1 -0
- package/dist/importer/zip_analyzer.d.ts +25 -0
- package/dist/importer/zip_analyzer.d.ts.map +1 -0
- package/dist/importer/zip_analyzer.js +84 -0
- package/dist/importer/zip_analyzer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/mathlive/opf_includes.d.ts +2 -0
- package/dist/mathlive/opf_includes.d.ts.map +1 -0
- package/dist/mathlive/opf_includes.js +25 -0
- package/dist/mathlive/opf_includes.js.map +1 -0
- package/dist/schema/common/annotate.d.ts +59 -0
- package/dist/schema/common/annotate.d.ts.map +1 -0
- package/dist/schema/common/annotate.js +75 -0
- package/dist/schema/common/annotate.js.map +1 -0
- package/dist/schema/common/base.d.ts +109 -0
- package/dist/schema/common/base.d.ts.map +1 -0
- package/dist/schema/common/base.js +109 -0
- package/dist/schema/common/base.js.map +1 -0
- package/dist/schema/common/citation.d.ts +29 -0
- package/dist/schema/common/citation.d.ts.map +1 -0
- package/dist/schema/common/citation.js +62 -0
- package/dist/schema/common/citation.js.map +1 -0
- package/dist/schema/common/equation.d.ts +18 -0
- package/dist/schema/common/equation.d.ts.map +1 -0
- package/dist/schema/common/equation.js +32 -0
- package/dist/schema/common/equation.js.map +1 -0
- package/dist/schema/common/figure.d.ts +108 -0
- package/dist/schema/common/figure.d.ts.map +1 -0
- package/dist/schema/common/figure.js +176 -0
- package/dist/schema/common/figure.js.map +1 -0
- package/dist/schema/common/heading.d.ts +33 -0
- package/dist/schema/common/heading.d.ts.map +1 -0
- package/dist/schema/common/heading.js +41 -0
- package/dist/schema/common/heading.js.map +1 -0
- package/dist/schema/common/index.d.ts +11 -0
- package/dist/schema/common/index.d.ts.map +1 -0
- package/dist/schema/common/index.js +11 -0
- package/dist/schema/common/index.js.map +1 -0
- package/dist/schema/common/list.d.ts +83 -0
- package/dist/schema/common/list.d.ts.map +1 -0
- package/dist/schema/common/list.js +92 -0
- package/dist/schema/common/list.js.map +1 -0
- package/dist/schema/common/reference.d.ts +78 -0
- package/dist/schema/common/reference.d.ts.map +1 -0
- package/dist/schema/common/reference.js +97 -0
- package/dist/schema/common/reference.js.map +1 -0
- package/dist/schema/common/table.d.ts +92 -0
- package/dist/schema/common/table.d.ts.map +1 -0
- package/dist/schema/common/table.js +85 -0
- package/dist/schema/common/table.js.map +1 -0
- package/dist/schema/common/track.d.ts +131 -0
- package/dist/schema/common/track.d.ts.map +1 -0
- package/dist/schema/common/track.js +184 -0
- package/dist/schema/common/track.js.map +1 -0
- package/dist/schema/const.d.ts +3 -0
- package/dist/schema/const.d.ts.map +1 -0
- package/{src → dist}/schema/const.js +3 -3
- package/dist/schema/const.js.map +1 -0
- package/dist/schema/convert.d.ts +3 -0
- package/dist/schema/convert.d.ts.map +1 -0
- package/dist/schema/convert.js +1215 -0
- package/dist/schema/convert.js.map +1 -0
- package/dist/schema/document/content.d.ts +137 -0
- package/dist/schema/document/content.d.ts.map +1 -0
- package/dist/schema/document/content.js +177 -0
- package/dist/schema/document/content.js.map +1 -0
- package/dist/schema/document/index.d.ts +879 -0
- package/dist/schema/document/index.d.ts.map +1 -0
- package/dist/schema/document/index.js +68 -0
- package/dist/schema/document/index.js.map +1 -0
- package/dist/schema/document/structure.d.ts +273 -0
- package/dist/schema/document/structure.d.ts.map +1 -0
- package/dist/schema/document/structure.js +445 -0
- package/dist/schema/document/structure.js.map +1 -0
- package/dist/schema/export.d.ts +880 -0
- package/dist/schema/export.d.ts.map +1 -0
- package/dist/schema/export.js +16 -0
- package/dist/schema/export.js.map +1 -0
- package/dist/schema/footnotes.d.ts +499 -0
- package/dist/schema/footnotes.d.ts.map +1 -0
- package/dist/schema/footnotes.js +88 -0
- package/dist/schema/footnotes.js.map +1 -0
- package/dist/schema/footnotes_convert.d.ts +5 -0
- package/dist/schema/footnotes_convert.d.ts.map +1 -0
- package/dist/schema/footnotes_convert.js +26 -0
- package/dist/schema/footnotes_convert.js.map +1 -0
- package/dist/schema/i18n.d.ts +586 -0
- package/dist/schema/i18n.d.ts.map +1 -0
- package/dist/schema/i18n.js +585 -0
- package/dist/schema/i18n.js.map +1 -0
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +6 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/mini_json.d.ts +5 -0
- package/dist/schema/mini_json.d.ts.map +1 -0
- package/dist/schema/mini_json.js +50 -0
- package/dist/schema/mini_json.js.map +1 -0
- package/dist/schema/text.d.ts +2 -0
- package/dist/schema/text.d.ts.map +1 -0
- package/dist/schema/text.js +23 -0
- package/dist/schema/text.js.map +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -16
- package/scripts/export-schema.js +1 -1
- package/src/exporter/tools/{file.js → file.ts} +1 -1
- package/src/exporter/tools/{json.js → json.ts} +30 -19
- package/src/global.d.ts +11 -0
- package/src/schema/const.ts +58 -0
- package/src/types.ts +136 -0
- package/jest.config.js +0 -24
- /package/src/{index.js → index.ts} +0 -0
|
@@ -0,0 +1,774 @@
|
|
|
1
|
+
import { escapeText } from "fwtoolkit";
|
|
2
|
+
import { BIBLIOGRAPHY_HEADERS } from "../../schema/i18n.js";
|
|
3
|
+
import { textContent } from "../tools/doc_content.js";
|
|
4
|
+
import { xmlDOM } from "../tools/xml.js";
|
|
5
|
+
export class DOCXExporterRender {
|
|
6
|
+
constructor(xml) {
|
|
7
|
+
this.xml = xml;
|
|
8
|
+
this.filePath = false; // "word/document.xml" or "word/document2.xml" in some cases
|
|
9
|
+
this.ctXML = false;
|
|
10
|
+
this.text = false;
|
|
11
|
+
}
|
|
12
|
+
init() {
|
|
13
|
+
return this.xml
|
|
14
|
+
.getXml("[Content_Types].xml")
|
|
15
|
+
.then(ctXML => {
|
|
16
|
+
this.ctXML = ctXML;
|
|
17
|
+
const documentOverride = this.ctXML.query("Override", {
|
|
18
|
+
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
|
|
19
|
+
});
|
|
20
|
+
this.filePath = documentOverride
|
|
21
|
+
.getAttribute("PartName")
|
|
22
|
+
.slice(1);
|
|
23
|
+
return this.xml.getXml(this.filePath);
|
|
24
|
+
})
|
|
25
|
+
.then(xml => {
|
|
26
|
+
this.text = xml;
|
|
27
|
+
// Ensure we support the three latest docx feature sets:
|
|
28
|
+
// wp14 (drawing 2010), w14 (word 2010), w15 (word 2012)
|
|
29
|
+
const documentEl = this.text.query("w:document");
|
|
30
|
+
if (!documentEl.getAttribute("xmlns:wp14")) {
|
|
31
|
+
documentEl.setAttribute("xmlns:wp14", "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
|
|
32
|
+
}
|
|
33
|
+
if (!documentEl.getAttribute("xmlns:w14")) {
|
|
34
|
+
documentEl.setAttribute("xmlns:w14", "http://schemas.microsoft.com/office/word/2010/wordml");
|
|
35
|
+
}
|
|
36
|
+
if (!documentEl.getAttribute("xmlns:w15")) {
|
|
37
|
+
documentEl.setAttribute("xmlns:w15", "http://schemas.microsoft.com/office/word/2012/wordml");
|
|
38
|
+
}
|
|
39
|
+
const ignorable = [
|
|
40
|
+
...new Set(["w14", "wp14", "w15"].concat(documentEl
|
|
41
|
+
.getAttribute("mc:Ignorable", "")
|
|
42
|
+
.split(" ")
|
|
43
|
+
.filter(item => item.length)))
|
|
44
|
+
];
|
|
45
|
+
documentEl.setAttribute("mc:Ignorable", ignorable.join(" "));
|
|
46
|
+
return Promise.resolve();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
parseStructuredTags(block, tag) {
|
|
50
|
+
let blockText = block.textContent;
|
|
51
|
+
const tagName = tag.title;
|
|
52
|
+
// Check for BEGIN...END loops (with optional limit)
|
|
53
|
+
const beginStartRegex = new RegExp(`\\{BEGIN_${tagName}(?::limit=(\\d+))?\\}`);
|
|
54
|
+
const beginStartMatch = blockText.match(beginStartRegex);
|
|
55
|
+
if (beginStartMatch &&
|
|
56
|
+
tag.content &&
|
|
57
|
+
Array.isArray(tag.content) &&
|
|
58
|
+
tag.content.length > 0) {
|
|
59
|
+
const limit = beginStartMatch[1]
|
|
60
|
+
? parseInt(beginStartMatch[1])
|
|
61
|
+
: null;
|
|
62
|
+
const beginStart = beginStartMatch.index;
|
|
63
|
+
const beginEnd = beginStart + beginStartMatch[0].length;
|
|
64
|
+
// Find matching {END_tag}
|
|
65
|
+
const endTag = `{END_${tagName}}`;
|
|
66
|
+
const endPos = blockText.indexOf(endTag, beginEnd);
|
|
67
|
+
if (endPos === -1) {
|
|
68
|
+
console.warn(`Missing ${endTag} for ${tagName}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const templateXml = blockText.slice(beginEnd, endPos);
|
|
72
|
+
const replacementXml = this.processLoop(templateXml, tag.content, tagName, limit);
|
|
73
|
+
const beforeText = blockText.slice(0, beginStart);
|
|
74
|
+
const afterText = blockText.slice(endPos + endTag.length);
|
|
75
|
+
const fullReplacement = beforeText + replacementXml + afterText;
|
|
76
|
+
block.innerXML = fullReplacement;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Check for IF...ELIF...ELSE...ENDIF conditionals
|
|
80
|
+
blockText = this.processConditionals(blockText, {
|
|
81
|
+
tagName,
|
|
82
|
+
count: tag.content ? tag.content.length : 0,
|
|
83
|
+
content: tag.content || []
|
|
84
|
+
});
|
|
85
|
+
if (blockText !== block.textContent) {
|
|
86
|
+
block.innerXML = blockText;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
processLoop(templateXml, items, tagName, limit = null) {
|
|
90
|
+
const effectiveItems = limit !== null ? items.slice(0, limit) : items;
|
|
91
|
+
const results = [];
|
|
92
|
+
effectiveItems.forEach((item, index) => {
|
|
93
|
+
const loopCtx = {
|
|
94
|
+
count: items.length,
|
|
95
|
+
index: index,
|
|
96
|
+
first: index === 0,
|
|
97
|
+
last: index === effectiveItems.length - 1,
|
|
98
|
+
item: item,
|
|
99
|
+
content: [item],
|
|
100
|
+
odd: index % 2 === 1,
|
|
101
|
+
even: index % 2 === 0
|
|
102
|
+
};
|
|
103
|
+
let itemXml = templateXml;
|
|
104
|
+
// Replace field placeholders
|
|
105
|
+
if (typeof item === "string") {
|
|
106
|
+
itemXml = itemXml.replace(/%tag/g, escapeText(item));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
itemXml = itemXml
|
|
110
|
+
.replace(/\{?%firstname\}?/g, escapeText(item.firstname || ""))
|
|
111
|
+
.replace(/\{?%lastname\}?/g, escapeText(item.lastname || ""))
|
|
112
|
+
.replace(/\{?%institution\}?/g, escapeText(item.institution || ""))
|
|
113
|
+
.replace(/\{?%email\}?/g, escapeText(item.email || ""))
|
|
114
|
+
.replace(/\{?%id_type\}?/g, escapeText(item.id_type || ""))
|
|
115
|
+
.replace(/\{?%id_value\}?/g, escapeText(item.id_value || ""));
|
|
116
|
+
}
|
|
117
|
+
// Handle conditionals inside the loop
|
|
118
|
+
itemXml = this.processConditionals(itemXml, { tagName, ...loopCtx });
|
|
119
|
+
// Handle special delimiters for DOCX
|
|
120
|
+
itemXml = itemXml.replace(/\\n/g, "<w:br/>");
|
|
121
|
+
itemXml = itemXml.replace(/\\p/g, "</w:p><w:p>");
|
|
122
|
+
results.push(itemXml);
|
|
123
|
+
});
|
|
124
|
+
return results.join("");
|
|
125
|
+
}
|
|
126
|
+
processConditionals(text, ctx) {
|
|
127
|
+
let result = text;
|
|
128
|
+
let changed = true;
|
|
129
|
+
while (changed) {
|
|
130
|
+
changed = false;
|
|
131
|
+
const ifStart = result.indexOf("{IF(");
|
|
132
|
+
if (ifStart === -1) {
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
let depth = 1;
|
|
136
|
+
let pos = ifStart + 4; // skip {IF(
|
|
137
|
+
// Find the closing ) of the IF expression
|
|
138
|
+
while (pos < result.length && result[pos] !== ")") {
|
|
139
|
+
pos++;
|
|
140
|
+
}
|
|
141
|
+
if (pos >= result.length) {
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
pos++; // skip )
|
|
145
|
+
// Now scan for matching {ENDIF}
|
|
146
|
+
while (pos < result.length && depth > 0) {
|
|
147
|
+
if (result.substr(pos, 4) === "{IF(") {
|
|
148
|
+
depth++;
|
|
149
|
+
pos += 4;
|
|
150
|
+
}
|
|
151
|
+
else if (result.substr(pos, 7) === "{ENDIF}") {
|
|
152
|
+
depth--;
|
|
153
|
+
if (depth > 0) {
|
|
154
|
+
pos += 7;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
pos++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (depth === 0) {
|
|
162
|
+
const exprEnd = result.indexOf(")", ifStart + 4);
|
|
163
|
+
const ifExpr = result.slice(ifStart + 4, exprEnd);
|
|
164
|
+
// Skip the closing } of {IF(...)} if present
|
|
165
|
+
let innerStart = exprEnd + 1;
|
|
166
|
+
if (result[innerStart] === "}") {
|
|
167
|
+
innerStart++;
|
|
168
|
+
}
|
|
169
|
+
const innerContent = result.slice(innerStart, pos);
|
|
170
|
+
const conditions = [];
|
|
171
|
+
conditions.push({ expr: ifExpr, content: "" });
|
|
172
|
+
const remaining = innerContent;
|
|
173
|
+
let lastIndex = 0;
|
|
174
|
+
const elifRegex = /\{ELIF\(([^)]+)\)\}/g;
|
|
175
|
+
let elifMatch;
|
|
176
|
+
while ((elifMatch = elifRegex.exec(remaining)) !== null) {
|
|
177
|
+
conditions[conditions.length - 1].content = remaining.slice(lastIndex, elifMatch.index);
|
|
178
|
+
conditions.push({ expr: elifMatch[1], content: "" });
|
|
179
|
+
lastIndex = elifMatch.index + elifMatch[0].length;
|
|
180
|
+
}
|
|
181
|
+
const elseMatch = remaining.slice(lastIndex).match(/\{ELSE\}/);
|
|
182
|
+
if (elseMatch) {
|
|
183
|
+
conditions[conditions.length - 1].content = remaining.slice(lastIndex, lastIndex + elseMatch.index);
|
|
184
|
+
conditions.push({
|
|
185
|
+
expr: null,
|
|
186
|
+
content: remaining.slice(lastIndex + elseMatch.index + elseMatch[0].length)
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
conditions[conditions.length - 1].content =
|
|
191
|
+
remaining.slice(lastIndex);
|
|
192
|
+
}
|
|
193
|
+
let replacement = "";
|
|
194
|
+
for (const cond of conditions) {
|
|
195
|
+
if (cond.expr === null ||
|
|
196
|
+
this.evaluateExpression(cond.expr, ctx)) {
|
|
197
|
+
replacement = cond.content;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
result =
|
|
202
|
+
result.slice(0, ifStart) +
|
|
203
|
+
replacement +
|
|
204
|
+
result.slice(pos + 7);
|
|
205
|
+
changed = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
evaluateExpression(expr, ctx) {
|
|
211
|
+
try {
|
|
212
|
+
// Allow explicit tag name references (e.g., authors.count -> ctx.count)
|
|
213
|
+
if (ctx.tagName) {
|
|
214
|
+
const safeTagName = ctx.tagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
215
|
+
expr = expr.replace(new RegExp(`\\b${safeTagName}\\b`, "g"), "ctx");
|
|
216
|
+
}
|
|
217
|
+
// Replace ctx.property accesses with literal values
|
|
218
|
+
const evalExpr = expr.replace(/ctx\.(\w+)(?:\.(\w+))?(?:\[(\d+)\])?/g, (_match, p1, p2, p3) => {
|
|
219
|
+
let val = ctx[p1];
|
|
220
|
+
if (p2 !== undefined && val !== undefined) {
|
|
221
|
+
val = val[p2];
|
|
222
|
+
}
|
|
223
|
+
if (p3 !== undefined && val !== undefined) {
|
|
224
|
+
val = val[parseInt(p3)];
|
|
225
|
+
}
|
|
226
|
+
return JSON.stringify(val);
|
|
227
|
+
});
|
|
228
|
+
// Remove string literals before character check
|
|
229
|
+
const safeExpr = evalExpr.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, '""');
|
|
230
|
+
// Check for unknown identifiers
|
|
231
|
+
const bareIdRegex = /\b[a-zA-Z_]\w*\b/g;
|
|
232
|
+
const allowed = ["true", "false", "null", "undefined"];
|
|
233
|
+
let m;
|
|
234
|
+
while ((m = bareIdRegex.exec(safeExpr)) !== null) {
|
|
235
|
+
if (!allowed.includes(m[0])) {
|
|
236
|
+
console.warn("Unknown identifier in expression:", m[0], "expression:", expr);
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Check for unsafe characters
|
|
241
|
+
if (/[^ \t\n\r0-9a-zA-Z_\.\+\-*\/%==<>!&|()\[\]]/.test(safeExpr)) {
|
|
242
|
+
console.warn("Unsafe characters in expression:", expr);
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
return new Function(`return (${evalExpr})`)();
|
|
246
|
+
}
|
|
247
|
+
catch (e) {
|
|
248
|
+
console.warn("Error evaluating expression:", expr, e);
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
processMultiBlockStructuredTags(blocks, tags) {
|
|
253
|
+
const tagMap = {};
|
|
254
|
+
tags.forEach(tag => {
|
|
255
|
+
if (tag.title) {
|
|
256
|
+
tagMap[tag.title] = tag;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
// Process from end to start to avoid index shifting issues
|
|
260
|
+
for (let i = blocks.length - 1; i >= 0; i--) {
|
|
261
|
+
const block = blocks[i];
|
|
262
|
+
const text = block.textContent;
|
|
263
|
+
// Check for multi-block BEGIN...END loops
|
|
264
|
+
for (const tag of tags) {
|
|
265
|
+
if (!tag.title || !tag.content || !Array.isArray(tag.content)) {
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
const tagName = tag.title;
|
|
269
|
+
const beginRegex = new RegExp(`\\{BEGIN_${tagName}(?::limit=(\\d+))?\\}`);
|
|
270
|
+
const beginMatch = text.match(beginRegex);
|
|
271
|
+
if (!beginMatch) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
// Find matching END in a later block
|
|
275
|
+
let endIndex = -1;
|
|
276
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
277
|
+
if (blocks[j].textContent.includes(`{END_${tagName}}`)) {
|
|
278
|
+
endIndex = j;
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (endIndex === -1 || endIndex === i) {
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
// Found multi-block loop - process it
|
|
286
|
+
const limit = beginMatch[1] ? parseInt(beginMatch[1]) : null;
|
|
287
|
+
this._replaceMultiBlockLoop(blocks, i, endIndex, tag, limit);
|
|
288
|
+
// Adjust i since blocks array was modified
|
|
289
|
+
i = Math.min(i, blocks.length - 1);
|
|
290
|
+
break; // Only process one loop per block per iteration
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Process multi-block conditionals from end to start
|
|
294
|
+
for (let i = blocks.length - 1; i >= 0; i--) {
|
|
295
|
+
const block = blocks[i];
|
|
296
|
+
const text = block.textContent;
|
|
297
|
+
const ifMatch = text.match(/\{IF\(([^)]+)\)\}/);
|
|
298
|
+
if (!ifMatch) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
// Find matching ENDIF in a later block
|
|
302
|
+
let endIndex = -1;
|
|
303
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
304
|
+
if (/\{ENDIF\}/.test(blocks[j].textContent)) {
|
|
305
|
+
endIndex = j;
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (endIndex === -1 || endIndex === i) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
this._replaceMultiBlockConditional(blocks, i, endIndex, ifMatch[1], tagMap);
|
|
313
|
+
i = Math.min(i, blocks.length - 1);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
_replaceMultiBlockLoop(blocks, beginIndex, endIndex, tag, limit) {
|
|
317
|
+
const tagName = tag.title;
|
|
318
|
+
const beginBlock = blocks[beginIndex];
|
|
319
|
+
// Concatenate all blocks from begin to end
|
|
320
|
+
let combinedXml = "";
|
|
321
|
+
for (let i = beginIndex; i <= endIndex; i++) {
|
|
322
|
+
combinedXml += blocks[i].toString();
|
|
323
|
+
}
|
|
324
|
+
// Find the BEGIN and END tags in the combined XML
|
|
325
|
+
const beginRegex = new RegExp(`\\{BEGIN_${tagName}(?::limit=\\d+)?\\}`);
|
|
326
|
+
const beginMatch = combinedXml.match(beginRegex);
|
|
327
|
+
const endTag = `{END_${tagName}}`;
|
|
328
|
+
const endPos = combinedXml.indexOf(endTag);
|
|
329
|
+
if (!beginMatch || endPos === -1) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const beforeXml = combinedXml.slice(0, beginMatch.index);
|
|
333
|
+
const templateXml = combinedXml.slice(beginMatch.index + beginMatch[0].length, endPos);
|
|
334
|
+
const afterXml = combinedXml.slice(endPos + endTag.length);
|
|
335
|
+
// Decode > so expressions like >= work in nested conditionals
|
|
336
|
+
const decodedTemplateXml = templateXml.replace(/>/g, ">");
|
|
337
|
+
const replacementXml = this.processLoop(decodedTemplateXml, tag.content, tagName, limit);
|
|
338
|
+
const fullReplacement = beforeXml + replacementXml + afterXml;
|
|
339
|
+
// Parse replacement
|
|
340
|
+
const parent = beginBlock.parentElement;
|
|
341
|
+
const dom = xmlDOM(`<root>${fullReplacement}</root>`);
|
|
342
|
+
const root = dom.query("root");
|
|
343
|
+
const newBlocks = root.children.filter(child => child.tagName === "w:p" || child.tagName === "w:sectPr");
|
|
344
|
+
// Insert new blocks before begin block
|
|
345
|
+
for (let i = newBlocks.length - 1; i >= 0; i--) {
|
|
346
|
+
parent.insertBefore(newBlocks[i], beginBlock);
|
|
347
|
+
}
|
|
348
|
+
// Remove old blocks
|
|
349
|
+
for (let i = endIndex; i >= beginIndex; i--) {
|
|
350
|
+
parent.removeChild(blocks[i]);
|
|
351
|
+
}
|
|
352
|
+
// Update blocks array
|
|
353
|
+
blocks.splice(beginIndex, endIndex - beginIndex + 1, ...newBlocks);
|
|
354
|
+
}
|
|
355
|
+
_replaceMultiBlockConditional(blocks, ifIndex, endIndex, expr, tagMap) {
|
|
356
|
+
const ifBlock = blocks[ifIndex];
|
|
357
|
+
// Concatenate all blocks from if to endif
|
|
358
|
+
let combinedXml = "";
|
|
359
|
+
for (let i = ifIndex; i <= endIndex; i++) {
|
|
360
|
+
combinedXml += blocks[i].toString();
|
|
361
|
+
}
|
|
362
|
+
// Determine which tag the expression references
|
|
363
|
+
let ctx = { count: 0, content: [] };
|
|
364
|
+
for (const tagName in tagMap) {
|
|
365
|
+
const safeTagName = tagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
366
|
+
if (new RegExp(`\\b${safeTagName}\\b`).test(expr)) {
|
|
367
|
+
const tag = tagMap[tagName];
|
|
368
|
+
ctx = {
|
|
369
|
+
tagName: tag.title,
|
|
370
|
+
count: tag.content ? tag.content.length : 0,
|
|
371
|
+
content: tag.content || []
|
|
372
|
+
};
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// Decode > so expressions like >= work in conditionals
|
|
377
|
+
const decodedXml = combinedXml.replace(/>/g, ">");
|
|
378
|
+
// Process conditionals on the combined XML
|
|
379
|
+
const processedXml = this.processConditionals(decodedXml, ctx);
|
|
380
|
+
if (processedXml === combinedXml) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
// Parse and replace
|
|
384
|
+
const parent = ifBlock.parentElement;
|
|
385
|
+
const dom = xmlDOM(`<root>${processedXml}</root>`);
|
|
386
|
+
const root = dom.query("root");
|
|
387
|
+
const newBlocks = root.children.filter(child => child.tagName === "w:p" || child.tagName === "w:sectPr");
|
|
388
|
+
for (let i = newBlocks.length - 1; i >= 0; i--) {
|
|
389
|
+
parent.insertBefore(newBlocks[i], ifBlock);
|
|
390
|
+
}
|
|
391
|
+
for (let i = endIndex; i >= ifIndex; i--) {
|
|
392
|
+
parent.removeChild(blocks[i]);
|
|
393
|
+
}
|
|
394
|
+
blocks.splice(ifIndex, endIndex - ifIndex + 1, ...newBlocks);
|
|
395
|
+
}
|
|
396
|
+
// Define the tags that are to be looked for in the document
|
|
397
|
+
getTagData(docContent, pmBib, settings) {
|
|
398
|
+
const tags = docContent.content.map(node => {
|
|
399
|
+
const tag = {};
|
|
400
|
+
switch (node.type) {
|
|
401
|
+
case "title":
|
|
402
|
+
tag.title = "title";
|
|
403
|
+
tag.content = textContent(node);
|
|
404
|
+
break;
|
|
405
|
+
case "heading_part":
|
|
406
|
+
tag.title = node.attrs.id;
|
|
407
|
+
tag.content = textContent(node);
|
|
408
|
+
break;
|
|
409
|
+
case "table_part":
|
|
410
|
+
case "richtext_part":
|
|
411
|
+
tag.title = `@${node.attrs.id}`;
|
|
412
|
+
tag.content = node.content;
|
|
413
|
+
break;
|
|
414
|
+
case "contributors_part":
|
|
415
|
+
tag.title = node.attrs.id;
|
|
416
|
+
// Return array of structured objects for format with delimiter support
|
|
417
|
+
tag.content = node.content
|
|
418
|
+
? node.content.map(node => {
|
|
419
|
+
const c = node.attrs;
|
|
420
|
+
return {
|
|
421
|
+
firstname: c.firstname || "",
|
|
422
|
+
lastname: c.lastname || "",
|
|
423
|
+
institution: c.institution || "",
|
|
424
|
+
email: c.email || "",
|
|
425
|
+
id_type: c.id_type || "",
|
|
426
|
+
id_value: c.id_value || ""
|
|
427
|
+
};
|
|
428
|
+
})
|
|
429
|
+
: [];
|
|
430
|
+
break;
|
|
431
|
+
case "tags_part":
|
|
432
|
+
tag.title = node.attrs.id;
|
|
433
|
+
// Return array of tag strings for format with delimiter support
|
|
434
|
+
tag.content = node.content
|
|
435
|
+
? node.content.map(node => node.attrs.tag)
|
|
436
|
+
: [];
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
return tag;
|
|
440
|
+
});
|
|
441
|
+
let bibliographyContent;
|
|
442
|
+
if (pmBib && pmBib.content && pmBib.content.length > 0) {
|
|
443
|
+
// Add bibliography heading and mark first/last items
|
|
444
|
+
const firstPmBib = pmBib.content[0];
|
|
445
|
+
const lastPmBib = pmBib.content[pmBib.content.length - 1];
|
|
446
|
+
firstPmBib.attrs = firstPmBib.attrs || {};
|
|
447
|
+
firstPmBib.attrs.first = true;
|
|
448
|
+
lastPmBib.attrs = lastPmBib.attrs || {};
|
|
449
|
+
lastPmBib.attrs.last = true;
|
|
450
|
+
const bibliographyHeader = settings.bibliography_header[settings.language] ||
|
|
451
|
+
BIBLIOGRAPHY_HEADERS[settings.language];
|
|
452
|
+
bibliographyContent = [
|
|
453
|
+
{
|
|
454
|
+
type: "bibliography_heading",
|
|
455
|
+
content: [{ type: "text", text: bibliographyHeader }]
|
|
456
|
+
},
|
|
457
|
+
pmBib
|
|
458
|
+
];
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
// No bibliography content, add a placeholder paragraph
|
|
462
|
+
bibliographyContent = [
|
|
463
|
+
{ type: "paragraph", content: [{ type: "text", text: " " }] }
|
|
464
|
+
];
|
|
465
|
+
}
|
|
466
|
+
// Add bibliography content
|
|
467
|
+
tags.push({
|
|
468
|
+
title: "@bibliography", // The '@' triggers handling as block
|
|
469
|
+
content: bibliographyContent
|
|
470
|
+
});
|
|
471
|
+
tags.push({
|
|
472
|
+
title: "@copyright", // The '@' triggers handling as block
|
|
473
|
+
content: settings.copyright && settings.copyright.holder
|
|
474
|
+
? [
|
|
475
|
+
{
|
|
476
|
+
type: "paragraph",
|
|
477
|
+
content: [
|
|
478
|
+
{
|
|
479
|
+
type: "text",
|
|
480
|
+
text: `© ${settings.copyright.year ? settings.copyright.year : new Date().getFullYear()} ${settings.copyright.holder}`
|
|
481
|
+
}
|
|
482
|
+
]
|
|
483
|
+
}
|
|
484
|
+
]
|
|
485
|
+
: [
|
|
486
|
+
{
|
|
487
|
+
type: "paragraph",
|
|
488
|
+
content: [{ type: "text", text: " " }]
|
|
489
|
+
}
|
|
490
|
+
]
|
|
491
|
+
});
|
|
492
|
+
tags.push({
|
|
493
|
+
title: "@licenses", // The '@' triggers handling as block
|
|
494
|
+
content: settings.copyright && settings.copyright.licenses.length
|
|
495
|
+
? settings.copyright.licenses.map(license => ({
|
|
496
|
+
type: "paragraph",
|
|
497
|
+
content: [
|
|
498
|
+
{
|
|
499
|
+
type: "text",
|
|
500
|
+
marks: [
|
|
501
|
+
{
|
|
502
|
+
type: "link",
|
|
503
|
+
attrs: {
|
|
504
|
+
href: license.url,
|
|
505
|
+
title: license.title
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
],
|
|
509
|
+
text: license.title
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
type: "text",
|
|
513
|
+
text: license.start
|
|
514
|
+
? ` (${license.start})`
|
|
515
|
+
: ""
|
|
516
|
+
}
|
|
517
|
+
]
|
|
518
|
+
}))
|
|
519
|
+
: [
|
|
520
|
+
{
|
|
521
|
+
type: "paragraph",
|
|
522
|
+
content: [{ type: "text", text: " " }]
|
|
523
|
+
}
|
|
524
|
+
]
|
|
525
|
+
});
|
|
526
|
+
return tags;
|
|
527
|
+
}
|
|
528
|
+
// go through document.xml looking for tags and replace them with the given
|
|
529
|
+
// replacements.
|
|
530
|
+
render(docContent, pmBib, settings, richtext, citations) {
|
|
531
|
+
const tags = this.getTagData(docContent, pmBib, settings);
|
|
532
|
+
// Including global page definition at end
|
|
533
|
+
const blocks = this.text.queryAll(["w:p", "w:sectPr"]);
|
|
534
|
+
// Process multi-block structured tags first (BEGIN...END across paragraphs)
|
|
535
|
+
this.processMultiBlockStructuredTags(blocks, tags);
|
|
536
|
+
const currentTags = [];
|
|
537
|
+
blocks.forEach(block => {
|
|
538
|
+
// Assuming there is nothing outside of <w:t>...</w:t>
|
|
539
|
+
const text = block.textContent;
|
|
540
|
+
tags.forEach(tag => {
|
|
541
|
+
const tagString = tag.title;
|
|
542
|
+
const hasInlineTag = text.includes(`{${tagString}}`) ||
|
|
543
|
+
text.includes(`{${tagString}:format=`);
|
|
544
|
+
const hasBeginTag = text.includes(`{BEGIN_${tagString}}`);
|
|
545
|
+
const hasIfTag = text.includes(`{IF(${tagString}.`) ||
|
|
546
|
+
text.includes(`{IF(ctx.`);
|
|
547
|
+
if (hasInlineTag || hasBeginTag || hasIfTag) {
|
|
548
|
+
currentTags.push(tag);
|
|
549
|
+
tag.block = block;
|
|
550
|
+
// We don't worry about the same tag appearing twice in the document,
|
|
551
|
+
// as that would make no sense.
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
// Parse structured tags (BEGIN...END and IF...ENDIF)
|
|
555
|
+
currentTags.forEach(tag => {
|
|
556
|
+
if (tag.block) {
|
|
557
|
+
this.parseStructuredTags(tag.block, tag);
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
const pageSize = block.query("w:pgSz");
|
|
561
|
+
const pageMargins = block.query("w:pgMar");
|
|
562
|
+
const cols = block.query("w:cols");
|
|
563
|
+
if (pageSize && pageMargins) {
|
|
564
|
+
// Not sure if these all need to come together
|
|
565
|
+
let width = Number.parseInt(pageSize.getAttribute("w:w")) -
|
|
566
|
+
Number.parseInt(pageMargins.getAttribute("w:right")) -
|
|
567
|
+
Number.parseInt(pageMargins.getAttribute("w:left"));
|
|
568
|
+
const height = Number.parseInt(pageSize.getAttribute("w:h")) -
|
|
569
|
+
Number.parseInt(pageMargins.getAttribute("w:bottom")) -
|
|
570
|
+
Number.parseInt(pageMargins.getAttribute("w:top")) -
|
|
571
|
+
Number.parseInt(pageMargins.getAttribute("w:header")) -
|
|
572
|
+
Number.parseInt(pageMargins.getAttribute("w:footer"));
|
|
573
|
+
const colCount = cols
|
|
574
|
+
? Number.parseInt(cols.getAttribute("w:num"))
|
|
575
|
+
: 1;
|
|
576
|
+
if (colCount > 1) {
|
|
577
|
+
const colSpace = Number.parseInt(cols.getAttribute("w:space"));
|
|
578
|
+
width = width - colSpace * (colCount - 1);
|
|
579
|
+
width = width / colCount;
|
|
580
|
+
}
|
|
581
|
+
while (currentTags.length) {
|
|
582
|
+
const tag = currentTags.pop();
|
|
583
|
+
tag.dimensions = {
|
|
584
|
+
width: width * 635, // convert to EMU
|
|
585
|
+
height: height * 635 // convert to EMU
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
tags.forEach(tag => {
|
|
591
|
+
if (!tag.title) {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
else if (tag.title[0] === "@") {
|
|
595
|
+
this.blockRender(tag, citations, richtext);
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
this.inlineRender(tag);
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
// Render Tags that only exchange inline content
|
|
603
|
+
inlineRender(tag) {
|
|
604
|
+
if (!tag.block) {
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const blockText = tag.block.textContent;
|
|
608
|
+
const tagString = `{${tag.title}}`;
|
|
609
|
+
if (!blockText.includes(`{${tag.title}`)) {
|
|
610
|
+
// No inline tag present - structured tags only
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
// Check for format string with delimiter: {tag:format=%firstname|; }
|
|
614
|
+
const formatRegex = new RegExp(`\\{${tag.title}:format=([^|]+)\\|?([^}]*)?\\}`);
|
|
615
|
+
const formatMatch = blockText.match(formatRegex);
|
|
616
|
+
let fullText = "";
|
|
617
|
+
if (formatMatch && tag.content && Array.isArray(tag.content)) {
|
|
618
|
+
// Find format string and delimiter
|
|
619
|
+
const [, format, delimiter = "; "] = formatMatch;
|
|
620
|
+
// Process each item with the format string
|
|
621
|
+
const formattedItems = tag.content
|
|
622
|
+
.map(item => {
|
|
623
|
+
if (typeof item === "string") {
|
|
624
|
+
// For tags (simple strings)
|
|
625
|
+
return format.replace(/%tag/g, item);
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
// For contributors (objects)
|
|
629
|
+
return format
|
|
630
|
+
.replace(/%firstname/g, item.firstname || "")
|
|
631
|
+
.replace(/%lastname/g, item.lastname || "")
|
|
632
|
+
.replace(/%institution/g, item.institution || "")
|
|
633
|
+
.replace(/%email/g, item.email || "")
|
|
634
|
+
.replace(/%id_type/g, item.id_type || "")
|
|
635
|
+
.replace(/%id_value/g, item.id_value || "");
|
|
636
|
+
}
|
|
637
|
+
})
|
|
638
|
+
.filter(s => s.trim() !== "");
|
|
639
|
+
// Handle special delimiters
|
|
640
|
+
let delimiterText = delimiter;
|
|
641
|
+
delimiterText = delimiterText.replace(/\\n/g, "\n");
|
|
642
|
+
delimiterText = delimiterText.replace(/\\p/g, "\n\n");
|
|
643
|
+
const replacement = formattedItems.join(delimiterText);
|
|
644
|
+
fullText = blockText.replace(formatRegex, replacement);
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
// Fall back to simple string replacement (backward compatible)
|
|
648
|
+
let contentStr = tag.content || "";
|
|
649
|
+
if (Array.isArray(contentStr)) {
|
|
650
|
+
if (contentStr.length === 0) {
|
|
651
|
+
contentStr = "";
|
|
652
|
+
}
|
|
653
|
+
else if (typeof contentStr[0] === "string") {
|
|
654
|
+
contentStr = contentStr.join(", ");
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
// Contributors - backward compatible formatting
|
|
658
|
+
contentStr = contentStr
|
|
659
|
+
.map(item => {
|
|
660
|
+
const nameParts = [];
|
|
661
|
+
let affiliation = false;
|
|
662
|
+
if (item.firstname) {
|
|
663
|
+
nameParts.push(item.firstname);
|
|
664
|
+
}
|
|
665
|
+
if (item.lastname) {
|
|
666
|
+
nameParts.push(item.lastname);
|
|
667
|
+
}
|
|
668
|
+
if (item.institution) {
|
|
669
|
+
if (nameParts.length) {
|
|
670
|
+
affiliation = item.institution;
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
nameParts.push(item.institution);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
const parts = [nameParts.join(" ")];
|
|
677
|
+
if (affiliation) {
|
|
678
|
+
parts.push(affiliation);
|
|
679
|
+
}
|
|
680
|
+
if (item.email) {
|
|
681
|
+
parts.push(item.email);
|
|
682
|
+
}
|
|
683
|
+
if (item.id_type && item.id_value) {
|
|
684
|
+
parts.push(`${item.id_type}: ${item.id_value}`);
|
|
685
|
+
}
|
|
686
|
+
return parts.join(", ");
|
|
687
|
+
})
|
|
688
|
+
.join("; ");
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
const texts = blockText.split(tagString);
|
|
692
|
+
fullText = texts[0] + contentStr + texts[1];
|
|
693
|
+
}
|
|
694
|
+
// Apply the replacement
|
|
695
|
+
const rs = tag.block.queryAll("w:r").reverse();
|
|
696
|
+
let lastR;
|
|
697
|
+
// Remove all <w:r> with text in them (<w:t>).
|
|
698
|
+
// Exclude <w:r> used for other things, like page breaks.
|
|
699
|
+
rs.forEach(r => {
|
|
700
|
+
if (r.query("w:t")) {
|
|
701
|
+
if (lastR) {
|
|
702
|
+
r.parentElement.removeChild(r);
|
|
703
|
+
}
|
|
704
|
+
else {
|
|
705
|
+
lastR = r;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
if (!lastR) {
|
|
710
|
+
// This should not be possible. Error.
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
if (fullText.length) {
|
|
714
|
+
if (fullText.includes("\n")) {
|
|
715
|
+
// Split on newlines and create <w:t> elements separated by <w:br/>
|
|
716
|
+
const parts = fullText.split("\n").map(part => escapeText(part));
|
|
717
|
+
lastR.innerXML = parts
|
|
718
|
+
.map((part, index) => {
|
|
719
|
+
const br = index > 0 ? "<w:br/>" : "";
|
|
720
|
+
return `${br}<w:t xml:space="preserve">${part}</w:t>`;
|
|
721
|
+
})
|
|
722
|
+
.join("");
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
let textAttr = "";
|
|
726
|
+
if (fullText[0] === " " ||
|
|
727
|
+
fullText[fullText.length - 1] === " ") {
|
|
728
|
+
textAttr += 'xml:space="preserve"';
|
|
729
|
+
}
|
|
730
|
+
lastR.innerXML = `<w:t ${textAttr}>${escapeText(fullText)}</w:t>`;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
lastR.parentElement.removeChild(lastR);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
// Render tags that exchange paragraphs
|
|
738
|
+
blockRender(tag, citations, richtext) {
|
|
739
|
+
if (!tag.block) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
const pStyle = tag.block.query("w:pStyle");
|
|
743
|
+
const options = {
|
|
744
|
+
dimensions: tag.dimensions,
|
|
745
|
+
citationType: citations.citFm.citationType,
|
|
746
|
+
section: pStyle ? pStyle.getAttribute("w:val") : "Normal",
|
|
747
|
+
tag: tag.title.slice(1)
|
|
748
|
+
};
|
|
749
|
+
const outXML = tag.content
|
|
750
|
+
? tag.content
|
|
751
|
+
.map((content, i) => richtext.run(content, options, tag.content[i + 1]))
|
|
752
|
+
.join("")
|
|
753
|
+
: "";
|
|
754
|
+
if (!outXML.length) {
|
|
755
|
+
// If there is no content, we need to put in a space to prevent the
|
|
756
|
+
// tag from being removed.
|
|
757
|
+
tag.block.innerXML = '<w:r><w:t xml:space="preserve"> </w:t></w:r>';
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
const parentElement = tag.block.parentElement;
|
|
761
|
+
const dom = xmlDOM(outXML);
|
|
762
|
+
const domPars = dom.node["#document"]?.slice() || [dom];
|
|
763
|
+
domPars.forEach(node => parentElement.insertBefore(node, tag.block));
|
|
764
|
+
// sectPr contains information about columns, etc. We need to move this
|
|
765
|
+
// to the last paragraph we will be adding.
|
|
766
|
+
const sectPr = tag.block.query("w:sectPr");
|
|
767
|
+
if (sectPr) {
|
|
768
|
+
const pPr = tag.block.previousSibling.query("w:pPr");
|
|
769
|
+
pPr.appendChild(sectPr);
|
|
770
|
+
}
|
|
771
|
+
parentElement.removeChild(tag.block);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
//# sourceMappingURL=render.js.map
|