batplot 1.8.53__tar.gz → 1.8.57__tar.gz

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 (350) hide show
  1. {batplot-1.8.53 → batplot-1.8.57}/PKG-INFO +5 -4
  2. {batplot-1.8.53 → batplot-1.8.57}/README.md +4 -3
  3. {batplot-1.8.53 → batplot-1.8.57}/batplot/__init__.py +1 -1
  4. {batplot-1.8.53 → batplot-1.8.57}/batplot/args.py +70 -8
  5. {batplot-1.8.53 → batplot-1.8.57}/batplot/data/CHANGELOG.md +19 -0
  6. {batplot-1.8.53 → batplot-1.8.57}/batplot/data/latest_release_notes.json +1 -1
  7. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_commands.py +18 -14
  8. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_menu_io.py +12 -5
  9. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/ec_batch_helpers.py +34 -0
  10. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/menu_cpc.py +4 -1
  11. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/menu_dqdv_2d.py +4 -1
  12. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/menu_ec.py +74 -1
  13. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/menu_histo.py +4 -1
  14. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/menu_operando.py +4 -1
  15. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/menu_xy.py +75 -36
  16. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/xy_batch_helpers.py +14 -2
  17. batplot-1.8.57/batplot/plot_modes/common/color_menu_help.py +228 -0
  18. batplot-1.8.57/batplot/plot_modes/common/curve_look_help.py +140 -0
  19. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/fonts.py +16 -1
  20. batplot-1.8.57/batplot/plot_modes/common/layout_compat.py +515 -0
  21. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/menu_rendering.py +61 -6
  22. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/palettes.py +18 -0
  23. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/spines.py +120 -4
  24. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/style_routing.py +2 -2
  25. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/terminal.py +37 -0
  26. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/actions.py +6 -10
  27. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/colors.py +80 -41
  28. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/interactive.py +22 -10
  29. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/labels.py +13 -7
  30. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/panel_menus.py +42 -12
  31. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/session.py +17 -15
  32. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/style.py +65 -18
  33. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/wasd_menu.py +9 -1
  34. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/actions.py +4 -9
  35. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/colors.py +36 -41
  36. batplot-1.8.57/batplot/plot_modes/electrochem/dqdv_norm.py +419 -0
  37. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/interactive.py +51 -13
  38. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/labels.py +13 -7
  39. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/line_style.py +19 -10
  40. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/menu.py +2 -0
  41. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/session.py +104 -8
  42. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/smoothing_menu.py +17 -0
  43. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/spine_colors.py +26 -16
  44. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/style.py +67 -0
  45. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/style_apply.py +64 -21
  46. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/undo_state.py +49 -2
  47. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/colors.py +36 -26
  48. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/density_curve.py +9 -4
  49. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/interactive.py +27 -14
  50. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/labels.py +18 -3
  51. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/line_style.py +10 -5
  52. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/session.py +2 -2
  53. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/spines.py +12 -4
  54. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/actions.py +2 -2
  55. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/cif_menu.py +3 -0
  56. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/colors.py +58 -38
  57. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/interactive.py +63 -12
  58. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/labels.py +21 -10
  59. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/layout.py +6 -0
  60. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/line_style.py +35 -25
  61. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/plot.py +19 -0
  62. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/session.py +27 -0
  63. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/spine_colors.py +36 -27
  64. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/style.py +140 -24
  65. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/style_apply.py +52 -15
  66. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/undo_state.py +14 -0
  67. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/arrange.py +33 -49
  68. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/axis_units.py +17 -8
  69. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/cif.py +49 -13
  70. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/colors.py +60 -43
  71. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/interactive.py +19 -16
  72. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/labels.py +25 -4
  73. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/line_style.py +19 -10
  74. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/pipeline.py +5 -2
  75. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/session.py +39 -12
  76. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/spines.py +64 -5
  77. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/style.py +217 -86
  78. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/undo_state.py +26 -10
  79. {batplot-1.8.53 → batplot-1.8.57}/batplot/ui.py +233 -21
  80. {batplot-1.8.53 → batplot-1.8.57}/batplot/utils.py +57 -4
  81. {batplot-1.8.53 → batplot-1.8.57}/batplot.egg-info/PKG-INFO +5 -4
  82. {batplot-1.8.53 → batplot-1.8.57}/batplot.egg-info/SOURCES.txt +13 -0
  83. {batplot-1.8.53 → batplot-1.8.57}/pyproject.toml +1 -1
  84. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_session.py +2 -2
  85. batplot-1.8.57/tests/test_batch_spine_sync.py +204 -0
  86. {batplot-1.8.53 → batplot-1.8.57}/tests/test_contracts.py +30 -0
  87. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cpc_canvas_undo.py +7 -5
  88. batplot-1.8.57/tests/test_curve_look_help.py +95 -0
  89. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_noninteractive_bugs.py +58 -4
  90. batplot-1.8.57/tests/test_dqdv_normalize.py +169 -0
  91. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_cpc_geometry_pisb_keys.py +7 -6
  92. {batplot-1.8.53 → batplot-1.8.57}/tests/test_histo_geometry_pisb_keys.py +7 -8
  93. {batplot-1.8.53 → batplot-1.8.57}/tests/test_histo_style_pisb_keys.py +7 -8
  94. {batplot-1.8.53 → batplot-1.8.57}/tests/test_label_shortcuts_math_help.py +31 -0
  95. batplot-1.8.57/tests/test_line_submenu_pisb_widths.py +156 -0
  96. {batplot-1.8.53 → batplot-1.8.57}/tests/test_menu_rendering_presentation.py +22 -5
  97. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_cif_color.py +6 -6
  98. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_geometry_pisb_keys.py +1 -1
  99. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_roundtrip.py +2 -2
  100. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_style_pisb_keys.py +1 -1
  101. batplot-1.8.57/tests/test_quit_confirm_export_save.py +98 -0
  102. {batplot-1.8.53 → batplot-1.8.57}/tests/test_spine_colors_pisb.py +216 -0
  103. batplot-1.8.57/tests/test_spine_wasd_figure_help.py +56 -0
  104. batplot-1.8.57/tests/test_stack_rearrange_tick_spacing.py +229 -0
  105. batplot-1.8.57/tests/test_style_layout_compat.py +230 -0
  106. batplot-1.8.57/tests/test_tick_display_color_contract.py +331 -0
  107. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_axis_units.py +55 -5
  108. batplot-1.8.57/tests/test_xy_bps_bpsg_key_matrix.py +291 -0
  109. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_cif_add.py +92 -6
  110. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_geometry_pisb_keys.py +119 -4
  111. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_style_pisb_keys.py +47 -18
  112. batplot-1.8.53/tests/test_batch_spine_sync.py +0 -82
  113. {batplot-1.8.53 → batplot-1.8.57}/DEVELOPING.md +0 -0
  114. {batplot-1.8.53 → batplot-1.8.57}/LICENSE +0 -0
  115. {batplot-1.8.53 → batplot-1.8.57}/MANIFEST.in +0 -0
  116. {batplot-1.8.53 → batplot-1.8.57}/NOTICE +0 -0
  117. {batplot-1.8.53 → batplot-1.8.57}/batplot/_mpl_backend.py +0 -0
  118. {batplot-1.8.53 → batplot-1.8.57}/batplot/batch.py +0 -0
  119. {batplot-1.8.53 → batplot-1.8.57}/batplot/batplot.py +0 -0
  120. {batplot-1.8.53 → batplot-1.8.57}/batplot/canvas_interactive.py +0 -0
  121. {batplot-1.8.53 → batplot-1.8.57}/batplot/cif.py +0 -0
  122. {batplot-1.8.53 → batplot-1.8.57}/batplot/cli.py +0 -0
  123. {batplot-1.8.53 → batplot-1.8.57}/batplot/cli_save.py +0 -0
  124. {batplot-1.8.53 → batplot-1.8.57}/batplot/color_utils.py +0 -0
  125. {batplot-1.8.53 → batplot-1.8.57}/batplot/config.py +0 -0
  126. {batplot-1.8.53 → batplot-1.8.57}/batplot/converters.py +0 -0
  127. {batplot-1.8.53 → batplot-1.8.57}/batplot/dev_upgrade.py +0 -0
  128. {batplot-1.8.53 → batplot-1.8.57}/batplot/ec_common.py +0 -0
  129. {batplot-1.8.53 → batplot-1.8.57}/batplot/modes.py +0 -0
  130. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/__init__.py +0 -0
  131. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/__init__.py +0 -0
  132. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_crosshair.py +0 -0
  133. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_figure_io.py +0 -0
  134. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_geom_helpers.py +0 -0
  135. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_io.py +0 -0
  136. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_menu_helpers.py +0 -0
  137. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_panel_state.py +0 -0
  138. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/batch_scoped_sync.py +0 -0
  139. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/common.py +0 -0
  140. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/cpc_batch_helpers.py +0 -0
  141. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/dqdv_2d_batch_helpers.py +0 -0
  142. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/histo_batch_helpers.py +0 -0
  143. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/kinds.py +0 -0
  144. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/load.py +0 -0
  145. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/operando_batch_helpers.py +0 -0
  146. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/batch_session/routing.py +0 -0
  147. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/__init__.py +0 -0
  148. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/axis_state.py +0 -0
  149. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/batch_font.py +0 -0
  150. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/crosshair_export.py +0 -0
  151. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/files.py +0 -0
  152. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/font_extras.py +0 -0
  153. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/interactive_state.py +0 -0
  154. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/line_dash.py +0 -0
  155. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/menus.py +0 -0
  156. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/overview_metrics.py +0 -0
  157. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/session_data_guarantee.py +0 -0
  158. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/session_helpers.py +0 -0
  159. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/session_key_smoke.py +0 -0
  160. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/size_spec.py +0 -0
  161. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/smoothing.py +0 -0
  162. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/sources.py +0 -0
  163. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/state_capture.py +0 -0
  164. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/common/title_offsets.py +0 -0
  165. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/__init__.py +0 -0
  166. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/add_file.py +0 -0
  167. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/legend.py +0 -0
  168. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/legend_order.py +0 -0
  169. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/load.py +0 -0
  170. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/menu.py +0 -0
  171. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/overview.py +0 -0
  172. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/routing.py +0 -0
  173. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/cpc/snapshots.py +0 -0
  174. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/__init__.py +0 -0
  175. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/capacity_cum.py +0 -0
  176. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/dqdv_2d.py +0 -0
  177. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/dual_axis_menu.py +0 -0
  178. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/export.py +0 -0
  179. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/legend.py +0 -0
  180. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/legend_order.py +0 -0
  181. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/overview.py +0 -0
  182. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/electrochem/routing.py +0 -0
  183. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/__init__.py +0 -0
  184. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/actions.py +0 -0
  185. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/fonts.py +0 -0
  186. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/load.py +0 -0
  187. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/plot.py +0 -0
  188. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/routing.py +0 -0
  189. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/toggles.py +0 -0
  190. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/wizard.py +0 -0
  191. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/histo/y_range.py +0 -0
  192. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/__init__.py +0 -0
  193. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/axes_limits_menu.py +0 -0
  194. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/axis_units.py +0 -0
  195. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/grid.py +0 -0
  196. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/intensity_menu.py +0 -0
  197. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/ions_axis.py +0 -0
  198. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/layout_menu.py +0 -0
  199. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/menu.py +0 -0
  200. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/peaks.py +0 -0
  201. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/routing.py +0 -0
  202. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/operando/visibility.py +0 -0
  203. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/session_routing.py +0 -0
  204. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/__init__.py +0 -0
  205. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/actions.py +0 -0
  206. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/axis_range.py +0 -0
  207. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/data_ops.py +0 -0
  208. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/derivative.py +0 -0
  209. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/full_data.py +0 -0
  210. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/game.py +0 -0
  211. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/menu.py +0 -0
  212. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/offset_menu.py +0 -0
  213. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/peaks.py +0 -0
  214. {batplot-1.8.53 → batplot-1.8.57}/batplot/plot_modes/xy/smoothing.py +0 -0
  215. {batplot-1.8.53 → batplot-1.8.57}/batplot/plotting.py +0 -0
  216. {batplot-1.8.53 → batplot-1.8.57}/batplot/readers.py +0 -0
  217. {batplot-1.8.53 → batplot-1.8.57}/batplot/readers_common.py +0 -0
  218. {batplot-1.8.53 → batplot-1.8.57}/batplot/readers_ec.py +0 -0
  219. {batplot-1.8.53 → batplot-1.8.57}/batplot/readers_xrd.py +0 -0
  220. {batplot-1.8.53 → batplot-1.8.57}/batplot/screen_color.py +0 -0
  221. {batplot-1.8.53 → batplot-1.8.57}/batplot/session.py +0 -0
  222. {batplot-1.8.53 → batplot-1.8.57}/batplot/showcol.py +0 -0
  223. {batplot-1.8.53 → batplot-1.8.57}/batplot/strip_header.py +0 -0
  224. {batplot-1.8.53 → batplot-1.8.57}/batplot/style.py +0 -0
  225. {batplot-1.8.53 → batplot-1.8.57}/batplot/version_check.py +0 -0
  226. {batplot-1.8.53 → batplot-1.8.57}/batplot.egg-info/dependency_links.txt +0 -0
  227. {batplot-1.8.53 → batplot-1.8.57}/batplot.egg-info/entry_points.txt +0 -0
  228. {batplot-1.8.53 → batplot-1.8.57}/batplot.egg-info/requires.txt +0 -0
  229. {batplot-1.8.53 → batplot-1.8.57}/batplot.egg-info/top_level.txt +0 -0
  230. {batplot-1.8.53 → batplot-1.8.57}/setup.cfg +0 -0
  231. {batplot-1.8.53 → batplot-1.8.57}/setup.py +0 -0
  232. {batplot-1.8.53 → batplot-1.8.57}/tests/test_all_menus_smoke.py +0 -0
  233. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_all_modes_sync.py +0 -0
  234. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_cpc_key_isolation.py +0 -0
  235. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_crosshair.py +0 -0
  236. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_dqdv_key_isolation.py +0 -0
  237. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_ec_cycles_status.py +0 -0
  238. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_font_menu.py +0 -0
  239. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_gc_key_isolation.py +0 -0
  240. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_geom_menu.py +0 -0
  241. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_geometry_pisb_keys.py +0 -0
  242. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_histo_key_isolation.py +0 -0
  243. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_menu_parity.py +0 -0
  244. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_operando_key_isolation.py +0 -0
  245. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_panel_status.py +0 -0
  246. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_pisb_contract.py +0 -0
  247. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_scoped_sync_modes.py +0 -0
  248. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_style_pisb_keys.py +0 -0
  249. {batplot-1.8.53 → batplot-1.8.57}/tests/test_batch_xy_key_isolation.py +0 -0
  250. {batplot-1.8.53 → batplot-1.8.57}/tests/test_bc_new_fields_defaults.py +0 -0
  251. {batplot-1.8.53 → batplot-1.8.57}/tests/test_bruker_intensity.py +0 -0
  252. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cif_tick_crystallography.py +0 -0
  253. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cli_all_flags.py +0 -0
  254. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cli_save.py +0 -0
  255. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cli_smoke.py +0 -0
  256. {batplot-1.8.53 → batplot-1.8.57}/tests/test_color_display_hex.py +0 -0
  257. {batplot-1.8.53 → batplot-1.8.57}/tests/test_color_listing_visible.py +0 -0
  258. {batplot-1.8.53 → batplot-1.8.57}/tests/test_color_utils.py +0 -0
  259. {batplot-1.8.53 → batplot-1.8.57}/tests/test_common_files.py +0 -0
  260. {batplot-1.8.53 → batplot-1.8.57}/tests/test_common_palettes.py +0 -0
  261. {batplot-1.8.53 → batplot-1.8.57}/tests/test_convert_xrd.py +0 -0
  262. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cpc_add_file.py +0 -0
  263. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cpc_legend_order.py +0 -0
  264. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cpc_roundtrip.py +0 -0
  265. {batplot-1.8.53 → batplot-1.8.57}/tests/test_critical_stability_fixes.py +0 -0
  266. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cross_os_deeper.py +0 -0
  267. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cross_os_oe_paths.py +0 -0
  268. {batplot-1.8.53 → batplot-1.8.57}/tests/test_cross_platform_parity.py +0 -0
  269. {batplot-1.8.53 → batplot-1.8.57}/tests/test_crosshair_export.py +0 -0
  270. {batplot-1.8.53 → batplot-1.8.57}/tests/test_csv_readers.py +0 -0
  271. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_residual_pisb_gates.py +0 -0
  272. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round10_bc_safe.py +0 -0
  273. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round11_title_fidelity.py +0 -0
  274. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round12_commercial_gates.py +0 -0
  275. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round13_final_key_audit.py +0 -0
  276. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round3_pisb_gates.py +0 -0
  277. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round4_pisb_gates.py +0 -0
  278. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round5_pisb_gates.py +0 -0
  279. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round6_session_fidelity.py +0 -0
  280. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round7_root_helpers.py +0 -0
  281. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round8_root_helpers.py +0 -0
  282. {batplot-1.8.53 → batplot-1.8.57}/tests/test_deep_round9_root_helpers.py +0 -0
  283. {batplot-1.8.53 → batplot-1.8.57}/tests/test_default_sizes_and_oe_persistence.py +0 -0
  284. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dev_upgrade.py +0 -0
  285. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dqdv_contour_session_keys.py +0 -0
  286. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dqdv_smooth_status.py +0 -0
  287. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dual_axis_menu_audit.py +0 -0
  288. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dual_mode_pisb.py +0 -0
  289. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dual_pisb_hard_gates.py +0 -0
  290. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dual_tk_a_coupling.py +0 -0
  291. {batplot-1.8.53 → batplot-1.8.57}/tests/test_dual_top_wasd_both_layers.py +0 -0
  292. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_cpc_style_pisb_keys.py +0 -0
  293. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_cycle_identity_roundtrip.py +0 -0
  294. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_cycles_three_color_modes.py +0 -0
  295. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_multifile_color_menu.py +0 -0
  296. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_old_session_three_color_modes.py +0 -0
  297. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_roundtrip.py +0 -0
  298. {batplot-1.8.53 → batplot-1.8.57}/tests/test_ec_session_bc_new_keys.py +0 -0
  299. {batplot-1.8.53 → batplot-1.8.57}/tests/test_every_key_behavioral_walk.py +0 -0
  300. {batplot-1.8.53 → batplot-1.8.57}/tests/test_file_dialogs_os.py +0 -0
  301. {batplot-1.8.53 → batplot-1.8.57}/tests/test_final_audit_residuals.py +0 -0
  302. {batplot-1.8.53 → batplot-1.8.57}/tests/test_full_menu_audit_gaps.py +0 -0
  303. {batplot-1.8.53 → batplot-1.8.57}/tests/test_gc_cumulative.py +0 -0
  304. {batplot-1.8.53 → batplot-1.8.57}/tests/test_geom_size_highlight.py +0 -0
  305. {batplot-1.8.53 → batplot-1.8.57}/tests/test_hard_check_twin_and_batch.py +0 -0
  306. {batplot-1.8.53 → batplot-1.8.57}/tests/test_histo.py +0 -0
  307. {batplot-1.8.53 → batplot-1.8.57}/tests/test_histo_interactive_imports.py +0 -0
  308. {batplot-1.8.53 → batplot-1.8.57}/tests/test_imk_stderr_guard.py +0 -0
  309. {batplot-1.8.53 → batplot-1.8.57}/tests/test_interactive_handler_intent.py +0 -0
  310. {batplot-1.8.53 → batplot-1.8.57}/tests/test_interactive_menu_smoke.py +0 -0
  311. {batplot-1.8.53 → batplot-1.8.57}/tests/test_interactive_state.py +0 -0
  312. {batplot-1.8.53 → batplot-1.8.57}/tests/test_line_dash_styles.py +0 -0
  313. {batplot-1.8.53 → batplot-1.8.57}/tests/test_menu_handler_imports.py +0 -0
  314. {batplot-1.8.53 → batplot-1.8.57}/tests/test_menu_prompt_order.py +0 -0
  315. {batplot-1.8.53 → batplot-1.8.57}/tests/test_mpl_backend.py +0 -0
  316. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_axis_units.py +0 -0
  317. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_batch_menu.py +0 -0
  318. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_cif_add.py +0 -0
  319. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_layout_menu.py +0 -0
  320. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_peaks_axis_units.py +0 -0
  321. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_spine_isolation.py +0 -0
  322. {batplot-1.8.53 → batplot-1.8.57}/tests/test_operando_submenu_smoke.py +0 -0
  323. {batplot-1.8.53 → batplot-1.8.57}/tests/test_overview_metrics.py +0 -0
  324. {batplot-1.8.53 → batplot-1.8.57}/tests/test_pi_axis_units_persistence.py +0 -0
  325. {batplot-1.8.53 → batplot-1.8.57}/tests/test_pisb_deep_all_modes.py +0 -0
  326. {batplot-1.8.53 → batplot-1.8.57}/tests/test_recent_axis_names.py +0 -0
  327. {batplot-1.8.53 → batplot-1.8.57}/tests/test_screen_color.py +0 -0
  328. {batplot-1.8.53 → batplot-1.8.57}/tests/test_screen_color_pisb.py +0 -0
  329. {batplot-1.8.53 → batplot-1.8.57}/tests/test_secondary_spine_colors.py +0 -0
  330. {batplot-1.8.53 → batplot-1.8.57}/tests/test_session_backward_compat.py +0 -0
  331. {batplot-1.8.53 → batplot-1.8.57}/tests/test_session_font_restore.py +0 -0
  332. {batplot-1.8.53 → batplot-1.8.57}/tests/test_session_full_data_guarantee.py +0 -0
  333. {batplot-1.8.53 → batplot-1.8.57}/tests/test_session_save_integrity.py +0 -0
  334. {batplot-1.8.53 → batplot-1.8.57}/tests/test_session_style_restore_parity.py +0 -0
  335. {batplot-1.8.53 → batplot-1.8.57}/tests/test_spine_wasd_pisb_all_modes.py +0 -0
  336. {batplot-1.8.53 → batplot-1.8.57}/tests/test_state_capture.py +0 -0
  337. {batplot-1.8.53 → batplot-1.8.57}/tests/test_strip_header.py +0 -0
  338. {batplot-1.8.53 → batplot-1.8.57}/tests/test_stupid_input_hardening.py +0 -0
  339. {batplot-1.8.53 → batplot-1.8.57}/tests/test_style_import_integrity.py +0 -0
  340. {batplot-1.8.53 → batplot-1.8.57}/tests/test_style_routing.py +0 -0
  341. {batplot-1.8.53 → batplot-1.8.57}/tests/test_tick_visibility_save_truth.py +0 -0
  342. {batplot-1.8.53 → batplot-1.8.57}/tests/test_undo_deep_all_modes.py +0 -0
  343. {batplot-1.8.53 → batplot-1.8.57}/tests/test_undo_stack_integrity.py +0 -0
  344. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xrd_crosshair_bragg.py +0 -0
  345. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_full_data_retention.py +0 -0
  346. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_generic_xy_default.py +0 -0
  347. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_modules.py +0 -0
  348. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_offset_menu.py +0 -0
  349. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_roundtrip.py +0 -0
  350. {batplot-1.8.53 → batplot-1.8.57}/tests/test_xy_source_files.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batplot
