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.
- scitex/_mcp_tools/audio.py +11 -65
- scitex/audio/README.md +40 -12
- scitex/audio/__init__.py +27 -235
- scitex/audio/_audio_check.py +93 -0
- scitex/audio/_mcp/speak_handlers.py +56 -8
- scitex/audio/_speak.py +295 -0
- scitex/audio/mcp_server.py +98 -73
- scitex/social/__init__.py +1 -24
- scitex/writer/README.md +25 -409
- scitex/writer/__init__.py +98 -13
- {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/METADATA +6 -1
- {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/RECORD +15 -62
- scitex/writer/Writer.py +0 -487
- scitex/writer/_clone_writer_project.py +0 -160
- scitex/writer/_compile/__init__.py +0 -41
- scitex/writer/_compile/_compile_async.py +0 -130
- scitex/writer/_compile/_compile_unified.py +0 -148
- scitex/writer/_compile/_parser.py +0 -63
- scitex/writer/_compile/_runner.py +0 -457
- scitex/writer/_compile/_validator.py +0 -46
- scitex/writer/_compile/manuscript.py +0 -110
- scitex/writer/_compile/revision.py +0 -82
- scitex/writer/_compile/supplementary.py +0 -100
- scitex/writer/_dataclasses/__init__.py +0 -44
- scitex/writer/_dataclasses/config/_CONSTANTS.py +0 -46
- scitex/writer/_dataclasses/config/_WriterConfig.py +0 -175
- scitex/writer/_dataclasses/config/__init__.py +0 -9
- scitex/writer/_dataclasses/contents/_ManuscriptContents.py +0 -236
- scitex/writer/_dataclasses/contents/_RevisionContents.py +0 -136
- scitex/writer/_dataclasses/contents/_SupplementaryContents.py +0 -114
- scitex/writer/_dataclasses/contents/__init__.py +0 -9
- scitex/writer/_dataclasses/core/_Document.py +0 -146
- scitex/writer/_dataclasses/core/_DocumentSection.py +0 -546
- scitex/writer/_dataclasses/core/__init__.py +0 -7
- scitex/writer/_dataclasses/results/_CompilationResult.py +0 -165
- scitex/writer/_dataclasses/results/_LaTeXIssue.py +0 -102
- scitex/writer/_dataclasses/results/_SaveSectionsResponse.py +0 -118
- scitex/writer/_dataclasses/results/_SectionReadResponse.py +0 -131
- scitex/writer/_dataclasses/results/__init__.py +0 -11
- scitex/writer/_dataclasses/tree/MINIMUM_FILES.md +0 -121
- scitex/writer/_dataclasses/tree/_ConfigTree.py +0 -86
- scitex/writer/_dataclasses/tree/_ManuscriptTree.py +0 -84
- scitex/writer/_dataclasses/tree/_RevisionTree.py +0 -97
- scitex/writer/_dataclasses/tree/_ScriptsTree.py +0 -118
- scitex/writer/_dataclasses/tree/_SharedTree.py +0 -100
- scitex/writer/_dataclasses/tree/_SupplementaryTree.py +0 -101
- scitex/writer/_dataclasses/tree/__init__.py +0 -23
- scitex/writer/_mcp/__init__.py +0 -4
- scitex/writer/_mcp/handlers.py +0 -32
- scitex/writer/_mcp/tool_schemas.py +0 -33
- scitex/writer/_project/__init__.py +0 -29
- scitex/writer/_project/_create.py +0 -89
- scitex/writer/_project/_trees.py +0 -63
- scitex/writer/_project/_validate.py +0 -61
- scitex/writer/utils/.legacy_git_retry.py +0 -164
- scitex/writer/utils/__init__.py +0 -24
- scitex/writer/utils/_converters.py +0 -635
- scitex/writer/utils/_parse_latex_logs.py +0 -138
- scitex/writer/utils/_parse_script_args.py +0 -156
- scitex/writer/utils/_verify_tree_structure.py +0 -205
- scitex/writer/utils/_watch.py +0 -96
- {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/WHEEL +0 -0
- {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/entry_points.txt +0 -0
- {scitex-2.16.0.dist-info → scitex-2.16.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-28 17:16:00 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/tree/_ConfigTree.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/tree/_ConfigTree.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
ConfigTree - dataclass for project config directory structure.
|
|
15
|
-
|
|
16
|
-
Represents the config/ directory with configuration files for different documents.
|
|
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 ConfigTree:
|
|
28
|
-
"""Config directory structure (config/)."""
|
|
29
|
-
|
|
30
|
-
root: Path
|
|
31
|
-
git_root: Optional[Path] = None
|
|
32
|
-
|
|
33
|
-
# Configuration files
|
|
34
|
-
config_manuscript: DocumentSection = None
|
|
35
|
-
config_supplementary: DocumentSection = None
|
|
36
|
-
config_revision: DocumentSection = None
|
|
37
|
-
load_config: DocumentSection = None
|
|
38
|
-
|
|
39
|
-
def __post_init__(self):
|
|
40
|
-
"""Initialize all DocumentSection instances."""
|
|
41
|
-
if self.config_manuscript is None:
|
|
42
|
-
self.config_manuscript = DocumentSection(
|
|
43
|
-
self.root / "config_manuscript.yaml", self.git_root
|
|
44
|
-
)
|
|
45
|
-
if self.config_supplementary is None:
|
|
46
|
-
self.config_supplementary = DocumentSection(
|
|
47
|
-
self.root / "config_supplementary.yaml", self.git_root
|
|
48
|
-
)
|
|
49
|
-
if self.config_revision is None:
|
|
50
|
-
self.config_revision = DocumentSection(
|
|
51
|
-
self.root / "config_revision.yaml", self.git_root
|
|
52
|
-
)
|
|
53
|
-
if self.load_config is None:
|
|
54
|
-
self.load_config = DocumentSection(
|
|
55
|
-
self.root / "load_config.sh", self.git_root
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
def verify_structure(self) -> tuple[bool, list[str]]:
|
|
59
|
-
"""
|
|
60
|
-
Verify config structure has required files.
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
(is_valid, list_of_missing_files_with_paths)
|
|
64
|
-
"""
|
|
65
|
-
required = [
|
|
66
|
-
("config_manuscript.yaml", self.config_manuscript),
|
|
67
|
-
("config_supplementary.yaml", self.config_supplementary),
|
|
68
|
-
("config_revision.yaml", self.config_revision),
|
|
69
|
-
]
|
|
70
|
-
|
|
71
|
-
missing = []
|
|
72
|
-
for name, section in required:
|
|
73
|
-
if not section.path.exists():
|
|
74
|
-
expected_path = (
|
|
75
|
-
section.path.relative_to(self.git_root)
|
|
76
|
-
if self.git_root
|
|
77
|
-
else section.path
|
|
78
|
-
)
|
|
79
|
-
missing.append(f"{name} (expected at: {expected_path})")
|
|
80
|
-
|
|
81
|
-
return len(missing) == 0, missing
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
__all__ = ["ConfigTree"]
|
|
85
|
-
|
|
86
|
-
# EOF
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-28 17:16:00 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/tree/_ManuscriptTree.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/tree/_ManuscriptTree.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
ManuscriptTree - dataclass for manuscript directory structure.
|
|
15
|
-
|
|
16
|
-
Represents the 01_manuscript/ directory with all subdirectories.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from typing import Optional
|
|
21
|
-
from dataclasses import dataclass
|
|
22
|
-
|
|
23
|
-
from ..contents import ManuscriptContents
|
|
24
|
-
from ..core import DocumentSection
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclass
|
|
28
|
-
class ManuscriptTree:
|
|
29
|
-
"""Manuscript directory structure (01_manuscript/)."""
|
|
30
|
-
|
|
31
|
-
root: Path
|
|
32
|
-
git_root: Optional[Path] = None
|
|
33
|
-
|
|
34
|
-
# Contents subdirectory
|
|
35
|
-
contents: ManuscriptContents = None
|
|
36
|
-
|
|
37
|
-
# Root level files
|
|
38
|
-
base: DocumentSection = None
|
|
39
|
-
readme: DocumentSection = None
|
|
40
|
-
|
|
41
|
-
# Directories
|
|
42
|
-
archive: Path = None
|
|
43
|
-
|
|
44
|
-
def __post_init__(self):
|
|
45
|
-
"""Initialize all instances."""
|
|
46
|
-
if self.contents is None:
|
|
47
|
-
self.contents = ManuscriptContents(self.root / "contents", self.git_root)
|
|
48
|
-
if self.base is None:
|
|
49
|
-
self.base = DocumentSection(self.root / "base.tex", self.git_root)
|
|
50
|
-
if self.readme is None:
|
|
51
|
-
self.readme = DocumentSection(self.root / "README.md", self.git_root)
|
|
52
|
-
if self.archive is None:
|
|
53
|
-
self.archive = self.root / "archive"
|
|
54
|
-
|
|
55
|
-
def verify_structure(self) -> tuple[bool, list[str]]:
|
|
56
|
-
"""
|
|
57
|
-
Verify manuscript structure has required components.
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
(is_valid, list_of_missing_items_with_paths)
|
|
61
|
-
"""
|
|
62
|
-
missing = []
|
|
63
|
-
|
|
64
|
-
# Check contents structure
|
|
65
|
-
contents_valid, contents_missing = self.contents.verify_structure()
|
|
66
|
-
if not contents_valid:
|
|
67
|
-
# Contents already includes full paths, just pass them through
|
|
68
|
-
missing.extend(contents_missing)
|
|
69
|
-
|
|
70
|
-
# Check root level files
|
|
71
|
-
if not self.base.path.exists():
|
|
72
|
-
expected_path = (
|
|
73
|
-
self.base.path.relative_to(self.git_root)
|
|
74
|
-
if self.git_root
|
|
75
|
-
else self.base.path
|
|
76
|
-
)
|
|
77
|
-
missing.append(f"base.tex (expected at: {expected_path})")
|
|
78
|
-
|
|
79
|
-
return len(missing) == 0, missing
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
__all__ = ["ManuscriptTree"]
|
|
83
|
-
|
|
84
|
-
# EOF
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-28 17:16:00 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/tree/_RevisionTree.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/tree/_RevisionTree.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
RevisionTree - dataclass for revision directory structure.
|
|
15
|
-
|
|
16
|
-
Represents the 03_revision/ directory with all subdirectories.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from typing import Optional
|
|
21
|
-
from dataclasses import dataclass
|
|
22
|
-
|
|
23
|
-
from ..contents import RevisionContents
|
|
24
|
-
from ..core import DocumentSection
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclass
|
|
28
|
-
class RevisionTree:
|
|
29
|
-
"""Revision directory structure (03_revision/)."""
|
|
30
|
-
|
|
31
|
-
root: Path
|
|
32
|
-
git_root: Optional[Path] = None
|
|
33
|
-
|
|
34
|
-
# Contents subdirectory
|
|
35
|
-
contents: RevisionContents = None
|
|
36
|
-
|
|
37
|
-
# Root level files
|
|
38
|
-
base: DocumentSection = None
|
|
39
|
-
revision: DocumentSection = None
|
|
40
|
-
readme: DocumentSection = None
|
|
41
|
-
|
|
42
|
-
# Directories
|
|
43
|
-
archive: Path = None
|
|
44
|
-
docs: Path = None
|
|
45
|
-
|
|
46
|
-
def __post_init__(self):
|
|
47
|
-
"""Initialize all instances."""
|
|
48
|
-
if self.contents is None:
|
|
49
|
-
self.contents = RevisionContents(self.root / "contents", self.git_root)
|
|
50
|
-
if self.base is None:
|
|
51
|
-
self.base = DocumentSection(self.root / "base.tex", self.git_root)
|
|
52
|
-
if self.revision is None:
|
|
53
|
-
self.revision = DocumentSection(self.root / "revision.tex", self.git_root)
|
|
54
|
-
if self.readme is None:
|
|
55
|
-
self.readme = DocumentSection(self.root / "README.md", self.git_root)
|
|
56
|
-
if self.archive is None:
|
|
57
|
-
self.archive = self.root / "archive"
|
|
58
|
-
if self.docs is None:
|
|
59
|
-
self.docs = self.root / "docs"
|
|
60
|
-
|
|
61
|
-
def verify_structure(self) -> tuple[bool, list[str]]:
|
|
62
|
-
"""
|
|
63
|
-
Verify revision structure has required components.
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
(is_valid, list_of_missing_items_with_paths)
|
|
67
|
-
"""
|
|
68
|
-
missing = []
|
|
69
|
-
|
|
70
|
-
# Check contents structure
|
|
71
|
-
contents_valid, contents_issues = self.contents.verify_structure()
|
|
72
|
-
if not contents_valid:
|
|
73
|
-
# Contents already includes full paths, just pass them through
|
|
74
|
-
missing.extend(contents_issues)
|
|
75
|
-
|
|
76
|
-
# Check root level files
|
|
77
|
-
if not self.base.path.exists():
|
|
78
|
-
expected_path = (
|
|
79
|
-
self.base.path.relative_to(self.git_root)
|
|
80
|
-
if self.git_root
|
|
81
|
-
else self.base.path
|
|
82
|
-
)
|
|
83
|
-
missing.append(f"base.tex (expected at: {expected_path})")
|
|
84
|
-
if not self.revision.path.exists():
|
|
85
|
-
expected_path = (
|
|
86
|
-
self.revision.path.relative_to(self.git_root)
|
|
87
|
-
if self.git_root
|
|
88
|
-
else self.revision.path
|
|
89
|
-
)
|
|
90
|
-
missing.append(f"revision.tex (expected at: {expected_path})")
|
|
91
|
-
|
|
92
|
-
return len(missing) == 0, missing
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
__all__ = ["RevisionTree"]
|
|
96
|
-
|
|
97
|
-
# EOF
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-28 17:16:00 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/tree/_ScriptsTree.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/tree/_ScriptsTree.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
ScriptsTree - dataclass for scripts directory structure.
|
|
15
|
-
|
|
16
|
-
Represents the scripts/ directory with compilation and helper scripts.
|
|
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 ScriptsTree:
|
|
28
|
-
"""Scripts directory structure (scripts/)."""
|
|
29
|
-
|
|
30
|
-
root: Path
|
|
31
|
-
git_root: Optional[Path] = None
|
|
32
|
-
|
|
33
|
-
# Subdirectories
|
|
34
|
-
examples: Path = None
|
|
35
|
-
installation: Path = None
|
|
36
|
-
powershell: Path = None
|
|
37
|
-
python: Path = None
|
|
38
|
-
shell: Path = None
|
|
39
|
-
|
|
40
|
-
# Shell compilation scripts
|
|
41
|
-
compile_manuscript: DocumentSection = None
|
|
42
|
-
compile_supplementary: DocumentSection = None
|
|
43
|
-
compile_revision: DocumentSection = None
|
|
44
|
-
watch_compile: DocumentSection = None
|
|
45
|
-
|
|
46
|
-
def __post_init__(self):
|
|
47
|
-
"""Initialize all Path and DocumentSection instances."""
|
|
48
|
-
if self.examples is None:
|
|
49
|
-
self.examples = self.root / "examples"
|
|
50
|
-
if self.installation is None:
|
|
51
|
-
self.installation = self.root / "installation"
|
|
52
|
-
if self.powershell is None:
|
|
53
|
-
self.powershell = self.root / "powershell"
|
|
54
|
-
if self.python is None:
|
|
55
|
-
self.python = self.root / "python"
|
|
56
|
-
if self.shell is None:
|
|
57
|
-
self.shell = self.root / "shell"
|
|
58
|
-
|
|
59
|
-
# Initialize compilation scripts
|
|
60
|
-
if self.compile_manuscript is None:
|
|
61
|
-
self.compile_manuscript = DocumentSection(
|
|
62
|
-
self.shell / "compile_manuscript.sh", self.git_root
|
|
63
|
-
)
|
|
64
|
-
if self.compile_supplementary is None:
|
|
65
|
-
self.compile_supplementary = DocumentSection(
|
|
66
|
-
self.shell / "compile_supplementary.sh", self.git_root
|
|
67
|
-
)
|
|
68
|
-
if self.compile_revision is None:
|
|
69
|
-
self.compile_revision = DocumentSection(
|
|
70
|
-
self.shell / "compile_revision.sh", self.git_root
|
|
71
|
-
)
|
|
72
|
-
if self.watch_compile is None:
|
|
73
|
-
self.watch_compile = DocumentSection(
|
|
74
|
-
self.shell / "watch_compile.sh", self.git_root
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
def verify_structure(self) -> tuple[bool, list[str]]:
|
|
78
|
-
"""
|
|
79
|
-
Verify scripts structure has required directories and scripts.
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
(is_valid, list_of_missing_items_with_paths)
|
|
83
|
-
"""
|
|
84
|
-
missing = []
|
|
85
|
-
|
|
86
|
-
# Check required directories
|
|
87
|
-
required_dirs = [
|
|
88
|
-
("python", self.python),
|
|
89
|
-
("shell", self.shell),
|
|
90
|
-
]
|
|
91
|
-
for name, path in required_dirs:
|
|
92
|
-
if not path.exists():
|
|
93
|
-
expected_path = (
|
|
94
|
-
path.relative_to(self.git_root) if self.git_root else path
|
|
95
|
-
)
|
|
96
|
-
missing.append(f"Missing {name}/ (expected at: {expected_path})")
|
|
97
|
-
|
|
98
|
-
# Check required compilation scripts
|
|
99
|
-
required_scripts = [
|
|
100
|
-
("compile_manuscript.sh", self.compile_manuscript),
|
|
101
|
-
("compile_supplementary.sh", self.compile_supplementary),
|
|
102
|
-
("compile_revision.sh", self.compile_revision),
|
|
103
|
-
]
|
|
104
|
-
for name, section in required_scripts:
|
|
105
|
-
if not section.path.exists():
|
|
106
|
-
expected_path = (
|
|
107
|
-
section.path.relative_to(self.git_root)
|
|
108
|
-
if self.git_root
|
|
109
|
-
else section.path
|
|
110
|
-
)
|
|
111
|
-
missing.append(f"Missing {name} (expected at: {expected_path})")
|
|
112
|
-
|
|
113
|
-
return len(missing) == 0, missing
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
__all__ = ["ScriptsTree"]
|
|
117
|
-
|
|
118
|
-
# EOF
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-29 06:13:09 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/types/tree/_SharedTree.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/types/tree/_SharedTree.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
SharedTree - dataclass for shared directory structure.
|
|
15
|
-
|
|
16
|
-
Represents the 00_shared/ directory with files used across documents.
|
|
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 SharedTree:
|
|
28
|
-
"""Shared directory structure (00_shared/)."""
|
|
29
|
-
|
|
30
|
-
root: Path
|
|
31
|
-
git_root: Optional[Path] = None
|
|
32
|
-
|
|
33
|
-
# Metadata files
|
|
34
|
-
authors: DocumentSection = None
|
|
35
|
-
title: DocumentSection = None
|
|
36
|
-
keywords: DocumentSection = None
|
|
37
|
-
journal_name: DocumentSection = None
|
|
38
|
-
|
|
39
|
-
# Directories
|
|
40
|
-
bib_files: Path = None
|
|
41
|
-
latex_styles: Path = None
|
|
42
|
-
templates: Path = None
|
|
43
|
-
|
|
44
|
-
# Bibliography
|
|
45
|
-
bibliography: DocumentSection = None
|
|
46
|
-
|
|
47
|
-
def __post_init__(self):
|
|
48
|
-
"""Initialize all DocumentSection and Path instances."""
|
|
49
|
-
if self.authors is None:
|
|
50
|
-
self.authors = DocumentSection(self.root / "authors.tex", self.git_root)
|
|
51
|
-
if self.title is None:
|
|
52
|
-
self.title = DocumentSection(self.root / "title.tex", self.git_root)
|
|
53
|
-
if self.keywords is None:
|
|
54
|
-
self.keywords = DocumentSection(self.root / "keywords.tex", self.git_root)
|
|
55
|
-
if self.journal_name is None:
|
|
56
|
-
self.journal_name = DocumentSection(
|
|
57
|
-
self.root / "journal_name.tex", self.git_root
|
|
58
|
-
)
|
|
59
|
-
if self.bibliography is None:
|
|
60
|
-
self.bibliography = DocumentSection(
|
|
61
|
-
self.root / "bib_files" / "bibliography.bib", self.git_root
|
|
62
|
-
)
|
|
63
|
-
if self.bib_files is None:
|
|
64
|
-
self.bib_files = self.root / "bib_files"
|
|
65
|
-
if self.latex_styles is None:
|
|
66
|
-
self.latex_styles = self.root / "latex_styles"
|
|
67
|
-
if self.templates is None:
|
|
68
|
-
self.templates = self.root / "templates"
|
|
69
|
-
|
|
70
|
-
def verify_structure(self) -> tuple[bool, list[str]]:
|
|
71
|
-
"""
|
|
72
|
-
Verify shared structure has required files.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
(is_valid, list_of_missing_files_with_paths)
|
|
76
|
-
"""
|
|
77
|
-
required = [
|
|
78
|
-
("authors.tex", self.authors),
|
|
79
|
-
("title.tex", self.title),
|
|
80
|
-
("keywords.tex", self.keywords),
|
|
81
|
-
("journal_name.tex", self.journal_name),
|
|
82
|
-
("bibliography.bib", self.bibliography),
|
|
83
|
-
]
|
|
84
|
-
|
|
85
|
-
missing = []
|
|
86
|
-
for name, section in required:
|
|
87
|
-
if not section.path.exists():
|
|
88
|
-
expected_path = (
|
|
89
|
-
section.path.relative_to(self.git_root)
|
|
90
|
-
if self.git_root
|
|
91
|
-
else section.path
|
|
92
|
-
)
|
|
93
|
-
missing.append(f"{name} (expected at: {expected_path})")
|
|
94
|
-
|
|
95
|
-
return len(missing) == 0, missing
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
__all__ = ["SharedTree"]
|
|
99
|
-
|
|
100
|
-
# EOF
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-28 17:16:00 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/tree/_SupplementaryTree.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/tree/_SupplementaryTree.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
SupplementaryTree - dataclass for supplementary directory structure.
|
|
15
|
-
|
|
16
|
-
Represents the 02_supplementary/ directory with all subdirectories.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from typing import Optional
|
|
21
|
-
from dataclasses import dataclass
|
|
22
|
-
|
|
23
|
-
from ..contents import SupplementaryContents
|
|
24
|
-
from ..core import DocumentSection
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclass
|
|
28
|
-
class SupplementaryTree:
|
|
29
|
-
"""Supplementary directory structure (02_supplementary/)."""
|
|
30
|
-
|
|
31
|
-
root: Path
|
|
32
|
-
git_root: Optional[Path] = None
|
|
33
|
-
|
|
34
|
-
# Contents subdirectory
|
|
35
|
-
contents: SupplementaryContents = None
|
|
36
|
-
|
|
37
|
-
# Root level files
|
|
38
|
-
base: DocumentSection = None
|
|
39
|
-
supplementary: DocumentSection = None
|
|
40
|
-
supplementary_diff: DocumentSection = None
|
|
41
|
-
readme: DocumentSection = None
|
|
42
|
-
|
|
43
|
-
# Directories
|
|
44
|
-
archive: Path = None
|
|
45
|
-
|
|
46
|
-
def __post_init__(self):
|
|
47
|
-
"""Initialize all instances."""
|
|
48
|
-
if self.contents is None:
|
|
49
|
-
self.contents = SupplementaryContents(self.root / "contents", self.git_root)
|
|
50
|
-
if self.base is None:
|
|
51
|
-
self.base = DocumentSection(self.root / "base.tex", self.git_root)
|
|
52
|
-
if self.supplementary is None:
|
|
53
|
-
self.supplementary = DocumentSection(
|
|
54
|
-
self.root / "supplementary.tex", self.git_root
|
|
55
|
-
)
|
|
56
|
-
if self.supplementary_diff is None:
|
|
57
|
-
self.supplementary_diff = DocumentSection(
|
|
58
|
-
self.root / "supplementary_diff.tex", self.git_root
|
|
59
|
-
)
|
|
60
|
-
if self.readme is None:
|
|
61
|
-
self.readme = DocumentSection(self.root / "README.md", self.git_root)
|
|
62
|
-
if self.archive is None:
|
|
63
|
-
self.archive = self.root / "archive"
|
|
64
|
-
|
|
65
|
-
def verify_structure(self) -> tuple[bool, list[str]]:
|
|
66
|
-
"""
|
|
67
|
-
Verify supplementary structure has required components.
|
|
68
|
-
|
|
69
|
-
Returns:
|
|
70
|
-
(is_valid, list_of_missing_items_with_paths)
|
|
71
|
-
"""
|
|
72
|
-
missing = []
|
|
73
|
-
|
|
74
|
-
# Check contents structure
|
|
75
|
-
contents_valid, contents_issues = self.contents.verify_structure()
|
|
76
|
-
if not contents_valid:
|
|
77
|
-
# Contents already includes full paths, just pass them through
|
|
78
|
-
missing.extend(contents_issues)
|
|
79
|
-
|
|
80
|
-
# Check root level files
|
|
81
|
-
if not self.base.path.exists():
|
|
82
|
-
expected_path = (
|
|
83
|
-
self.base.path.relative_to(self.git_root)
|
|
84
|
-
if self.git_root
|
|
85
|
-
else self.base.path
|
|
86
|
-
)
|
|
87
|
-
missing.append(f"base.tex (expected at: {expected_path})")
|
|
88
|
-
if not self.supplementary.path.exists():
|
|
89
|
-
expected_path = (
|
|
90
|
-
self.supplementary.path.relative_to(self.git_root)
|
|
91
|
-
if self.git_root
|
|
92
|
-
else self.supplementary.path
|
|
93
|
-
)
|
|
94
|
-
missing.append(f"supplementary.tex (expected at: {expected_path})")
|
|
95
|
-
|
|
96
|
-
return len(missing) == 0, missing
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
__all__ = ["SupplementaryTree"]
|
|
100
|
-
|
|
101
|
-
# EOF
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/tree/__init__.py
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
Tree dataclasses for Writer module (internal use).
|
|
7
|
-
|
|
8
|
-
Provides dataclasses for directory tree structures at the project level.
|
|
9
|
-
Not intended for public API - access trees through Writer class.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
# Import for internal use only
|
|
13
|
-
from ._ConfigTree import ConfigTree
|
|
14
|
-
from ._SharedTree import SharedTree
|
|
15
|
-
from ._ScriptsTree import ScriptsTree
|
|
16
|
-
from ._ManuscriptTree import ManuscriptTree
|
|
17
|
-
from ._SupplementaryTree import SupplementaryTree
|
|
18
|
-
from ._RevisionTree import RevisionTree
|
|
19
|
-
|
|
20
|
-
# Do not expose in __all__ - internal use only
|
|
21
|
-
__all__ = []
|
|
22
|
-
|
|
23
|
-
# EOF
|
scitex/writer/_mcp/__init__.py
DELETED
scitex/writer/_mcp/handlers.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2026-01-20
|
|
3
|
-
# File: src/scitex/writer/_mcp/handlers.py
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
MCP Handler for SciTeX Writer module.
|
|
7
|
-
|
|
8
|
-
Delegates to scitex-writer package for usage instructions.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async def writer_usage_handler() -> dict:
|
|
15
|
-
"""Get usage guide for SciTeX Writer."""
|
|
16
|
-
try:
|
|
17
|
-
from scitex_writer._server import INSTRUCTIONS
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
"success": True,
|
|
21
|
-
"instructions": INSTRUCTIONS,
|
|
22
|
-
}
|
|
23
|
-
except ImportError:
|
|
24
|
-
return {
|
|
25
|
-
"success": False,
|
|
26
|
-
"error": "scitex-writer is required. Install with: pip install scitex-writer",
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
__all__ = ["writer_usage_handler"]
|
|
31
|
-
|
|
32
|
-
# EOF
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2026-01-20
|
|
3
|
-
# File: src/scitex/writer/_mcp/tool_schemas.py
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
MCP Tool schemas for SciTeX Writer module.
|
|
7
|
-
|
|
8
|
-
Provides usage instructions for shell-based compilation workflow.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
|
|
13
|
-
import mcp.types as types
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def get_tool_schemas() -> list[types.Tool]:
|
|
17
|
-
"""Return list of available MCP tools for writer operations."""
|
|
18
|
-
return [
|
|
19
|
-
types.Tool(
|
|
20
|
-
name="writer_usage",
|
|
21
|
-
description="[writer] Get usage guide for SciTeX Writer LaTeX manuscript compilation system.",
|
|
22
|
-
inputSchema={
|
|
23
|
-
"type": "object",
|
|
24
|
-
"properties": {},
|
|
25
|
-
"required": [],
|
|
26
|
-
},
|
|
27
|
-
),
|
|
28
|
-
]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
__all__ = ["get_tool_schemas"]
|
|
32
|
-
|
|
33
|
-
# EOF
|