scitex 2.16.0__py3-none-any.whl → 2.16.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. scitex/_mcp_tools/audio.py +11 -65
  2. scitex/audio/README.md +40 -12
  3. scitex/audio/__init__.py +27 -235
  4. scitex/audio/_audio_check.py +93 -0
  5. scitex/audio/_mcp/speak_handlers.py +56 -8
  6. scitex/audio/_speak.py +295 -0
  7. scitex/audio/mcp_server.py +98 -73
  8. scitex/social/__init__.py +1 -24
  9. scitex/writer/README.md +25 -409
  10. scitex/writer/__init__.py +98 -13
  11. {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/METADATA +6 -1
  12. {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/RECORD +15 -62
  13. scitex/writer/Writer.py +0 -487
  14. scitex/writer/_clone_writer_project.py +0 -160
  15. scitex/writer/_compile/__init__.py +0 -41
  16. scitex/writer/_compile/_compile_async.py +0 -130
  17. scitex/writer/_compile/_compile_unified.py +0 -148
  18. scitex/writer/_compile/_parser.py +0 -63
  19. scitex/writer/_compile/_runner.py +0 -457
  20. scitex/writer/_compile/_validator.py +0 -46
  21. scitex/writer/_compile/manuscript.py +0 -110
  22. scitex/writer/_compile/revision.py +0 -82
  23. scitex/writer/_compile/supplementary.py +0 -100
  24. scitex/writer/_dataclasses/__init__.py +0 -44
  25. scitex/writer/_dataclasses/config/_CONSTANTS.py +0 -46
  26. scitex/writer/_dataclasses/config/_WriterConfig.py +0 -175
  27. scitex/writer/_dataclasses/config/__init__.py +0 -9
  28. scitex/writer/_dataclasses/contents/_ManuscriptContents.py +0 -236
  29. scitex/writer/_dataclasses/contents/_RevisionContents.py +0 -136
  30. scitex/writer/_dataclasses/contents/_SupplementaryContents.py +0 -114
  31. scitex/writer/_dataclasses/contents/__init__.py +0 -9
  32. scitex/writer/_dataclasses/core/_Document.py +0 -146
  33. scitex/writer/_dataclasses/core/_DocumentSection.py +0 -546
  34. scitex/writer/_dataclasses/core/__init__.py +0 -7
  35. scitex/writer/_dataclasses/results/_CompilationResult.py +0 -165
  36. scitex/writer/_dataclasses/results/_LaTeXIssue.py +0 -102
  37. scitex/writer/_dataclasses/results/_SaveSectionsResponse.py +0 -118
  38. scitex/writer/_dataclasses/results/_SectionReadResponse.py +0 -131
  39. scitex/writer/_dataclasses/results/__init__.py +0 -11
  40. scitex/writer/_dataclasses/tree/MINIMUM_FILES.md +0 -121
  41. scitex/writer/_dataclasses/tree/_ConfigTree.py +0 -86
  42. scitex/writer/_dataclasses/tree/_ManuscriptTree.py +0 -84
  43. scitex/writer/_dataclasses/tree/_RevisionTree.py +0 -97
  44. scitex/writer/_dataclasses/tree/_ScriptsTree.py +0 -118
  45. scitex/writer/_dataclasses/tree/_SharedTree.py +0 -100
  46. scitex/writer/_dataclasses/tree/_SupplementaryTree.py +0 -101
  47. scitex/writer/_dataclasses/tree/__init__.py +0 -23
  48. scitex/writer/_mcp/__init__.py +0 -4
  49. scitex/writer/_mcp/handlers.py +0 -32
  50. scitex/writer/_mcp/tool_schemas.py +0 -33
  51. scitex/writer/_project/__init__.py +0 -29
  52. scitex/writer/_project/_create.py +0 -89
  53. scitex/writer/_project/_trees.py +0 -63
  54. scitex/writer/_project/_validate.py +0 -61
  55. scitex/writer/utils/.legacy_git_retry.py +0 -164
  56. scitex/writer/utils/__init__.py +0 -24
  57. scitex/writer/utils/_converters.py +0 -635
  58. scitex/writer/utils/_parse_latex_logs.py +0 -138
  59. scitex/writer/utils/_parse_script_args.py +0 -156
  60. scitex/writer/utils/_verify_tree_structure.py +0 -205
  61. scitex/writer/utils/_watch.py +0 -96
  62. {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/WHEEL +0 -0
  63. {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/entry_points.txt +0 -0
  64. {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,160 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-11-18 15:41:26 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/_clone_writer_project.py
5
-
6
- import os
7
-
8
- """
9
- Writer project template management.
10
-
11
- Provides functions to create and copy writer project templates.
12
- """
13
-
14
- from typing import Optional
15
-
16
- from scitex.logging import getLogger
17
-
18
- logger = getLogger(__name__)
19
-
20
-
21
- def clone_writer_project(
22
- project_dir: str,
23
- git_strategy: Optional[str] = "child",
24
- branch: Optional[str] = None,
25
- tag: Optional[str] = None,
26
- ) -> bool:
27
- """
28
- Initialize a new writer project directory from scitex-writer template.
29
-
30
- Convenience wrapper for scitex.template.clone_writer_directory.
31
- Handles template cloning and project setup automatically.
32
-
33
- Args:
34
- project_dir: Path to project directory (will be created)
35
- git_strategy: Git initialization strategy (optional)
36
- - 'child': Create isolated git in project directory (default)
37
- - 'parent': Use parent git repository
38
- - 'origin': Preserve template's original git history
39
- - None: Disable git initialization
40
- branch: Specific branch of the template repository to clone (optional)
41
- If None, clones the default branch. Mutually exclusive with tag.
42
- tag: Specific tag/release of the template repository to clone (optional)
43
- If None, clones the default branch. Mutually exclusive with branch.
44
-
45
- Returns:
46
- True if successful, False otherwise
47
-
48
- Examples:
49
- >>> from scitex.writer import clone_writer_project
50
- >>> clone_writer_project("my_paper")
51
- >>> clone_writer_project("./papers/my_paper")
52
- >>> clone_writer_project("my_paper", git_strategy="parent")
53
- >>> clone_writer_project("my_paper", branch="develop")
54
- >>> clone_writer_project("my_paper", tag="v1.0.0")
55
- """
56
- from scitex.template import clone_writer_directory
57
-
58
- try:
59
- result = clone_writer_directory(project_dir, git_strategy, branch, tag)
60
- return result
61
- except Exception as e:
62
- logger.error(f"Failed to initialize writer directory: {e}")
63
- return False
64
-
65
-
66
- def run_session() -> None:
67
- """Initialize scitex framework, run main function, and cleanup."""
68
- global CONFIG, CC, sys, plt, rng
69
- import sys
70
- import matplotlib.pyplot as plt
71
- import scitex as stx
72
-
73
- args = parse_args()
74
-
75
- CONFIG, sys.stdout, sys.stderr, plt, CC, rng = stx.session.start(
76
- sys,
77
- plt,
78
- args=args,
79
- file=__FILE__,
80
- sdir_suffix=None,
81
- verbose=False,
82
- agg=True,
83
- )
84
-
85
- exit_status = main(args)
86
-
87
- stx.session.close(
88
- CONFIG,
89
- verbose=False,
90
- notify=False,
91
- message="",
92
- exit_status=exit_status,
93
- )
94
-
95
-
96
- def main(args):
97
- result = clone_writer_project(
98
- args.project_dir,
99
- git_strategy=args.git_strategy,
100
- branch=args.branch,
101
- tag=args.tag,
102
- )
103
-
104
- if result:
105
- print(f"Successfully created writer project: {args.project_dir}")
106
- return 0
107
- else:
108
- print(f"Failed to create writer project: {args.project_dir}")
109
- return 1
110
-
111
-
112
- def parse_args():
113
- import argparse
114
-
115
- parser = argparse.ArgumentParser(description="Clone scitex writer project template")
116
- parser.add_argument(
117
- "project_dir",
118
- type=str,
119
- help="Path to project directory (will be created)",
120
- )
121
- parser.add_argument(
122
- "--git-strategy",
123
- "-g",
124
- type=str,
125
- choices=["child", "parent", "origin", "none"],
126
- default="child",
127
- help="Git initialization strategy (default: child)",
128
- )
129
- parser.add_argument(
130
- "--branch",
131
- "-b",
132
- type=str,
133
- default=None,
134
- help="Specific branch of template to clone (mutually exclusive with --tag)",
135
- )
136
- parser.add_argument(
137
- "--tag",
138
- "-t",
139
- type=str,
140
- default=None,
141
- help="Specific tag/release of template to clone (mutually exclusive with --branch)",
142
- )
143
-
144
- return parser.parse_args()
145
-
146
-
147
- if __name__ == "__main__":
148
- run_session()
149
-
150
-
151
- __all__ = [
152
- "clone_writer_project",
153
- ]
154
-
155
- # python -m scitex.writer._clone_writer_project my_paper --git-strategy child
156
- # python -m scitex.writer._clone_writer_project ./papers/my_paper
157
- # python -m scitex.writer._clone_writer_project my_paper --branch develop
158
- # python -m scitex.writer._clone_writer_project my_paper --tag v1.0.0
159
-
160
- # EOF
@@ -1,41 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: "2025-11-08 (ywatanabe)"
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/_compile/__init__.py
4
- # ----------------------------------------
5
- from __future__ import annotations
6
-
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/_compile/__init__.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- LaTeX compilation module for writer.
15
-
16
- Provides organized compilation functionality:
17
- - manuscript: Manuscript compilation with figure/conversion options
18
- - supplementary: Supplementary materials compilation
19
- - revision: Revision response compilation with change tracking
20
- - _runner: Script execution engine
21
- - _parser: Output parsing utilities
22
- - _validator: Pre-compile validation
23
- """
24
-
25
- from .._dataclasses import CompilationResult
26
- from ._compile_unified import compile
27
- from ._runner import run_compile
28
- from .manuscript import compile_manuscript
29
- from .revision import compile_revision
30
- from .supplementary import compile_supplementary
31
-
32
- __all__ = [
33
- "compile",
34
- "run_compile",
35
- "compile_manuscript",
36
- "compile_supplementary",
37
- "compile_revision",
38
- "CompilationResult",
39
- ]
40
-
41
- # EOF
@@ -1,130 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: "2025-10-28 17:43:50 (ywatanabe)"
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/_compile_async.py
4
- # ----------------------------------------
5
- from __future__ import annotations
6
-
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/_compile_async.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- Asynchronous compilation support for writer module.
15
-
16
- Allows non-blocking compilation operations for concurrent workflows.
17
- """
18
-
19
- import asyncio
20
- from concurrent.futures import ThreadPoolExecutor
21
- from functools import partial, wraps
22
- from pathlib import Path
23
- from typing import Any, Callable
24
-
25
- from scitex.logging import getLogger
26
-
27
- from .._dataclasses import CompilationResult
28
- from .manuscript import compile_manuscript
29
- from .revision import compile_revision
30
- from .supplementary import compile_supplementary
31
-
32
- logger = getLogger(__name__)
33
-
34
- # Thread pool for async operations
35
- _executor = ThreadPoolExecutor(max_workers=2)
36
-
37
-
38
- def _make_async_wrapper(sync_func: Callable) -> Callable:
39
- """
40
- Factory function to create async wrappers for sync compilation functions.
41
-
42
- Args:
43
- sync_func: Synchronous compilation function
44
-
45
- Returns
46
- -------
47
- Async wrapper function
48
- """
49
-
50
- @wraps(sync_func)
51
- async def async_wrapper(*args: Any, **kwargs: Any) -> CompilationResult:
52
- loop = asyncio.get_event_loop()
53
- # Use partial to bind kwargs since run_in_executor only accepts positional args
54
- bound_func = partial(sync_func, *args, **kwargs)
55
- return await loop.run_in_executor(_executor, bound_func)
56
-
57
- return async_wrapper
58
-
59
-
60
- # Create async wrappers using factory function
61
- compile_manuscript_async = _make_async_wrapper(compile_manuscript)
62
- compile_supplementary_async = _make_async_wrapper(compile_supplementary)
63
- compile_revision_async = _make_async_wrapper(compile_revision)
64
-
65
-
66
- async def compile_all_async(
67
- project_dir: Path, track_changes: bool = False, timeout: int = 300
68
- ) -> dict:
69
- """
70
- Compile all document dataclasses concurrently.
71
-
72
- Runs all three document compilations in parallel for faster overall completion.
73
-
74
- Args:
75
- project_dir: Path to writer project
76
- track_changes: Whether to track changes in revision
77
- timeout: Timeout per compilation
78
-
79
- Returns
80
- -------
81
- Dict with keys 'manuscript', 'supplementary', 'revision' and CompilationResult values.
82
- If a compilation fails, the value will be None.
83
-
84
- Example:
85
- >>> results = await compile_all_async(Path("my_paper"))
86
- >>> for doc_type, result in results.items():
87
- ... if result and result.success:
88
- ... print(f"{doc_type}: OK")
89
- ... else:
90
- ... print(f"{doc_type}: FAILED")
91
- """
92
- logger.info(f"Starting concurrent compilation of all documents in {project_dir}")
93
-
94
- try:
95
- results = await asyncio.gather(
96
- compile_manuscript_async(project_dir, timeout=timeout),
97
- compile_supplementary_async(project_dir, timeout=timeout),
98
- compile_revision_async(project_dir, track_changes, timeout=timeout),
99
- return_exceptions=True,
100
- )
101
- except Exception as e:
102
- logger.error(f"Error during concurrent compilation: {e}")
103
- return {
104
- "manuscript": None,
105
- "supplementary": None,
106
- "revision": None,
107
- }
108
-
109
- # Handle exceptions and convert to None
110
- def safe_result(result):
111
- if isinstance(result, Exception):
112
- logger.error(f"Compilation exception: {result}")
113
- return None
114
- return result
115
-
116
- return {
117
- "manuscript": safe_result(results[0]),
118
- "supplementary": safe_result(results[1]),
119
- "revision": safe_result(results[2]),
120
- }
121
-
122
-
123
- __all__ = [
124
- "compile_manuscript_async",
125
- "compile_supplementary_async",
126
- "compile_revision_async",
127
- "compile_all_async",
128
- ]
129
-
130
- # EOF
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/_compile_unified.py
3
-
4
- """
5
- Unified compilation interface for writer module.
6
-
7
- Provides a single `compile()` function that handles all document types
8
- with optional async support.
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- import asyncio
14
- from pathlib import Path
15
- from typing import Literal, Optional, Union
16
-
17
- from .._dataclasses import CompilationResult
18
- from ._compile_async import (
19
- compile_all_async,
20
- compile_manuscript_async,
21
- compile_revision_async,
22
- compile_supplementary_async,
23
- )
24
- from .manuscript import compile_manuscript
25
- from .revision import compile_revision
26
- from .supplementary import compile_supplementary
27
-
28
- DocType = Literal["manuscript", "supplementary", "revision", "all"]
29
-
30
-
31
- def compile(
32
- *doc_types: DocType,
33
- project_dir: Optional[Path] = None,
34
- async_: bool = False,
35
- track_changes: bool = False,
36
- timeout: int = 300,
37
- ) -> Union[CompilationResult, dict, asyncio.coroutine]:
38
- """
39
- Unified compilation function for LaTeX documents.
40
-
41
- Args:
42
- *doc_types: Document types to compile. One or more of:
43
- - "manuscript": Main document
44
- - "supplementary": Supplementary materials
45
- - "revision": Revision response
46
- - "all": All document types (async only)
47
- project_dir: Path to writer project directory
48
- async_: If True, returns awaitable coroutine
49
- track_changes: Enable change tracking for revision (default: False)
50
- timeout: Compilation timeout in seconds (default: 300)
51
-
52
- Returns
53
- -------
54
- - Single doc_type (sync): CompilationResult
55
- - Multiple doc_types (sync): dict of {doc_type: CompilationResult}
56
- - async_=True: Awaitable coroutine returning above
57
-
58
- Examples
59
- --------
60
- >>> # Sync single document
61
- >>> result = compile("manuscript", project_dir=Path("."))
62
-
63
- >>> # Sync multiple documents
64
- >>> results = compile("manuscript", "supplementary", project_dir=Path("."))
65
- >>> results["manuscript"].success
66
-
67
- >>> # Async single document
68
- >>> result = await compile("manuscript", project_dir=Path("."), async_=True)
69
-
70
- >>> # Async all documents (parallel)
71
- >>> results = await compile("all", project_dir=Path("."), async_=True)
72
- """
73
- if not doc_types:
74
- raise ValueError("At least one document type required")
75
-
76
- if project_dir is None:
77
- raise ValueError("project_dir is required")
78
-
79
- project_dir = Path(project_dir)
80
-
81
- # Map doc types to functions
82
- sync_funcs = {
83
- "manuscript": lambda: compile_manuscript(project_dir, timeout=timeout),
84
- "supplementary": lambda: compile_supplementary(project_dir, timeout=timeout),
85
- "revision": lambda: compile_revision(
86
- project_dir, track_changes, timeout=timeout
87
- ),
88
- }
89
-
90
- async_funcs = {
91
- "manuscript": lambda: compile_manuscript_async(project_dir, timeout=timeout),
92
- "supplementary": lambda: compile_supplementary_async(
93
- project_dir, timeout=timeout
94
- ),
95
- "revision": lambda: compile_revision_async(
96
- project_dir, track_changes, timeout=timeout
97
- ),
98
- }
99
-
100
- # Handle "all" special case
101
- if "all" in doc_types:
102
- if async_:
103
- return compile_all_async(
104
- project_dir, track_changes=track_changes, timeout=timeout
105
- )
106
- else:
107
- # Sync "all" - compile sequentially
108
- return {
109
- "manuscript": sync_funcs["manuscript"](),
110
- "supplementary": sync_funcs["supplementary"](),
111
- "revision": sync_funcs["revision"](),
112
- }
113
-
114
- # Validate doc types
115
- valid_types = {"manuscript", "supplementary", "revision"}
116
- for dt in doc_types:
117
- if dt not in valid_types:
118
- raise ValueError(
119
- f"Invalid document type: {dt}. Must be one of {valid_types}"
120
- )
121
-
122
- # Single document
123
- if len(doc_types) == 1:
124
- doc_type = doc_types[0]
125
- if async_:
126
- return async_funcs[doc_type]()
127
- else:
128
- return sync_funcs[doc_type]()
129
-
130
- # Multiple documents
131
- if async_:
132
-
133
- async def _compile_multiple():
134
- tasks = [async_funcs[dt]() for dt in doc_types]
135
- results = await asyncio.gather(*tasks, return_exceptions=True)
136
- return {
137
- dt: (None if isinstance(r, Exception) else r)
138
- for dt, r in zip(doc_types, results)
139
- }
140
-
141
- return _compile_multiple()
142
- else:
143
- return {dt: sync_funcs[dt]() for dt in doc_types}
144
-
145
-
146
- __all__ = ["compile"]
147
-
148
- # EOF
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/_compile/_parser.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/_compile/_parser.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- Compilation output parsing.
15
-
16
- Parses LaTeX compilation output and log files for errors and warnings.
17
- """
18
-
19
- from pathlib import Path
20
- from typing import Tuple, List, Optional
21
-
22
- from scitex.logging import getLogger
23
- from scitex.writer.utils._parse_latex_logs import parse_compilation_output
24
-
25
- logger = getLogger(__name__)
26
-
27
-
28
- def parse_output(
29
- stdout: str,
30
- stderr: str,
31
- log_file: Optional[Path] = None,
32
- ) -> Tuple[List[str], List[str]]:
33
- """
34
- Parse compilation output for errors and warnings.
35
-
36
- Parameters
37
- ----------
38
- stdout : str
39
- Standard output from compilation
40
- stderr : str
41
- Standard error from compilation
42
- log_file : Path, optional
43
- Path to LaTeX log file
44
-
45
- Returns
46
- -------
47
- tuple
48
- (errors, warnings) as lists of strings
49
- """
50
- error_issues, warning_issues = parse_compilation_output(
51
- stdout + stderr, log_file=log_file
52
- )
53
-
54
- # Convert LaTeXIssue objects to strings for backward compatibility
55
- errors = [str(issue) for issue in error_issues]
56
- warnings = [str(issue) for issue in warning_issues]
57
-
58
- return errors, warnings
59
-
60
-
61
- __all__ = ["parse_output"]
62
-
63
- # EOF