3
- Version: 1.8.53
3
+ Version: 1.8.57
4
4
  Summary: Interactive plotting tool for material science (1D plot) and electrochemistry (GC, CV, dQ/dV, CPC, operando) with batch processing
5
5
  Author-email: Tian Dai <tianda@uio.no>
6
6
  License: MIT License
@@ -85,8 +85,8 @@ pip install batplot
85
85
  ## Quick Start
86
86
 
87
87
  - User manual: https://chem-plot.github.io/batplot/
88
- - Tutorial: https://drive.google.com/file/d/1NTFJWNBbWW4mgz0H5ZelGjuOBWxoFgkr/view
89
- - Tutorial files: https://github.com/chem-plot/batplot/blob/main/batplot_tutorial.zip
88
+ - Tutorial videos: https://www.youtube.com/watch?v=gnX1ytqlV4k&list=PLaJaXAfs1irk
89
+ - Demo files: https://github.com/chem-plot/batplot/blob/main/batplot_demo_files.zip
90
90
 
91
91
  ---
92
92
 
@@ -491,7 +491,8 @@ With `--interactive`:
491
491
 
492
492
  ## Help & Documentation
493
493
 
494
- Illustrated user manual (GitHub Pages): https://chem-plot.github.io/batplot/
494
+ - Illustrated user manual: https://chem-plot.github.io/batplot/
495
+ - Tutorial videos: https://www.youtube.com/watch?v=gnX1ytqlV4k&list=PLaJaXAfs1irk
495
496
 
