scitex 2.7.0__py3-none-any.whl → 2.8.1__py3-none-any.whl
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.
- scitex/__init__.py +6 -2
- scitex/__version__.py +1 -1
- scitex/audio/README.md +52 -0
- scitex/audio/__init__.py +384 -0
- scitex/audio/__main__.py +129 -0
- scitex/audio/_tts.py +334 -0
- scitex/audio/engines/__init__.py +44 -0
- scitex/audio/engines/base.py +275 -0
- scitex/audio/engines/elevenlabs_engine.py +143 -0
- scitex/audio/engines/gtts_engine.py +162 -0
- scitex/audio/engines/pyttsx3_engine.py +131 -0
- scitex/audio/mcp_server.py +757 -0
- scitex/bridge/_helpers.py +1 -1
- scitex/bridge/_plt_vis.py +1 -1
- scitex/bridge/_stats_vis.py +1 -1
- scitex/dev/plt/__init__.py +272 -0
- scitex/dev/plt/plot_mpl_axhline.py +28 -0
- scitex/dev/plt/plot_mpl_axhspan.py +28 -0
- scitex/dev/plt/plot_mpl_axvline.py +28 -0
- scitex/dev/plt/plot_mpl_axvspan.py +28 -0
- scitex/dev/plt/plot_mpl_bar.py +29 -0
- scitex/dev/plt/plot_mpl_barh.py +29 -0
- scitex/dev/plt/plot_mpl_boxplot.py +28 -0
- scitex/dev/plt/plot_mpl_contour.py +31 -0
- scitex/dev/plt/plot_mpl_contourf.py +31 -0
- scitex/dev/plt/plot_mpl_errorbar.py +30 -0
- scitex/dev/plt/plot_mpl_eventplot.py +28 -0
- scitex/dev/plt/plot_mpl_fill.py +30 -0
- scitex/dev/plt/plot_mpl_fill_between.py +31 -0
- scitex/dev/plt/plot_mpl_hexbin.py +28 -0
- scitex/dev/plt/plot_mpl_hist.py +28 -0
- scitex/dev/plt/plot_mpl_hist2d.py +28 -0
- scitex/dev/plt/plot_mpl_imshow.py +29 -0
- scitex/dev/plt/plot_mpl_pcolormesh.py +31 -0
- scitex/dev/plt/plot_mpl_pie.py +29 -0
- scitex/dev/plt/plot_mpl_plot.py +29 -0
- scitex/dev/plt/plot_mpl_quiver.py +31 -0
- scitex/dev/plt/plot_mpl_scatter.py +28 -0
- scitex/dev/plt/plot_mpl_stackplot.py +31 -0
- scitex/dev/plt/plot_mpl_stem.py +29 -0
- scitex/dev/plt/plot_mpl_step.py +29 -0
- scitex/dev/plt/plot_mpl_violinplot.py +28 -0
- scitex/dev/plt/plot_sns_barplot.py +29 -0
- scitex/dev/plt/plot_sns_boxplot.py +29 -0
- scitex/dev/plt/plot_sns_heatmap.py +28 -0
- scitex/dev/plt/plot_sns_histplot.py +29 -0
- scitex/dev/plt/plot_sns_kdeplot.py +29 -0
- scitex/dev/plt/plot_sns_lineplot.py +31 -0
- scitex/dev/plt/plot_sns_scatterplot.py +29 -0
- scitex/dev/plt/plot_sns_stripplot.py +29 -0
- scitex/dev/plt/plot_sns_swarmplot.py +29 -0
- scitex/dev/plt/plot_sns_violinplot.py +29 -0
- scitex/dev/plt/plot_stx_bar.py +29 -0
- scitex/dev/plt/plot_stx_barh.py +29 -0
- scitex/dev/plt/plot_stx_box.py +28 -0
- scitex/dev/plt/plot_stx_boxplot.py +28 -0
- scitex/dev/plt/plot_stx_conf_mat.py +28 -0
- scitex/dev/plt/plot_stx_contour.py +31 -0
- scitex/dev/plt/plot_stx_ecdf.py +28 -0
- scitex/dev/plt/plot_stx_errorbar.py +30 -0
- scitex/dev/plt/plot_stx_fill_between.py +31 -0
- scitex/dev/plt/plot_stx_fillv.py +28 -0
- scitex/dev/plt/plot_stx_heatmap.py +28 -0
- scitex/dev/plt/plot_stx_image.py +28 -0
- scitex/dev/plt/plot_stx_imshow.py +28 -0
- scitex/dev/plt/plot_stx_joyplot.py +28 -0
- scitex/dev/plt/plot_stx_kde.py +28 -0
- scitex/dev/plt/plot_stx_line.py +28 -0
- scitex/dev/plt/plot_stx_mean_ci.py +28 -0
- scitex/dev/plt/plot_stx_mean_std.py +28 -0
- scitex/dev/plt/plot_stx_median_iqr.py +28 -0
- scitex/dev/plt/plot_stx_raster.py +28 -0
- scitex/dev/plt/plot_stx_rectangle.py +28 -0
- scitex/dev/plt/plot_stx_scatter.py +29 -0
- scitex/dev/plt/plot_stx_shaded_line.py +29 -0
- scitex/dev/plt/plot_stx_violin.py +28 -0
- scitex/dev/plt/plot_stx_violinplot.py +28 -0
- scitex/diagram/README.md +197 -0
- scitex/diagram/__init__.py +48 -0
- scitex/diagram/_compile.py +312 -0
- scitex/diagram/_diagram.py +355 -0
- scitex/diagram/_presets.py +173 -0
- scitex/diagram/_schema.py +182 -0
- scitex/diagram/_split.py +278 -0
- scitex/fig/__init__.py +352 -0
- scitex/{vis → fig}/backend/_parser.py +1 -1
- scitex/{vis → fig}/canvas.py +1 -1
- scitex/{vis → fig}/editor/__init__.py +5 -2
- scitex/{vis → fig}/editor/_dearpygui_editor.py +1 -1
- scitex/{vis → fig}/editor/_defaults.py +70 -5
- scitex/{vis → fig}/editor/_mpl_editor.py +1 -1
- scitex/{vis → fig}/editor/_qt_editor.py +182 -2
- scitex/{vis → fig}/editor/_tkinter_editor.py +1 -1
- scitex/fig/editor/edit/__init__.py +50 -0
- scitex/fig/editor/edit/backend_detector.py +109 -0
- scitex/fig/editor/edit/bundle_resolver.py +240 -0
- scitex/fig/editor/edit/editor_launcher.py +239 -0
- scitex/fig/editor/edit/manual_handler.py +53 -0
- scitex/fig/editor/edit/panel_loader.py +232 -0
- scitex/fig/editor/edit/path_resolver.py +67 -0
- scitex/fig/editor/flask_editor/_bbox.py +1299 -0
- scitex/fig/editor/flask_editor/_core.py +1429 -0
- scitex/{vis → fig}/editor/flask_editor/_plotter.py +38 -4
- scitex/fig/editor/flask_editor/_renderer.py +813 -0
- scitex/fig/editor/flask_editor/static/css/base/reset.css +41 -0
- scitex/fig/editor/flask_editor/static/css/base/typography.css +16 -0
- scitex/fig/editor/flask_editor/static/css/base/variables.css +85 -0
- scitex/fig/editor/flask_editor/static/css/components/buttons.css +217 -0
- scitex/fig/editor/flask_editor/static/css/components/context-menu.css +93 -0
- scitex/fig/editor/flask_editor/static/css/components/dropdown.css +57 -0
- scitex/fig/editor/flask_editor/static/css/components/forms.css +112 -0
- scitex/fig/editor/flask_editor/static/css/components/modal.css +59 -0
- scitex/fig/editor/flask_editor/static/css/components/sections.css +212 -0
- scitex/fig/editor/flask_editor/static/css/features/canvas.css +176 -0
- scitex/fig/editor/flask_editor/static/css/features/element-inspector.css +190 -0
- scitex/fig/editor/flask_editor/static/css/features/loading.css +59 -0
- scitex/fig/editor/flask_editor/static/css/features/overlay.css +45 -0
- scitex/fig/editor/flask_editor/static/css/features/panel-grid.css +95 -0
- scitex/fig/editor/flask_editor/static/css/features/selection.css +101 -0
- scitex/fig/editor/flask_editor/static/css/features/statistics.css +138 -0
- scitex/fig/editor/flask_editor/static/css/index.css +31 -0
- scitex/fig/editor/flask_editor/static/css/layout/container.css +7 -0
- scitex/fig/editor/flask_editor/static/css/layout/controls.css +56 -0
- scitex/fig/editor/flask_editor/static/css/layout/preview.css +78 -0
- scitex/fig/editor/flask_editor/static/js/alignment/axis.js +314 -0
- scitex/fig/editor/flask_editor/static/js/alignment/basic.js +107 -0
- scitex/fig/editor/flask_editor/static/js/alignment/distribute.js +54 -0
- scitex/fig/editor/flask_editor/static/js/canvas/canvas.js +172 -0
- scitex/fig/editor/flask_editor/static/js/canvas/dragging.js +258 -0
- scitex/fig/editor/flask_editor/static/js/canvas/resize.js +48 -0
- scitex/fig/editor/flask_editor/static/js/canvas/selection.js +71 -0
- scitex/fig/editor/flask_editor/static/js/core/api.js +288 -0
- scitex/fig/editor/flask_editor/static/js/core/state.js +143 -0
- scitex/fig/editor/flask_editor/static/js/core/utils.js +245 -0
- scitex/fig/editor/flask_editor/static/js/dev/element-inspector.js +992 -0
- scitex/fig/editor/flask_editor/static/js/editor/bbox.js +339 -0
- scitex/fig/editor/flask_editor/static/js/editor/element-drag.js +286 -0
- scitex/fig/editor/flask_editor/static/js/editor/overlay.js +371 -0
- scitex/fig/editor/flask_editor/static/js/editor/preview.js +293 -0
- scitex/fig/editor/flask_editor/static/js/main.js +426 -0
- scitex/fig/editor/flask_editor/static/js/shortcuts/context-menu.js +152 -0
- scitex/fig/editor/flask_editor/static/js/shortcuts/keyboard.js +265 -0
- scitex/fig/editor/flask_editor/static/js/ui/controls.js +184 -0
- scitex/fig/editor/flask_editor/static/js/ui/download.js +57 -0
- scitex/fig/editor/flask_editor/static/js/ui/help.js +100 -0
- scitex/fig/editor/flask_editor/static/js/ui/theme.js +34 -0
- scitex/fig/editor/flask_editor/templates/__init__.py +123 -0
- scitex/fig/editor/flask_editor/templates/_html.py +852 -0
- scitex/fig/editor/flask_editor/templates/_scripts.py +4933 -0
- scitex/fig/editor/flask_editor/templates/_styles.py +1658 -0
- scitex/{vis → fig}/io/__init__.py +13 -1
- scitex/fig/io/_bundle.py +1058 -0
- scitex/{vis → fig}/io/_canvas.py +1 -1
- scitex/{vis → fig}/io/_data.py +1 -1
- scitex/{vis → fig}/io/_export.py +1 -1
- scitex/{vis → fig}/io/_load.py +1 -1
- scitex/{vis → fig}/io/_panel.py +1 -1
- scitex/{vis → fig}/io/_save.py +1 -1
- scitex/{vis → fig}/model/__init__.py +1 -1
- scitex/{vis → fig}/model/_annotations.py +1 -1
- scitex/{vis → fig}/model/_axes.py +1 -1
- scitex/{vis → fig}/model/_figure.py +1 -1
- scitex/{vis → fig}/model/_guides.py +1 -1
- scitex/{vis → fig}/model/_plot.py +1 -1
- scitex/{vis → fig}/model/_styles.py +1 -1
- scitex/{vis → fig}/utils/__init__.py +1 -1
- scitex/io/__init__.py +22 -26
- scitex/io/_bundle.py +493 -0
- scitex/io/_flush.py +5 -2
- scitex/io/_load.py +98 -0
- scitex/io/_load_modules/_H5Explorer.py +5 -2
- scitex/io/_load_modules/_canvas.py +2 -2
- scitex/io/_load_modules/_image.py +3 -4
- scitex/io/_load_modules/_txt.py +4 -2
- scitex/io/_metadata.py +34 -324
- scitex/io/_metadata_modules/__init__.py +46 -0
- scitex/io/_metadata_modules/_embed.py +70 -0
- scitex/io/_metadata_modules/_read.py +64 -0
- scitex/io/_metadata_modules/_utils.py +79 -0
- scitex/io/_metadata_modules/embed_metadata_jpeg.py +74 -0
- scitex/io/_metadata_modules/embed_metadata_pdf.py +53 -0
- scitex/io/_metadata_modules/embed_metadata_png.py +26 -0
- scitex/io/_metadata_modules/embed_metadata_svg.py +62 -0
- scitex/io/_metadata_modules/read_metadata_jpeg.py +57 -0
- scitex/io/_metadata_modules/read_metadata_pdf.py +51 -0
- scitex/io/_metadata_modules/read_metadata_png.py +39 -0
- scitex/io/_metadata_modules/read_metadata_svg.py +44 -0
- scitex/io/_qr_utils.py +5 -3
- scitex/io/_save.py +548 -30
- scitex/io/_save_modules/_canvas.py +3 -3
- scitex/io/_save_modules/_image.py +5 -9
- scitex/io/_save_modules/_tex.py +7 -4
- scitex/io/_zip_bundle.py +439 -0
- scitex/io/utils/h5_to_zarr.py +11 -9
- scitex/msword/__init__.py +255 -0
- scitex/msword/profiles.py +357 -0
- scitex/msword/reader.py +753 -0
- scitex/msword/utils.py +289 -0
- scitex/msword/writer.py +362 -0
- scitex/plt/__init__.py +5 -2
- scitex/plt/_subplots/_AxesWrapper.py +6 -6
- scitex/plt/_subplots/_AxisWrapper.py +15 -9
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +36 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +264 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +213 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +128 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +59 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +34 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +593 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +654 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +527 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +321 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +33 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +152 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +600 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +79 -5
- scitex/plt/_subplots/_FigWrapper.py +6 -6
- scitex/plt/_subplots/_SubplotsWrapper.py +28 -18
- scitex/plt/_subplots/_export_as_csv.py +35 -5
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +8 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +10 -21
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +18 -7
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +28 -12
- scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +10 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +13 -1
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +12 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +10 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +18 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +44 -36
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +14 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +11 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +84 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +85 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +14 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_contour.py +54 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +14 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +120 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +16 -6
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +29 -19
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_imshow.py +63 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +22 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +18 -14
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +18 -14
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +18 -14
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +10 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +51 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +18 -9
- scitex/plt/ax/_plot/_stx_ecdf.py +4 -2
- scitex/plt/gallery/_generate.py +421 -14
- scitex/plt/io/__init__.py +53 -0
- scitex/plt/io/_bundle.py +490 -0
- scitex/plt/io/_layered_bundle.py +1343 -0
- scitex/plt/styles/SCITEX_STYLE.yaml +26 -0
- scitex/plt/styles/__init__.py +14 -0
- scitex/plt/styles/presets.py +78 -0
- scitex/plt/utils/__init__.py +13 -1
- scitex/plt/utils/_collect_figure_metadata.py +10 -14
- scitex/plt/utils/_configure_mpl.py +6 -18
- scitex/plt/utils/_crop.py +32 -14
- scitex/plt/utils/_csv_column_naming.py +54 -0
- scitex/plt/utils/_figure_mm.py +116 -1
- scitex/plt/utils/_hitmap.py +1643 -0
- scitex/plt/utils/metadata/__init__.py +25 -0
- scitex/plt/utils/metadata/_core.py +9 -10
- scitex/plt/utils/metadata/_dimensions.py +6 -3
- scitex/plt/utils/metadata/_editable_export.py +405 -0
- scitex/plt/utils/metadata/_geometry_extraction.py +570 -0
- scitex/schema/__init__.py +109 -16
- scitex/schema/_canvas.py +1 -1
- scitex/schema/_plot.py +1015 -0
- scitex/schema/_stats.py +2 -2
- scitex/stats/__init__.py +117 -0
- scitex/stats/io/__init__.py +29 -0
- scitex/stats/io/_bundle.py +156 -0
- scitex/tex/__init__.py +4 -0
- scitex/tex/_export.py +890 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/METADATA +11 -1
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/RECORD +294 -170
- scitex/io/memo.md +0 -2827
- scitex/plt/REQUESTS.md +0 -191
- scitex/plt/_subplots/TODO.md +0 -53
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +0 -559
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +0 -1609
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +0 -447
- scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +0 -110
- scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +0 -88
- scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +0 -103
- scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +0 -106
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +0 -83
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +0 -93
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +0 -91
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +0 -91
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +0 -91
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +0 -97
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +0 -98
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +0 -101
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +0 -93
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +0 -83
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +0 -121
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +0 -110
- scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +0 -94
- scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +0 -109
- scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +0 -108
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +0 -93
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +0 -99
- scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +0 -100
- scitex/vis/__init__.py +0 -177
- scitex/vis/editor/_edit.py +0 -390
- scitex/vis/editor/flask_editor/_bbox.py +0 -529
- scitex/vis/editor/flask_editor/_core.py +0 -168
- scitex/vis/editor/flask_editor/_renderer.py +0 -393
- scitex/vis/editor/flask_editor/templates/__init__.py +0 -33
- scitex/vis/editor/flask_editor/templates/_html.py +0 -513
- scitex/vis/editor/flask_editor/templates/_scripts.py +0 -1261
- scitex/vis/editor/flask_editor/templates/_styles.py +0 -739
- /scitex/{vis → fig}/README.md +0 -0
- /scitex/{vis → fig}/backend/__init__.py +0 -0
- /scitex/{vis → fig}/backend/_export.py +0 -0
- /scitex/{vis → fig}/backend/_render.py +0 -0
- /scitex/{vis → fig}/docs/CANVAS_ARCHITECTURE.md +0 -0
- /scitex/{vis → fig}/editor/_flask_editor.py +0 -0
- /scitex/{vis → fig}/editor/flask_editor/__init__.py +0 -0
- /scitex/{vis → fig}/editor/flask_editor/_utils.py +0 -0
- /scitex/{vis → fig}/io/_directory.py +0 -0
- /scitex/{vis → fig}/model/_plot_types.py +0 -0
- /scitex/{vis → fig}/utils/_defaults.py +0 -0
- /scitex/{vis → fig}/utils/_validate.py +0 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/WHEEL +0 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/entry_points.txt +0 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: 2025-12-11 15:15:00
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/msword/__init__.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MS Word (DOCX) import/export utilities for SciTeX.
|
|
8
|
+
|
|
9
|
+
This module provides high-level functions to convert between
|
|
10
|
+
MS Word .docx files and SciTeX's internal writer document model.
|
|
11
|
+
|
|
12
|
+
Strategy:
|
|
13
|
+
---------
|
|
14
|
+
- Word users write text only (paragraphs, minimal formatting)
|
|
15
|
+
- SciTeX handles: figures, tables, references, LaTeX generation
|
|
16
|
+
- SciTeX JSON is the "source of truth", Word is just a view/edit layer
|
|
17
|
+
|
|
18
|
+
Typical usage:
|
|
19
|
+
--------------
|
|
20
|
+
from scitex.msword import load_docx, save_docx, list_profiles
|
|
21
|
+
|
|
22
|
+
# Import from Word
|
|
23
|
+
doc = load_docx("input.docx", profile="generic")
|
|
24
|
+
|
|
25
|
+
# Manipulate via scitex.writer...
|
|
26
|
+
# doc.normalize()
|
|
27
|
+
|
|
28
|
+
# Export to Word (different journal template)
|
|
29
|
+
save_docx(doc, "output.docx", profile="mdpi-ijerph")
|
|
30
|
+
|
|
31
|
+
Available profiles:
|
|
32
|
+
-------------------
|
|
33
|
+
- generic: Standard Word with Heading 1/2/3
|
|
34
|
+
- mdpi-ijerph: MDPI IJERPH journal template
|
|
35
|
+
- resna-2025: RESNA 2025 scientific paper template
|
|
36
|
+
- iop-double-anonymous: IOP double-anonymous template
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
from __future__ import annotations
|
|
40
|
+
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
from typing import Any, Optional
|
|
43
|
+
|
|
44
|
+
from .profiles import (
|
|
45
|
+
BaseWordProfile,
|
|
46
|
+
get_profile,
|
|
47
|
+
list_profiles,
|
|
48
|
+
register_profile,
|
|
49
|
+
)
|
|
50
|
+
from .reader import WordReader
|
|
51
|
+
from .writer import WordWriter
|
|
52
|
+
from .utils import (
|
|
53
|
+
link_captions_to_images,
|
|
54
|
+
link_captions_to_images_by_proximity,
|
|
55
|
+
normalize_section_headings,
|
|
56
|
+
validate_document,
|
|
57
|
+
create_post_import_hook,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def load_docx(
|
|
62
|
+
path: str | Path,
|
|
63
|
+
profile: str | None = None,
|
|
64
|
+
extract_images: bool = True,
|
|
65
|
+
) -> dict[str, Any]:
|
|
66
|
+
"""
|
|
67
|
+
Load a DOCX file and convert it into a SciTeX writer document.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
path : str | Path
|
|
72
|
+
Path to the .docx file.
|
|
73
|
+
profile : str | None
|
|
74
|
+
Optional profile name that specifies how to interpret Word styles
|
|
75
|
+
(e.g., "mdpi-ijerph", "resna-2025"). If None, "generic" is used.
|
|
76
|
+
extract_images : bool
|
|
77
|
+
If True, extract embedded images and store references.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
dict
|
|
82
|
+
A SciTeX writer document structure containing:
|
|
83
|
+
- blocks: List of document blocks (headings, paragraphs, captions, etc.)
|
|
84
|
+
- metadata: Profile and source file information
|
|
85
|
+
- images: Extracted image references (if extract_images=True)
|
|
86
|
+
- references: Parsed reference entries
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
>>> from scitex.msword import load_docx
|
|
91
|
+
>>> doc = load_docx("manuscript.docx", profile="mdpi-ijerph")
|
|
92
|
+
>>> print(doc["metadata"]["profile"])
|
|
93
|
+
'mdpi-ijerph'
|
|
94
|
+
"""
|
|
95
|
+
path = Path(path)
|
|
96
|
+
profile_obj: BaseWordProfile = get_profile(profile)
|
|
97
|
+
reader = WordReader(profile=profile_obj, extract_images=extract_images)
|
|
98
|
+
return reader.read(path)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def save_docx(
|
|
102
|
+
writer_doc: dict[str, Any] | Any,
|
|
103
|
+
path: str | Path,
|
|
104
|
+
profile: str | None = None,
|
|
105
|
+
overwrite: bool = True,
|
|
106
|
+
template_path: str | Path | None = None,
|
|
107
|
+
) -> Path:
|
|
108
|
+
"""
|
|
109
|
+
Save a SciTeX writer document as a DOCX file.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
writer_doc : dict | Any
|
|
114
|
+
SciTeX writer document instance to export.
|
|
115
|
+
path : str | Path
|
|
116
|
+
Output path for the .docx file.
|
|
117
|
+
profile : str | None
|
|
118
|
+
Optional profile name that controls how sections, headings,
|
|
119
|
+
figures, tables and references are mapped to Word styles.
|
|
120
|
+
If None, "generic" is used.
|
|
121
|
+
overwrite : bool
|
|
122
|
+
If False and the file already exists, raises FileExistsError.
|
|
123
|
+
template_path : str | Path | None
|
|
124
|
+
Optional path to a Word template (.dotx/.docx) to use as base.
|
|
125
|
+
This allows using journal-specific formatting.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
Path
|
|
130
|
+
The path to the written .docx file.
|
|
131
|
+
|
|
132
|
+
Examples
|
|
133
|
+
--------
|
|
134
|
+
>>> from scitex.msword import save_docx
|
|
135
|
+
>>> save_docx(doc, "submission_resna_2025.docx", profile="resna-2025")
|
|
136
|
+
PosixPath('submission_resna_2025.docx')
|
|
137
|
+
"""
|
|
138
|
+
output_path = Path(path)
|
|
139
|
+
if output_path.exists() and not overwrite:
|
|
140
|
+
raise FileExistsError(f"File already exists: {output_path}")
|
|
141
|
+
|
|
142
|
+
profile_obj: BaseWordProfile = get_profile(profile)
|
|
143
|
+
writer = WordWriter(profile=profile_obj, template_path=template_path)
|
|
144
|
+
writer.write(writer_doc, output_path)
|
|
145
|
+
return output_path
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def convert_docx_to_tex(
|
|
149
|
+
input_path: str | Path,
|
|
150
|
+
output_path: str | Path,
|
|
151
|
+
profile: str | None = None,
|
|
152
|
+
*,
|
|
153
|
+
image_dir: str | Path | None = None,
|
|
154
|
+
link_images: bool = True,
|
|
155
|
+
link_mode: str = "by-number",
|
|
156
|
+
normalize_headings: bool = True,
|
|
157
|
+
validate: bool = True,
|
|
158
|
+
) -> Path:
|
|
159
|
+
"""
|
|
160
|
+
Convert a DOCX file directly to LaTeX.
|
|
161
|
+
|
|
162
|
+
This is a convenience function that:
|
|
163
|
+
1. Loads the DOCX file into SciTeX intermediate format
|
|
164
|
+
2. (Optionally) normalizes headings
|
|
165
|
+
3. (Optionally) links figure captions to images
|
|
166
|
+
4. (Optionally) validates the document and adds warnings
|
|
167
|
+
5. Exports to LaTeX (including figures via image_dir)
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
input_path : str | Path
|
|
172
|
+
Path to the input .docx file.
|
|
173
|
+
output_path : str | Path
|
|
174
|
+
Path for the output .tex file.
|
|
175
|
+
profile : str | None
|
|
176
|
+
Word profile for interpreting styles
|
|
177
|
+
(e.g., "resna-2025", "iop-double-anonymous").
|
|
178
|
+
image_dir : str | Path | None, optional
|
|
179
|
+
Directory where extracted figure image files will be saved.
|
|
180
|
+
If None, the LaTeX exporter will create "<tex_stem>_figures"
|
|
181
|
+
next to `output_path`.
|
|
182
|
+
link_images : bool, default True
|
|
183
|
+
Whether to link figure captions to extracted images so that
|
|
184
|
+
LaTeX can generate \\includegraphics inside figure environments.
|
|
185
|
+
link_mode : {"by-number", "by-proximity"}, default "by-number"
|
|
186
|
+
Strategy for linking captions to images:
|
|
187
|
+
- "by-number": Figure 1 -> first image, Figure 2 -> second image...
|
|
188
|
+
- "by-proximity": assign images in document order, useful when
|
|
189
|
+
figure numbers and image order don't match.
|
|
190
|
+
normalize_headings : bool, default True
|
|
191
|
+
If True, apply common heading normalizations
|
|
192
|
+
(e.g., "intro" -> "Introduction").
|
|
193
|
+
validate : bool, default True
|
|
194
|
+
If True, run basic structural checks and populate
|
|
195
|
+
doc["warnings"] with any issues.
|
|
196
|
+
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
Path
|
|
200
|
+
The path to the written .tex file.
|
|
201
|
+
|
|
202
|
+
Examples
|
|
203
|
+
--------
|
|
204
|
+
>>> from scitex.msword import convert_docx_to_tex
|
|
205
|
+
>>> convert_docx_to_tex(
|
|
206
|
+
... "RESNA 2025 Scientific Paper Template.docx",
|
|
207
|
+
... "manuscript.tex",
|
|
208
|
+
... profile="resna-2025",
|
|
209
|
+
... image_dir="figures",
|
|
210
|
+
... )
|
|
211
|
+
PosixPath('manuscript.tex')
|
|
212
|
+
"""
|
|
213
|
+
# Import here to avoid circular imports
|
|
214
|
+
from scitex.tex import export_tex
|
|
215
|
+
|
|
216
|
+
# 1. DOCX -> SciTeX intermediate format
|
|
217
|
+
doc = load_docx(input_path, profile=profile, extract_images=True)
|
|
218
|
+
|
|
219
|
+
# 2. Normalize headings (optional)
|
|
220
|
+
if normalize_headings:
|
|
221
|
+
doc = normalize_section_headings(doc)
|
|
222
|
+
|
|
223
|
+
# 3. Link captions to images (optional)
|
|
224
|
+
if link_images and doc.get("images"):
|
|
225
|
+
if link_mode == "by-proximity":
|
|
226
|
+
doc = link_captions_to_images_by_proximity(doc)
|
|
227
|
+
else:
|
|
228
|
+
# Default: link by figure number
|
|
229
|
+
doc = link_captions_to_images(doc)
|
|
230
|
+
|
|
231
|
+
# 4. Validate document structure (optional)
|
|
232
|
+
if validate:
|
|
233
|
+
doc = validate_document(doc)
|
|
234
|
+
|
|
235
|
+
# 5. SciTeX -> LaTeX (with figures)
|
|
236
|
+
return export_tex(doc, output_path, image_dir=image_dir)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
__all__ = [
|
|
240
|
+
"load_docx",
|
|
241
|
+
"save_docx",
|
|
242
|
+
"convert_docx_to_tex",
|
|
243
|
+
"list_profiles",
|
|
244
|
+
"get_profile",
|
|
245
|
+
"register_profile",
|
|
246
|
+
"BaseWordProfile",
|
|
247
|
+
"WordReader",
|
|
248
|
+
"WordWriter",
|
|
249
|
+
# Utility functions for post-processing
|
|
250
|
+
"link_captions_to_images",
|
|
251
|
+
"link_captions_to_images_by_proximity",
|
|
252
|
+
"normalize_section_headings",
|
|
253
|
+
"validate_document",
|
|
254
|
+
"create_post_import_hook",
|
|
255
|
+
]
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: 2025-12-11 15:15:00
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/msword/profiles.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Profiles for mapping MS Word styles to SciTeX writer structures.
|
|
8
|
+
|
|
9
|
+
Each profile corresponds to a journal / conference template, such as:
|
|
10
|
+
- "generic"
|
|
11
|
+
- "mdpi-ijerph"
|
|
12
|
+
- "resna-2025"
|
|
13
|
+
- "iop-double-anonymous"
|
|
14
|
+
|
|
15
|
+
The profiles define:
|
|
16
|
+
- Which Word style names correspond to section headings
|
|
17
|
+
- How to detect captions for figures and tables
|
|
18
|
+
- How to handle references, lists, equations, etc.
|
|
19
|
+
- Layout settings (columns, margins, fonts)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
from dataclasses import dataclass, field
|
|
25
|
+
from typing import Dict, List, Optional, Callable
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class BaseWordProfile:
|
|
30
|
+
"""
|
|
31
|
+
Base configuration for mapping between DOCX and SciTeX writer documents.
|
|
32
|
+
|
|
33
|
+
Attributes
|
|
34
|
+
----------
|
|
35
|
+
name : str
|
|
36
|
+
Profile identifier (e.g., "mdpi-ijerph").
|
|
37
|
+
description : str
|
|
38
|
+
Human-readable description.
|
|
39
|
+
heading_styles : dict[int, str]
|
|
40
|
+
Mapping from section depth (1, 2, 3...) to Word style names
|
|
41
|
+
(e.g., {1: "Heading 1", 2: "Heading 2"}).
|
|
42
|
+
caption_style : str
|
|
43
|
+
Word style name used for figure/table captions.
|
|
44
|
+
normal_style : str
|
|
45
|
+
Default paragraph style.
|
|
46
|
+
reference_section_titles : list[str]
|
|
47
|
+
Titles that indicate the start of the reference section.
|
|
48
|
+
figure_caption_prefixes : list[str]
|
|
49
|
+
Prefixes that identify figure captions (e.g., ["Figure", "Fig."]).
|
|
50
|
+
table_caption_prefixes : list[str]
|
|
51
|
+
Prefixes that identify table captions (e.g., ["Table"]).
|
|
52
|
+
list_styles : dict[str, str]
|
|
53
|
+
Mapping for list styles (bullet, numbered).
|
|
54
|
+
equation_style : str | None
|
|
55
|
+
Style name for equations, if any.
|
|
56
|
+
columns : int
|
|
57
|
+
Number of columns in the layout (1 or 2).
|
|
58
|
+
double_anonymous : bool
|
|
59
|
+
Whether this profile requires double-anonymous formatting.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
name: str
|
|
63
|
+
description: str
|
|
64
|
+
heading_styles: Dict[int, str] = field(default_factory=dict)
|
|
65
|
+
caption_style: str = "Caption"
|
|
66
|
+
normal_style: str = "Normal"
|
|
67
|
+
reference_section_titles: List[str] = field(
|
|
68
|
+
default_factory=lambda: ["References", "REFERENCES"]
|
|
69
|
+
)
|
|
70
|
+
figure_caption_prefixes: List[str] = field(
|
|
71
|
+
default_factory=lambda: ["Figure", "Fig.", "Fig"]
|
|
72
|
+
)
|
|
73
|
+
table_caption_prefixes: List[str] = field(
|
|
74
|
+
default_factory=lambda: ["Table", "Tab.", "Tab"]
|
|
75
|
+
)
|
|
76
|
+
list_styles: Dict[str, str] = field(
|
|
77
|
+
default_factory=lambda: {
|
|
78
|
+
"bullet": "List Bullet",
|
|
79
|
+
"numbered": "List Number",
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
equation_style: Optional[str] = None
|
|
83
|
+
columns: int = 1
|
|
84
|
+
double_anonymous: bool = False
|
|
85
|
+
|
|
86
|
+
# Post-processing hooks
|
|
87
|
+
post_import_hooks: List[Callable] = field(default_factory=list)
|
|
88
|
+
pre_export_hooks: List[Callable] = field(default_factory=list)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# --- Concrete profiles ------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _generic_profile() -> BaseWordProfile:
|
|
95
|
+
"""
|
|
96
|
+
Generic Word template profile.
|
|
97
|
+
|
|
98
|
+
This profile is intentionally conservative and assumes that:
|
|
99
|
+
- "Heading 1/2/3" are used for section headings.
|
|
100
|
+
- "Caption" is used for figure/table captions.
|
|
101
|
+
- "Normal" is the default body text.
|
|
102
|
+
|
|
103
|
+
This should work reasonably well for many simple manuscripts.
|
|
104
|
+
"""
|
|
105
|
+
return BaseWordProfile(
|
|
106
|
+
name="generic",
|
|
107
|
+
description="Generic Word mapping with standard Heading styles.",
|
|
108
|
+
heading_styles={
|
|
109
|
+
1: "Heading 1",
|
|
110
|
+
2: "Heading 2",
|
|
111
|
+
3: "Heading 3",
|
|
112
|
+
4: "Heading 4",
|
|
113
|
+
},
|
|
114
|
+
caption_style="Caption",
|
|
115
|
+
normal_style="Normal",
|
|
116
|
+
reference_section_titles=["References", "REFERENCES", "Bibliography"],
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _mdpi_ijerph_profile() -> BaseWordProfile:
|
|
121
|
+
"""
|
|
122
|
+
MDPI IJERPH template profile.
|
|
123
|
+
|
|
124
|
+
Based on the MDPI Word template structure:
|
|
125
|
+
- Section headings use built-in heading styles.
|
|
126
|
+
- References section is titled "References".
|
|
127
|
+
- Single column layout.
|
|
128
|
+
- Specific section order: Introduction, Materials and Methods,
|
|
129
|
+
Results, Discussion, Conclusions.
|
|
130
|
+
"""
|
|
131
|
+
return BaseWordProfile(
|
|
132
|
+
name="mdpi-ijerph",
|
|
133
|
+
description="MDPI IJERPH (Int. J. Environ. Res. Public Health) Word template.",
|
|
134
|
+
heading_styles={
|
|
135
|
+
1: "Heading 1",
|
|
136
|
+
2: "Heading 2",
|
|
137
|
+
3: "Heading 3",
|
|
138
|
+
},
|
|
139
|
+
caption_style="Caption",
|
|
140
|
+
normal_style="Normal",
|
|
141
|
+
reference_section_titles=["References"],
|
|
142
|
+
columns=1,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _resna_2025_profile() -> BaseWordProfile:
|
|
147
|
+
"""
|
|
148
|
+
RESNA 2025 scientific paper template profile.
|
|
149
|
+
|
|
150
|
+
The RESNA template:
|
|
151
|
+
- Uses all-caps section headings (INTRODUCTION, METHODS, etc.)
|
|
152
|
+
- Strict 4-page layout
|
|
153
|
+
- Two-column format
|
|
154
|
+
"""
|
|
155
|
+
return BaseWordProfile(
|
|
156
|
+
name="resna-2025",
|
|
157
|
+
description="RESNA 2025 Scientific Paper Word template.",
|
|
158
|
+
heading_styles={
|
|
159
|
+
1: "Heading 1", # INTRODUCTION, METHODS, etc.
|
|
160
|
+
2: "Heading 2", # First-level sub-heading
|
|
161
|
+
},
|
|
162
|
+
caption_style="Caption",
|
|
163
|
+
normal_style="Normal",
|
|
164
|
+
reference_section_titles=["References", "REFERENCES"],
|
|
165
|
+
columns=2,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _iop_double_anonymous_profile() -> BaseWordProfile:
|
|
170
|
+
"""
|
|
171
|
+
IOP double-anonymous Word template profile.
|
|
172
|
+
|
|
173
|
+
The IOP template uses custom styles:
|
|
174
|
+
- IOPH1, IOPH2, IOPH3 for headings
|
|
175
|
+
- IOPTitle for title
|
|
176
|
+
- IOPAbsText for abstract
|
|
177
|
+
- IOPAff for affiliations
|
|
178
|
+
- Requires removal of author-identifying information
|
|
179
|
+
"""
|
|
180
|
+
return BaseWordProfile(
|
|
181
|
+
name="iop-double-anonymous",
|
|
182
|
+
description="IOP double-anonymous Word template.",
|
|
183
|
+
heading_styles={
|
|
184
|
+
1: "IOPH1",
|
|
185
|
+
2: "IOPH2",
|
|
186
|
+
3: "IOPH3",
|
|
187
|
+
},
|
|
188
|
+
caption_style="Caption",
|
|
189
|
+
normal_style="Normal",
|
|
190
|
+
reference_section_titles=["References"],
|
|
191
|
+
double_anonymous=True,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _ieee_profile() -> BaseWordProfile:
|
|
196
|
+
"""
|
|
197
|
+
IEEE conference/journal template profile.
|
|
198
|
+
|
|
199
|
+
The IEEE template:
|
|
200
|
+
- Two-column format
|
|
201
|
+
- Roman numeral section numbering
|
|
202
|
+
- Specific citation style
|
|
203
|
+
"""
|
|
204
|
+
return BaseWordProfile(
|
|
205
|
+
name="ieee",
|
|
206
|
+
description="IEEE conference/journal Word template.",
|
|
207
|
+
heading_styles={
|
|
208
|
+
1: "Heading 1",
|
|
209
|
+
2: "Heading 2",
|
|
210
|
+
3: "Heading 3",
|
|
211
|
+
},
|
|
212
|
+
caption_style="Caption",
|
|
213
|
+
normal_style="Normal",
|
|
214
|
+
reference_section_titles=["References", "REFERENCES"],
|
|
215
|
+
columns=2,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _springer_profile() -> BaseWordProfile:
|
|
220
|
+
"""
|
|
221
|
+
Springer Nature journal template profile.
|
|
222
|
+
"""
|
|
223
|
+
return BaseWordProfile(
|
|
224
|
+
name="springer",
|
|
225
|
+
description="Springer Nature journal Word template.",
|
|
226
|
+
heading_styles={
|
|
227
|
+
1: "Heading 1",
|
|
228
|
+
2: "Heading 2",
|
|
229
|
+
3: "Heading 3",
|
|
230
|
+
},
|
|
231
|
+
caption_style="Caption",
|
|
232
|
+
normal_style="Normal",
|
|
233
|
+
reference_section_titles=["References"],
|
|
234
|
+
columns=1,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _elsevier_profile() -> BaseWordProfile:
|
|
239
|
+
"""
|
|
240
|
+
Elsevier journal template profile.
|
|
241
|
+
"""
|
|
242
|
+
return BaseWordProfile(
|
|
243
|
+
name="elsevier",
|
|
244
|
+
description="Elsevier journal Word template.",
|
|
245
|
+
heading_styles={
|
|
246
|
+
1: "Heading 1",
|
|
247
|
+
2: "Heading 2",
|
|
248
|
+
3: "Heading 3",
|
|
249
|
+
},
|
|
250
|
+
caption_style="Caption",
|
|
251
|
+
normal_style="Normal",
|
|
252
|
+
reference_section_titles=["References"],
|
|
253
|
+
columns=1,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# Registry of known profiles
|
|
258
|
+
_PROFILES: Dict[str, BaseWordProfile] = {
|
|
259
|
+
"generic": _generic_profile(),
|
|
260
|
+
"mdpi-ijerph": _mdpi_ijerph_profile(),
|
|
261
|
+
"mdpi": _mdpi_ijerph_profile(), # Alias
|
|
262
|
+
"resna-2025": _resna_2025_profile(),
|
|
263
|
+
"resna": _resna_2025_profile(), # Alias
|
|
264
|
+
"iop-double-anonymous": _iop_double_anonymous_profile(),
|
|
265
|
+
"iop": _iop_double_anonymous_profile(), # Alias
|
|
266
|
+
"ieee": _ieee_profile(),
|
|
267
|
+
"springer": _springer_profile(),
|
|
268
|
+
"elsevier": _elsevier_profile(),
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def list_profiles() -> list[str]:
|
|
273
|
+
"""
|
|
274
|
+
List available MS Word profiles.
|
|
275
|
+
|
|
276
|
+
Returns
|
|
277
|
+
-------
|
|
278
|
+
list[str]
|
|
279
|
+
List of profile names (e.g., ["generic", "mdpi-ijerph", ...]).
|
|
280
|
+
|
|
281
|
+
Examples
|
|
282
|
+
--------
|
|
283
|
+
>>> from scitex.msword import list_profiles
|
|
284
|
+
>>> profiles = list_profiles()
|
|
285
|
+
>>> "generic" in profiles
|
|
286
|
+
True
|
|
287
|
+
"""
|
|
288
|
+
return sorted(_PROFILES.keys())
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def get_profile(name: str | None) -> BaseWordProfile:
|
|
292
|
+
"""
|
|
293
|
+
Get a Word profile by name.
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
name : str | None
|
|
298
|
+
Profile name. If None, "generic" is used.
|
|
299
|
+
|
|
300
|
+
Returns
|
|
301
|
+
-------
|
|
302
|
+
BaseWordProfile
|
|
303
|
+
The requested profile.
|
|
304
|
+
|
|
305
|
+
Raises
|
|
306
|
+
------
|
|
307
|
+
KeyError
|
|
308
|
+
If the profile name is unknown.
|
|
309
|
+
|
|
310
|
+
Examples
|
|
311
|
+
--------
|
|
312
|
+
>>> from scitex.msword import get_profile
|
|
313
|
+
>>> profile = get_profile("mdpi-ijerph")
|
|
314
|
+
>>> profile.columns
|
|
315
|
+
1
|
|
316
|
+
"""
|
|
317
|
+
if name is None:
|
|
318
|
+
return _PROFILES["generic"]
|
|
319
|
+
try:
|
|
320
|
+
return _PROFILES[name]
|
|
321
|
+
except KeyError as exc:
|
|
322
|
+
available = ", ".join(list_profiles())
|
|
323
|
+
raise KeyError(
|
|
324
|
+
f"Unknown MS Word profile: {name!r}. " f"Available profiles: {available}"
|
|
325
|
+
) from exc
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def register_profile(profile: BaseWordProfile) -> None:
|
|
329
|
+
"""
|
|
330
|
+
Register a custom Word profile.
|
|
331
|
+
|
|
332
|
+
Parameters
|
|
333
|
+
----------
|
|
334
|
+
profile : BaseWordProfile
|
|
335
|
+
The profile to register.
|
|
336
|
+
|
|
337
|
+
Examples
|
|
338
|
+
--------
|
|
339
|
+
>>> from scitex.msword import BaseWordProfile, register_profile
|
|
340
|
+
>>> custom = BaseWordProfile(
|
|
341
|
+
... name="my-journal",
|
|
342
|
+
... description="My custom journal template",
|
|
343
|
+
... heading_styles={1: "Title", 2: "Subtitle"},
|
|
344
|
+
... )
|
|
345
|
+
>>> register_profile(custom)
|
|
346
|
+
>>> "my-journal" in list_profiles()
|
|
347
|
+
True
|
|
348
|
+
"""
|
|
349
|
+
_PROFILES[profile.name] = profile
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
__all__ = [
|
|
353
|
+
"BaseWordProfile",
|
|
354
|
+
"list_profiles",
|
|
355
|
+
"get_profile",
|
|
356
|
+
"register_profile",
|
|
357
|
+
]
|