plotstyle 1.2.0__tar.gz → 1.2.1__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 (124) hide show
  1. plotstyle-1.2.1/CHANGELOG.md +155 -0
  2. {plotstyle-1.2.0 → plotstyle-1.2.1}/PKG-INFO +114 -24
  3. {plotstyle-1.2.0 → plotstyle-1.2.1}/README.md +113 -23
  4. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/__init__.py +1 -1
  5. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/_compat/mpl_style.py +2 -2
  6. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/_version.py +2 -2
  7. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/cli/main.py +3 -3
  8. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/_rendering.py +1 -1
  9. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/accessibility.py +1 -1
  10. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/core/export.py +12 -7
  11. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/core/figure.py +3 -3
  12. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/core/migrate.py +7 -7
  13. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/core/style.py +14 -14
  14. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/engine/fonts.py +9 -8
  15. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/engine/latex.py +2 -2
  16. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/engine/rcparams.py +5 -5
  17. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/__init__.py +2 -2
  18. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/schema.py +3 -3
  19. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/preview/print_size.py +1 -1
  20. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/__init__.py +27 -24
  21. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/_templates.toml +1 -1
  22. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/schema.py +2 -2
  23. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/units.py +2 -2
  24. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/__init__.py +1 -1
  25. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/_base.py +1 -1
  26. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/dimensions.py +2 -2
  27. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/typography.py +1 -1
  28. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/report.py +1 -1
  29. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_cli/test_main.py +3 -3
  30. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_color/test_accessibility.py +1 -1
  31. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_color/test_grayscale.py +1 -1
  32. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_engine/test_rcparams.py +13 -13
  33. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_integrations/test_seaborn.py +3 -3
  34. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_preview/test_gallery.py +1 -1
  35. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_preview/test_print_size.py +1 -1
  36. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_specs/test_registry.py +3 -3
  37. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_specs/test_schema.py +6 -6
  38. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_specs/test_units.py +8 -8
  39. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_utils/test_io.py +5 -5
  40. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_utils/test_warnings.py +1 -1
  41. plotstyle-1.2.0/CHANGELOG.md +0 -135
  42. {plotstyle-1.2.0 → plotstyle-1.2.1}/.gitignore +0 -0
  43. {plotstyle-1.2.0 → plotstyle-1.2.1}/LICENSE +0 -0
  44. {plotstyle-1.2.0 → plotstyle-1.2.1}/pyproject.toml +0 -0
  45. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/_compat/__init__.py +0 -0
  46. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/_utils/__init__.py +0 -0
  47. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/_utils/io.py +0 -0
  48. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/_utils/warnings.py +0 -0
  49. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/cli/__init__.py +0 -0
  50. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/__init__.py +0 -0
  51. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/okabe_ito.json +0 -0
  52. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/safe_grayscale.json +0 -0
  53. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_bright.json +0 -0
  54. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_high_contrast.json +0 -0
  55. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_light.json +0 -0
  56. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_muted.json +0 -0
  57. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_rainbow_10.json +0 -0
  58. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_rainbow_12.json +0 -0
  59. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_rainbow_4.json +0 -0
  60. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_rainbow_6.json +0 -0
  61. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_rainbow_8.json +0 -0
  62. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/data/tol_vibrant.json +0 -0
  63. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/grayscale.py +0 -0
  64. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/color/palettes.py +0 -0
  65. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/core/__init__.py +0 -0
  66. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/engine/__init__.py +0 -0
  67. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/integrations/__init__.py +0 -0
  68. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/integrations/seaborn.py +0 -0
  69. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/bar.toml +0 -0
  70. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/cjk-japanese.toml +0 -0
  71. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/cjk-korean.toml +0 -0
  72. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/cjk-simplified.toml +0 -0
  73. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/cjk-traditional.toml +0 -0
  74. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/grid.toml +0 -0
  75. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/high-vis.toml +0 -0
  76. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/latex-sans.toml +0 -0
  77. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/minimal.toml +0 -0
  78. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/no-latex.toml +0 -0
  79. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/notebook.toml +0 -0
  80. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/okabe-ito.toml +0 -0
  81. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/pgf.toml +0 -0
  82. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/presentation.toml +0 -0
  83. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/russian.toml +0 -0
  84. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/safe-grayscale.toml +0 -0
  85. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/scatter.toml +0 -0
  86. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-bright.toml +0 -0
  87. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-high-contrast.toml +0 -0
  88. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-light.toml +0 -0
  89. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-muted.toml +0 -0
  90. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-rainbow-10.toml +0 -0
  91. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-rainbow-12.toml +0 -0
  92. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-rainbow-4.toml +0 -0
  93. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-rainbow-6.toml +0 -0
  94. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-rainbow-8.toml +0 -0
  95. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/tol-vibrant.toml +0 -0
  96. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/overlays/turkish.toml +0 -0
  97. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/preview/__init__.py +0 -0
  98. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/preview/gallery.py +0 -0
  99. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/py.typed +0 -0
  100. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/acs.toml +0 -0
  101. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/cell.toml +0 -0
  102. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/elsevier.toml +0 -0
  103. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/ieee.toml +0 -0
  104. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/nature.toml +0 -0
  105. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/plos.toml +0 -0
  106. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/prl.toml +0 -0
  107. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/science.toml +0 -0
  108. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/springer.toml +0 -0
  109. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/specs/wiley.toml +0 -0
  110. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/__init__.py +0 -0
  111. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/colors.py +0 -0
  112. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/export.py +0 -0
  113. {plotstyle-1.2.0 → plotstyle-1.2.1}/src/plotstyle/validation/checks/lines.py +0 -0
  114. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/conftest.py +0 -0
  115. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_color/test_palettes.py +0 -0
  116. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_color/test_rendering.py +0 -0
  117. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_core/test_export.py +0 -0
  118. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_core/test_figure.py +0 -0
  119. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_core/test_migrate.py +0 -0
  120. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_core/test_style.py +0 -0
  121. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_engine/test_fonts.py +0 -0
  122. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_engine/test_latex.py +0 -0
  123. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_validation/test_checks.py +0 -0
  124. {plotstyle-1.2.0 → plotstyle-1.2.1}/tests/test_validation/test_report.py +0 -0