496
497
  ```bash
497
498
  batplot --h # General help
@@ -29,8 +29,8 @@ pip install batplot
29
29
  ## Quick Start
30
30
 
31
31
  - User manual: https://chem-plot.github.io/batplot/
32
- - Tutorial: https://drive.google.com/file/d/1NTFJWNBbWW4mgz0H5ZelGjuOBWxoFgkr/view
33
- - Tutorial files: https://github.com/chem-plot/batplot/blob/main/batplot_tutorial.zip
32
+ - Tutorial videos: https://www.youtube.com/watch?v=gnX1ytqlV4k&list=PLaJaXAfs1irk
33
+ - Demo files: https://github.com/chem-plot/batplot/blob/main/batplot_demo_files.zip
34
34
 
35
35
  ---
36
36
 
@@ -435,7 +435,8 @@ With `--interactive`:
435
435
 
436
436
  ## Help & Documentation
437
437
 
438
- Illustrated user manual (GitHub Pages): https://chem-plot.github.io/batplot/
438
+ - Illustrated user manual: https://chem-plot.github.io/batplot/
439
+ - Tutorial videos: https://www.youtube.com/watch?v=gnX1ytqlV4k&list=PLaJaXAfs1irk
439
440
 
440
441
  ```bash
441
442
  batplot --h # General help
