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,136 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 06:08:44 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_RevisionContents.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/dataclasses/_RevisionContents.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- RevisionContents - dataclass for revision contents structure.
15
-
16
- Represents the 03_revision/contents/ directory structure.
17
- """
18
-
19
- from pathlib import Path
20
- from typing import Optional
21
- from dataclasses import dataclass
22
-
23
- from ..core import DocumentSection
24
-
25
-
26
- @dataclass
27
- class RevisionContents:
28
- """Contents subdirectory of revision (03_revision/contents/)."""
29
-
30
- root: Path
31
- git_root: Optional[Path] = None
32
-
33
- # Core sections
34
- introduction: DocumentSection = None
35
- conclusion: DocumentSection = None
36
- references: DocumentSection = None
37
-
38
- # Metadata
39
- title: DocumentSection = None
40
- authors: DocumentSection = None
41
- keywords: DocumentSection = None
42
- journal_name: DocumentSection = None
43
-
44
- # Reviewer responses (subdirectories)
45
- editor: Path = None
46
- reviewer1: Path = None
47
- reviewer2: Path = None
48
-
49
- # Files/directories
50
- figures: Path = None
51
- tables: Path = None
52
- bibliography: DocumentSection = None
53
- latex_styles: Path = None
54
-
55
- def __post_init__(self):
56
- """Initialize all DocumentSection instances."""
57
- if self.introduction is None:
58
- self.introduction = DocumentSection(
59
- self.root / "introduction.tex", self.git_root
60
- )
61
- if self.conclusion is None:
62
- self.conclusion = DocumentSection(
63
- self.root / "conclusion.tex", self.git_root
64
- )
65
- if self.references is None:
66
- self.references = DocumentSection(
67
- self.root / "references.tex", self.git_root
68
- )
69
- if self.title is None:
70
- self.title = DocumentSection(self.root / "title.tex", self.git_root)
71
- if self.authors is None:
72
- self.authors = DocumentSection(self.root / "authors.tex", self.git_root)
73
- if self.keywords is None:
74
- self.keywords = DocumentSection(self.root / "keywords.tex", self.git_root)
75
- if self.journal_name is None:
76
- self.journal_name = DocumentSection(
77
- self.root / "journal_name.tex", self.git_root
78
- )
79
- if self.editor is None:
80
- self.editor = self.root / "editor"
81
- if self.reviewer1 is None:
82
- self.reviewer1 = self.root / "reviewer1"
83
- if self.reviewer2 is None:
84
- self.reviewer2 = self.root / "reviewer2"
85
- if self.figures is None:
86
- self.figures = self.root / "figures"
87
- if self.tables is None:
88
- self.tables = self.root / "tables"
89
- if self.bibliography is None:
90
- self.bibliography = DocumentSection(
91
- self.root / "bibliography.bib", self.git_root
92
- )
93
- if self.latex_styles is None:
94
- self.latex_styles = self.root / "latex_styles"
95
-
96
- def verify_structure(self) -> tuple[bool, list[str]]:
97
- """
98
- Verify revision contents structure.
99
-
100
- Returns:
101
- (is_valid, list_of_issues_with_paths)
102
- """
103
- issues = []
104
-
105
- # Check required directories
106
- if not self.figures.exists():
107
- expected_path = (
108
- self.figures.relative_to(self.git_root)
109
- if self.git_root
110
- else self.figures
111
- )
112
- issues.append(f"Missing figures/ (expected at: {expected_path})")
113
- if not self.tables.exists():
114
- expected_path = (
115
- self.tables.relative_to(self.git_root) if self.git_root else self.tables
116
- )
117
- issues.append(f"Missing tables/ (expected at: {expected_path})")
118
- if not self.latex_styles.exists():
119
- expected_path = (
120
- self.latex_styles.relative_to(self.git_root)
121
- if self.git_root
122
- else self.latex_styles
123
- )
124
- issues.append(f"Missing latex_styles/ (expected at: {expected_path})")
125
- if not self.editor.exists():
126
- expected_path = (
127
- self.editor.relative_to(self.git_root) if self.git_root else self.editor
128
- )
129
- issues.append(f"Missing editor/ (expected at: {expected_path})")
130
-
131
- return len(issues) == 0, issues
132
-
133
-
134
- __all__ = ["RevisionContents"]
135
-
136
- # EOF
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 06:08:46 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_SupplementaryContents.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/dataclasses/_SupplementaryContents.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- SupplementaryContents - dataclass for supplementary contents structure.
15
-
16
- Represents the 02_supplementary/contents/ directory structure.
17
- """
18
-
19
- from pathlib import Path
20
- from typing import Optional
21
- from dataclasses import dataclass
22
-
23
- from ..core import DocumentSection
24
-
25
-
26
- @dataclass
27
- class SupplementaryContents:
28
- """Contents subdirectory of supplementary (02_supplementary/contents/)."""
29
-
30
- root: Path
31
- git_root: Optional[Path] = None
32
-
33
- # Core sections
34
- methods: DocumentSection = None
35
- results: DocumentSection = None
36
-
37
- # Metadata
38
- title: DocumentSection = None
39
- authors: DocumentSection = None
40
- keywords: DocumentSection = None
41
- journal_name: DocumentSection = None
42
-
43
- # Files/directories
44
- figures: Path = None
45
- tables: Path = None
46
- bibliography: DocumentSection = None
47
- latex_styles: Path = None
48
- wordcount: DocumentSection = None
49
-
50
- def __post_init__(self):
51
- """Initialize all DocumentSection instances."""
52
- if self.methods is None:
53
- self.methods = DocumentSection(self.root / "methods.tex", self.git_root)
54
- if self.results is None:
55
- self.results = DocumentSection(self.root / "results.tex", self.git_root)
56
- if self.title is None:
57
- self.title = DocumentSection(self.root / "title.tex", self.git_root)
58
- if self.authors is None:
59
- self.authors = DocumentSection(self.root / "authors.tex", self.git_root)
60
- if self.keywords is None:
61
- self.keywords = DocumentSection(self.root / "keywords.tex", self.git_root)
62
- if self.journal_name is None:
63
- self.journal_name = DocumentSection(
64
- self.root / "journal_name.tex", self.git_root
65
- )
66
- if self.figures is None:
67
- self.figures = self.root / "figures"
68
- if self.tables is None:
69
- self.tables = self.root / "tables"
70
- if self.bibliography is None:
71
- self.bibliography = DocumentSection(
72
- self.root / "bibliography.bib", self.git_root
73
- )
74
- if self.latex_styles is None:
75
- self.latex_styles = self.root / "latex_styles"
76
- if self.wordcount is None:
77
- self.wordcount = DocumentSection(self.root / "wordcount.tex", self.git_root)
78
-
79
- def verify_structure(self) -> tuple[bool, list[str]]:
80
- """
81
- Verify supplementary contents structure.
82
-
83
- Returns:
84
- (is_valid, list_of_issues_with_paths)
85
- """
86
- issues = []
87
-
88
- # Check required directories
89
- if not self.figures.exists():
90
- expected_path = (
91
- self.figures.relative_to(self.git_root)
92
- if self.git_root
93
- else self.figures
94
- )
95
- issues.append(f"Missing figures/ (expected at: {expected_path})")
96
- if not self.tables.exists():
97
- expected_path = (
98
- self.tables.relative_to(self.git_root) if self.git_root else self.tables
99
- )
100
- issues.append(f"Missing tables/ (expected at: {expected_path})")
101
- if not self.latex_styles.exists():
102
- expected_path = (
103
- self.latex_styles.relative_to(self.git_root)
104
- if self.git_root
105
- else self.latex_styles
106
- )
107
- issues.append(f"Missing latex_styles/ (expected at: {expected_path})")
108
-
109
- return len(issues) == 0, issues
110
-
111
-
112
- __all__ = ["SupplementaryContents"]
113
-
114
- # EOF
@@ -1,9 +0,0 @@
1
- from ._ManuscriptContents import ManuscriptContents
2
- from ._SupplementaryContents import SupplementaryContents
3
- from ._RevisionContents import RevisionContents
4
-
5
- __all__ = [
6
- "ManuscriptContents",
7
- "SupplementaryContents",
8
- "RevisionContents",
9
- ]
@@ -1,146 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 06:08:38 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_Document.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/dataclasses/_Document.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- Base Document class for document type accessors.
15
-
16
- Provides dynamic file access via attribute lookups.
17
- """
18
-
19
- from pathlib import Path
20
- from typing import Optional
21
-
22
- from ._DocumentSection import DocumentSection
23
-
24
-
25
- class Document:
26
- """
27
- Base document accessor.
28
-
29
- Provides dynamic file access by mapping attribute names to .tex files:
30
- - document.introduction -> introduction.tex
31
- - document.methods -> methods.tex
32
- - Custom: document.custom_section -> custom_section.tex
33
- """
34
-
35
- def __init__(self, doc_dir: Path, git_root: Optional[Path] = None):
36
- """
37
- Initialize document accessor.
38
-
39
- Args:
40
- doc_dir: Path to document directory (contains 'contents/' subdirectory)
41
- git_root: Path to git repository root (optional, for efficiency)
42
- """
43
- self.dir = doc_dir
44
- self.git_root = git_root
45
-
46
- def __getattr__(self, name: str) -> DocumentSection:
47
- """
48
- Get file path by name (e.g., introduction -> introduction.tex).
49
-
50
- Args:
51
- name: Section name without .tex extension
52
-
53
- Returns:
54
- DocumentSection for the requested file
55
-
56
- Example:
57
- >>> manuscript = ManuscriptDocument(Path("01_manuscript"))
58
- >>> manuscript.introduction.read() # Reads contents/introduction.tex
59
- """
60
- if name.startswith("_"):
61
- # Avoid infinite recursion for private attributes
62
- raise AttributeError(
63
- f"'{self.__class__.__name__}' has no attribute '{name}'"
64
- )
65
-
66
- file_path = self.dir / "contents" / f"{name}.tex"
67
- return DocumentSection(file_path, git_root=self.git_root)
68
-
69
- def __repr__(self) -> str:
70
- """String representation."""
71
- return f"{self.__class__.__name__}({self.dir.name})"
72
-
73
-
74
- def run_session() -> None:
75
- """Initialize scitex framework, run main function, and cleanup."""
76
- global CONFIG, CC, sys, plt, rng
77
- import sys
78
- import matplotlib.pyplot as plt
79
- import scitex as stx
80
-
81
- args = parse_args()
82
-
83
- CONFIG, sys.stdout, sys.stderr, plt, CC, rng = stx.session.start(
84
- sys,
85
- plt,
86
- args=args,
87
- file=__FILE__,
88
- sdir_suffix=None,
89
- verbose=False,
90
- agg=True,
91
- )
92
-
93
- exit_status = main(args)
94
-
95
- stx.session.close(
96
- CONFIG,
97
- verbose=False,
98
- notify=False,
99
- message="",
100
- exit_status=exit_status,
101
- )
102
-
103
-
104
- def main(args):
105
- doc = Document(Path(args.dir))
106
-
107
- print(f"Document: {doc}")
108
- print(f"Directory: {doc.dir}")
109
-
110
- contents_dir = doc.dir / "contents"
111
- if contents_dir.exists():
112
- tex_files = list(contents_dir.glob("*.tex"))
113
- print(f"\nAvailable sections ({len(tex_files)}):")
114
- for tex_file in sorted(tex_files):
115
- section_name = tex_file.stem
116
- print(f" - {section_name}")
117
-
118
- return 0
119
-
120
-
121
- def parse_args():
122
- import argparse
123
-
124
- parser = argparse.ArgumentParser(
125
- description="Demonstrate Document accessor functionality"
126
- )
127
- parser.add_argument(
128
- "--dir",
129
- "-d",
130
- type=str,
131
- required=True,
132
- help="Path to document directory",
133
- )
134
-
135
- return parser.parse_args()
136
-
137
-
138
- if __name__ == "__main__":
139
- run_session()
140
-
141
-
142
- __all__ = ["Document"]
143
-
144
- # python -m scitex.writer._dataclasses.core._Document --dir ./01_manuscript
145
-
146
- # EOF