@@ -0,0 +1,155 @@
1
+ # Changelog
2
+
3
+ All notable changes to **plotstyle** will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [PEP 440](https://peps.python.org/pep-0440/) versioning.
7
+
8
+ ---
9
+
10
+ ## [Unreleased]
11
+
12
+ _Nothing yet._
13
+
14
+ ---
15
+
16
+ ## [1.2.1] - 2026-04-26
17
+
18
+ Patch release: `simulate_cvd` example, warning quality improvements, and docs/example content fixes.
19
+
20
+ ### Added
21
+
22
+ - **`simulate_cvd` example in `04_accessibility_checks.py`**: demonstrates low-level CVD simulation by rendering a figure to an RGB array and applying a single `CVDType` matrix directly via `simulate_cvd()`.
23
+
24
+ ### Changed
25
+
26
+ - **`SpecAssumptionWarning` deduplication**: each spec now emits the assumption warning at most once per session. A `_warned_specs` set on `SpecRegistry` tracks which specs have already warned; `reset()` clears it alongside the spec cache.
27
+ - **Clearer `OverlaySizeWarning`**: the message now names the journal, the overlay, the actual width, the limit, and the fix action, replacing the previous vague description.
28
+ - **Improved font-fallback warning**: lists font names in a readable comma-separated form and adds a hint to rebuild the Matplotlib font cache after installing a new font.
29
+ - **FontTools log suppression during PDF export**: `savefig()` temporarily sets the `fontTools` logger to `ERROR` level during `fig.savefig()` to suppress low-level font subsetting noise.
30
+ - **`SpecRegistry.get()` uses `_silent=True` during background style registration**: prevents the assumption warning from firing during the import-time `register_all_styles()` call.
31
+ - **Docs and example content fixes**: factual errors corrected across API reference, guides, CLI docs, and Jupyter notebooks; overlay guide expanded with additional coverage.
32
+
33
+ ---
34
+
35
+ ## [1.2.0] - 2026-04-23
36
+
37
+ Feature release: **overlays**, **units & conversions**, **Seaborn integration**, improved **font/LaTeX controls**, plus major CLI/docs/example expansion.
38
+
39
+ ### Added
40
+
41
+ - **Style overlays** (`plotstyle.overlays`, `plotstyle.list_overlays()`): additive layers that can be composed with a base journal preset.
42
+ - Categories: `color`, `context`, `rendering`, `plot-type`, `script`.
43
+ - Built-in overlays include `minimal`, `notebook`, `presentation`, `high-vis`, `grid`, `bar`, `scatter`, `no-latex`, `pgf`, `latex-sans`, `okabe-ito`, `safe-grayscale`, and `tol-*` palette overlays, plus CJK/Turkish/Russian script overlays.
44
+ - **New CLI commands for overlays**
45
+ - `plotstyle overlays [--category <category>]` to list overlays.
46
+ - `plotstyle overlay-info <overlay>` to inspect overlay metadata and `rcParams`.
47
+ - **Font checks for overlays**: `plotstyle fonts --overlay <overlay>` (in addition to `--journal`).
48
+ - **Seaborn integration**: helpers to keep PlotStyle `rcParams` consistent when using Seaborn themes (`patch_seaborn()`, `plotstyle_theme()`, `unpatch_seaborn()`).
49
+ - **Units & conversions**: new/expanded utilities and docs for consistent size specification across specs and helpers.
50
+ - **Matplotlib-native styles compatibility**: support for registering/using PlotStyle presets as Matplotlib styles where applicable.
51
+ - **New examples & previews**: additional example scripts including overlays, Seaborn integration, units/conversions, print-size preview, Matplotlib native styles, and LaTeX/fonts.
52
+
53
+ ### Changed
54
+
55
+ - **CLI UX improvements**
56
+ - `plotstyle fonts` now supports `--journal` *or* `--overlay` (mutually exclusive, required).
57
+ - More robust argument parsing (e.g. ignores empty entries in `--formats`).
58
+ - Friendlier output for empty registries (journals/overlays) and clearer reporting for overlay font availability.
59
+ - **Docs & README expansion**: new/expanded guides and API reference for overlays, units, warnings, Seaborn, preview tooling, and updated patterns/examples.
60
+
61
+ ### Fixed
62
+
63
+ - **CLI stability**: avoid noisy/unclear behavior in edge cases (empty registry listings, malformed format lists) and improve error messaging around missing overlay keys.
64
+
65
+ ---
66
+
67
+ ## [1.1.0] - 2026-04-16
68
+
69
+ Minor feature release : ergonomics improvements, hardened error handling, and spec updates.
70
+
71
+ ### Added
72
+
73
+ - **`quiet` parameter on `JournalStyle.export()`** : suppresses compliance summaries and manifest output for scripting workflows.
74
+ - **Pre-computed Type 3 font checks** : compliance summary now accepts a pre-computed result for Type 3 font detection, improving performance when the check has already been run by the caller.
75
+ - **`JournalSpec` key access** : `JournalSpec` now supports key-style access, and the dimension check message has been updated for clarity.
76
+
77
+ ### Fixed
78
+
79
+ - **`SpecNotFoundError` base classes** : now inherits from both `ValueError` and `KeyError` so existing `except ValueError` and `except KeyError` handlers catch it correctly; a custom `__str__` produces clearer diagnostic messages.
80
+
81
+ ### Changed
82
+
83
+ - **IEEE Transactions spec updated** : column widths, max height, font family, panel-label properties, and preferred output formats revised to match current IEEE author guidelines.
84
+ - **CI documentation build** : Sphinx `docs` job (`sphinx-build -W -n`) added to the CI workflow; rendered HTML is uploaded as an artifact on every push.
85
+ - **Module docstrings** : expanded and standardised across `__init__.py`, `_utils/`, `color/`, `core/`, and `validation/` for consistent Sphinx rendering.
86
+ - **Context-manager examples** : all `plotstyle.use()` call sites in docs and examples updated to the `with plotstyle.use(...) as style:` form to ensure correct `rcParams` restoration.
87
+
88
+ ---
89
+
90
+ ## [1.0.0] - 2026-04-12
91
+
92
+ First stable release: production-ready for scientific publication workflows.
93
+
94
+ ### Changed
95
+
96
+ - **Stable release**: promoted from alpha (`0.1.0a2`) to stable (`1.0.0`); all public APIs are now considered stable and subject to semantic versioning guarantees.
97
+ - **PyPI classifiers** updated to `Development Status :: 5 - Production/Stable`.
98
+ - **Enhanced project metadata**: expanded keywords, classifiers, and project URLs in `pyproject.toml` for better PyPI discoverability.
99
+ - **README improvements**: added more badges (downloads, docs status, code style), expanded feature descriptions, and added star-history / citation section.
100
+
101
+ ---
102
+
103
+ ## [0.1.0a2] - 2026-04-12
104
+
105
+ Second alpha: full documentation suite, comprehensive test coverage, and hardened validation.
106
+
107
+ ### Added
108
+
109
+ - **Full documentation suite**: Sphinx/MyST docs covering installation, quickstart, concepts, CLI reference, complete API reference for every public symbol, how-to guides (accessibility, export, migration, multi-panel, palettes, seaborn), FAQ, and a journal comparison index.
110
+ - **ReadTheDocs integration**: `.readthedocs.yaml` added; docs build automatically on every push; Furo theme configured with custom CSS.
111
+ - **Comprehensive test suite**: new test modules added: `test_style`, `test_palettes`, `test_accessibility`, `test_grayscale`, `test_rendering`, `test_gallery`, `test_print_size`, `test_cli`, `test_io`, `test_warnings`, `test_checks`, `test_report`; existing modules `test_figure`, `test_export`, `test_migrate`, `test_fonts`, and `test_registry` substantially expanded.
112
+ - **Export DPI validation**: `validation/checks/export.py` now emits a hard `FAIL` (instead of a `WARN`) when `savefig.dpi` is a numeric value that is provably below the journal's minimum DPI requirement.
113
+ - **Dependabot**: `.github/dependabot.yml` added for automated dependency-update pull requests.
114
+ - **`_format_panel_label()` range guard**: raises `ValueError` for panel indices ≥ 702 (beyond the two-character `"zz"` label); valid range is now explicitly documented as 0–701.
115
+
116
+ ### Changed
117
+
118
+ - CI workflow extended: a `docs` build job added to `.github/workflows/ci.yml` - runs `sphinx-build -W -n` on every push and uploads the rendered HTML as an artifact.
119
+ - Module docstring quick-start example in `__init__.py` updated to use the context-manager form (`with plotstyle.use(...) as style:`) and `plotstyle.figure()` instead of `plotstyle.subplots()`.
120
+ - Docstrings across `migrate.py`, `report.py`, `style.py`, `figure.py`, `export.py`, and `accessibility.py` converted to NumPy-style attribute sections for consistent Sphinx rendering.
121
+ - `FORMAT_EXTENSIONS` constant in `export.py` annotated as a module-level Sphinx data comment (`#:`) so it appears correctly in the API docs.
122
+ - `pyproject.toml` documentation extras updated: `furo` pinned to `>=2025.12.19` and `myst-parser` bumped to `>=5.0,<6`.
123
+
124
+ ---
125
+
126
+ ## [0.1.0a1] - 2026-04-07
127
+
128
+ First public alpha release.
129
+
130
+ ### Added
131
+
132
+ - **Core style engine**: `plotstyle.use()` applies journal presets to Matplotlib's `rcParams`; works as a context manager with automatic restoration on exit.
133
+ - **Figure helpers**: `plotstyle.figure()` and `plotstyle.subplots()` create correctly-sized figures at the exact column width and max height specified by each journal.
134
+ - **Auto panel labels**: multi-panel figures receive **(a)**, **(b)**, **(c)**, … labels placed according to the journal's style rules.
135
+ - **Colorblind-safe palettes**: built-in Okabe–Ito, Tol Bright, Tol Vibrant, Tol Muted, and Safe Grayscale palettes (`plotstyle.palette()`).
136
+ - **Accessibility previews**: `plotstyle.preview_colorblind()` simulates deuteranopia, protanopia, and tritanopia; `plotstyle.preview_grayscale()` previews grayscale rendering.
137
+ - **Pre-submission validation**: `plotstyle.validate()` checks dimensions, typography, line weights, color accessibility, and export settings against a target journal spec.
138
+ - **Submission-ready export**: `plotstyle.savefig()` saves with font embedding and DPI enforcement; `plotstyle.export_submission()` batch-exports to all formats a journal accepts.
139
+ - **Spec diffing & migration**: `plotstyle.diff()` compares two journal specs; `plotstyle.migrate()` re-targets a figure from one journal to another.
140
+ - **Seaborn integration**: `patch_seaborn()` / `plotstyle_theme()` ensure PlotStyle `rcParams` survive `sns.set_theme()` calls.
141
+ - **Gallery & print-size preview**: `plotstyle.gallery()` generates sample figures; `plotstyle.preview_print_size()` opens an interactive scaled preview window.
142
+ - **Journal spec registry**: programmatic access via `plotstyle.registry`; specs are TOML files validated by immutable, typed dataclasses.
143
+ - **CLI**: `plotstyle list`, `plotstyle info`, `plotstyle diff`, `plotstyle fonts`, `plotstyle validate`, and `plotstyle export` sub-commands.
144
+ - **10 journal presets**: ACS, Cell, Elsevier, IEEE, Nature, PLOS, PRL, Science, Springer, Wiley.
145
+ - **10 working examples**: quick start, multi-panel, palettes, accessibility, validation, export, diff/migrate, gallery, registry, context manager patterns.
146
+ - **Dynamic versioning**: version derived from git tags via `hatch-vcs` and `importlib.metadata`.
147
+ - **CI/CD pipeline**: GitHub Actions workflows for lint, type-check, test matrix, and automated PyPI release via OIDC Trusted Publishing.
148
+
149
+ [Unreleased]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.1...HEAD
150
+ [1.2.1]: https://github.com/rahulkaushal04/plotstyle/compare/v1.2.0...v1.2.1
151
+ [1.2.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.1.0...v1.2.0
152
+ [1.1.0]: https://github.com/rahulkaushal04/plotstyle/compare/v1.0.0...v1.1.0
153
+ [1.0.0]: https://github.com/rahulkaushal04/plotstyle/compare/v0.1.0a2...v1.0.0
154
+ [0.1.0a2]: https://github.com/rahulkaushal04/plotstyle/compare/v0.1.0a1...v0.1.0a2
155
+ [0.1.0a1]: https://github.com/rahulkaushal04/plotstyle/releases/tag/v0.1.0a1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotstyle
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Matplotlib/seaborn style presets matching scientific journal requirements, with validation, export safety, and preview capabilities.
5
5
  Project-URL: Homepage, https://github.com/rahulkaushal04/plotstyle
6
6
  Project-URL: Documentation, https://plotstyle.readthedocs.io
@@ -244,45 +244,95 @@ fig.savefig("palette_comparison.png", dpi=150)
244
244
  Pass `with_markers=True` to get `(color, linestyle, marker)` tuples, useful for journals like IEEE that print in grayscale:
245
245
 
246
246
  ```python
247
- styled = plotstyle.palette("ieee", n=4, with_markers=True)
248
- for color, ls, marker in styled:
249
- ax.plot(x, y, color=color, linestyle=ls, marker=marker)
247
+ import numpy as np
248
+ import plotstyle
249
+
250
+ x = np.linspace(0, 2 * np.pi, 100)
251
+ curves = [np.sin(x + i * 0.5) for i in range(4)]
252
+
253
+ with plotstyle.use("ieee") as style:
254
+ fig, ax = style.figure(columns=1)
255
+ styled = plotstyle.palette("ieee", n=4, with_markers=True)
256
+ for i, (color, ls, marker) in enumerate(styled):
257
+ ax.plot(x, curves[i], color=color, linestyle=ls, marker=marker,
258
+ markevery=20, label=f"Series {i + 1}")
259
+ ax.set_xlabel("x")
260
+ ax.set_ylabel("y")
261
+ ax.legend()
262
+ style.savefig(fig, "ieee_markers.pdf")
250
263
  ```
251
264
 
252
265
  ```text
253
- # styled one (color, linestyle, marker) tuple per series:
266
+ # styled: one (color, linestyle, marker) tuple per series:
254
267
  [('#000000', '-', 'o'), ('#333333', '--', 's'), ('#666666', '-.', '^'), ('#999999', ':', 'D')]
255
268
  ```
256
269
 
270
+ <p align="center">
271
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/palette_styled_ieee.png" width="55%" alt="IEEE figure with per-series color, linestyle, and marker combinations">
272
+ </p>
273
+
257
274
  ---
258
275
 
259
276
  ### Overlays
260
277
 
261
- Overlays are additive patches that layer on top of a journal preset. They let you adjust one aspect of a figure the colour palette, the context, the chart type without changing the base journal settings.
278
+ Overlays are additive patches that layer on top of a journal preset. They let you adjust one aspect of a figure (the colour palette, the context, the chart type) without changing the base journal settings.
262
279
 
263
280
  Pass overlay names in the same list as the journal key:
264
281
 
265
282
  ```python
283
+ import matplotlib.pyplot as plt
266
284
  import plotstyle
267
285
 
268
286
  # Strip top/right spines for a clean editorial look
269
287
  with plotstyle.use(["nature", "minimal"]) as style:
270
288
  fig, ax = style.figure(columns=1)
271
- ax.plot([1, 2, 3])
272
- style.savefig(fig, "figure.pdf")
289
+ ax.plot([1, 2, 3], label="data")
290
+ ax.set_xlabel("x")
291
+ ax.set_ylabel("y")
292
+ ax.legend()
293
+ style.savefig(fig, "minimal_figure.pdf")
294
+ ```
295
+
296
+ <p align="center">
297
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_minimal.png" width="45%" alt="Nature figure with minimal overlay: no top/right spines">
298
+ </p>
299
+
300
+ ```python
301
+ import matplotlib.pyplot as plt
302
+ import plotstyle
273
303
 
274
304
  # Larger figure and fonts for Jupyter notebooks
275
305
  with plotstyle.use(["nature", "notebook"]) as style:
276
- import matplotlib.pyplot as plt
277
306
  fig, ax = plt.subplots() # plt.subplots() picks up the notebook figsize
278
- ax.plot([1, 2, 3])
307
+ ax.plot([1, 2, 3], label="data")
308
+ ax.set_xlabel("x")
309
+ ax.set_ylabel("y")
310
+ ax.legend()
311
+ style.savefig(fig, "notebook_figure.pdf")
312
+ ```
313
+
314
+ <p align="center">
315
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_notebook.png" width="60%" alt="Nature figure with notebook overlay: larger fonts and figure size">
316
+ </p>
317
+
318
+ ```python
319
+ import matplotlib.pyplot as plt
320
+ import plotstyle
279
321
 
280
322
  # Swap the colour cycle to a specific palette
281
323
  with plotstyle.use(["ieee", "okabe-ito"]) as style:
282
324
  fig, ax = style.figure(columns=1)
283
- ax.plot([1, 2, 3])
325
+ ax.plot([1, 2, 3], label="data")
326
+ ax.set_xlabel("x")
327
+ ax.set_ylabel("y")
328
+ ax.legend()
329
+ style.savefig(fig, "okabe_ito_figure.pdf")
284
330
  ```
285
331
 
332
+ <p align="center">
333
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_okabe_ito.png" width="55%" alt="IEEE figure with okabe-ito colorblind-safe palette">
334
+ </p>
335
+
286
336
  | Category | Purpose | Examples |
287
337
  |----------|---------|---------|
288
338
  | `color` | Swap the colour cycle | `okabe-ito`, `tol-bright`, `safe-grayscale` |
@@ -353,18 +403,44 @@ with plotstyle.use("nature") as style:
353
403
  Validate a figure against the journal's requirements, then export in all required formats at once.
354
404
 
355
405
  ```python
406
+ import numpy as np
407
+ import matplotlib.pyplot as plt
408
+ import plotstyle
409
+
410
+ x = np.linspace(0, 2 * np.pi, 100)
411
+
412
+ # Outside plotstyle.use() — some checks will fail
413
+ fig, ax = plt.subplots()
414
+ ax.plot(x, np.sin(x), label="sin(x)")
415
+ ax.set_xlabel("Phase (rad)")
416
+ ax.set_ylabel("Amplitude")
417
+ ax.legend()
418
+
356
419
  report = plotstyle.validate(fig, journal="nature")
357
420
  print(report) # formatted compliance table
358
- print(report.passed) # True if everything is OK
421
+ print(report.passed) # False rcParams not configured
359
422
 
360
423
  for failure in report.failures:
361
424
  print(failure.message) # what failed
362
425
  print(failure.fix_suggestion) # how to fix it
426
+ plt.close(fig)
427
+
428
+ # Inside plotstyle.use() — all checks pass
429
+ with plotstyle.use("nature") as style:
430
+ fig, ax = style.figure(columns=1)
431
+ ax.plot(x, np.sin(x), label="sin(x)")
432
+ ax.set_xlabel("Phase (rad)")
433
+ ax.set_ylabel("Amplitude")
434
+ ax.legend()
435
+
436
+ report = plotstyle.validate(fig, journal="nature")
437
+ print(report)
438
+ print(report.passed) # True
363
439
  ```
364
440
 
365
441
  ```text
366
442
  ┌──────────────────────────────────────────────────────┐
367
- │ PlotStyle Validation Report Nature
443
+ │ PlotStyle Validation Report: Nature
368
444
  ├──────────┬───────────────────────────────────────────┤
369
445
  │ ✓ PASS │ Figure width 89.0mm matches single colu...│
370
446
  │ ✓ PASS │ Figure height 55.0mm is within the Natu...│
@@ -387,7 +463,7 @@ When called inside `plotstyle.use()`, all checks pass:
387
463
 
388
464
  ```text
389
465
  ┌──────────────────────────────────────────────────────┐
390
- │ PlotStyle Validation Report Nature
466
+ │ PlotStyle Validation Report: Nature
391
467
  ├──────────┬───────────────────────────────────────────┤
392
468
  │ ✓ PASS │ Figure width 89.0mm matches single colu...│
393
469
  │ ✓ PASS │ Figure height 55.0mm is within the Natu...│
@@ -403,14 +479,28 @@ passed: True
403
479
  ```
404
480
 
405
481
  ```python
406
- paths = plotstyle.export_submission(
407
- fig,
408
- "figure1",
409
- journal="ieee",
410
- author_surname="Smith", # IEEE prepends the surname prefix to filenames
411
- output_dir="submission/",
412
- )
413
- print(paths)
482
+ import numpy as np
483
+ import os
484
+ import plotstyle
485
+
486
+ os.makedirs("submission", exist_ok=True)
487
+
488
+ with plotstyle.use("ieee") as style:
489
+ fig, ax = style.figure(columns=1)
490
+ x = np.linspace(0, 2 * np.pi, 100)
491
+ ax.plot(x, np.sin(x), label="sin(x)")
492
+ ax.set_xlabel("Phase (rad)")
493
+ ax.set_ylabel("Amplitude")
494
+ ax.legend()
495
+
496
+ paths = plotstyle.export_submission(
497
+ fig,
498
+ "figure1",
499
+ journal="ieee",
500
+ author_surname="Smith", # IEEE prepends the surname prefix to filenames
501
+ output_dir="submission/",
502
+ )
503
+ print(paths)
414
504
  ```
415
505
 
416
506
  ```text
@@ -498,7 +588,7 @@ Nature → Science
498
588
  ──────────────────────────────────────────────────
499
589
  Column Width (single): 89.0mm → 86.4mm
500
590
  Column Width (double): 183.0mm → 177.8mm
501
- Max Height: 247.0mm →
591
+ Max Height: 247.0mm → -
502
592
  Font Family: Helvetica, Arial → Minion Pro, Benton Sans Condensed
503
593
  Min Font Size: 5.0pt → 7.5pt
504
594
  Max Font Size: 7.0pt → 10.0pt
@@ -583,7 +673,7 @@ If PlotStyle helps your research, a citation or star is appreciated:
583
673
  title = {PlotStyle: Publication-ready scientific figure presets for Matplotlib},
584
674
  year = {2026},
585
675
  url = {https://github.com/rahulkaushal04/plotstyle},
586
- note = {Version 1.2.0},
676
+ note = {Version 1.2.1},
587
677
  }
588
678
  ```
589
679
 
@@ -163,45 +163,95 @@ fig.savefig("palette_comparison.png", dpi=150)
163
163
  Pass `with_markers=True` to get `(color, linestyle, marker)` tuples, useful for journals like IEEE that print in grayscale:
164
164
 
165
165
  ```python
166
- styled = plotstyle.palette("ieee", n=4, with_markers=True)
167
- for color, ls, marker in styled:
168
- ax.plot(x, y, color=color, linestyle=ls, marker=marker)
166
+ import numpy as np
167
+ import plotstyle
168
+
169
+ x = np.linspace(0, 2 * np.pi, 100)
170
+ curves = [np.sin(x + i * 0.5) for i in range(4)]
171
+
172
+ with plotstyle.use("ieee") as style:
173
+ fig, ax = style.figure(columns=1)
174
+ styled = plotstyle.palette("ieee", n=4, with_markers=True)
175
+ for i, (color, ls, marker) in enumerate(styled):
176
+ ax.plot(x, curves[i], color=color, linestyle=ls, marker=marker,
177
+ markevery=20, label=f"Series {i + 1}")
178
+ ax.set_xlabel("x")
179
+ ax.set_ylabel("y")
180
+ ax.legend()
181
+ style.savefig(fig, "ieee_markers.pdf")
169
182
  ```
170
183
 
171
184
  ```text
172
- # styled one (color, linestyle, marker) tuple per series:
185
+ # styled: one (color, linestyle, marker) tuple per series:
173
186
  [('#000000', '-', 'o'), ('#333333', '--', 's'), ('#666666', '-.', '^'), ('#999999', ':', 'D')]
174
187
  ```
175
188
 
189
+ <p align="center">
190
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/palette_styled_ieee.png" width="55%" alt="IEEE figure with per-series color, linestyle, and marker combinations">
191
+ </p>
192
+
176
193
  ---
177
194
 
178
195
  ### Overlays
179
196
 
180
- Overlays are additive patches that layer on top of a journal preset. They let you adjust one aspect of a figure the colour palette, the context, the chart type without changing the base journal settings.
197
+ Overlays are additive patches that layer on top of a journal preset. They let you adjust one aspect of a figure (the colour palette, the context, the chart type) without changing the base journal settings.
181
198
 
182
199
  Pass overlay names in the same list as the journal key:
183
200
 
184
201
  ```python
202
+ import matplotlib.pyplot as plt
185
203
  import plotstyle
186
204
 
187
205
  # Strip top/right spines for a clean editorial look
188
206
  with plotstyle.use(["nature", "minimal"]) as style:
189
207
  fig, ax = style.figure(columns=1)
190
- ax.plot([1, 2, 3])
191
- style.savefig(fig, "figure.pdf")
208
+ ax.plot([1, 2, 3], label="data")
209
+ ax.set_xlabel("x")
210
+ ax.set_ylabel("y")
211
+ ax.legend()
212
+ style.savefig(fig, "minimal_figure.pdf")
213
+ ```
214
+
215
+ <p align="center">
216
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_minimal.png" width="45%" alt="Nature figure with minimal overlay: no top/right spines">
217
+ </p>
218
+
219
+ ```python
220
+ import matplotlib.pyplot as plt
221
+ import plotstyle
192
222
 
193
223
  # Larger figure and fonts for Jupyter notebooks
194
224
  with plotstyle.use(["nature", "notebook"]) as style:
195
- import matplotlib.pyplot as plt
196
225
  fig, ax = plt.subplots() # plt.subplots() picks up the notebook figsize
197
- ax.plot([1, 2, 3])
226
+ ax.plot([1, 2, 3], label="data")
227
+ ax.set_xlabel("x")
228
+ ax.set_ylabel("y")
229
+ ax.legend()
230
+ style.savefig(fig, "notebook_figure.pdf")
231
+ ```
232
+
233
+ <p align="center">
234
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_notebook.png" width="60%" alt="Nature figure with notebook overlay: larger fonts and figure size">
235
+ </p>
236
+
237
+ ```python
238
+ import matplotlib.pyplot as plt
239
+ import plotstyle
198
240
 
199
241
  # Swap the colour cycle to a specific palette
200
242
  with plotstyle.use(["ieee", "okabe-ito"]) as style:
201
243
  fig, ax = style.figure(columns=1)
202
- ax.plot([1, 2, 3])
244
+ ax.plot([1, 2, 3], label="data")
245
+ ax.set_xlabel("x")
246
+ ax.set_ylabel("y")
247
+ ax.legend()
248
+ style.savefig(fig, "okabe_ito_figure.pdf")
203
249
  ```
204
250
 
251
+ <p align="center">
252
+ <img src="https://raw.githubusercontent.com/rahulkaushal04/plotstyle/main/examples/output/overlay_okabe_ito.png" width="55%" alt="IEEE figure with okabe-ito colorblind-safe palette">
253
+ </p>
254
+
205
255
  | Category | Purpose | Examples |
206
256
  |----------|---------|---------|
207
257
  | `color` | Swap the colour cycle | `okabe-ito`, `tol-bright`, `safe-grayscale` |
@@ -272,18 +322,44 @@ with plotstyle.use("nature") as style:
272
322
  Validate a figure against the journal's requirements, then export in all required formats at once.
273
323
 
274
324
  ```python
325
+ import numpy as np
326
+ import matplotlib.pyplot as plt
327
+ import plotstyle
328
+
329
+ x = np.linspace(0, 2 * np.pi, 100)
330
+
331
+ # Outside plotstyle.use() — some checks will fail
332
+ fig, ax = plt.subplots()
333
+ ax.plot(x, np.sin(x), label="sin(x)")
334
+ ax.set_xlabel("Phase (rad)")
335
+ ax.set_ylabel("Amplitude")
336
+ ax.legend()
337
+
275
338
  report = plotstyle.validate(fig, journal="nature")
276
339
  print(report) # formatted compliance table
277
- print(report.passed) # True if everything is OK
340
+ print(report.passed) # False rcParams not configured
278
341
 
279
342
  for failure in report.failures:
280
343
  print(failure.message) # what failed
281
344
  print(failure.fix_suggestion) # how to fix it
345
+ plt.close(fig)
346
+
347
+ # Inside plotstyle.use() — all checks pass
348
+ with plotstyle.use("nature") as style:
349
+ fig, ax = style.figure(columns=1)
350
+ ax.plot(x, np.sin(x), label="sin(x)")
351
+ ax.set_xlabel("Phase (rad)")
352
+ ax.set_ylabel("Amplitude")
353
+ ax.legend()
354
+
355
+ report = plotstyle.validate(fig, journal="nature")
356
+ print(report)
357
+ print(report.passed) # True
282
358
  ```
283
359
 
284
360
  ```text
285
361
  ┌──────────────────────────────────────────────────────┐
286
- │ PlotStyle Validation Report Nature
362
+ │ PlotStyle Validation Report: Nature
287
363
  ├──────────┬───────────────────────────────────────────┤
288
364
  │ ✓ PASS │ Figure width 89.0mm matches single colu...│
289
365
  │ ✓ PASS │ Figure height 55.0mm is within the Natu...│
@@ -306,7 +382,7 @@ When called inside `plotstyle.use()`, all checks pass:
306
382
 
307
383
  ```text
308
384
  ┌──────────────────────────────────────────────────────┐
309
- │ PlotStyle Validation Report Nature
385
+ │ PlotStyle Validation Report: Nature
310
386
  ├──────────┬───────────────────────────────────────────┤
311
387
  │ ✓ PASS │ Figure width 89.0mm matches single colu...│
312
388
  │ ✓ PASS │ Figure height 55.0mm is within the Natu...│
@@ -322,14 +398,28 @@ passed: True
322
398
  ```
323
399
 
324
400
  ```python
325
- paths = plotstyle.export_submission(
326
- fig,
327
- "figure1",
328
- journal="ieee",
329
- author_surname="Smith", # IEEE prepends the surname prefix to filenames
330
- output_dir="submission/",
331
- )
332
- print(paths)
401
+ import numpy as np
402
+ import os
403
+ import plotstyle
404
+
405
+ os.makedirs("submission", exist_ok=True)
406
+
407
+ with plotstyle.use("ieee") as style:
408
+ fig, ax = style.figure(columns=1)
409
+ x = np.linspace(0, 2 * np.pi, 100)
410
+ ax.plot(x, np.sin(x), label="sin(x)")
411
+ ax.set_xlabel("Phase (rad)")
412
+ ax.set_ylabel("Amplitude")
413
+ ax.legend()
414
+
415
+ paths = plotstyle.export_submission(
416
+ fig,
417
+ "figure1",
418
+ journal="ieee",
419
+ author_surname="Smith", # IEEE prepends the surname prefix to filenames
420
+ output_dir="submission/",
421
+ )
422
+ print(paths)
333
423
  ```
334
424
 
335
425
  ```text
@@ -417,7 +507,7 @@ Nature → Science
417
507
  ──────────────────────────────────────────────────
418
508
  Column Width (single): 89.0mm → 86.4mm
419
509
  Column Width (double): 183.0mm → 177.8mm
420
- Max Height: 247.0mm →
510
+ Max Height: 247.0mm → -
421
511
  Font Family: Helvetica, Arial → Minion Pro, Benton Sans Condensed
422
512
  Min Font Size: 5.0pt → 7.5pt
423
513
  Max Font Size: 7.0pt → 10.0pt
@@ -502,7 +592,7 @@ If PlotStyle helps your research, a citation or star is appreciated:
502
592
  title = {PlotStyle: Publication-ready scientific figure presets for Matplotlib},
503
593
  year = {2026},
504
594
  url = {https://github.com/rahulkaushal04/plotstyle},
505
- note = {Version 1.2.0},
595
+ note = {Version 1.2.1},
506
596
  }
507
597
  ```
508
598
 
@@ -1,4 +1,4 @@
1
- """PlotStyle scientific journal figure style presets for Matplotlib.
1
+ """PlotStyle: scientific journal figure style presets for Matplotlib.
2
2
 
3
3
  Key entry points: ``figure`` / ``subplots`` to create journal-sized figures,
4
4
  ``use`` to apply a journal's rcParams preset, ``validate`` to check a figure
@@ -89,7 +89,7 @@ def build_overlay_snapshot(overlay: StyleOverlay) -> dict[str, Any]:
89
89
  def register_all_styles() -> None:
90
90
  """Inject all plotstyle journal presets and overlays into ``matplotlib.style.core.library``.
91
91
 
92
- Called once at ``import plotstyle``. Re-calling is safe existing keys
92
+ Called once at ``import plotstyle``. Re-calling is safe; existing keys
93
93
  are overwritten with identical values. Wrapped in a broad ``try/except``
94
94
  in the caller so a matplotlib internal API change never breaks the import.
95
95
 
@@ -115,7 +115,7 @@ def register_all_styles() -> None:
115
115
  for key in registry.list_available():
116
116
  full_key = f"{_PREFIX}{key}"
117
117
  with contextlib.suppress(Exception):
118
- library[full_key] = build_style_snapshot(registry.get(key))
118
+ library[full_key] = build_style_snapshot(registry.get(key, _silent=True))
119
119
  registered_journal_keys.add(full_key)
120
120
 
121
121
  for key in overlay_registry.list_available():
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.2.0'
22
- __version_tuple__ = version_tuple = (1, 2, 0)
21
+ __version__ = version = '1.2.1'
22
+ __version_tuple__ = version_tuple = (1, 2, 1)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -185,7 +185,7 @@ def _cmd_validate(file: str, journal: str) -> int:
185
185
  hits = verify_embedded(path)
186
186
  type3_found = any(h.get("type") == "Type3" for h in hits)
187
187
  if type3_found:
188
- print("✗ FAIL Type 3 fonts detected submission systems may reject this.")
188
+ print("✗ FAIL Type 3 fonts detected: submission systems may reject this.")
189
189
  else:
190
190
  print("✓ PASS No Type 3 fonts detected (TrueType embedding OK).")
191
191
  else:
@@ -292,7 +292,7 @@ def _build_parser() -> argparse.ArgumentParser:
292
292
  """Build and return the top-level argument parser with all sub-commands."""
293
293
  parser = argparse.ArgumentParser(
294
294
  prog="plotstyle",
295
- description="PlotStyle journal-compliant Matplotlib figure toolkit",
295
+ description="PlotStyle: journal-compliant Matplotlib figure toolkit",
296
296
  formatter_class=argparse.RawDescriptionHelpFormatter,
297
297
  epilog=(
298
298
  "Examples:\n"
@@ -398,7 +398,7 @@ def _build_parser() -> argparse.ArgumentParser:
398
398
  description=(
399
399
  "Prints a ready-to-run Python snippet that calls "
400
400
  "plotstyle.export_submission() with the requested settings. "
401
- "No file is created re-export requires the original Matplotlib "
401
+ "No file is created; re-export requires the original Matplotlib "
402
402
  "Figure object, which cannot be recovered from a saved file."
403
403
  ),
404
404
  )