@@ -7,7 +7,7 @@ import importlib.abc
7
7
  import importlib.machinery
8
8
  import sys
9
9
 
10
- __version__ = "1.8.53"
10
+ __version__ = "1.8.57"
11
11
 
12
12
 
13
13
  _LEGACY_MODULE_ALIASES = {
@@ -173,7 +173,7 @@ def _print_general_help() -> None:
173
173
  "Features:\n"
174
174
  " • Interactive (--i): styling, ranges, fonts, export, sessions\n"
175
175
  " • XRD wavelength: --wl 1.54 or file.xye:1.5406 for Q conversion\n"
176
- " • XRD axis units (interactive): Options u converts 2θ ↔ Q ↔ d (XY + operando; needs λ for 2θ)\n"
176
+ " • XRD axis units (interactive): Options u converts 2θ ↔ Q (XY; needs λ for 2θ); operando also offers d\n"
177
177
  " • CIF phase ticks: add .cif (or file.cif:wl); ticks follow the current axis (2θ / Q / d)\n"
178
178
  " • X-axis range: --xrange min max\n"
179
179
  " • Save figure: --out filename (default .svg)\n"
@@ -201,6 +201,7 @@ def _print_general_help() -> None:
201
201
  " Personal page: https://www.mn.uio.no/kjemi/english/people/aca/tianda/\n"
202
202
  " GitHub: https://github.com/chem-plot/batplot\n"
203
203
  " User manual: https://chem-plot.github.io/batplot/\n"
204
+ " Tutorial videos: https://www.youtube.com/watch?v=gnX1ytqlV4k&list=PLaJaXAfs1irk\n"
204
205
  " Kindly cite Tian's github page if the plot is used for publication\n"
205
206
  )
