streamtex 0.7.78__tar.gz → 0.7.80__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.
- {streamtex-0.7.78/streamtex.egg-info → streamtex-0.7.80}/PKG-INFO +2 -1
- {streamtex-0.7.78 → streamtex-0.7.80}/pyproject.toml +2 -1
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/__init__.py +17 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/bib.py +38 -18
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/book.py +77 -15
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/claude_cmd.py +13 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/claude_project.py +8 -1
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/commands.py +2 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/export_cmd.py +3 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/release_cmd.py +12 -0
- streamtex-0.7.80/streamtex/cli/styles_cmd.py +360 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/deploy/stx_auth.py +1 -1
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/export_enrich.py +28 -2
- streamtex-0.7.80/streamtex/glossary.py +261 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/target.py +32 -6
- streamtex-0.7.80/streamtex/stage.py +183 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/default.css +49 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/utils.py +7 -2
- {streamtex-0.7.78 → streamtex-0.7.80/streamtex.egg-info}/PKG-INFO +2 -1
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex.egg-info/SOURCES.txt +3 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex.egg-info/requires.txt +1 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/LICENSE +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/MANIFEST.in +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/README.md +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/setup.cfg +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/__main__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/config.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/generate.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/history.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/metadata.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/providers/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/providers/base.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/providers/fal.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/providers/google.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/providers/openai.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/ai/providers/registry.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/auth.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/banner.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/bib_preview.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/block_helpers.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/blocks.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/browser.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/_claude_files.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/_divergence.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/_install_local_packs.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/_shared.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/_stx_toml.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/_toml_helpers.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/artifact_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/bib_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/build_check.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/cache_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/claude_global.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/component_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/console.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/coolify.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/deploy_auth_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/deploy_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/dev_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/dev_config.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/ds_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/install_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/kit_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/main.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/migrations/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/migrations/base.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/migrations/compat.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/migrations/registry.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/migrations/v0_4_0.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/migrations/v0_4_6.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/pack_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/project_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/project_rules.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/publish_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/published_check.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/run_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/run_set.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/screenshot_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/shortcuts.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/status_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/sync_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/upgrade_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/validate_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/cli/workspace_cmd.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/code.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/collection.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/constants.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/container.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/_frontmatter.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/agent.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/ai_prompt.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/archetype.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/asset.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/discovery.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/guideline.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/install.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/integration.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/loaders.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/palette.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/skill.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/spec.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/artifacts/validation.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/contracts.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/discovery.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/core/validation.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/countdown.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/deeplink.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/deploy/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/enums.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/export.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/export_paginate.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/export_widgets.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/facts.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/grid.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/gsheet.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/hover_tooltip.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/i18n.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/image.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/image_crop.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/image_editor.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/image_utils.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/inspector.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/kept.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/latex.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/latex_utils.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/link_config.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/link_preview.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/list.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/loading.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/markdown.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/marker.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/marker_runtime.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/media_overlay.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/mermaid.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/overlay.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/pagewalk.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/pdf_export.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/plantuml.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/presentation.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/presentation_profile.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/printing.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/build.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/config.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/coolify.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/levels.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/media.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/ops.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/passwords.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/state.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/live/Dockerfile +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/live/entrypoint.sh +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/live/nginx.conf +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/live/stx-http.conf +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/live/supervisord.conf +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/10-stx-init.sh +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/20-stx-auth.sh +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/Dockerfile +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/closed.html +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/nginx.conf +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/stx-http.conf +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/release/templates/static/stx_auth.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/runtime_flags.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/scripts/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/scripts/migrate_curves_to_relative.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/search.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/slide.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/slide_note.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/space.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/spacing.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/css/stx_global.css +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/js/stx_countdown.js +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/js/stx_marker_observer.js +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/js/stx_scroll_spy.js +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/js/stx_video.js +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/logo-stx-tiny.png +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/static/logo-stx.png +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/__init__.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/base.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/container.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/core.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/scale.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/scale_curves.toml +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/text.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/styles/visibility.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/tikz.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/toc.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/watch.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/write.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex/zoom.py +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex.egg-info/dependency_links.txt +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex.egg-info/entry_points.txt +0 -0
- {streamtex-0.7.78 → streamtex-0.7.80}/streamtex.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamtex
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.80
|
|
4
4
|
Summary: AI-powered content framework for Streamlit — create presentations, courses, and web-books with Claude or Cursor, no coding required.
|
|
5
5
|
Author-email: Nicolas Guelfi <nicolas.guelfi@laposte.net>
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -38,6 +38,7 @@ Requires-Dist: streamlit-mermaid>=0.3.0
|
|
|
38
38
|
Requires-Dist: mermaid-py>=0.5.0
|
|
39
39
|
Requires-Dist: python-dotenv>=1.2.1
|
|
40
40
|
Requires-Dist: Pillow>=10.0
|
|
41
|
+
Requires-Dist: pyyaml>=6.0
|
|
41
42
|
Provides-Extra: inspector
|
|
42
43
|
Requires-Dist: streamlit-ace>=0.1.1; extra == "inspector"
|
|
43
44
|
Provides-Extra: cli
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "streamtex"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.80"
|
|
8
8
|
description = "AI-powered content framework for Streamlit — create presentations, courses, and web-books with Claude or Cursor, no coding required."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -43,6 +43,7 @@ dependencies = [
|
|
|
43
43
|
"mermaid-py>=0.5.0",
|
|
44
44
|
"python-dotenv>=1.2.1",
|
|
45
45
|
"Pillow>=10.0",
|
|
46
|
+
"pyyaml>=6.0",
|
|
46
47
|
]
|
|
47
48
|
|
|
48
49
|
[project.scripts]
|
|
@@ -178,6 +178,14 @@ try:
|
|
|
178
178
|
st_refs, BibRefs, generate_bib_stubs,
|
|
179
179
|
)
|
|
180
180
|
|
|
181
|
+
# Glossary: hover definitions, CSS only (#12)
|
|
182
|
+
from .glossary import (
|
|
183
|
+
GlossaryConfig, GlossaryRegistry,
|
|
184
|
+
set_glossary_config, get_glossary_config,
|
|
185
|
+
get_glossary_registry, reset_glossary_registry,
|
|
186
|
+
load_glossary, gloss, st_glossary,
|
|
187
|
+
)
|
|
188
|
+
|
|
181
189
|
# Link behavior configuration
|
|
182
190
|
from .link_config import LinkConfig, set_link_config, get_link_config
|
|
183
191
|
|
|
@@ -290,6 +298,8 @@ __all__ = [
|
|
|
290
298
|
"ProfileConfig",
|
|
291
299
|
"ProjectBlockRegistry",
|
|
292
300
|
"ProjectMeta",
|
|
301
|
+
"GlossaryConfig",
|
|
302
|
+
"GlossaryRegistry",
|
|
293
303
|
"ReuseArchitectureError",
|
|
294
304
|
"SLIDE_CONTAINER",
|
|
295
305
|
"SLIDE_NOTE_STYLE",
|
|
@@ -320,6 +330,8 @@ __all__ = [
|
|
|
320
330
|
"exec_static",
|
|
321
331
|
"export_bibtex",
|
|
322
332
|
"export_pdf",
|
|
333
|
+
"load_glossary",
|
|
334
|
+
"reset_glossary_registry",
|
|
323
335
|
"extract_frames",
|
|
324
336
|
"extract_math",
|
|
325
337
|
"extract_tikz",
|
|
@@ -329,6 +341,9 @@ __all__ = [
|
|
|
329
341
|
"get_ai_image_config",
|
|
330
342
|
"get_available_models",
|
|
331
343
|
"get_bib_config",
|
|
344
|
+
"get_glossary_config",
|
|
345
|
+
"get_glossary_registry",
|
|
346
|
+
"gloss",
|
|
332
347
|
"get_bib_registry",
|
|
333
348
|
"get_block_helper_config",
|
|
334
349
|
"get_block_spacing",
|
|
@@ -381,6 +396,7 @@ __all__ = [
|
|
|
381
396
|
"save_image_version",
|
|
382
397
|
"set_ai_image_config",
|
|
383
398
|
"set_bib_config",
|
|
399
|
+
"set_glossary_config",
|
|
384
400
|
"set_block_helper_config",
|
|
385
401
|
"set_block_spacing",
|
|
386
402
|
"set_gsheet_config",
|
|
@@ -402,6 +418,7 @@ __all__ = [
|
|
|
402
418
|
"st_audio",
|
|
403
419
|
"st_bar_chart",
|
|
404
420
|
"st_bibliography",
|
|
421
|
+
"st_glossary",
|
|
405
422
|
"st_block",
|
|
406
423
|
"st_book",
|
|
407
424
|
"st_br",
|
|
@@ -1065,7 +1065,9 @@ def st_bibliography(*, style=None, title: str = "References",
|
|
|
1065
1065
|
toc_lvl: Optional[str] = None,
|
|
1066
1066
|
only_cited: bool = True,
|
|
1067
1067
|
format: Optional[BibFormat] = None,
|
|
1068
|
-
label_style: Optional[CitationStyle] = None
|
|
1068
|
+
label_style: Optional[CitationStyle] = None,
|
|
1069
|
+
chunk_size: Optional[int] = None,
|
|
1070
|
+
slide_break_config=None) -> None:
|
|
1069
1071
|
"""Render the full bibliography list.
|
|
1070
1072
|
|
|
1071
1073
|
Args:
|
|
@@ -1082,9 +1084,16 @@ def st_bibliography(*, style=None, title: str = "References",
|
|
|
1082
1084
|
shows inline: ``(Dart et al., 2013)`` in AUTHOR_YEAR, ``[3]`` in
|
|
1083
1085
|
NUMERIC and SUPERSCRIPT. Pass ``CitationStyle.NUMERIC`` to keep
|
|
1084
1086
|
``[N]`` beside author-year citations.
|
|
1087
|
+
chunk_size: When set, at most this many entries per slide: a
|
|
1088
|
+
``st_slide_break()`` separates the chunks, each repeats the title
|
|
1089
|
+
with its rank (``References (2/5)``) and the numbering goes on.
|
|
1090
|
+
The TOC gets the plain title once. ``None``: one list (#23).
|
|
1091
|
+
slide_break_config: The ``SlideBreakConfig`` of the breaks between
|
|
1092
|
+
chunks (default: the global one).
|
|
1085
1093
|
"""
|
|
1086
1094
|
from .container import st_block
|
|
1087
1095
|
from .export import _render
|
|
1096
|
+
from .slide import st_slide_break
|
|
1088
1097
|
from .space import st_space
|
|
1089
1098
|
from .styles import StxStyles
|
|
1090
1099
|
from .write import st_write
|
|
@@ -1099,28 +1108,39 @@ def st_bibliography(*, style=None, title: str = "References",
|
|
|
1099
1108
|
# Sort
|
|
1100
1109
|
entries = _sort_entries(entries, cfg.sort_by)
|
|
1101
1110
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
st_space("v", 2)
|
|
1111
|
+
if chunk_size is not None and chunk_size < 1:
|
|
1112
|
+
raise ValueError(f"st_bibliography: chunk_size must be at least 1, not {chunk_size}")
|
|
1113
|
+
size = chunk_size or len(entries)
|
|
1114
|
+
chunks = [entries[i:i + size] for i in range(0, len(entries), size)]
|
|
1107
1115
|
|
|
1108
|
-
|
|
1116
|
+
ts = title_style or (StxStyles.big + StxStyles.bold)
|
|
1109
1117
|
entry_css = entry_style.css if entry_style else ""
|
|
1110
1118
|
number_css = number_style.css if number_style else "font-weight:bold;"
|
|
1111
1119
|
labels = label_style or cfg.citation_style
|
|
1112
1120
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1121
|
+
first = 1
|
|
1122
|
+
for k, chunk in enumerate(chunks, 1):
|
|
1123
|
+
if k > 1:
|
|
1124
|
+
st_slide_break(marker_label=f"{title or 'References'} {k}/{len(chunks)}",
|
|
1125
|
+
config=slide_break_config)
|
|
1126
|
+
if title:
|
|
1127
|
+
rank = f" ({k}/{len(chunks)})" if len(chunks) > 1 else ""
|
|
1128
|
+
if k == 1:
|
|
1129
|
+
st_write(ts, title + rank, toc_lvl=toc_lvl, label=title if toc_lvl else "")
|
|
1130
|
+
else:
|
|
1131
|
+
st_write(ts, title + rank)
|
|
1132
|
+
st_space("v", 2)
|
|
1133
|
+
with st_block(style):
|
|
1134
|
+
for i, entry in enumerate(chunk, first):
|
|
1135
|
+
formatted = format_entry(entry, fmt, number=0)
|
|
1136
|
+
num_html = f'<span style="{number_css}">{_entry_label(entry, i, labels)}</span> '
|
|
1137
|
+
anchor_id = f"bib-{entry.key}"
|
|
1138
|
+
_render(
|
|
1139
|
+
f'<p id="{anchor_id}" style="margin-bottom:10px;text-indent:-2.5em;'
|
|
1140
|
+
f'padding-left:2.5em;line-height:1.6;overflow-wrap:anywhere;{entry_css}">'
|
|
1141
|
+
f'{num_html}{formatted}</p>'
|
|
1142
|
+
)
|
|
1143
|
+
first += len(chunk)
|
|
1124
1144
|
|
|
1125
1145
|
|
|
1126
1146
|
def _entry_label(entry: BibEntry, number: int, style: CitationStyle) -> str:
|
|
@@ -85,6 +85,7 @@ from .spacing import (
|
|
|
85
85
|
resolve_block_spacing,
|
|
86
86
|
set_active_profile,
|
|
87
87
|
)
|
|
88
|
+
from .stage import STAGE_KEY
|
|
88
89
|
from .styles import Style
|
|
89
90
|
from .toc import NumberingMode, TOCConfig, reset_toc_registry, toc_entries
|
|
90
91
|
from .utils import inject_link_preview_scaffold
|
|
@@ -536,6 +537,7 @@ def _offer_export_downloads(html: str, base_name: str,
|
|
|
536
537
|
doc_version=_cache.get("doc_version", ""),
|
|
537
538
|
lib_version=_cache.get("lib_version", ""),
|
|
538
539
|
notice=rules["notice"],
|
|
540
|
+
stage=st.session_state.get(STAGE_KEY),
|
|
539
541
|
)
|
|
540
542
|
# Apply custom title override
|
|
541
543
|
if enrich_title:
|
|
@@ -726,24 +728,44 @@ def _resolve_sidebar_max_level(toc_config: TOCConfig, paginated: bool) -> int |
|
|
|
726
728
|
return 1 if paginated else 2
|
|
727
729
|
|
|
728
730
|
|
|
729
|
-
def _setup_bibliography(bib_sources, bib_config):
|
|
730
|
-
"""Load bibliography sources and set config (called at start of st_book).
|
|
731
|
+
def _setup_bibliography(bib_sources, bib_config, glossary_sources=None, glossary_config=None):
|
|
732
|
+
"""Load bibliography and glossary sources and set config (called at start of st_book).
|
|
733
|
+
|
|
734
|
+
The ``@glossary`` entries of a bibliography source go to the glossary, so
|
|
735
|
+
they never take a citation number (#12).
|
|
736
|
+
"""
|
|
731
737
|
from .bib import get_bib_registry, load_bib, reset_bib_registry, set_bib_config
|
|
738
|
+
from .glossary import (
|
|
739
|
+
get_glossary_registry,
|
|
740
|
+
is_glossary,
|
|
741
|
+
load_glossary,
|
|
742
|
+
reset_glossary_registry,
|
|
743
|
+
set_glossary_config,
|
|
744
|
+
)
|
|
732
745
|
|
|
733
746
|
reset_bib_registry()
|
|
747
|
+
reset_glossary_registry()
|
|
734
748
|
|
|
735
749
|
if bib_config is not None:
|
|
736
750
|
set_bib_config(bib_config)
|
|
751
|
+
if glossary_config is not None:
|
|
752
|
+
set_glossary_config(glossary_config)
|
|
737
753
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
754
|
+
registry = get_bib_registry()
|
|
755
|
+
glossary = get_glossary_registry()
|
|
756
|
+
for source_path in bib_sources or []:
|
|
757
|
+
try:
|
|
758
|
+
entries = load_bib(source_path)
|
|
759
|
+
registry.register_many([e for e in entries if not is_glossary(e)])
|
|
760
|
+
glossary.register_many([e for e in entries if is_glossary(e)])
|
|
761
|
+
logger.debug(f"Loaded {len(entries)} bib entries from {source_path}")
|
|
762
|
+
except Exception as e:
|
|
763
|
+
logger.warning(f"Failed to load bibliography from {source_path}: {e}")
|
|
764
|
+
for source_path in glossary_sources or []:
|
|
765
|
+
try:
|
|
766
|
+
glossary.register_many(load_glossary(source_path))
|
|
767
|
+
except Exception as e:
|
|
768
|
+
logger.warning(f"Failed to load glossary from {source_path}: {e}")
|
|
747
769
|
|
|
748
770
|
|
|
749
771
|
def _inject_bib_preview_if_enabled():
|
|
@@ -779,7 +801,9 @@ def _st_book_impl(module_list, toc_config: TOCConfig = None, marker_config: Mark
|
|
|
779
801
|
lang: str | None = None,
|
|
780
802
|
html_export_zoom: int = 0,
|
|
781
803
|
notice=None,
|
|
782
|
-
printable: bool | PrintConfig = True
|
|
804
|
+
printable: bool | PrintConfig = True,
|
|
805
|
+
glossary_sources=None, glossary_config=None,
|
|
806
|
+
stage=(1920, 1080)):
|
|
783
807
|
"""Generates a web page e-book from a list of block modules.
|
|
784
808
|
|
|
785
809
|
:param separator: Optional module with a build() function, rendered between each block.
|
|
@@ -811,6 +835,15 @@ def _st_book_impl(module_list, toc_config: TOCConfig = None, marker_config: Mark
|
|
|
811
835
|
:param banner: Optional BannerConfig for full banner customisation (overrides banner_color).
|
|
812
836
|
:param bib_sources: Optional list of paths to .bib, .json, .ris, or .csl-json files.
|
|
813
837
|
:param bib_config: Optional BibConfig to configure bibliography formatting.
|
|
838
|
+
:param glossary_sources: Optional list of glossary files for ``gloss()``:
|
|
839
|
+
``.yaml``/``.yml``, ``.json`` (``{"LLM": "Large Language Model"}``)
|
|
840
|
+
or ``.bib`` (its ``@glossary`` entries). See ``streamtex.glossary``.
|
|
841
|
+
:param glossary_config: Optional GlossaryConfig (``strict=True``: an unknown key raises).
|
|
842
|
+
:param stage: Size of the stage (#105): ``(1920, 1080)`` (default),
|
|
843
|
+
``[w, h]`` or ``"WxH"``. A link under the zoom controls, and in the
|
|
844
|
+
HTML export's sidebar, opens the document in a virtual screen of this
|
|
845
|
+
size scaled to the window, with black bands (``?stage=WxH`` in the
|
|
846
|
+
URL). ``False``: no stage.
|
|
814
847
|
:param inspector: Optional InspectorConfig to enable the block inspector panel.
|
|
815
848
|
:param page_width: Page width as % of browser width (default 90).
|
|
816
849
|
:param zoom: Default zoom level as % (default 100).
|
|
@@ -862,6 +895,10 @@ def _st_book_impl(module_list, toc_config: TOCConfig = None, marker_config: Mark
|
|
|
862
895
|
_block_kwargs = dict(block_kwargs or {})
|
|
863
896
|
# --- Usage notice and print rules (#107): read by the panel and every export ---
|
|
864
897
|
st.session_state[PRINT_KEY] = print_state(printable, notice, _block_kwargs.get("lang"))
|
|
898
|
+
# --- Stage size (#105): the sidebar link, and the HTML export's ---
|
|
899
|
+
from .stage import parse_stage, render_stage, requested_stage
|
|
900
|
+
_stage = parse_stage(stage)
|
|
901
|
+
st.session_state[STAGE_KEY] = _stage
|
|
865
902
|
# --- Resolve PdfConfig from exports list if not provided directly ---
|
|
866
903
|
if pdf_config is None and exports:
|
|
867
904
|
for _ecfg in exports:
|
|
@@ -901,13 +938,19 @@ def _st_book_impl(module_list, toc_config: TOCConfig = None, marker_config: Mark
|
|
|
901
938
|
if _warmup_mode:
|
|
902
939
|
# The references first: an HTML export without them shows every
|
|
903
940
|
# citation as [key?] and an empty bibliography.
|
|
904
|
-
_setup_bibliography(bib_sources, bib_config)
|
|
941
|
+
_setup_bibliography(bib_sources, bib_config, glossary_sources, glossary_config)
|
|
905
942
|
_warmup_build_cache(module_list, toc_config, marker_config,
|
|
906
943
|
separator,
|
|
907
944
|
block_args=_block_args,
|
|
908
945
|
block_kwargs=_block_kwargs)
|
|
909
946
|
return
|
|
910
947
|
|
|
948
|
+
# --- Stage (#105): this tab only frames the document, which has its own gate ---
|
|
949
|
+
_stage_now = requested_stage(_query_params(), _stage)
|
|
950
|
+
if _stage_now:
|
|
951
|
+
render_stage(_stage_now)
|
|
952
|
+
return
|
|
953
|
+
|
|
911
954
|
# --- Password gate (env-driven, no-op locally) ---
|
|
912
955
|
_password_gate()
|
|
913
956
|
|
|
@@ -936,7 +979,7 @@ def _st_book_impl(module_list, toc_config: TOCConfig = None, marker_config: Mark
|
|
|
936
979
|
st.session_state[_STX_THEME_BG_KEY] = _bg
|
|
937
980
|
st.session_state[_STX_THEME_TEXT_KEY] = _txt
|
|
938
981
|
# --- Bibliography setup ---
|
|
939
|
-
_setup_bibliography(bib_sources, bib_config)
|
|
982
|
+
_setup_bibliography(bib_sources, bib_config, glossary_sources, glossary_config)
|
|
940
983
|
# --- Presentation profiles ---
|
|
941
984
|
default_profile = build_default_profile(page_width, zoom, paginate)
|
|
942
985
|
user_profiles = presentation_profiles or []
|
|
@@ -1052,6 +1095,9 @@ def _st_book_impl(module_list, toc_config: TOCConfig = None, marker_config: Mark
|
|
|
1052
1095
|
)
|
|
1053
1096
|
add_zoom_options(default_page_width=page_width, default_zoom=zoom,
|
|
1054
1097
|
container=_stx_settings)
|
|
1098
|
+
if _stage:
|
|
1099
|
+
from .stage import stage_link
|
|
1100
|
+
stage_link(_query_params(), _stage, container=_stx_settings)
|
|
1055
1101
|
add_wrap_all_option(container=_stx_settings)
|
|
1056
1102
|
_stx_settings.divider()
|
|
1057
1103
|
add_slide_break_options(container=_stx_settings)
|
|
@@ -1949,6 +1995,14 @@ _STX_PAGE_KEY = "_stx_current_page"
|
|
|
1949
1995
|
_STX_INITIAL_MARKER_KEY = "_stx_initial_marker"
|
|
1950
1996
|
|
|
1951
1997
|
|
|
1998
|
+
def _query_params() -> dict:
|
|
1999
|
+
"""The URL's query parameters; ``{}`` outside a real script run (tests, headless)."""
|
|
2000
|
+
try:
|
|
2001
|
+
return st.query_params.to_dict()
|
|
2002
|
+
except Exception: # noqa: BLE001 -- no script context / mocked st
|
|
2003
|
+
return {}
|
|
2004
|
+
|
|
2005
|
+
|
|
1952
2006
|
def _initial_page_from_url(cache, total) -> tuple[int, int | None]:
|
|
1953
2007
|
"""Resolve the first page of the session from the URL (deep link).
|
|
1954
2008
|
|
|
@@ -2752,7 +2806,9 @@ def _build_page_cache(module_list, toc_config, marker_config, separator,
|
|
|
2752
2806
|
# Persist cited bibliography keys so st_bibliography(only_cited=True) works
|
|
2753
2807
|
# in paginated mode (cite() calls only run during cache build, not per-page).
|
|
2754
2808
|
from .bib import get_bib_registry as _get_bib_registry
|
|
2809
|
+
from .glossary import get_glossary_registry as _get_glossary_registry
|
|
2755
2810
|
_bib_cited = list(_get_bib_registry()._cited)
|
|
2811
|
+
_gloss_used = list(_get_glossary_registry()._used) # st_glossary(only_used=True) (#12)
|
|
2756
2812
|
|
|
2757
2813
|
st.session_state[_STX_CACHE_KEY] = {
|
|
2758
2814
|
"hash": cache_hash,
|
|
@@ -2764,6 +2820,7 @@ def _build_page_cache(module_list, toc_config, marker_config, separator,
|
|
|
2764
2820
|
"pages": pages,
|
|
2765
2821
|
"search_index": search_index,
|
|
2766
2822
|
"cited_keys": _bib_cited,
|
|
2823
|
+
"glossary_used": _gloss_used,
|
|
2767
2824
|
"doc_version": st.session_state.get("_stx_doc_version", ""),
|
|
2768
2825
|
"lib_version": st.session_state.get("_stx_lib_version", ""),
|
|
2769
2826
|
# Data files the blocks read through stx.load_*/watch_file during
|
|
@@ -3553,6 +3610,10 @@ def _paginated_book(module_list, toc_config, marker_config, separator,
|
|
|
3553
3610
|
for _key in cache["cited_keys"]:
|
|
3554
3611
|
if _key not in _bib_reg._cited:
|
|
3555
3612
|
_bib_reg._cited.append(_key)
|
|
3613
|
+
if cache.get("glossary_used"):
|
|
3614
|
+
from .glossary import get_glossary_registry as _get_gloss_reg
|
|
3615
|
+
for _key in cache["glossary_used"]:
|
|
3616
|
+
_get_gloss_reg().use(_key)
|
|
3556
3617
|
|
|
3557
3618
|
# --- Banner — page titles for navigation labels ---
|
|
3558
3619
|
page_titles = _get_page_titles(cache, total)
|
|
@@ -3783,6 +3844,7 @@ def _paginated_book(module_list, toc_config, marker_config, separator,
|
|
|
3783
3844
|
BOOK_DEFAULT_KEYS = frozenset({
|
|
3784
3845
|
"paginate", "paginate_by", "html_export_mode", "page_width", "zoom", "export", "export_title", "loading",
|
|
3785
3846
|
"chrome_banner", "banner_color", "doc_version", "lang", "html_export_zoom",
|
|
3847
|
+
"stage", # stage = [1920, 1080] (#105)
|
|
3786
3848
|
})
|
|
3787
3849
|
|
|
3788
3850
|
|
|
@@ -3855,7 +3917,7 @@ _DEFAULTS_DOC = """Generates a web page e-book from a list of block modules.
|
|
|
3855
3917
|
taken from ``[book.defaults]`` of the project's ``stx.toml`` when it
|
|
3856
3918
|
declares them (``paginate``, ``page_width``, ``zoom``, ``export``,
|
|
3857
3919
|
``export_title``, ``loading``, ``chrome_banner``, ``banner_color``,
|
|
3858
|
-
``doc_version``, ``lang``), then from the defaults below.
|
|
3920
|
+
``doc_version``, ``lang``, ``stage``), then from the defaults below.
|
|
3859
3921
|
``doc_version="auto"`` reads ``[project].version`` of ``pyproject.toml``.
|
|
3860
3922
|
"""
|
|
3861
3923
|
|
|
@@ -286,6 +286,12 @@ def install_profile(claude_repo: str, profile: str, target: str) -> list[str]:
|
|
|
286
286
|
if rendered and rendered not in installed:
|
|
287
287
|
installed.append(rendered)
|
|
288
288
|
|
|
289
|
+
# The styles reference, generated from the code after the read-only copies (#6)
|
|
290
|
+
from .styles_cmd import refresh_reference
|
|
291
|
+
styles_ref = refresh_reference(target)
|
|
292
|
+
if styles_ref:
|
|
293
|
+
installed.append(styles_ref)
|
|
294
|
+
|
|
289
295
|
return sorted(installed)
|
|
290
296
|
|
|
291
297
|
|
|
@@ -294,6 +300,7 @@ _GENERATED_PATHS = frozenset({
|
|
|
294
300
|
os.path.join(".claude", ".stx-profile"),
|
|
295
301
|
os.path.join(".claude", "CLAUDE.md"), # profile text when the root CLAUDE.md is the user's
|
|
296
302
|
os.path.join(".claude", "stx.lock"), # project mode lock file
|
|
303
|
+
os.path.join(".claude", "references", "streamtex_styles_api.md"), # stx styles dump (#6)
|
|
297
304
|
})
|
|
298
305
|
|
|
299
306
|
|
|
@@ -1209,6 +1216,12 @@ def _update_single_target(
|
|
|
1209
1216
|
"Claude Code reads both files.[/dim]"
|
|
1210
1217
|
)
|
|
1211
1218
|
|
|
1219
|
+
# The styles reference, regenerated when the version or its inputs changed (#6)
|
|
1220
|
+
from .styles_cmd import refresh_reference
|
|
1221
|
+
styles_ref = refresh_reference(target)
|
|
1222
|
+
if styles_ref:
|
|
1223
|
+
updated.append(styles_ref)
|
|
1224
|
+
|
|
1212
1225
|
if updated:
|
|
1213
1226
|
console.print(f"\n[green]Updated {len(updated)} file(s).[/green]")
|
|
1214
1227
|
for f in updated:
|
|
@@ -391,10 +391,13 @@ def sync_project(
|
|
|
391
391
|
|
|
392
392
|
claude_dir = os.path.join(target, ".claude")
|
|
393
393
|
if remove:
|
|
394
|
-
|
|
394
|
+
from .styles_cmd import REFERENCE
|
|
395
|
+
for rel in (os.path.join(".claude", ".stx-profile"), LOCK_PATH, REFERENCE):
|
|
395
396
|
p = os.path.join(target, rel)
|
|
396
397
|
if os.path.isfile(p):
|
|
398
|
+
os.chmod(p, 0o644)
|
|
397
399
|
os.remove(p)
|
|
400
|
+
_remove_empty_dirs(target, [REFERENCE])
|
|
398
401
|
if lock and lock.claude_md and lock.claude_md_sha:
|
|
399
402
|
p = os.path.join(target, lock.claude_md)
|
|
400
403
|
if os.path.isfile(p) and sha256_file(p) == lock.claude_md_sha:
|
|
@@ -439,6 +442,10 @@ def sync_project(
|
|
|
439
442
|
claude_md=claude_md, claude_md_sha=claude_md_sha, files=new_files,
|
|
440
443
|
))
|
|
441
444
|
_ensure_gitignore(target, console)
|
|
445
|
+
# The styles reference, generated from the code (#6): never in the lock, never pruned
|
|
446
|
+
from .styles_cmd import refresh_reference
|
|
447
|
+
if refresh_reference(target):
|
|
448
|
+
console.print(" [green]✓[/green] .claude/references/streamtex_styles_api.md (generated)")
|
|
442
449
|
return plan
|
|
443
450
|
|
|
444
451
|
|
|
@@ -64,6 +64,7 @@ from .run_cmd import run as stx_run
|
|
|
64
64
|
from .screenshot_cmd import screenshot as stx_screenshot
|
|
65
65
|
from .shortcuts import run_lint, run_test
|
|
66
66
|
from .status_cmd import status as workspace_status
|
|
67
|
+
from .styles_cmd import styles as styles_group
|
|
67
68
|
from .sync_cmd import sync as stx_sync
|
|
68
69
|
from .upgrade_cmd import upgrade as project_upgrade
|
|
69
70
|
from .validate_cmd import validate as stx_validate
|
|
@@ -217,6 +218,7 @@ cli.add_command(ds_group, name="ds")
|
|
|
217
218
|
cli.add_command(kit_group, name="kit")
|
|
218
219
|
cli.add_command(artifact_group, name="artifact")
|
|
219
220
|
cli.add_command(stx_validate, name="validate")
|
|
221
|
+
cli.add_command(styles_group, name="styles")
|
|
220
222
|
|
|
221
223
|
|
|
222
224
|
# --- Dev subgroup ----------------------------------------------------------
|
|
@@ -263,6 +263,8 @@ def export_html(path, output, asset_mode, title, no_nav, theme_mode, theme_bg, t
|
|
|
263
263
|
_cache_data = st.session_state.get(_book_mod._STX_CACHE_KEY) or {}
|
|
264
264
|
from ..printing import get_print_state
|
|
265
265
|
print_rules = get_print_state(st.session_state) # notice, html_print (#107)
|
|
266
|
+
from ..stage import STAGE_KEY
|
|
267
|
+
stage_size = st.session_state.get(STAGE_KEY) # the sidebar's stage link (#105)
|
|
266
268
|
|
|
267
269
|
elapsed = time.time() - t0
|
|
268
270
|
|
|
@@ -343,6 +345,7 @@ def export_html(path, output, asset_mode, title, no_nav, theme_mode, theme_bg, t
|
|
|
343
345
|
lib_version=_cache_data.get("lib_version", ""),
|
|
344
346
|
page_nav=page_nav,
|
|
345
347
|
notice=print_rules["notice"],
|
|
348
|
+
stage=stage_size,
|
|
346
349
|
)
|
|
347
350
|
|
|
348
351
|
if not no_nav and nav_data:
|
|
@@ -27,6 +27,16 @@ def _passwords(cfg):
|
|
|
27
27
|
return pw.load_file(pw.passwords_path(cfg.root))
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
def _require_running(t, apps) -> None:
|
|
31
|
+
"""The containers the command needs run, checked before an export: a wrong --target used to fail at the
|
|
32
|
+
first reload, after the export (all-trainings, 2026-10-29: 25 s, then "No such container: stx-static")."""
|
|
33
|
+
down = [a for a in sorted(set(apps)) if not t.running(a)]
|
|
34
|
+
if down:
|
|
35
|
+
hint = "start them (stx release local up) or " if t.kind == "local" else ""
|
|
36
|
+
raise ReleaseError(f"target {t.name}: the {' and '.join(down)} container(s) do not run — "
|
|
37
|
+
f"{hint}choose another --target")
|
|
38
|
+
|
|
39
|
+
|
|
30
40
|
_target = click.option("--target", "target", default=None, help="Target name in .stx-release.json "
|
|
31
41
|
"(default: its default_target).")
|
|
32
42
|
|
|
@@ -83,6 +93,7 @@ def publish_cmd(sites, groups, all_, target, allow_skew, html_env):
|
|
|
83
93
|
raise ReleaseError("name the sites to publish, a --group, or --all for every site")
|
|
84
94
|
cfg, state, t = _ctx(target)
|
|
85
95
|
chosen = cfg.select(sites, groups)
|
|
96
|
+
_require_running(t, ["static" if f == "html" else "live" for s in chosen for f in s.faces])
|
|
86
97
|
env = _html_env(html_env)
|
|
87
98
|
release_name = build.require_committed(cfg.root)
|
|
88
99
|
build.require_lock(cfg)
|
|
@@ -160,6 +171,7 @@ def limit_cmd(site, slide, labels, target, allow_skew, html_env):
|
|
|
160
171
|
s = cfg.site(site)
|
|
161
172
|
if "html" not in s.faces:
|
|
162
173
|
raise ReleaseError(f"{s.site} has no HTML face: a slide limit applies to the HTML face")
|
|
174
|
+
_require_running(t, ["static"])
|
|
163
175
|
_skew(cfg, t, allow_skew)
|
|
164
176
|
if labels:
|
|
165
177
|
names = [x.strip() for x in labels.split(",") if x.strip()]
|