scitex 2.16.0__py3-none-any.whl → 2.16.2__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/scholar/url_finder/.tmp/open_url/KNOWN_RESOLVERS.py +462 -0
- scitex/scholar/url_finder/.tmp/open_url/README.md +223 -0
- scitex/scholar/url_finder/.tmp/open_url/_DOIToURLResolver.py +694 -0
- scitex/scholar/url_finder/.tmp/open_url/_OpenURLResolver.py +1160 -0
- scitex/scholar/url_finder/.tmp/open_url/_ResolverLinkFinder.py +344 -0
- scitex/scholar/url_finder/.tmp/open_url/__init__.py +24 -0
- 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.2.dist-info}/METADATA +6 -1
- {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/RECORD +21 -93
- scitex/dev/plt/data/mpl/PLOTTING_FUNCTIONS.yaml +0 -90
- scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES.yaml +0 -1571
- scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES_DETAILED.yaml +0 -6262
- scitex/dev/plt/data/mpl/SIGNATURES_FLATTENED.yaml +0 -1274
- scitex/dev/plt/data/mpl/dir_ax.txt +0 -459
- scitex/scholar/data/.gitkeep +0 -0
- scitex/scholar/data/README.md +0 -44
- scitex/scholar/data/bib_files/bibliography.bib +0 -1952
- scitex/scholar/data/bib_files/neurovista.bib +0 -277
- scitex/scholar/data/bib_files/neurovista_enriched.bib +0 -441
- scitex/scholar/data/bib_files/neurovista_enriched_enriched.bib +0 -441
- scitex/scholar/data/bib_files/neurovista_processed.bib +0 -338
- scitex/scholar/data/bib_files/openaccess.bib +0 -89
- scitex/scholar/data/bib_files/pac-seizure_prediction_enriched.bib +0 -2178
- scitex/scholar/data/bib_files/pac.bib +0 -698
- scitex/scholar/data/bib_files/pac_enriched.bib +0 -1061
- scitex/scholar/data/bib_files/pac_processed.bib +0 -0
- scitex/scholar/data/bib_files/pac_titles.txt +0 -75
- scitex/scholar/data/bib_files/paywalled.bib +0 -98
- scitex/scholar/data/bib_files/related-papers-by-coauthors.bib +0 -58
- scitex/scholar/data/bib_files/related-papers-by-coauthors_enriched.bib +0 -87
- scitex/scholar/data/bib_files/seizure_prediction.bib +0 -694
- scitex/scholar/data/bib_files/seizure_prediction_processed.bib +0 -0
- scitex/scholar/data/bib_files/test_complete_enriched.bib +0 -437
- scitex/scholar/data/bib_files/test_final_enriched.bib +0 -437
- scitex/scholar/data/bib_files/test_seizure.bib +0 -46
- scitex/scholar/data/impact_factor/JCR_IF_2022.xlsx +0 -0
- scitex/scholar/data/impact_factor/JCR_IF_2024.db +0 -0
- scitex/scholar/data/impact_factor/JCR_IF_2024.xlsx +0 -0
- scitex/scholar/data/impact_factor/JCR_IF_2024_v01.db +0 -0
- scitex/scholar/data/impact_factor.db +0 -0
- 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.2.dist-info}/WHEEL +0 -0
- {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/entry_points.txt +0 -0
- {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-29 06:08:35 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_CompilationResult.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/_CompilationResult.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
CompilationResult - dataclass for LaTeX compilation results.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from dataclasses import dataclass
|
|
18
|
-
from dataclasses import field
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from typing import Optional
|
|
21
|
-
from typing import List
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@dataclass
|
|
25
|
-
class CompilationResult:
|
|
26
|
-
"""Result of LaTeX compilation."""
|
|
27
|
-
|
|
28
|
-
success: bool
|
|
29
|
-
"""Whether compilation succeeded (exit code 0)"""
|
|
30
|
-
|
|
31
|
-
exit_code: int
|
|
32
|
-
"""Process exit code"""
|
|
33
|
-
|
|
34
|
-
stdout: str
|
|
35
|
-
"""Standard output from compilation"""
|
|
36
|
-
|
|
37
|
-
stderr: str
|
|
38
|
-
"""Standard error from compilation"""
|
|
39
|
-
|
|
40
|
-
output_pdf: Optional[Path] = None
|
|
41
|
-
"""Path to generated PDF (if successful)"""
|
|
42
|
-
|
|
43
|
-
diff_pdf: Optional[Path] = None
|
|
44
|
-
"""Path to diff PDF with tracked changes (if generated)"""
|
|
45
|
-
|
|
46
|
-
log_file: Optional[Path] = None
|
|
47
|
-
"""Path to compilation log file"""
|
|
48
|
-
|
|
49
|
-
duration: float = 0.0
|
|
50
|
-
"""Compilation duration in seconds"""
|
|
51
|
-
|
|
52
|
-
errors: List[str] = field(default_factory=list)
|
|
53
|
-
"""Parsed LaTeX errors (if any)"""
|
|
54
|
-
|
|
55
|
-
warnings: List[str] = field(default_factory=list)
|
|
56
|
-
"""Parsed LaTeX warnings (if any)"""
|
|
57
|
-
|
|
58
|
-
def __str__(self):
|
|
59
|
-
"""Human-readable summary."""
|
|
60
|
-
status = "SUCCESS" if self.success else "FAILED"
|
|
61
|
-
lines = [
|
|
62
|
-
f"Compilation {status} (exit code: {self.exit_code})",
|
|
63
|
-
f"Duration: {self.duration:.2f}s",
|
|
64
|
-
]
|
|
65
|
-
if self.output_pdf:
|
|
66
|
-
lines.append(f"Output: {self.output_pdf}")
|
|
67
|
-
if self.errors:
|
|
68
|
-
lines.append(f"Errors: {len(self.errors)}")
|
|
69
|
-
if self.warnings:
|
|
70
|
-
lines.append(f"Warnings: {len(self.warnings)}")
|
|
71
|
-
return "\n".join(lines)
|
|
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
|
-
result = CompilationResult(
|
|
106
|
-
success=args.success,
|
|
107
|
-
exit_code=args.exit_code,
|
|
108
|
-
stdout="Sample stdout",
|
|
109
|
-
stderr="Sample stderr" if not args.success else "",
|
|
110
|
-
output_pdf=Path(args.pdf) if args.pdf else None,
|
|
111
|
-
duration=args.duration,
|
|
112
|
-
errors=["Error 1", "Error 2"] if not args.success else [],
|
|
113
|
-
warnings=["Warning 1"] if args.warnings else [],
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
print(result)
|
|
117
|
-
return 0
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def parse_args():
|
|
121
|
-
import argparse
|
|
122
|
-
|
|
123
|
-
parser = argparse.ArgumentParser(
|
|
124
|
-
description="Demonstrate CompilationResult dataclass"
|
|
125
|
-
)
|
|
126
|
-
parser.add_argument(
|
|
127
|
-
"--success",
|
|
128
|
-
action="store_true",
|
|
129
|
-
help="Simulate successful compilation",
|
|
130
|
-
)
|
|
131
|
-
parser.add_argument(
|
|
132
|
-
"--exit-code",
|
|
133
|
-
type=int,
|
|
134
|
-
default=1,
|
|
135
|
-
help="Exit code (default: 1)",
|
|
136
|
-
)
|
|
137
|
-
parser.add_argument(
|
|
138
|
-
"--pdf",
|
|
139
|
-
type=str,
|
|
140
|
-
help="Output PDF path",
|
|
141
|
-
)
|
|
142
|
-
parser.add_argument(
|
|
143
|
-
"--duration",
|
|
144
|
-
type=float,
|
|
145
|
-
default=5.0,
|
|
146
|
-
help="Compilation duration in seconds (default: 5.0)",
|
|
147
|
-
)
|
|
148
|
-
parser.add_argument(
|
|
149
|
-
"--warnings",
|
|
150
|
-
action="store_true",
|
|
151
|
-
help="Include warnings",
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
return parser.parse_args()
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if __name__ == "__main__":
|
|
158
|
-
run_session()
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
__all__ = ["CompilationResult"]
|
|
162
|
-
|
|
163
|
-
# python -m scitex.writer._dataclasses.results._CompilationResult --success --pdf ./manuscript.pdf --duration 10.5
|
|
164
|
-
|
|
165
|
-
# EOF
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-10-29 06:08:41 (ywatanabe)"
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_LaTeXIssue.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/writer/dataclasses/_LaTeXIssue.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
LaTeXIssue - dataclass for LaTeX compilation issues.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from dataclasses import dataclass
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@dataclass
|
|
21
|
-
class LaTeXIssue:
|
|
22
|
-
"""Single LaTeX error or warning."""
|
|
23
|
-
|
|
24
|
-
type: str # 'error' or 'warning'
|
|
25
|
-
message: str
|
|
26
|
-
|
|
27
|
-
def __str__(self) -> str:
|
|
28
|
-
"""Human-readable string representation."""
|
|
29
|
-
return f"{self.type.upper()}: {self.message}"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def run_session() -> None:
|
|
33
|
-
"""Initialize scitex framework, run main function, and cleanup."""
|
|
34
|
-
global CONFIG, CC, sys, plt, rng
|
|
35
|
-
import sys
|
|
36
|
-
import matplotlib.pyplot as plt
|
|
37
|
-
import scitex as stx
|
|
38
|
-
|
|
39
|
-
args = parse_args()
|
|
40
|
-
|
|
41
|
-
CONFIG, sys.stdout, sys.stderr, plt, CC, rng = stx.session.start(
|
|
42
|
-
sys,
|
|
43
|
-
plt,
|
|
44
|
-
args=args,
|
|
45
|
-
file=__FILE__,
|
|
46
|
-
sdir_suffix=None,
|
|
47
|
-
verbose=False,
|
|
48
|
-
agg=True,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
exit_status = main(args)
|
|
52
|
-
|
|
53
|
-
stx.session.close(
|
|
54
|
-
CONFIG,
|
|
55
|
-
verbose=False,
|
|
56
|
-
notify=False,
|
|
57
|
-
message="",
|
|
58
|
-
exit_status=exit_status,
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def main(args):
|
|
63
|
-
issue = LaTeXIssue(
|
|
64
|
-
type=args.type,
|
|
65
|
-
message=args.message,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
print(issue)
|
|
69
|
-
print(f"\nFormatted: {issue}")
|
|
70
|
-
return 0
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def parse_args():
|
|
74
|
-
import argparse
|
|
75
|
-
|
|
76
|
-
parser = argparse.ArgumentParser(description="Demonstrate LaTeXIssue dataclass")
|
|
77
|
-
parser.add_argument(
|
|
78
|
-
"--type",
|
|
79
|
-
type=str,
|
|
80
|
-
default="error",
|
|
81
|
-
choices=["error", "warning"],
|
|
82
|
-
help="Issue type (default: error)",
|
|
83
|
-
)
|
|
84
|
-
parser.add_argument(
|
|
85
|
-
"--message",
|
|
86
|
-
type=str,
|
|
87
|
-
default="Undefined control sequence",
|
|
88
|
-
help="Issue message (default: 'Undefined control sequence')",
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
return parser.parse_args()
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if __name__ == "__main__":
|
|
95
|
-
run_session()
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
__all__ = ["LaTeXIssue"]
|
|
99
|
-
|
|
100
|
-
# python -m scitex.writer._dataclasses.results._LaTeXIssue --type warning --message "Citation not found"
|
|
101
|
-
|
|
102
|
-
# EOF
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/results/_SaveSectionsResponse.py
|
|
4
|
-
# ----------------------------------------
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
import os
|
|
7
|
-
|
|
8
|
-
__FILE__ = "./src/scitex/writer/dataclasses/results/_SaveSectionsResponse.py"
|
|
9
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
-
# ----------------------------------------
|
|
11
|
-
|
|
12
|
-
"""
|
|
13
|
-
SaveSectionsResponse - dataclass for section save operation results.
|
|
14
|
-
Ensures type safety and prevents silent failures.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from dataclasses import dataclass, field
|
|
18
|
-
from typing import List, Dict, Optional
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@dataclass
|
|
22
|
-
class SaveSectionsResponse:
|
|
23
|
-
"""Result of saving multiple sections."""
|
|
24
|
-
|
|
25
|
-
success: bool
|
|
26
|
-
"""Whether the save operation succeeded"""
|
|
27
|
-
|
|
28
|
-
sections_saved: int
|
|
29
|
-
"""Number of sections successfully saved"""
|
|
30
|
-
|
|
31
|
-
sections_skipped: int = 0
|
|
32
|
-
"""Number of sections skipped or failed"""
|
|
33
|
-
|
|
34
|
-
message: str = ""
|
|
35
|
-
"""Human-readable status message"""
|
|
36
|
-
|
|
37
|
-
errors: List[str] = field(default_factory=list)
|
|
38
|
-
"""List of error messages (if any)"""
|
|
39
|
-
|
|
40
|
-
error_details: Dict[str, str] = field(default_factory=dict)
|
|
41
|
-
"""Detailed errors per section: {section_id: error_message}"""
|
|
42
|
-
|
|
43
|
-
def to_dict(self) -> dict:
|
|
44
|
-
"""Convert to dictionary for JSON serialization."""
|
|
45
|
-
return {
|
|
46
|
-
"success": self.success,
|
|
47
|
-
"sections_saved": self.sections_saved,
|
|
48
|
-
"sections_skipped": self.sections_skipped,
|
|
49
|
-
"message": self.message,
|
|
50
|
-
"errors": self.errors,
|
|
51
|
-
"error_details": self.error_details,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
def __str__(self):
|
|
55
|
-
"""Human-readable summary."""
|
|
56
|
-
status = "SUCCESS" if self.success else "FAILED"
|
|
57
|
-
lines = [
|
|
58
|
-
f"Save {status}: {self.sections_saved} saved, {self.sections_skipped} skipped",
|
|
59
|
-
]
|
|
60
|
-
if self.message:
|
|
61
|
-
lines.append(f"Message: {self.message}")
|
|
62
|
-
if self.errors:
|
|
63
|
-
lines.append(f"Errors: {len(self.errors)}")
|
|
64
|
-
for error in self.errors[:3]: # Show first 3 errors
|
|
65
|
-
lines.append(f" - {error}")
|
|
66
|
-
return "\n".join(lines)
|
|
67
|
-
|
|
68
|
-
@classmethod
|
|
69
|
-
def create_success(
|
|
70
|
-
cls, sections_saved: int, message: str = ""
|
|
71
|
-
) -> SaveSectionsResponse:
|
|
72
|
-
"""Create a successful response."""
|
|
73
|
-
return cls(
|
|
74
|
-
success=True,
|
|
75
|
-
sections_saved=sections_saved,
|
|
76
|
-
sections_skipped=0,
|
|
77
|
-
message=message or f"Saved {sections_saved} sections",
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
@classmethod
|
|
81
|
-
def create_failure(
|
|
82
|
-
cls, error_message: str, errors: List[str] = None, sections_saved: int = 0
|
|
83
|
-
) -> SaveSectionsResponse:
|
|
84
|
-
"""Create a failed response."""
|
|
85
|
-
return cls(
|
|
86
|
-
success=False,
|
|
87
|
-
sections_saved=sections_saved,
|
|
88
|
-
sections_skipped=len(errors) if errors else 0,
|
|
89
|
-
message=error_message,
|
|
90
|
-
errors=errors or [error_message],
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
def validate(self) -> None:
|
|
94
|
-
"""Validate response data - raises ValueError if invalid."""
|
|
95
|
-
if self.success and self.sections_saved == 0:
|
|
96
|
-
raise ValueError(
|
|
97
|
-
"SaveSectionsResponse marked as success but no sections were saved"
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
if not self.success and not self.errors:
|
|
101
|
-
raise ValueError(
|
|
102
|
-
"SaveSectionsResponse marked as failed but no errors provided"
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
if self.sections_saved < 0:
|
|
106
|
-
raise ValueError(
|
|
107
|
-
f"Invalid sections_saved: {self.sections_saved} (must be >= 0)"
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
if self.sections_skipped < 0:
|
|
111
|
-
raise ValueError(
|
|
112
|
-
f"Invalid sections_skipped: {self.sections_skipped} (must be >= 0)"
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
__all__ = ["SaveSectionsResponse"]
|
|
117
|
-
|
|
118
|
-
# EOF
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/results/_SectionReadResponse.py
|
|
4
|
-
# ----------------------------------------
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
import os
|
|
7
|
-
|
|
8
|
-
__FILE__ = "./src/scitex/writer/dataclasses/results/_SectionReadResponse.py"
|
|
9
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
-
# ----------------------------------------
|
|
11
|
-
|
|
12
|
-
"""
|
|
13
|
-
SectionReadResponse - dataclass for section read operation results.
|
|
14
|
-
Ensures type safety and prevents silent failures.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from dataclasses import dataclass
|
|
18
|
-
from typing import Optional
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class SectionReadResponse:
|
|
24
|
-
"""Result of reading a section."""
|
|
25
|
-
|
|
26
|
-
success: bool
|
|
27
|
-
"""Whether the read operation succeeded"""
|
|
28
|
-
|
|
29
|
-
content: str
|
|
30
|
-
"""Section content (LaTeX code)"""
|
|
31
|
-
|
|
32
|
-
section_name: str
|
|
33
|
-
"""Section name (e.g., 'abstract', 'introduction')"""
|
|
34
|
-
|
|
35
|
-
section_id: str
|
|
36
|
-
"""Full hierarchical section ID (e.g., 'manuscript/abstract')"""
|
|
37
|
-
|
|
38
|
-
doc_type: str
|
|
39
|
-
"""Document type: 'manuscript', 'supplementary', 'revision', or 'shared'"""
|
|
40
|
-
|
|
41
|
-
file_path: Optional[Path] = None
|
|
42
|
-
"""Absolute path to the section .tex file"""
|
|
43
|
-
|
|
44
|
-
error: Optional[str] = None
|
|
45
|
-
"""Error message if read failed"""
|
|
46
|
-
|
|
47
|
-
def to_dict(self) -> dict:
|
|
48
|
-
"""Convert to dictionary for JSON serialization."""
|
|
49
|
-
return {
|
|
50
|
-
"success": self.success,
|
|
51
|
-
"content": self.content,
|
|
52
|
-
"section_name": self.section_name,
|
|
53
|
-
"section_id": self.section_id,
|
|
54
|
-
"doc_type": self.doc_type,
|
|
55
|
-
"file_path": str(self.file_path) if self.file_path else None,
|
|
56
|
-
"error": self.error,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
def __str__(self):
|
|
60
|
-
"""Human-readable summary."""
|
|
61
|
-
if self.success:
|
|
62
|
-
return f"Read {self.section_id}: {len(self.content)} chars"
|
|
63
|
-
else:
|
|
64
|
-
return f"Failed to read {self.section_id}: {self.error}"
|
|
65
|
-
|
|
66
|
-
@classmethod
|
|
67
|
-
def create_success(
|
|
68
|
-
cls,
|
|
69
|
-
content: str,
|
|
70
|
-
section_name: str,
|
|
71
|
-
section_id: str,
|
|
72
|
-
doc_type: str,
|
|
73
|
-
file_path: Optional[Path] = None,
|
|
74
|
-
) -> SectionReadResponse:
|
|
75
|
-
"""Create a successful response."""
|
|
76
|
-
return cls(
|
|
77
|
-
success=True,
|
|
78
|
-
content=content,
|
|
79
|
-
section_name=section_name,
|
|
80
|
-
section_id=section_id,
|
|
81
|
-
doc_type=doc_type,
|
|
82
|
-
file_path=file_path,
|
|
83
|
-
error=None,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
@classmethod
|
|
87
|
-
def create_failure(cls, section_id: str, error_message: str) -> SectionReadResponse:
|
|
88
|
-
"""Create a failed response."""
|
|
89
|
-
parts = section_id.split("/")
|
|
90
|
-
doc_type = parts[0] if len(parts) > 1 else "manuscript"
|
|
91
|
-
section_name = parts[1] if len(parts) > 1 else section_id
|
|
92
|
-
|
|
93
|
-
return cls(
|
|
94
|
-
success=False,
|
|
95
|
-
content="",
|
|
96
|
-
section_name=section_name,
|
|
97
|
-
section_id=section_id,
|
|
98
|
-
doc_type=doc_type,
|
|
99
|
-
file_path=None,
|
|
100
|
-
error=error_message,
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
def validate(self) -> None:
|
|
104
|
-
"""Validate response data - raises ValueError if invalid."""
|
|
105
|
-
if (
|
|
106
|
-
self.success
|
|
107
|
-
and not self.content
|
|
108
|
-
and self.section_name not in ["compiled_pdf", "compiled_tex"]
|
|
109
|
-
):
|
|
110
|
-
raise ValueError(
|
|
111
|
-
f"SectionReadResponse marked as success but content is empty for {self.section_id}"
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
if not self.success and not self.error:
|
|
115
|
-
raise ValueError(
|
|
116
|
-
f"SectionReadResponse marked as failed but no error message for {self.section_id}"
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
if not self.section_name:
|
|
120
|
-
raise ValueError("section_name cannot be empty")
|
|
121
|
-
|
|
122
|
-
if not self.section_id:
|
|
123
|
-
raise ValueError("section_id cannot be empty")
|
|
124
|
-
|
|
125
|
-
if self.doc_type not in ["manuscript", "supplementary", "revision", "shared"]:
|
|
126
|
-
raise ValueError(f"Invalid doc_type: {self.doc_type}")
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
__all__ = ["SectionReadResponse"]
|
|
130
|
-
|
|
131
|
-
# EOF
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from ._CompilationResult import CompilationResult
|
|
2
|
-
from ._LaTeXIssue import LaTeXIssue
|
|
3
|
-
from ._SaveSectionsResponse import SaveSectionsResponse
|
|
4
|
-
from ._SectionReadResponse import SectionReadResponse
|
|
5
|
-
|
|
6
|
-
__all__ = [
|
|
7
|
-
"CompilationResult",
|
|
8
|
-
"LaTeXIssue",
|
|
9
|
-
"SaveSectionsResponse",
|
|
10
|
-
"SectionReadResponse",
|
|
11
|
-
]
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
<!-- ---
|
|
2
|
-
!-- Timestamp: 2025-10-28 16:37:52
|
|
3
|
-
!-- Author: ywatanabe
|
|
4
|
-
!-- File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/necessary_structure.md
|
|
5
|
-
!-- --- -->
|
|
6
|
-
|
|
7
|
-
test-writer-project/
|
|
8
|
-
├── 01_manuscript
|
|
9
|
-
│ ├── archive
|
|
10
|
-
│ ├── base.tex
|
|
11
|
-
│ ├── contents
|
|
12
|
-
│ │ ├── abstract.tex
|
|
13
|
-
│ │ ├── additional_info.tex
|
|
14
|
-
│ │ ├── authors.tex
|
|
15
|
-
│ │ ├── bibliography.bib
|
|
16
|
-
│ │ ├── data_availability.tex
|
|
17
|
-
│ │ ├── discussion.tex
|
|
18
|
-
│ │ ├── figures
|
|
19
|
-
│ │ ├── graphical_abstract.tex
|
|
20
|
-
│ │ ├── highlights.tex
|
|
21
|
-
│ │ ├── introduction.tex
|
|
22
|
-
│ │ ├── journal_name.tex
|
|
23
|
-
│ │ ├── keywords.tex
|
|
24
|
-
│ │ ├── latex_styles
|
|
25
|
-
│ │ ├── methods.tex
|
|
26
|
-
│ │ ├── results.tex
|
|
27
|
-
│ │ ├── tables
|
|
28
|
-
│ │ ├── title.tex
|
|
29
|
-
│ │ └── wordcount.tex
|
|
30
|
-
│ └── README.md
|
|
31
|
-
├── 02_supplementary
|
|
32
|
-
│ ├── archive
|
|
33
|
-
│ ├── base.tex
|
|
34
|
-
│ ├── contents
|
|
35
|
-
│ │ ├── authors.tex
|
|
36
|
-
│ │ ├── bibliography.bib
|
|
37
|
-
│ │ ├── figures
|
|
38
|
-
│ │ ├── journal_name.tex
|
|
39
|
-
│ │ ├── keywords.tex
|
|
40
|
-
│ │ ├── latex_styles
|
|
41
|
-
│ │ ├── methods.tex
|
|
42
|
-
│ │ ├── results.tex
|
|
43
|
-
│ │ ├── tables
|
|
44
|
-
│ │ ├── title.tex
|
|
45
|
-
│ │ └── wordcount.tex
|
|
46
|
-
│ ├── README.md
|
|
47
|
-
│ ├── supplementary_diff.tex
|
|
48
|
-
│ └── supplementary.tex
|
|
49
|
-
├── 03_revision
|
|
50
|
-
│ ├── archive
|
|
51
|
-
│ ├── base.tex
|
|
52
|
-
│ ├── contents
|
|
53
|
-
│ │ ├── authors.tex
|
|
54
|
-
│ │ ├── bibliography.bib
|
|
55
|
-
│ │ ├── conclusion.tex
|
|
56
|
-
│ │ ├── editor
|
|
57
|
-
│ │ ├── figures
|
|
58
|
-
│ │ ├── introduction.tex
|
|
59
|
-
│ │ ├── journal_name.tex
|
|
60
|
-
│ │ ├── keywords.tex
|
|
61
|
-
│ │ ├── latex_styles
|
|
62
|
-
│ │ ├── README.md
|
|
63
|
-
│ │ ├── references.tex
|
|
64
|
-
│ │ ├── reviewer1
|
|
65
|
-
│ │ ├── reviewer2
|
|
66
|
-
│ │ ├── tables
|
|
67
|
-
│ │ └── title.tex
|
|
68
|
-
│ ├── docs
|
|
69
|
-
│ │ └── email.md
|
|
70
|
-
│ ├── README.md
|
|
71
|
-
│ └── revision.tex
|
|
72
|
-
├── compile
|
|
73
|
-
├── config
|
|
74
|
-
│ ├── config_manuscript.yaml
|
|
75
|
-
│ ├── config_revision.yaml
|
|
76
|
-
│ ├── config_supplementary.yaml
|
|
77
|
-
│ └── load_config.sh
|
|
78
|
-
├── Makefile
|
|
79
|
-
├── README.md
|
|
80
|
-
├── scripts
|
|
81
|
-
│ ├── examples
|
|
82
|
-
│ │ └── link_project_assets.sh
|
|
83
|
-
│ ├── installation
|
|
84
|
-
│ │ ├── check_requirements.sh
|
|
85
|
-
│ │ ├── download_containers.sh
|
|
86
|
-
│ │ └── install_on_ubuntu.sh
|
|
87
|
-
│ ├── powershell
|
|
88
|
-
│ │ └── pptx2tiff.ps1
|
|
89
|
-
│ ├── python
|
|
90
|
-
│ │ ├── crop_tif.py
|
|
91
|
-
│ │ ├── csv2latex.py
|
|
92
|
-
│ │ ├── explore_bibtex.py
|
|
93
|
-
│ │ ├── generate_ai2_prompt.py
|
|
94
|
-
│ │ ├── optimize_figure.py
|
|
95
|
-
│ │ ├── pptx2tif.py
|
|
96
|
-
│ │ └── tile_panels.py
|
|
97
|
-
│ └── shell
|
|
98
|
-
│ ├── compile_manuscript.sh
|
|
99
|
-
│ ├── compile_revision.sh
|
|
100
|
-
│ ├── compile_supplementary.sh
|
|
101
|
-
│ ├── modules
|
|
102
|
-
│ └── watch_compile.sh
|
|
103
|
-
├── shared
|
|
104
|
-
│ ├── authors.tex
|
|
105
|
-
│ ├── bib_files
|
|
106
|
-
│ │ ├── bibliography.bib
|
|
107
|
-
│ ├── bibliography.bib
|
|
108
|
-
│ ├── journal_name.tex
|
|
109
|
-
│ ├── keywords.tex
|
|
110
|
-
│ ├── latex_styles
|
|
111
|
-
│ │ ├── bibliography.tex
|
|
112
|
-
│ │ ├── columns.tex
|
|
113
|
-
│ │ ├── formatting.tex
|
|
114
|
-
│ │ ├── linker.tex
|
|
115
|
-
│ │ └── packages.tex
|
|
116
|
-
│ ├── README.md
|
|
117
|
-
│ ├── templates
|
|
118
|
-
│ │ └── tables
|
|
119
|
-
│ └── title.tex
|
|
120
|
-
|
|
121
|
-
<!-- EOF -->
|