206
207
  _print_help(msg)
@@ -218,8 +219,9 @@ def _print_xy_help() -> None:
218
219
  "A wavelength can be converted into a different wave length by file.xye:1.54:0.709.\n"
219
220
  "For electrochemistry CSV/MPT time-potential plots, use --xaxis time.\n\n"
220
221
  "Interactive XRD axis units (Options u):\n"
221
- " In --i, press u to convert the plotted XRD axis among 2θ ↔ Q ↔ d (XRD data only).\n"
222
+ " In --i, press u to convert the plotted XRD axis between 2θ ↔ Q (XRD data only).\n"
222
223
  " Conversions involving 2θ need λ (--wl, file:wl, or prompt). CIF ticks stay Bragg-aligned.\n"
224
+ " d-spacing is not offered as a plot domain in 1D Options u.\n"
223
225
  " Not for PDF (.gr), XAS (.nor/.chik/.chir), or other non-diffraction axes.\n"
224
226
  " Example: batplot data.xye:0.709 --xaxis 2theta --i then u → q (uses λ=0.709 Å).\n\n"
225
227
  "CIF phase ticks:\n"
@@ -773,20 +775,66 @@ def parse_args(argv=None):
773
775
  # Keys use the exact file token (e.g. "file.xy:1.54") for wavelength match.
