@fiduswriter/document 0.1.0-alpha.2 → 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,644 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* Create Zotero bibliography reference mark name for ODT.
|
|
7
|
+
* @returns {string} Reference mark name
|
|
8
|
+
*/
|
|
9
|
+
export function createOdtBibliographyMark() {
|
|
10
|
+
return "ZOTERO_BIBL CSL_BIBLIOGRAPHY";
|
|
11
|
+
}
|
|
12
|
+
export class ODTExporterRender {
|
|
13
|
+
constructor(xml) {
|
|
14
|
+
this.xml = xml;
|
|
15
|
+
this.filePath = "content.xml";
|
|
16
|
+
this.text = false;
|
|
17
|
+
}
|
|
18
|
+
init() {
|
|
19
|
+
return this.xml.getXml(this.filePath).then(xml => {
|
|
20
|
+
this.text = xml.query("office:text");
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
parseStructuredTags(block, tag) {
|
|
25
|
+
let blockText = block.textContent;
|
|
26
|
+
const tagName = tag.title;
|
|
27
|
+
// Check for BEGIN...END loops (with optional limit)
|
|
28
|
+
const beginStartRegex = new RegExp(`\\{BEGIN_${tagName}(?::limit=(\\d+))?\\}`);
|
|
29
|
+
const beginStartMatch = blockText.match(beginStartRegex);
|
|
30
|
+
if (beginStartMatch &&
|
|
31
|
+
tag.content &&
|
|
32
|
+
Array.isArray(tag.content) &&
|
|
33
|
+
tag.content.length > 0) {
|
|
34
|
+
const limit = beginStartMatch[1]
|
|
35
|
+
? parseInt(beginStartMatch[1])
|
|
36
|
+
: null;
|
|
37
|
+
const beginStart = beginStartMatch.index;
|
|
38
|
+
const beginEnd = beginStart + beginStartMatch[0].length;
|
|
39
|
+
// Find matching {END_tag}
|
|
40
|
+
const endTag = `{END_${tagName}}`;
|
|
41
|
+
const endPos = blockText.indexOf(endTag, beginEnd);
|
|
42
|
+
if (endPos === -1) {
|
|
43
|
+
console.warn(`Missing ${endTag} for ${tagName}`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const templateXml = blockText.slice(beginEnd, endPos);
|
|
47
|
+
const replacementXml = this.processLoop(templateXml, tag.content, tagName, limit);
|
|
48
|
+
const beforeText = blockText.slice(0, beginStart);
|
|
49
|
+
const afterText = blockText.slice(endPos + endTag.length);
|
|
50
|
+
const fullReplacement = beforeText + replacementXml + afterText;
|
|
51
|
+
block.innerXML = fullReplacement;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Check for IF...ELIF...ELSE...ENDIF conditionals
|
|
55
|
+
blockText = this.processConditionals(blockText, {
|
|
56
|
+
tagName,
|
|
57
|
+
count: tag.content ? tag.content.length : 0,
|
|
58
|
+
content: tag.content || []
|
|
59
|
+
});
|
|
60
|
+
if (blockText !== block.textContent) {
|
|
61
|
+
block.innerXML = blockText;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
processLoop(templateXml, items, tagName, limit = null) {
|
|
65
|
+
const effectiveItems = limit !== null ? items.slice(0, limit) : items;
|
|
66
|
+
const results = [];
|
|
67
|
+
effectiveItems.forEach((item, index) => {
|
|
68
|
+
const loopCtx = {
|
|
69
|
+
count: items.length,
|
|
70
|
+
index: index,
|
|
71
|
+
first: index === 0,
|
|
72
|
+
last: index === effectiveItems.length - 1,
|
|
73
|
+
item: item,
|
|
74
|
+
content: [item],
|
|
75
|
+
odd: index % 2 === 1,
|
|
76
|
+
even: index % 2 === 0
|
|
77
|
+
};
|
|
78
|
+
let itemXml = templateXml;
|
|
79
|
+
// Replace field placeholders
|
|
80
|
+
if (typeof item === "string") {
|
|
81
|
+
itemXml = itemXml.replace(/%tag/g, escapeText(item));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
itemXml = itemXml
|
|
85
|
+
.replace(/\{?%firstname\}?/g, escapeText(item.firstname || ""))
|
|
86
|
+
.replace(/\{?%lastname\}?/g, escapeText(item.lastname || ""))
|
|
87
|
+
.replace(/\{?%institution\}?/g, escapeText(item.institution || ""))
|
|
88
|
+
.replace(/\{?%email\}?/g, escapeText(item.email || ""))
|
|
89
|
+
.replace(/\{?%id_type\}?/g, escapeText(item.id_type || ""))
|
|
90
|
+
.replace(/\{?%id_value\}?/g, escapeText(item.id_value || ""));
|
|
91
|
+
}
|
|
92
|
+
// Handle conditionals inside the loop
|
|
93
|
+
itemXml = this.processConditionals(itemXml, { tagName, ...loopCtx });
|
|
94
|
+
// Handle special delimiters for ODT
|
|
95
|
+
itemXml = itemXml.replace(/\\n/g, "<text:line-break/>");
|
|
96
|
+
itemXml = itemXml.replace(/\\p/g, "</text:p><text:p>");
|
|
97
|
+
results.push(itemXml);
|
|
98
|
+
});
|
|
99
|
+
return results.join("");
|
|
100
|
+
}
|
|
101
|
+
processConditionals(text, ctx) {
|
|
102
|
+
let result = text;
|
|
103
|
+
let changed = true;
|
|
104
|
+
while (changed) {
|
|
105
|
+
changed = false;
|
|
106
|
+
const ifStart = result.indexOf("{IF(");
|
|
107
|
+
if (ifStart === -1) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
let depth = 1;
|
|
111
|
+
let pos = ifStart + 4; // skip {IF(
|
|
112
|
+
// Find the closing ) of the IF expression
|
|
113
|
+
while (pos < result.length && result[pos] !== ")") {
|
|
114
|
+
pos++;
|
|
115
|
+
}
|
|
116
|
+
if (pos >= result.length) {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
pos++; // skip )
|
|
120
|
+
// Now scan for matching {ENDIF}
|
|
121
|
+
while (pos < result.length && depth > 0) {
|
|
122
|
+
if (result.substr(pos, 4) === "{IF(") {
|
|
123
|
+
depth++;
|
|
124
|
+
pos += 4;
|
|
125
|
+
}
|
|
126
|
+
else if (result.substr(pos, 7) === "{ENDIF}") {
|
|
127
|
+
depth--;
|
|
128
|
+
if (depth > 0) {
|
|
129
|
+
pos += 7;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
pos++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (depth === 0) {
|
|
137
|
+
const exprEnd = result.indexOf(")", ifStart + 4);
|
|
138
|
+
const ifExpr = result.slice(ifStart + 4, exprEnd);
|
|
139
|
+
// Skip the closing } of {IF(...)} if present
|
|
140
|
+
let innerStart = exprEnd + 1;
|
|
141
|
+
if (result[innerStart] === "}") {
|
|
142
|
+
innerStart++;
|
|
143
|
+
}
|
|
144
|
+
const innerContent = result.slice(innerStart, pos);
|
|
145
|
+
const conditions = [];
|
|
146
|
+
conditions.push({ expr: ifExpr, content: "" });
|
|
147
|
+
const remaining = innerContent;
|
|
148
|
+
let lastIndex = 0;
|
|
149
|
+
const elifRegex = /\{ELIF\(([^)]+)\)\}/g;
|
|
150
|
+
let elifMatch;
|
|
151
|
+
while ((elifMatch = elifRegex.exec(remaining)) !== null) {
|
|
152
|
+
conditions[conditions.length - 1].content = remaining.slice(lastIndex, elifMatch.index);
|
|
153
|
+
conditions.push({ expr: elifMatch[1], content: "" });
|
|
154
|
+
lastIndex = elifMatch.index + elifMatch[0].length;
|
|
155
|
+
}
|
|
156
|
+
const elseMatch = remaining.slice(lastIndex).match(/\{ELSE\}/);
|
|
157
|
+
if (elseMatch) {
|
|
158
|
+
conditions[conditions.length - 1].content = remaining.slice(lastIndex, lastIndex + elseMatch.index);
|
|
159
|
+
conditions.push({
|
|
160
|
+
expr: null,
|
|
161
|
+
content: remaining.slice(lastIndex + elseMatch.index + elseMatch[0].length)
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
conditions[conditions.length - 1].content =
|
|
166
|
+
remaining.slice(lastIndex);
|
|
167
|
+
}
|
|
168
|
+
let replacement = "";
|
|
169
|
+
for (const cond of conditions) {
|
|
170
|
+
if (cond.expr === null ||
|
|
171
|
+
this.evaluateExpression(cond.expr, ctx)) {
|
|
172
|
+
replacement = cond.content;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
result =
|
|
177
|
+
result.slice(0, ifStart) +
|
|
178
|
+
replacement +
|
|
179
|
+
result.slice(pos + 7);
|
|
180
|
+
changed = true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
evaluateExpression(expr, ctx) {
|
|
186
|
+
try {
|
|
187
|
+
// Allow explicit tag name references (e.g., authors.count -> ctx.count)
|
|
188
|
+
if (ctx.tagName) {
|
|
189
|
+
const safeTagName = ctx.tagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
190
|
+
expr = expr.replace(new RegExp(`\\b${safeTagName}\\b`, "g"), "ctx");
|
|
191
|
+
}
|
|
192
|
+
// Replace ctx.property accesses with literal values
|
|
193
|
+
const evalExpr = expr.replace(/ctx\.(\w+)(?:\.(\w+))?(?:\[(\d+)\])?/g, (_match, p1, p2, p3) => {
|
|
194
|
+
let val = ctx[p1];
|
|
195
|
+
if (p2 !== undefined && val !== undefined) {
|
|
196
|
+
val = val[p2];
|
|
197
|
+
}
|
|
198
|
+
if (p3 !== undefined && val !== undefined) {
|
|
199
|
+
val = val[parseInt(p3)];
|
|
200
|
+
}
|
|
201
|
+
return JSON.stringify(val);
|
|
202
|
+
});
|
|
203
|
+
// Remove string literals before character check
|
|
204
|
+
const safeExpr = evalExpr.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, '""');
|
|
205
|
+
// Check for unknown identifiers
|
|
206
|
+
const bareIdRegex = /\b[a-zA-Z_]\w*\b/g;
|
|
207
|
+
const allowed = ["true", "false", "null", "undefined"];
|
|
208
|
+
let m;
|
|
209
|
+
while ((m = bareIdRegex.exec(safeExpr)) !== null) {
|
|
210
|
+
if (!allowed.includes(m[0])) {
|
|
211
|
+
console.warn("Unknown identifier in expression:", m[0], "expression:", expr);
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Check for unsafe characters
|
|
216
|
+
if (/[^ \t\n\r0-9a-zA-Z_\.\+\-*\/%==<>!&|()\[\]]/.test(safeExpr)) {
|
|
217
|
+
console.warn("Unsafe characters in expression:", expr);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return new Function(`return (${evalExpr})`)();
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
console.warn("Error evaluating expression:", expr, e);
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Define the tags that are to be looked for in the document
|
|
228
|
+
getTagData(docContent, pmBib, settings) {
|
|
229
|
+
const tags = docContent.content.map(node => {
|
|
230
|
+
const tag = {};
|
|
231
|
+
switch (node.type) {
|
|
232
|
+
case "title":
|
|
233
|
+
tag.title = "title";
|
|
234
|
+
tag.content = textContent(node);
|
|
235
|
+
break;
|
|
236
|
+
case "heading_part":
|
|
237
|
+
tag.title = node.attrs.id;
|
|
238
|
+
tag.content = textContent(node);
|
|
239
|
+
break;
|
|
240
|
+
case "table_part":
|
|
241
|
+
case "richtext_part":
|
|
242
|
+
tag.title = `@${node.attrs.id}`;
|
|
243
|
+
tag.content = node.content;
|
|
244
|
+
break;
|
|
245
|
+
case "contributors_part":
|
|
246
|
+
tag.title = node.attrs.id;
|
|
247
|
+
// Return array of structured objects for format with delimiter support
|
|
248
|
+
tag.content = node.content
|
|
249
|
+
? node.content.map(node => {
|
|
250
|
+
const c = node.attrs;
|
|
251
|
+
return {
|
|
252
|
+
firstname: c.firstname || "",
|
|
253
|
+
lastname: c.lastname || "",
|
|
254
|
+
institution: c.institution || "",
|
|
255
|
+
email: c.email || "",
|
|
256
|
+
id_type: c.id_type || "",
|
|
257
|
+
id_value: c.id_value || ""
|
|
258
|
+
};
|
|
259
|
+
})
|
|
260
|
+
: [];
|
|
261
|
+
break;
|
|
262
|
+
case "tags_part":
|
|
263
|
+
tag.title = node.attrs.id;
|
|
264
|
+
// Return array of tag strings for format with delimiter support
|
|
265
|
+
tag.content = node.content
|
|
266
|
+
? node.content.map(node => node.attrs.tag)
|
|
267
|
+
: [];
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
return tag;
|
|
271
|
+
});
|
|
272
|
+
const bibliographyHeader = settings.bibliography_header[settings.language] ||
|
|
273
|
+
BIBLIOGRAPHY_HEADERS[settings.language];
|
|
274
|
+
tags.push({
|
|
275
|
+
title: "@bibliography", // The '@' triggers handling as block
|
|
276
|
+
content: pmBib
|
|
277
|
+
? [
|
|
278
|
+
{
|
|
279
|
+
type: "bibliography_heading",
|
|
280
|
+
content: [{ type: "text", text: bibliographyHeader }]
|
|
281
|
+
},
|
|
282
|
+
pmBib
|
|
283
|
+
]
|
|
284
|
+
: [{ type: "paragraph", content: [{ type: "text", text: " " }] }]
|
|
285
|
+
});
|
|
286
|
+
tags.push({
|
|
287
|
+
title: "@copyright", // The '@' triggers handling as block
|
|
288
|
+
content: settings.copyright && settings.copyright.holder
|
|
289
|
+
? [
|
|
290
|
+
{
|
|
291
|
+
type: "paragraph",
|
|
292
|
+
content: [
|
|
293
|
+
{
|
|
294
|
+
type: "text",
|
|
295
|
+
text: `© ${settings.copyright.year ? settings.copyright.year : new Date().getFullYear()} ${settings.copyright.holder}`
|
|
296
|
+
}
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
: [
|
|
301
|
+
{
|
|
302
|
+
type: "paragraph",
|
|
303
|
+
content: [{ type: "text", text: " " }]
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
});
|
|
307
|
+
tags.push({
|
|
308
|
+
title: "@licenses", // The '@' triggers handling as block
|
|
309
|
+
content: settings.copyright && settings.copyright.licenses.length
|
|
310
|
+
? settings.copyright.licenses.map(license => ({
|
|
311
|
+
type: "paragraph",
|
|
312
|
+
content: [
|
|
313
|
+
{
|
|
314
|
+
type: "text",
|
|
315
|
+
marks: [
|
|
316
|
+
{
|
|
317
|
+
type: "link",
|
|
318
|
+
attrs: {
|
|
319
|
+
href: license.url,
|
|
320
|
+
title: license.url
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
text: license.title
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
type: "text",
|
|
328
|
+
text: license.start
|
|
329
|
+
? ` (${license.start})`
|
|
330
|
+
: ""
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}))
|
|
334
|
+
: [
|
|
335
|
+
{
|
|
336
|
+
type: "paragraph",
|
|
337
|
+
content: [{ type: "text", text: " " }]
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
});
|
|
341
|
+
return tags;
|
|
342
|
+
}
|
|
343
|
+
processMultiBlockStructuredTags(blocks, tags) {
|
|
344
|
+
const tagMap = {};
|
|
345
|
+
tags.forEach(tag => {
|
|
346
|
+
if (tag.title) {
|
|
347
|
+
tagMap[tag.title] = tag;
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
// Process from end to start to avoid index shifting issues
|
|
351
|
+
for (let i = blocks.length - 1; i >= 0; i--) {
|
|
352
|
+
const block = blocks[i];
|
|
353
|
+
const text = block.textContent;
|
|
354
|
+
// Check for multi-block BEGIN...END loops
|
|
355
|
+
for (const tag of tags) {
|
|
356
|
+
if (!tag.title || !tag.content || !Array.isArray(tag.content)) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const tagName = tag.title;
|
|
360
|
+
const beginRegex = new RegExp(`\\{BEGIN_${tagName}(?::limit=(\\d+))?\\}`);
|
|
361
|
+
const beginMatch = text.match(beginRegex);
|
|
362
|
+
if (!beginMatch) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
// Find matching END in a later block
|
|
366
|
+
let endIndex = -1;
|
|
367
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
368
|
+
if (blocks[j].textContent.includes(`{END_${tagName}}`)) {
|
|
369
|
+
endIndex = j;
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (endIndex === -1 || endIndex === i) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
// Found multi-block loop - process it
|
|
377
|
+
const limit = beginMatch[1] ? parseInt(beginMatch[1]) : null;
|
|
378
|
+
this._replaceMultiBlockLoop(blocks, i, endIndex, tag, limit);
|
|
379
|
+
i = Math.min(i, blocks.length - 1);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// Process multi-block conditionals from end to start
|
|
384
|
+
for (let i = blocks.length - 1; i >= 0; i--) {
|
|
385
|
+
const block = blocks[i];
|
|
386
|
+
const text = block.textContent;
|
|
387
|
+
const ifMatch = text.match(/\{IF\(([^)]+)\)\}/);
|
|
388
|
+
if (!ifMatch) {
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
// Find matching ENDIF in a later block
|
|
392
|
+
let endIndex = -1;
|
|
393
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
394
|
+
if (/\{ENDIF\}/.test(blocks[j].textContent)) {
|
|
395
|
+
endIndex = j;
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (endIndex === -1 || endIndex === i) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
this._replaceMultiBlockConditional(blocks, i, endIndex, ifMatch[1], tagMap);
|
|
403
|
+
i = Math.min(i, blocks.length - 1);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
_replaceMultiBlockLoop(blocks, beginIndex, endIndex, tag, limit) {
|
|
407
|
+
const tagName = tag.title;
|
|
408
|
+
const beginBlock = blocks[beginIndex];
|
|
409
|
+
// Concatenate all blocks from begin to end
|
|
410
|
+
let combinedXml = "";
|
|
411
|
+
for (let i = beginIndex; i <= endIndex; i++) {
|
|
412
|
+
combinedXml += blocks[i].toString();
|
|
413
|
+
}
|
|
414
|
+
// Find the BEGIN and END tags in the combined XML
|
|
415
|
+
const beginRegex = new RegExp(`\\{BEGIN_${tagName}(?::limit=\\d+)?\\}`);
|
|
416
|
+
const beginMatch = combinedXml.match(beginRegex);
|
|
417
|
+
const endTag = `{END_${tagName}}`;
|
|
418
|
+
const endPos = combinedXml.indexOf(endTag);
|
|
419
|
+
if (!beginMatch || endPos === -1) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const beforeXml = combinedXml.slice(0, beginMatch.index);
|
|
423
|
+
const templateXml = combinedXml.slice(beginMatch.index + beginMatch[0].length, endPos);
|
|
424
|
+
const afterXml = combinedXml.slice(endPos + endTag.length);
|
|
425
|
+
// Decode > so expressions like >= work in nested conditionals
|
|
426
|
+
const decodedTemplateXml = templateXml.replace(/>/g, ">");
|
|
427
|
+
const replacementXml = this.processLoop(decodedTemplateXml, tag.content, tagName, limit);
|
|
428
|
+
const fullReplacement = beforeXml + replacementXml + afterXml;
|
|
429
|
+
// Parse replacement
|
|
430
|
+
const parent = beginBlock.parentElement;
|
|
431
|
+
const dom = xmlDOM(`<root>${fullReplacement}</root>`);
|
|
432
|
+
const root = dom.query("root");
|
|
433
|
+
const newBlocks = root.children.filter(child => child.tagName === "text:p" || child.tagName === "text:h");
|
|
434
|
+
// Insert new blocks before begin block
|
|
435
|
+
for (let i = newBlocks.length - 1; i >= 0; i--) {
|
|
436
|
+
parent.insertBefore(newBlocks[i], beginBlock);
|
|
437
|
+
}
|
|
438
|
+
// Remove old blocks
|
|
439
|
+
for (let i = endIndex; i >= beginIndex; i--) {
|
|
440
|
+
parent.removeChild(blocks[i]);
|
|
441
|
+
}
|
|
442
|
+
// Update blocks array
|
|
443
|
+
blocks.splice(beginIndex, endIndex - beginIndex + 1, ...newBlocks);
|
|
444
|
+
}
|
|
445
|
+
_replaceMultiBlockConditional(blocks, ifIndex, endIndex, expr, tagMap) {
|
|
446
|
+
const ifBlock = blocks[ifIndex];
|
|
447
|
+
// Concatenate all blocks from if to endif
|
|
448
|
+
let combinedXml = "";
|
|
449
|
+
for (let i = ifIndex; i <= endIndex; i++) {
|
|
450
|
+
combinedXml += blocks[i].toString();
|
|
451
|
+
}
|
|
452
|
+
// Determine which tag the expression references
|
|
453
|
+
let ctx = { count: 0, content: [] };
|
|
454
|
+
for (const tagName in tagMap) {
|
|
455
|
+
const safeTagName = tagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
456
|
+
if (new RegExp(`\\b${safeTagName}\\b`).test(expr)) {
|
|
457
|
+
const tag = tagMap[tagName];
|
|
458
|
+
ctx = {
|
|
459
|
+
tagName: tag.title,
|
|
460
|
+
count: tag.content ? tag.content.length : 0,
|
|
461
|
+
content: tag.content || []
|
|
462
|
+
};
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// Decode > so expressions like >= work in conditionals
|
|
467
|
+
const decodedXml = combinedXml.replace(/>/g, ">");
|
|
468
|
+
// Process conditionals on the combined XML
|
|
469
|
+
const processedXml = this.processConditionals(decodedXml, ctx);
|
|
470
|
+
if (processedXml === combinedXml) {
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
// Parse and replace
|
|
474
|
+
const parent = ifBlock.parentElement;
|
|
475
|
+
const dom = xmlDOM(`<root>${processedXml}</root>`);
|
|
476
|
+
const root = dom.query("root");
|
|
477
|
+
const newBlocks = root.children.filter(child => child.tagName === "text:p" || child.tagName === "text:h");
|
|
478
|
+
for (let i = newBlocks.length - 1; i >= 0; i--) {
|
|
479
|
+
parent.insertBefore(newBlocks[i], ifBlock);
|
|
480
|
+
}
|
|
481
|
+
for (let i = endIndex; i >= ifIndex; i--) {
|
|
482
|
+
parent.removeChild(blocks[i]);
|
|
483
|
+
}
|
|
484
|
+
blocks.splice(ifIndex, endIndex - ifIndex + 1, ...newBlocks);
|
|
485
|
+
}
|
|
486
|
+
// go through content.xml looking for tags and replace them with the given
|
|
487
|
+
// replacements.
|
|
488
|
+
render(docContent, pmBib, settings, richtext, citations) {
|
|
489
|
+
const tags = this.getTagData(docContent, pmBib, settings);
|
|
490
|
+
const textBlocks = this.text.queryAll(["text:p", "text:h"]);
|
|
491
|
+
// Process multi-block structured tags first (BEGIN...END across paragraphs)
|
|
492
|
+
this.processMultiBlockStructuredTags(textBlocks, tags);
|
|
493
|
+
textBlocks.forEach(block => {
|
|
494
|
+
if (block.parentElement.nodeName === "text:deletion") {
|
|
495
|
+
// Inside of tracked changes deletion, don't do anything
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
const text = block.textContent;
|
|
499
|
+
tags.forEach(tag => {
|
|
500
|
+
const tagString = tag.title;
|
|
501
|
+
const hasInlineTag = text.includes(`{${tagString}}`) ||
|
|
502
|
+
text.includes(`{${tagString}:format=`);
|
|
503
|
+
const hasBeginTag = text.includes(`{BEGIN_${tagString}}`);
|
|
504
|
+
const hasIfTag = text.includes(`{IF(${tagString}.`) ||
|
|
505
|
+
text.includes(`{IF(ctx.`);
|
|
506
|
+
if (hasInlineTag || hasBeginTag || hasIfTag) {
|
|
507
|
+
tag.block = block;
|
|
508
|
+
if (hasInlineTag && tag.title[0] === "@") {
|
|
509
|
+
this.blockRender(tag, richtext, citations);
|
|
510
|
+
}
|
|
511
|
+
else if (hasInlineTag && tag.title[0] !== "@") {
|
|
512
|
+
this.inlineRender(tag);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
// Parse structured tags (BEGIN...END and IF...ENDIF)
|
|
517
|
+
tags.forEach(tag => {
|
|
518
|
+
if (tag.block) {
|
|
519
|
+
this.parseStructuredTags(tag.block, tag);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
// Render Tags that only exchange inline content
|
|
525
|
+
inlineRender(tag) {
|
|
526
|
+
const blockText = tag.block.textContent;
|
|
527
|
+
const tagString = tag.title;
|
|
528
|
+
if (!blockText.includes(`{${tag.title}`)) {
|
|
529
|
+
// No inline tag present - structured tags only
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
// Check for format string with delimiter: {tag:format=%firstname|; }
|
|
533
|
+
const formatRegex = new RegExp(`\\{${tagString}:format=([^|]+)\\|?([^}]*)?\\}`);
|
|
534
|
+
const formatMatch = blockText.match(formatRegex);
|
|
535
|
+
let fullText = "";
|
|
536
|
+
if (formatMatch && tag.content && Array.isArray(tag.content)) {
|
|
537
|
+
// Find format string and delimiter
|
|
538
|
+
const [, format, delimiter = "; "] = formatMatch;
|
|
539
|
+
// Process each item with the format string
|
|
540
|
+
const formattedItems = tag.content
|
|
541
|
+
.map(item => {
|
|
542
|
+
if (typeof item === "string") {
|
|
543
|
+
// For tags (simple strings)
|
|
544
|
+
return format.replace(/%tag/g, item);
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
// For contributors (objects)
|
|
548
|
+
return format
|
|
549
|
+
.replace(/%firstname/g, item.firstname || "")
|
|
550
|
+
.replace(/%lastname/g, item.lastname || "")
|
|
551
|
+
.replace(/%institution/g, item.institution || "")
|
|
552
|
+
.replace(/%email/g, item.email || "")
|
|
553
|
+
.replace(/%id_type/g, item.id_type || "")
|
|
554
|
+
.replace(/%id_value/g, item.id_value || "");
|
|
555
|
+
}
|
|
556
|
+
})
|
|
557
|
+
.filter(s => s.trim() !== "");
|
|
558
|
+
// Handle special delimiters for ODT
|
|
559
|
+
let delimiterXml = delimiter;
|
|
560
|
+
delimiterXml = delimiterXml.replace(/\\n/g, "<text:line-break/>");
|
|
561
|
+
delimiterXml = delimiterXml.replace(/\\p/g, "<text:line-break/><text:line-break/>");
|
|
562
|
+
const replacement = formattedItems.join(delimiterXml);
|
|
563
|
+
fullText = blockText.replace(formatRegex, replacement);
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
// Fall back to simple string replacement (backward compatible)
|
|
567
|
+
let contentStr = tag.content || "";
|
|
568
|
+
if (Array.isArray(contentStr)) {
|
|
569
|
+
if (contentStr.length === 0) {
|
|
570
|
+
contentStr = "";
|
|
571
|
+
}
|
|
572
|
+
else if (typeof contentStr[0] === "string") {
|
|
573
|
+
contentStr = contentStr.join(", ");
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
// Contributors - backward compatible formatting
|
|
577
|
+
contentStr = contentStr
|
|
578
|
+
.map(item => {
|
|
579
|
+
const nameParts = [];
|
|
580
|
+
let affiliation = false;
|
|
581
|
+
if (item.firstname) {
|
|
582
|
+
nameParts.push(item.firstname);
|
|
583
|
+
}
|
|
584
|
+
if (item.lastname) {
|
|
585
|
+
nameParts.push(item.lastname);
|
|
586
|
+
}
|
|
587
|
+
if (item.institution) {
|
|
588
|
+
if (nameParts.length) {
|
|
589
|
+
affiliation = item.institution;
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
nameParts.push(item.institution);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
const parts = [nameParts.join(" ")];
|
|
596
|
+
if (affiliation) {
|
|
597
|
+
parts.push(affiliation);
|
|
598
|
+
}
|
|
599
|
+
if (item.email) {
|
|
600
|
+
parts.push(item.email);
|
|
601
|
+
}
|
|
602
|
+
if (item.id_type && item.id_value) {
|
|
603
|
+
parts.push(`${item.id_type}: ${item.id_value}`);
|
|
604
|
+
}
|
|
605
|
+
return parts.join(", ");
|
|
606
|
+
})
|
|
607
|
+
.join("; ");
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
const texts = blockText.split(`{${tagString}}`);
|
|
611
|
+
fullText = texts[0] + contentStr + texts[1];
|
|
612
|
+
}
|
|
613
|
+
// Escape text but restore ODT XML line break tags
|
|
614
|
+
fullText = escapeText(fullText).replace(/<text:line-break\/>/g, "<text:line-break/>");
|
|
615
|
+
tag.block.innerXML = fullText.replace(/^\s+|\s+$/g, match => "<text:s/>".repeat(match.length));
|
|
616
|
+
}
|
|
617
|
+
// Render tags that exchange text blocks
|
|
618
|
+
blockRender(tag, richtext, citations) {
|
|
619
|
+
const section = tag.block.hasAttribute("text:style-name")
|
|
620
|
+
? tag.block.getAttribute("text:style-name")
|
|
621
|
+
: "Text_20_body";
|
|
622
|
+
const outXML = tag.content
|
|
623
|
+
? tag.content
|
|
624
|
+
.map((content, contentIndex) => richtext.run(content, {
|
|
625
|
+
citationType: citations.citFm.citationType,
|
|
626
|
+
section,
|
|
627
|
+
tag: tag.title.slice(1)
|
|
628
|
+
}, tag, contentIndex))
|
|
629
|
+
.join("")
|
|
630
|
+
: "";
|
|
631
|
+
if (!outXML.length) {
|
|
632
|
+
// If there is no content, we need to put in a space to prevent the
|
|
633
|
+
// tag from being removed by LibreOffice.
|
|
634
|
+
tag.block.innerXML = "<text:s/>";
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const parentElement = tag.block.parentElement;
|
|
638
|
+
const dom = xmlDOM(outXML);
|
|
639
|
+
const domPars = dom.node["#document"]?.slice() || [dom];
|
|
640
|
+
domPars.forEach(node => parentElement.insertBefore(node, tag.block));
|
|
641
|
+
parentElement.removeChild(tag.block);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
//# sourceMappingURL=render.js.map
|