scitex 2.7.0__py3-none-any.whl → 2.7.3__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.
Files changed (297) hide show
  1. scitex/__init__.py +6 -2
  2. scitex/__version__.py +1 -1
  3. scitex/audio/README.md +52 -0
  4. scitex/audio/__init__.py +384 -0
  5. scitex/audio/__main__.py +129 -0
  6. scitex/audio/_tts.py +334 -0
  7. scitex/audio/engines/__init__.py +44 -0
  8. scitex/audio/engines/base.py +275 -0
  9. scitex/audio/engines/elevenlabs_engine.py +143 -0
  10. scitex/audio/engines/gtts_engine.py +162 -0
  11. scitex/audio/engines/pyttsx3_engine.py +131 -0
  12. scitex/audio/mcp_server.py +757 -0
  13. scitex/bridge/_helpers.py +1 -1
  14. scitex/bridge/_plt_vis.py +1 -1
  15. scitex/bridge/_stats_vis.py +1 -1
  16. scitex/dev/plt/__init__.py +272 -0
  17. scitex/dev/plt/plot_mpl_axhline.py +28 -0
  18. scitex/dev/plt/plot_mpl_axhspan.py +28 -0
  19. scitex/dev/plt/plot_mpl_axvline.py +28 -0
  20. scitex/dev/plt/plot_mpl_axvspan.py +28 -0
  21. scitex/dev/plt/plot_mpl_bar.py +29 -0
  22. scitex/dev/plt/plot_mpl_barh.py +29 -0
  23. scitex/dev/plt/plot_mpl_boxplot.py +28 -0
  24. scitex/dev/plt/plot_mpl_contour.py +31 -0
  25. scitex/dev/plt/plot_mpl_contourf.py +31 -0
  26. scitex/dev/plt/plot_mpl_errorbar.py +30 -0
  27. scitex/dev/plt/plot_mpl_eventplot.py +28 -0
  28. scitex/dev/plt/plot_mpl_fill.py +30 -0
  29. scitex/dev/plt/plot_mpl_fill_between.py +31 -0
  30. scitex/dev/plt/plot_mpl_hexbin.py +28 -0
  31. scitex/dev/plt/plot_mpl_hist.py +28 -0
  32. scitex/dev/plt/plot_mpl_hist2d.py +28 -0
  33. scitex/dev/plt/plot_mpl_imshow.py +29 -0
  34. scitex/dev/plt/plot_mpl_pcolormesh.py +31 -0
  35. scitex/dev/plt/plot_mpl_pie.py +29 -0
  36. scitex/dev/plt/plot_mpl_plot.py +29 -0
  37. scitex/dev/plt/plot_mpl_quiver.py +31 -0
  38. scitex/dev/plt/plot_mpl_scatter.py +28 -0
  39. scitex/dev/plt/plot_mpl_stackplot.py +31 -0
  40. scitex/dev/plt/plot_mpl_stem.py +29 -0
  41. scitex/dev/plt/plot_mpl_step.py +29 -0
  42. scitex/dev/plt/plot_mpl_violinplot.py +28 -0
  43. scitex/dev/plt/plot_sns_barplot.py +29 -0
  44. scitex/dev/plt/plot_sns_boxplot.py +29 -0
  45. scitex/dev/plt/plot_sns_heatmap.py +28 -0
  46. scitex/dev/plt/plot_sns_histplot.py +29 -0
  47. scitex/dev/plt/plot_sns_kdeplot.py +29 -0
  48. scitex/dev/plt/plot_sns_lineplot.py +31 -0
  49. scitex/dev/plt/plot_sns_scatterplot.py +29 -0
  50. scitex/dev/plt/plot_sns_stripplot.py +29 -0
  51. scitex/dev/plt/plot_sns_swarmplot.py +29 -0
  52. scitex/dev/plt/plot_sns_violinplot.py +29 -0
  53. scitex/dev/plt/plot_stx_bar.py +29 -0
  54. scitex/dev/plt/plot_stx_barh.py +29 -0
  55. scitex/dev/plt/plot_stx_box.py +28 -0
  56. scitex/dev/plt/plot_stx_boxplot.py +28 -0
  57. scitex/dev/plt/plot_stx_conf_mat.py +28 -0
  58. scitex/dev/plt/plot_stx_contour.py +31 -0
  59. scitex/dev/plt/plot_stx_ecdf.py +28 -0
  60. scitex/dev/plt/plot_stx_errorbar.py +30 -0
  61. scitex/dev/plt/plot_stx_fill_between.py +31 -0
  62. scitex/dev/plt/plot_stx_fillv.py +28 -0
  63. scitex/dev/plt/plot_stx_heatmap.py +28 -0
  64. scitex/dev/plt/plot_stx_image.py +28 -0
  65. scitex/dev/plt/plot_stx_imshow.py +28 -0
  66. scitex/dev/plt/plot_stx_joyplot.py +28 -0
  67. scitex/dev/plt/plot_stx_kde.py +28 -0
  68. scitex/dev/plt/plot_stx_line.py +28 -0
  69. scitex/dev/plt/plot_stx_mean_ci.py +28 -0
  70. scitex/dev/plt/plot_stx_mean_std.py +28 -0
  71. scitex/dev/plt/plot_stx_median_iqr.py +28 -0
  72. scitex/dev/plt/plot_stx_raster.py +28 -0
  73. scitex/dev/plt/plot_stx_rectangle.py +28 -0
  74. scitex/dev/plt/plot_stx_scatter.py +29 -0
  75. scitex/dev/plt/plot_stx_shaded_line.py +29 -0
  76. scitex/dev/plt/plot_stx_violin.py +28 -0
  77. scitex/dev/plt/plot_stx_violinplot.py +28 -0
  78. scitex/fig/__init__.py +352 -0
  79. scitex/{vis → fig}/backend/_parser.py +1 -1
  80. scitex/{vis → fig}/canvas.py +1 -1
  81. scitex/{vis → fig}/editor/_defaults.py +70 -5
  82. scitex/fig/editor/_edit.py +751 -0
  83. scitex/{vis → fig}/editor/_qt_editor.py +181 -1
  84. scitex/fig/editor/flask_editor/_bbox.py +1276 -0
  85. scitex/fig/editor/flask_editor/_core.py +624 -0
  86. scitex/{vis → fig}/editor/flask_editor/_plotter.py +38 -4
  87. scitex/fig/editor/flask_editor/_renderer.py +739 -0
  88. scitex/{vis → fig}/editor/flask_editor/templates/__init__.py +1 -1
  89. scitex/fig/editor/flask_editor/templates/_html.py +834 -0
  90. scitex/fig/editor/flask_editor/templates/_scripts.py +3136 -0
  91. scitex/{vis → fig}/editor/flask_editor/templates/_styles.py +625 -18
  92. scitex/{vis → fig}/io/__init__.py +13 -1
  93. scitex/fig/io/_bundle.py +973 -0
  94. scitex/{vis → fig}/io/_canvas.py +1 -1
  95. scitex/{vis → fig}/io/_data.py +1 -1
  96. scitex/{vis → fig}/io/_export.py +1 -1
  97. scitex/{vis → fig}/io/_load.py +1 -1
  98. scitex/{vis → fig}/io/_panel.py +1 -1
  99. scitex/{vis → fig}/io/_save.py +1 -1
  100. scitex/{vis → fig}/model/__init__.py +1 -1
  101. scitex/{vis → fig}/model/_annotations.py +1 -1
  102. scitex/{vis → fig}/model/_axes.py +1 -1
  103. scitex/{vis → fig}/model/_figure.py +1 -1
  104. scitex/{vis → fig}/model/_guides.py +1 -1
  105. scitex/{vis → fig}/model/_plot.py +1 -1
  106. scitex/{vis → fig}/model/_styles.py +1 -1
  107. scitex/{vis → fig}/utils/__init__.py +1 -1
  108. scitex/io/__init__.py +10 -26
  109. scitex/io/_bundle.py +434 -0
  110. scitex/io/_flush.py +5 -2
  111. scitex/io/_load.py +98 -0
  112. scitex/io/_load_modules/_H5Explorer.py +5 -2
  113. scitex/io/_load_modules/_canvas.py +2 -2
  114. scitex/io/_load_modules/_image.py +3 -4
  115. scitex/io/_load_modules/_txt.py +4 -2
  116. scitex/io/_metadata.py +34 -324
  117. scitex/io/_metadata_modules/__init__.py +46 -0
  118. scitex/io/_metadata_modules/_embed.py +70 -0
  119. scitex/io/_metadata_modules/_read.py +64 -0
  120. scitex/io/_metadata_modules/_utils.py +79 -0
  121. scitex/io/_metadata_modules/embed_metadata_jpeg.py +74 -0
  122. scitex/io/_metadata_modules/embed_metadata_pdf.py +53 -0
  123. scitex/io/_metadata_modules/embed_metadata_png.py +26 -0
  124. scitex/io/_metadata_modules/embed_metadata_svg.py +62 -0
  125. scitex/io/_metadata_modules/read_metadata_jpeg.py +57 -0
  126. scitex/io/_metadata_modules/read_metadata_pdf.py +51 -0
  127. scitex/io/_metadata_modules/read_metadata_png.py +39 -0
  128. scitex/io/_metadata_modules/read_metadata_svg.py +44 -0
  129. scitex/io/_qr_utils.py +5 -3
  130. scitex/io/_save.py +548 -30
  131. scitex/io/_save_modules/_canvas.py +3 -3
  132. scitex/io/_save_modules/_image.py +5 -9
  133. scitex/io/_save_modules/_tex.py +7 -4
  134. scitex/io/utils/h5_to_zarr.py +11 -9
  135. scitex/msword/__init__.py +255 -0
  136. scitex/msword/profiles.py +357 -0
  137. scitex/msword/reader.py +753 -0
  138. scitex/msword/utils.py +289 -0
  139. scitex/msword/writer.py +362 -0
  140. scitex/plt/__init__.py +5 -2
  141. scitex/plt/_subplots/_AxesWrapper.py +6 -6
  142. scitex/plt/_subplots/_AxisWrapper.py +15 -9
  143. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +36 -0
  144. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +264 -0
  145. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +213 -0
  146. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +128 -0
  147. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +59 -0
  148. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +34 -0
  149. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +593 -0
  150. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +654 -0
  151. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +527 -0
  152. scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +321 -0
  153. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +33 -0
  154. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +152 -0
  155. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +600 -0
  156. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +79 -5
  157. scitex/plt/_subplots/_FigWrapper.py +6 -6
  158. scitex/plt/_subplots/_SubplotsWrapper.py +28 -18
  159. scitex/plt/_subplots/_export_as_csv.py +35 -5
  160. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +8 -0
  161. scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +10 -21
  162. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +18 -7
  163. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +28 -12
  164. scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +10 -4
  165. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +13 -1
  166. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +12 -2
  167. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +10 -3
  168. scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -4
  169. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +18 -3
  170. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +44 -36
  171. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +14 -2
  172. scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +11 -5
  173. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +84 -0
  174. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +85 -0
  175. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +14 -3
  176. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_contour.py +54 -0
  177. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +14 -2
  178. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +120 -0
  179. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +16 -6
  180. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +29 -19
  181. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_imshow.py +63 -0
  182. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +22 -5
  183. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +18 -14
  184. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +18 -14
  185. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +18 -14
  186. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +10 -2
  187. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +51 -0
  188. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +18 -9
  189. scitex/plt/ax/_plot/_stx_ecdf.py +4 -2
  190. scitex/plt/gallery/_generate.py +421 -14
  191. scitex/plt/io/__init__.py +53 -0
  192. scitex/plt/io/_bundle.py +490 -0
  193. scitex/plt/io/_layered_bundle.py +1343 -0
  194. scitex/plt/styles/SCITEX_STYLE.yaml +26 -0
  195. scitex/plt/styles/__init__.py +14 -0
  196. scitex/plt/styles/presets.py +78 -0
  197. scitex/plt/utils/__init__.py +13 -1
  198. scitex/plt/utils/_collect_figure_metadata.py +10 -14
  199. scitex/plt/utils/_configure_mpl.py +6 -18
  200. scitex/plt/utils/_crop.py +32 -14
  201. scitex/plt/utils/_csv_column_naming.py +54 -0
  202. scitex/plt/utils/_figure_mm.py +116 -1
  203. scitex/plt/utils/_hitmap.py +1643 -0
  204. scitex/plt/utils/metadata/__init__.py +25 -0
  205. scitex/plt/utils/metadata/_core.py +9 -10
  206. scitex/plt/utils/metadata/_dimensions.py +6 -3
  207. scitex/plt/utils/metadata/_editable_export.py +405 -0
  208. scitex/plt/utils/metadata/_geometry_extraction.py +570 -0
  209. scitex/schema/__init__.py +109 -16
  210. scitex/schema/_canvas.py +1 -1
  211. scitex/schema/_plot.py +1015 -0
  212. scitex/schema/_stats.py +2 -2
  213. scitex/stats/__init__.py +117 -0
  214. scitex/stats/io/__init__.py +29 -0
  215. scitex/stats/io/_bundle.py +156 -0
  216. scitex/tex/__init__.py +4 -0
  217. scitex/tex/_export.py +890 -0
  218. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/METADATA +11 -1
  219. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/RECORD +238 -170
  220. scitex/io/memo.md +0 -2827
  221. scitex/plt/REQUESTS.md +0 -191
  222. scitex/plt/_subplots/TODO.md +0 -53
  223. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +0 -559
  224. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +0 -1609
  225. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +0 -447
  226. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +0 -110
  227. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +0 -88
  228. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +0 -103
  229. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +0 -106
  230. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +0 -92
  231. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +0 -92
  232. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +0 -92
  233. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +0 -84
  234. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +0 -84
  235. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +0 -83
  236. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +0 -93
  237. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +0 -91
  238. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +0 -91
  239. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +0 -91
  240. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +0 -97
  241. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +0 -98
  242. scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +0 -84
  243. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +0 -101
  244. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +0 -96
  245. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +0 -95
  246. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +0 -95
  247. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +0 -93
  248. scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +0 -95
  249. scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +0 -95
  250. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +0 -83
  251. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +0 -92
  252. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +0 -121
  253. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +0 -84
  254. scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +0 -110
  255. scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +0 -92
  256. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +0 -95
  257. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +0 -96
  258. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +0 -95
  259. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +0 -95
  260. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +0 -92
  261. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +0 -84
  262. scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +0 -94
  263. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +0 -109
  264. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +0 -108
  265. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +0 -93
  266. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +0 -84
  267. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +0 -96
  268. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +0 -96
  269. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +0 -96
  270. scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +0 -99
  271. scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +0 -100
  272. scitex/vis/__init__.py +0 -177
  273. scitex/vis/editor/_edit.py +0 -390
  274. scitex/vis/editor/flask_editor/_bbox.py +0 -529
  275. scitex/vis/editor/flask_editor/_core.py +0 -168
  276. scitex/vis/editor/flask_editor/_renderer.py +0 -393
  277. scitex/vis/editor/flask_editor/templates/_html.py +0 -513
  278. scitex/vis/editor/flask_editor/templates/_scripts.py +0 -1261
  279. /scitex/{vis → fig}/README.md +0 -0
  280. /scitex/{vis → fig}/backend/__init__.py +0 -0
  281. /scitex/{vis → fig}/backend/_export.py +0 -0
  282. /scitex/{vis → fig}/backend/_render.py +0 -0
  283. /scitex/{vis → fig}/docs/CANVAS_ARCHITECTURE.md +0 -0
  284. /scitex/{vis → fig}/editor/__init__.py +0 -0
  285. /scitex/{vis → fig}/editor/_dearpygui_editor.py +0 -0
  286. /scitex/{vis → fig}/editor/_flask_editor.py +0 -0
  287. /scitex/{vis → fig}/editor/_mpl_editor.py +0 -0
  288. /scitex/{vis → fig}/editor/_tkinter_editor.py +0 -0
  289. /scitex/{vis → fig}/editor/flask_editor/__init__.py +0 -0
  290. /scitex/{vis → fig}/editor/flask_editor/_utils.py +0 -0
  291. /scitex/{vis → fig}/io/_directory.py +0 -0
  292. /scitex/{vis → fig}/model/_plot_types.py +0 -0
  293. /scitex/{vis → fig}/utils/_defaults.py +0 -0
  294. /scitex/{vis → fig}/utils/_validate.py +0 -0
  295. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/WHEEL +0 -0
  296. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/entry_points.txt +0 -0
  297. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/licenses/LICENSE +0 -0
@@ -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
+ ]