774
776
  # Style files (.bps, .bpsg, .bpcfg) are NOT treated as file tokens so that
775
777
  # "batplot --all style.bps --readcol 2 3" uses global readcol, not per-file.
778
+ #
779
+ # Values of known options (--wl 0.259, --xaxis q, --out out.svg, …) must
780
+ # NOT update last_file_token. Otherwise
781
+ # batplot TD_R02.dat --wl 0.259 --readcol 1 3
782
+ # binds readcol to "0.259" and the plot silently falls back to cols 1,2.
776
783
  # ====================================================================
777
784
  readcol_by_file = {}
778
785
  global_readcol_expanded = None
779
786
  filtered_argv = []
780
787
  last_file_token = None
781
788
  _STYLE_EXTENSIONS = ('.bps', '.bpsg', '.bpcfg')
789
+ # Exact value counts for options that take fixed nargs (after short→long).
790
+ # store_true / flag-only options are omitted (0 values).
791
+ _OPTION_VALUE_COUNTS = {
792
+ '--wl': 1,
793
+ '--xaxis': 1,
794
+ '--out': 1,
795
+ '--savefig': 1,
796
+ '--delta': 1,
797
+ '--format': 1,
798
+ '--mass': 1,
799
+ '--cd': 1,
800
+ '--average': 1,
801
+ '--sum': 1,
802
+ '--histocol': 1,
803
+ '--binwidth': 1,
804
+ '--bins': 1,
805
+ '--ext': 1,
806
+ '--convert-ext': 1,
807
+ '--xrange': 2,
808
+ '--convert': 2,
809
+ '--pw': 2,
810
+ '--b': 2,
811
+ '--readcolxy': 2,
812
+ '--readcolxye': 2,
813
+ '--readcolqye': 2,
814
+ '--readcolnor': 2,
815
+ '--readcoldat': 2,
816
+ '--readcolcsv': 2,
817
+ '--readcolc': 2,
818
+ '--readcols': 2,
819
+ }
820
+ for _ext in custom_readcol_exts:
821
+ _OPTION_VALUE_COUNTS[f'--readcol{_ext}'] = 2
822
+ # Optional single value (nargs='?'): consume at most one non-option token.
823
+ _OPTIONAL_ONE_VALUE = {'--all', '--help', '--extract-brml-scans'}
824
+
825
+ def _option_value_count(flag: str) -> int:
826
+ if flag in _OPTION_VALUE_COUNTS:
827
+ return _OPTION_VALUE_COUNTS[flag]
828
+ if flag in _OPTIONAL_ONE_VALUE:
829
+ return 1
830
+ if flag == '--fullprof':
831
+ # nargs='+': consume following non-option tokens
832
+ return 10**9
833
+ return 0
834
+
782
835
  i = 0
783
836
  while i < len(argv):
784
837
  arg = argv[i]
785
- # Track non-option tokens as potential file specs (exclude style files)
786
- if not arg.startswith('-'):
787
- arg_lower = arg.lower()
788
- if not arg_lower.endswith(_STYLE_EXTENSIONS):
789
- last_file_token = arg
790
838
  if arg == '--readcol' and i + 1 < len(argv):
791
839
  tokens = []
792
840
  j = i + 1
@@ -824,9 +872,23 @@ def parse_args(argv=None):
824
872
  global_readcol_expanded = pairs[0] if len(pairs) == 1 else pairs
825
873
  i = j
826
874
  continue
875
+ if arg.startswith('-'):
876
+ filtered_argv.append(arg)
877
+ n_vals = _option_value_count(arg)
878
+ i += 1
879
+ taken = 0
880
+ while taken < n_vals and i < len(argv) and not argv[i].startswith('-'):
881
+ filtered_argv.append(argv[i])
882
+ i += 1
883
+ taken += 1
884
+ continue
885
+ # Non-option: potential file spec (exclude style files)
886
+ arg_lower = arg.lower()
887
+ if not arg_lower.endswith(_STYLE_EXTENSIONS):
888
+ last_file_token = arg
827
889
  filtered_argv.append(arg)
828
890
  i += 1
829
-
891
+
830
892
  argv = filtered_argv
831
893
 
832
894
  # ====================================================================
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.56] - 2026-09-25
4
+ - Add normalization suppor for dQdV mode
5
+
6
+
7
+ ## [1.8.57] - 2026-09-25
8
+ - Bug fixes
9
+
10
+
11
+ ## [1.8.55] - 2026-09-15
12
+ - Bug fixes
13
+
14
+
15
+ ## [1.8.54] - 2026-09-14
16
+ - Fix --readcol after --wl / other option values (cols no longer stuck on 1–2)
17
+ - Quit prompt: e=export and s=save work in every interactive / batch menu
18
+ - Color menus (c/k): WASD side rectangle like spines t, for all modes
19
+ - User manual homepage: GitHub repo + tutorial zip links
20
+
21
+
3
22
  ## [1.8.53] - 2026-09-09
4
23
  - Bug fixes
5
24
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.8.53",
2
+ "version": "1.8.57",
3
3
  "custom_message": "- Bug fixes",
4
4
  "update_notes": [
5
5
  "- Bug fixes"
@@ -26,20 +26,24 @@ def append_batch_io_shortcuts(options: List[str], panels: Sequence[Any]) -> None
26
26
 
27
27
 
28
28
  def batch_quit_confirm(*, allow_export: bool = True) -> str | None:
29
- """Return ``y`` to quit, ``s`` to save all sessions first, or ``None`` to stay."""
30
- try:
31
- if allow_export:
32
- prompt = "Quit batch interactive? (s=save all sessions, y/n): "
33
- else:
34
- prompt = "Quit batch interactive? Quit now? (y/n): "
35
- confirm = safe_input(colorize_prompt(prompt), cancel_on_interrupt=True).strip().lower()
36
- except (KeyboardInterrupt, EOFError):
37
- return "y"
38
- if confirm == "y":
39
- return "y"
40
- if allow_export and confirm == "s":
41
- return "s"
42
- return None
29
+ """Return ``y`` to quit, ``e``/``s`` to run export/save next, or ``None`` to stay."""
30
+ from ..common.terminal import confirm_quit_interactive
31
+
32
+ if not allow_export:
33
+ try:
34
+ confirm = safe_input(
35
+ colorize_prompt("Quit batch interactive? Quit now? (y/n): "),
36
+ cancel_on_interrupt=True,
37
+ ).strip().lower()
38
+ except (KeyboardInterrupt, EOFError):
39
+ return "y"
40
+ return "y" if confirm == "y" else None
41
+
42
+ return confirm_quit_interactive(
43
+ label="Quit batch interactive?",
44
+ safe_input_fn=lambda prompt: safe_input(prompt, cancel_on_interrupt=True),
45
+ colorize_fn=colorize_prompt,
46
+ )
43
47
 
44
48
 
45
49
  def run_batch_save_all(panels: Sequence[Any], save_panel: Callable[[Any, str], None]) -> None:
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any, Callable, Sequence
6
6
 
7
- from .batch_commands import batch_quit_confirm, run_batch_overwrite_sessions, run_batch_save_all
7
+ from .batch_commands import batch_quit_confirm, run_batch_overwrite_sessions
8
8
  from .batch_figure_io import run_batch_export_figures, run_batch_overwrite_figures
9
9
  from .batch_io import run_batch_export_style, run_batch_import_style, run_batch_save_sessions
10
10
 
@@ -12,13 +12,20 @@ from .batch_io import run_batch_export_style, run_batch_import_style, run_batch_
12
12
  def batch_quit_or_save_all(
13
13
  panels: Sequence[Any],
14
14
  save_panel: Callable[[Any, str], None],
15
- ) -> bool:
16
- """Handle ``q`` quit prompt. Returns True when the menu loop should exit."""
15
+ ) -> bool | str:
16
+ """Handle ``q`` quit prompt.
17
+
18
+ Returns:
19
+ ``True`` when the menu loop should exit,
20
+ ``"e"`` / ``"s"`` to dispatch export/save on the next loop iteration,
21
+ ``False`` to stay in the menu.
22
+ """
23
+ _ = (panels, save_panel) # call-site signature unchanged; e/s use pending keys
17
24
  action = batch_quit_confirm(allow_export=True)
18
25
  if action == "y":
19
26
  return True
20
- if action == "s":
21
- run_batch_save_all(panels, save_panel)
27
+ if action in ("e", "s"):
28
+ return action
22
29
  return False
23
30
 
24
31
 
@@ -55,6 +55,7 @@ __all__ = [
55
55
  "apply_ec_line_chrome_only",
56
56
  "apply_ec_scoped_sync",
57
57
  "apply_ec_smooth_only",
58
+ "apply_ec_norm_only",
58
59
  "apply_ec_spine_colors_only",
59
60
  "apply_ec_wasd_chrome_only",
60
61
  "default_ec_tick_state",
@@ -526,6 +527,39 @@ def apply_ec_smooth_only(panel: EcPanel, cfg: dict, *, silent: bool = True) -> b
526
527
  return True
527
528
 
528
529
 
530
+ def apply_ec_norm_only(panel: EcPanel, cfg: dict, *, silent: bool = True) -> bool:
531
+ """Batch ``nm`` (dQdV): sync normalize settings and re-apply (not colors / WASD)."""
532
+ from ..electrochem.dqdv_norm import apply_dqdv_norm, reset_dqdv_norm
533
+
534
+ cfg = dict(cfg) if isinstance(cfg, dict) else {}
535
+ norm = cfg.get("_dqdv_norm_settings")
536
+ if not isinstance(norm, dict):
537
+ return False
538
+ file_data, cycle_lines, is_multi = ec_normalize_file_data(panel)
539
+ try:
540
+ if bool(norm.get("enabled")):
541
+ apply_dqdv_norm(
542
+ panel.fig,
543
+ file_data=file_data if is_multi else None,
544
+ cycle_lines=cycle_lines,
545
+ method=norm.get("method"),
546
+ visible_only=False,
547
+ ax=panel.ax,
548
+ )
549
+ else:
550
+ reset_dqdv_norm(
551
+ panel.fig,
552
+ file_data=file_data if is_multi else None,
553
+ cycle_lines=cycle_lines,
554
+ ax=panel.ax,
555
+ )
556
+ except Exception as exc:
557
+ if not silent:
558
+ print(f"dQ/dV normalize sync failed for {getattr(panel, 'path', '?')}: {exc}")
559
+ return False
560
+ return True
561
+
562
+
529
563
  def ec_panel_is_dqdv(panel: EcPanel) -> bool:
530
564
  """True when this EC panel is a dQ/dV (differential capacity) session."""
531
565
  ax = getattr(panel, "ax", None)
@@ -385,8 +385,11 @@ def run_cpc_batch_menu(panels: List[CpcPanel]) -> None:
385
385
  continue
386
386
 
387
387
  if cmd == "q":
388
- if batch_quit_or_save_all(panels, _save_cpc_panel):
388
+ result = batch_quit_or_save_all(panels, _save_cpc_panel)
389
+ if result is True:
389
390
  break
391
+ if result in ("e", "s"):
392
+ pending = result
390
393
  continue
391
394
 
392
395
  if cmd == "b":
@@ -185,8 +185,11 @@ def run_dqdv_2d_batch_menu(panels: List[OperandoPanel]) -> None:
185
185
  continue
186
186
 
187
187
  if cmd == "q":
188
- if batch_quit_or_save_all(panels, save_dqdv_2d_panel):
188
+ result = batch_quit_or_save_all(panels, save_dqdv_2d_panel)
189
+ if result is True:
189
190
  break
191
+ if result in ("e", "s"):
192
+ pending = result
190
193
  continue
191
194
 
192
195
  if cmd == "b":
@@ -82,6 +82,7 @@ from .ec_batch_helpers import (
82
82
  apply_ec_legend_only,
83
83
  apply_ec_line_chrome_only,
84
84
  apply_ec_smooth_only,
85
+ apply_ec_norm_only,
85
86
  apply_ec_spine_colors_only,
86
87
  apply_ec_wasd_chrome_only,
87
88
  default_ec_tick_state,
@@ -103,6 +104,7 @@ from .ec_batch_helpers import (
103
104
  from ..electrochem.interactive import _apply_stored_smooth_settings
104
105
  from ..electrochem.legend_order import run_ec_legend_order_menu
105
106
  from ..electrochem.smoothing_menu import run_dqdv_smoothing_menu
107
+ from ..electrochem.dqdv_norm import run_dqdv_norm_menu
106
108
  from .load import EcPanel
107
109
 
108
110
 
@@ -140,6 +142,8 @@ def _print_ec_batch_menu(panels: List[EcPanel]) -> None:
140
142
  ]
141
143
  if is_dqdv:
142
144
  col1.insert(2, "sm: smooth")
145
+ # Batch: normalize each panel (multi-file overlay or peer single-file panels).
146
+ col1.insert(3, "nm: normalize")
143
147
  if _ec_batch_has_multi_file(panels):
144
148
  # Match interactive: only list file visibility when multi-file
145
149
  col1.insert(-1, "v: show/hide files")
@@ -279,8 +283,11 @@ def run_ec_batch_menu(panels: List[EcPanel]) -> None:
279
283
  continue
280
284
 
281
285
  if cmd == "q":
282
- if batch_quit_or_save_all(panels, _save_ec_panel):
286
+ result = batch_quit_or_save_all(panels, _save_ec_panel)
287
+ if result is True:
283
288
  break
289
+ if result in ("e", "s"):
290
+ pending = result
284
291
  continue
285
292
 
286
293
  if cmd == "b":
@@ -386,10 +393,76 @@ def run_ec_batch_menu(panels: List[EcPanel]) -> None:
386
393
  safe_input=safe_input,
387
394
  colorize_menu=_colorize_menu,
388
395
  colorize_prompt=colorize_prompt,
396
+ ax=ref.ax,
389
397
  ),
390
398
  )
391
399
  continue
392
400
 
401
+ if cmd == "nm":
402
+ if not is_dqdv:
403
+ print("'nm' is only available in batch dQ/dV mode.")
404
+ continue
405
+ file_data, cycle_lines, is_multi_file, print_file_list = _ref_menu_context(ref)
406
+ # Interactive nm requires multi-file on the ref panel; for single-file
407
+ # batch peers, apply normalize directly then sync settings.
408
+ def _edit_nm() -> None:
409
+ if is_multi_file and file_data and len(file_data) >= 2:
410
+ run_dqdv_norm_menu(
411
+ fig=ref.fig,
412
+ ax=ref.ax,
413
+ cycle_lines=cycle_lines,
414
+ file_data=file_data,
415
+ current_file_idx=0,
416
+ all_cycles=ec_all_cycles(cycle_lines, file_data),
417
+ is_dqdv=True,
418
+ is_multi_file=True,
419
+ menu_title="",
420
+ canvas_mode=False,
421
+ print_menu=lambda *_a, **_k: None,
422
+ print_file_list=print_file_list,
423
+ push_state=noop_snapshot,
424
+ safe_input=safe_input,
425
+ colorize_menu=_colorize_menu,
426
+ colorize_prompt=colorize_prompt,
427
+ )
428
+ else:
429
+ from ..electrochem.dqdv_norm import (
430
+ apply_dqdv_norm,
431
+ format_dqdv_norm_status,
432
+ reset_dqdv_norm,
433
+ )
434
+
435
+ print("\n" + format_dqdv_norm_status(ref.fig))
436
+ print(" a: normalize this panel | r: reset | q: back")
437
+ sub = safe_input(colorize_prompt("Normalize (a/r/q): ")).strip().lower()
438
+ if sub in ("a", "all"):
439
+ apply_dqdv_norm(
440
+ ref.fig,
441
+ file_data=None,
442
+ cycle_lines=cycle_lines,
443
+ ax=ref.ax,
444
+ )
445
+ print("Normalized.")
446
+ elif sub == "r":
447
+ reset_dqdv_norm(
448
+ ref.fig,
449
+ file_data=None,
450
+ cycle_lines=cycle_lines,
451
+ ax=ref.ax,
452
+ )
453
+ print("Normalize reset.")
454
+
455
+ edit_ref_then_sync(
456
+ ref,
457
+ panels,
458
+ undo=undo,
459
+ capture_panel=_capture_panel,
460
+ apply_cfg=apply_ec_norm_only,
461
+ draw_all=lambda: draw_panels(panels),
462
+ edit_fn=_edit_nm,
463
+ )
464
+ continue
465
+
393
466
  if cmd == "t":
394
467
  run_ec_batch_spine_menu(
395
468
  ref,
@@ -162,8 +162,11 @@ def run_histo_batch_menu(panels: List[HistoPanel]) -> None:
162
162
  continue
163
163
 
164
164
  if cmd == "q":
165
- if batch_quit_or_save_all(panels, _save_histo_panel):
165
+ result = batch_quit_or_save_all(panels, _save_histo_panel)
166
+ if result is True:
166
167
  break
168
+ if result in ("e", "s"):
169
+ pending = result
167
170
  continue
168
171
 
169
172
  if cmd == "b":
@@ -352,8 +352,11 @@ def run_operando_batch_menu(panels: List[OperandoPanel]) -> None:
352
352
  continue
353
353
 
354
354
  if cmd == "q":
355
- if batch_quit_or_save_all(panels, _save_operando_panel):
355
+ result = batch_quit_or_save_all(panels, _save_operando_panel)
356
+ if result is True:
356
357
  break
358
+ if result in ("e", "s"):
359
+ pending = result
357
360
  continue
358
361
 
359
362
  if cmd == "b":