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.
Files changed (101) 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/scholar/url_finder/.tmp/open_url/KNOWN_RESOLVERS.py +462 -0
  9. scitex/scholar/url_finder/.tmp/open_url/README.md +223 -0
  10. scitex/scholar/url_finder/.tmp/open_url/_DOIToURLResolver.py +694 -0
  11. scitex/scholar/url_finder/.tmp/open_url/_OpenURLResolver.py +1160 -0
  12. scitex/scholar/url_finder/.tmp/open_url/_ResolverLinkFinder.py +344 -0
  13. scitex/scholar/url_finder/.tmp/open_url/__init__.py +24 -0
  14. scitex/social/__init__.py +1 -24
  15. scitex/writer/README.md +25 -409
  16. scitex/writer/__init__.py +98 -13
  17. {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/METADATA +6 -1
  18. {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/RECORD +21 -93
  19. scitex/dev/plt/data/mpl/PLOTTING_FUNCTIONS.yaml +0 -90
  20. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES.yaml +0 -1571
  21. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES_DETAILED.yaml +0 -6262
  22. scitex/dev/plt/data/mpl/SIGNATURES_FLATTENED.yaml +0 -1274
  23. scitex/dev/plt/data/mpl/dir_ax.txt +0 -459
  24. scitex/scholar/data/.gitkeep +0 -0
  25. scitex/scholar/data/README.md +0 -44
  26. scitex/scholar/data/bib_files/bibliography.bib +0 -1952
  27. scitex/scholar/data/bib_files/neurovista.bib +0 -277
  28. scitex/scholar/data/bib_files/neurovista_enriched.bib +0 -441
  29. scitex/scholar/data/bib_files/neurovista_enriched_enriched.bib +0 -441
  30. scitex/scholar/data/bib_files/neurovista_processed.bib +0 -338
  31. scitex/scholar/data/bib_files/openaccess.bib +0 -89
  32. scitex/scholar/data/bib_files/pac-seizure_prediction_enriched.bib +0 -2178
  33. scitex/scholar/data/bib_files/pac.bib +0 -698
  34. scitex/scholar/data/bib_files/pac_enriched.bib +0 -1061
  35. scitex/scholar/data/bib_files/pac_processed.bib +0 -0
  36. scitex/scholar/data/bib_files/pac_titles.txt +0 -75
  37. scitex/scholar/data/bib_files/paywalled.bib +0 -98
  38. scitex/scholar/data/bib_files/related-papers-by-coauthors.bib +0 -58
  39. scitex/scholar/data/bib_files/related-papers-by-coauthors_enriched.bib +0 -87
  40. scitex/scholar/data/bib_files/seizure_prediction.bib +0 -694
  41. scitex/scholar/data/bib_files/seizure_prediction_processed.bib +0 -0
  42. scitex/scholar/data/bib_files/test_complete_enriched.bib +0 -437
  43. scitex/scholar/data/bib_files/test_final_enriched.bib +0 -437
  44. scitex/scholar/data/bib_files/test_seizure.bib +0 -46
  45. scitex/scholar/data/impact_factor/JCR_IF_2022.xlsx +0 -0
  46. scitex/scholar/data/impact_factor/JCR_IF_2024.db +0 -0
  47. scitex/scholar/data/impact_factor/JCR_IF_2024.xlsx +0 -0
  48. scitex/scholar/data/impact_factor/JCR_IF_2024_v01.db +0 -0
  49. scitex/scholar/data/impact_factor.db +0 -0
  50. scitex/writer/Writer.py +0 -487
  51. scitex/writer/_clone_writer_project.py +0 -160
  52. scitex/writer/_compile/__init__.py +0 -41
  53. scitex/writer/_compile/_compile_async.py +0 -130
  54. scitex/writer/_compile/_compile_unified.py +0 -148
  55. scitex/writer/_compile/_parser.py +0 -63
  56. scitex/writer/_compile/_runner.py +0 -457
  57. scitex/writer/_compile/_validator.py +0 -46
  58. scitex/writer/_compile/manuscript.py +0 -110
  59. scitex/writer/_compile/revision.py +0 -82
  60. scitex/writer/_compile/supplementary.py +0 -100
  61. scitex/writer/_dataclasses/__init__.py +0 -44
  62. scitex/writer/_dataclasses/config/_CONSTANTS.py +0 -46
  63. scitex/writer/_dataclasses/config/_WriterConfig.py +0 -175
  64. scitex/writer/_dataclasses/config/__init__.py +0 -9
  65. scitex/writer/_dataclasses/contents/_ManuscriptContents.py +0 -236
  66. scitex/writer/_dataclasses/contents/_RevisionContents.py +0 -136
  67. scitex/writer/_dataclasses/contents/_SupplementaryContents.py +0 -114
  68. scitex/writer/_dataclasses/contents/__init__.py +0 -9
  69. scitex/writer/_dataclasses/core/_Document.py +0 -146
  70. scitex/writer/_dataclasses/core/_DocumentSection.py +0 -546
  71. scitex/writer/_dataclasses/core/__init__.py +0 -7
  72. scitex/writer/_dataclasses/results/_CompilationResult.py +0 -165
  73. scitex/writer/_dataclasses/results/_LaTeXIssue.py +0 -102
  74. scitex/writer/_dataclasses/results/_SaveSectionsResponse.py +0 -118
  75. scitex/writer/_dataclasses/results/_SectionReadResponse.py +0 -131
  76. scitex/writer/_dataclasses/results/__init__.py +0 -11
  77. scitex/writer/_dataclasses/tree/MINIMUM_FILES.md +0 -121
  78. scitex/writer/_dataclasses/tree/_ConfigTree.py +0 -86
  79. scitex/writer/_dataclasses/tree/_ManuscriptTree.py +0 -84
  80. scitex/writer/_dataclasses/tree/_RevisionTree.py +0 -97
  81. scitex/writer/_dataclasses/tree/_ScriptsTree.py +0 -118
  82. scitex/writer/_dataclasses/tree/_SharedTree.py +0 -100
  83. scitex/writer/_dataclasses/tree/_SupplementaryTree.py +0 -101
  84. scitex/writer/_dataclasses/tree/__init__.py +0 -23
  85. scitex/writer/_mcp/__init__.py +0 -4
  86. scitex/writer/_mcp/handlers.py +0 -32
  87. scitex/writer/_mcp/tool_schemas.py +0 -33
  88. scitex/writer/_project/__init__.py +0 -29
  89. scitex/writer/_project/_create.py +0 -89
  90. scitex/writer/_project/_trees.py +0 -63
  91. scitex/writer/_project/_validate.py +0 -61
  92. scitex/writer/utils/.legacy_git_retry.py +0 -164
  93. scitex/writer/utils/__init__.py +0 -24
  94. scitex/writer/utils/_converters.py +0 -635
  95. scitex/writer/utils/_parse_latex_logs.py +0 -138
  96. scitex/writer/utils/_parse_script_args.py +0 -156
  97. scitex/writer/utils/_verify_tree_structure.py +0 -205
  98. scitex/writer/utils/_watch.py +0 -96
  99. {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/WHEEL +0 -0
  100. {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/entry_points.txt +0 -0
  101. {scitex-2.16.0.dist-info → scitex-2.16.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-11-08 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/_compile/supplementary.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/_compile/supplementary.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- Supplementary materials compilation function.
15
-
16
- Provides supplementary-specific compilation with options for:
17
- - Figure inclusion (default)
18
- - PowerPoint to TIF conversion
19
- - TIF cropping
20
- - Quiet mode
21
- """
22
-
23
- from pathlib import Path
24
- from typing import Optional, Callable
25
- from ._runner import run_compile
26
- from .._dataclasses import CompilationResult
27
-
28
-
29
- def compile_supplementary(
30
- project_dir: Path,
31
- timeout: int = 300,
32
- no_figs: bool = False,
33
- ppt2tif: bool = False,
34
- crop_tif: bool = False,
35
- quiet: bool = False,
36
- log_callback: Optional[Callable[[str], None]] = None,
37
- progress_callback: Optional[Callable[[int, str], None]] = None,
38
- ) -> CompilationResult:
39
- """
40
- Compile supplementary materials with optional callbacks.
41
-
42
- Parameters
43
- ----------
44
- project_dir : Path
45
- Path to writer project directory
46
- timeout : int
47
- Timeout in seconds
48
- no_figs : bool
49
- Exclude figures (default includes figures)
50
- ppt2tif : bool
51
- Convert PowerPoint to TIF on WSL
52
- crop_tif : bool
53
- Crop TIF images to remove excess whitespace
54
- quiet : bool
55
- Suppress detailed logs for LaTeX compilation
56
- log_callback : Optional[Callable[[str], None]]
57
- Called with each log line
58
- progress_callback : Optional[Callable[[int, str], None]]
59
- Called with progress updates (percent, step)
60
-
61
- Returns
62
- -------
63
- CompilationResult
64
- Compilation status and outputs
65
-
66
- Examples
67
- --------
68
- >>> from pathlib import Path
69
- >>> from scitex.writer._compile import compile_supplementary
70
- >>>
71
- >>> # Standard compilation with figures
72
- >>> result = compile_supplementary(
73
- ... project_dir=Path("~/my-paper"),
74
- ... ppt2tif=True,
75
- ... quiet=False
76
- ... )
77
- >>>
78
- >>> # Quick compilation without figures
79
- >>> result = compile_supplementary(
80
- ... project_dir=Path("~/my-paper"),
81
- ... no_figs=True,
82
- ... quiet=True
83
- ... )
84
- """
85
- return run_compile(
86
- "supplementary",
87
- project_dir,
88
- timeout=timeout,
89
- no_figs=no_figs,
90
- ppt2tif=ppt2tif,
91
- crop_tif=crop_tif,
92
- quiet=quiet,
93
- log_callback=log_callback,
94
- progress_callback=progress_callback,
95
- )
96
-
97
-
98
- __all__ = ["compile_supplementary"]
99
-
100
- # EOF
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/__init__.py
4
-
5
- """
6
- Type definitions for Writer module.
7
-
8
- Provides dataclasses for document structures with clear separation of concerns.
9
- Each document type includes:
10
- - Typed access to sections and files
11
- - Nested Contents dataclass for content/ subdirectory
12
- - verify_structure() method for validation
13
- """
14
-
15
- from .core import Document, DocumentSection
16
- from .contents import ManuscriptContents, SupplementaryContents, RevisionContents
17
- from .config import WriterConfig
18
- from .results import CompilationResult, LaTeXIssue
19
-
20
- # Tree structures (internal use)
21
- from .tree import (
22
- ConfigTree,
23
- SharedTree,
24
- ScriptsTree,
25
- ManuscriptTree,
26
- SupplementaryTree,
27
- RevisionTree,
28
- )
29
-
30
- __all__ = [
31
- # Core document dataclasses
32
- "DocumentSection",
33
- "Document",
34
- # Document contents
35
- "ManuscriptContents",
36
- "SupplementaryContents",
37
- "RevisionContents",
38
- # Configuration and results
39
- "CompilationResult",
40
- "WriterConfig",
41
- "LaTeXIssue",
42
- ]
43
-
44
- # EOF
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 06:08:36 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_CONSTANTS.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/dataclasses/_CONSTANTS.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- Constants for writer module.
15
-
16
- Centralized definitions for document dataclasses and directory mappings.
17
- """
18
-
19
- # Document type to directory mapping
20
- DOC_TYPE_DIRS = {
21
- "manuscript": "01_manuscript",
22
- "supplementary": "02_supplementary",
23
- "revision": "03_revision",
24
- }
25
-
26
- # Document type to command-line flag mapping
27
- DOC_TYPE_FLAGS = {
28
- "manuscript": "-m",
29
- "supplementary": "-s",
30
- "revision": "-r",
31
- }
32
-
33
- # Document type to PDF filename mapping
34
- DOC_TYPE_PDFS = {
35
- "manuscript": "manuscript.pdf",
36
- "supplementary": "supplementary.pdf",
37
- "revision": "revision.pdf",
38
- }
39
-
40
- __all__ = [
41
- "DOC_TYPE_DIRS",
42
- "DOC_TYPE_FLAGS",
43
- "DOC_TYPE_PDFS",
44
- ]
45
-
46
- # EOF
@@ -1,175 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 06:08:47 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_WriterConfig.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/dataclasses/_WriterConfig.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- WriterConfig - dataclass for writer configuration.
15
- """
16
-
17
- from dataclasses import dataclass
18
- from pathlib import Path
19
- from typing import Optional
20
-
21
-
22
- @dataclass
23
- class WriterConfig:
24
- """Configuration for scitex.writer."""
25
-
26
- project_dir: Path
27
- """Root directory of writer project"""
28
-
29
- manuscript_dir: Path
30
- """Directory for manuscript (01_manuscript/)"""
31
-
32
- supplementary_dir: Path
33
- """Directory for supplementary (02_supplementary/)"""
34
-
35
- revision_dir: Path
36
- """Directory for revision (03_revision/)"""
37
-
38
- shared_dir: Path
39
- """Directory for shared resources (00_shared/)"""
40
-
41
- compile_script: Optional[Path] = None
42
- """Path to compile script (auto-detected if None)"""
43
-
44
- @classmethod
45
- def from_directory(cls, project_dir: Path) -> "WriterConfig":
46
- """
47
- Create config from project directory.
48
-
49
- Args:
50
- project_dir: Path to writer project root
51
-
52
- Returns:
53
- WriterConfig instance
54
-
55
- Examples:
56
- >>> config = WriterConfig.from_directory(Path("/path/to/project"))
57
- >>> print(config.manuscript_dir)
58
- """
59
- project_dir = Path(project_dir)
60
-
61
- return cls(
62
- project_dir=project_dir,
63
- manuscript_dir=project_dir / "01_manuscript",
64
- supplementary_dir=project_dir / "02_supplementary",
65
- revision_dir=project_dir / "03_revision",
66
- shared_dir=project_dir / "00_shared",
67
- )
68
-
69
- def validate(self) -> bool:
70
- """
71
- Validate that required directories exist.
72
-
73
- Returns:
74
- True if valid writer project structure
75
-
76
- Raises:
77
- ValueError: If invalid structure
78
- """
79
- if not self.project_dir.exists():
80
- raise ValueError(f"Project directory not found: {self.project_dir}")
81
-
82
- # Check for at least one document directory
83
- doc_dirs = [
84
- self.manuscript_dir,
85
- self.supplementary_dir,
86
- self.revision_dir,
87
- ]
88
-
89
- if not any(d.exists() for d in doc_dirs):
90
- raise ValueError(
91
- f"No document directories found in {self.project_dir}. "
92
- "Expected: 01_manuscript/, 02_supplementary/, or 03_revision/"
93
- )
94
-
95
- return True
96
-
97
-
98
- def run_session() -> None:
99
- """Initialize scitex framework, run main function, and cleanup."""
100
- global CONFIG, CC, sys, plt, rng
101
- import sys
102
- import matplotlib.pyplot as plt
103
- import scitex as stx
104
-
105
- args = parse_args()
106
-
107
- CONFIG, sys.stdout, sys.stderr, plt, CC, rng = stx.session.start(
108
- sys,
109
- plt,
110
- args=args,
111
- file=__FILE__,
112
- sdir_suffix=None,
113
- verbose=False,
114
- agg=True,
115
- )
116
-
117
- exit_status = main(args)
118
-
119
- stx.session.close(
120
- CONFIG,
121
- verbose=False,
122
- notify=False,
123
- message="",
124
- exit_status=exit_status,
125
- )
126
-
127
-
128
- def main(args):
129
- config = WriterConfig.from_directory(Path(args.dir))
130
-
131
- print(f"Project dir: {config.project_dir}")
132
- print(f"Manuscript dir: {config.manuscript_dir}")
133
- print(f"Supplementary dir: {config.supplementary_dir}")
134
- print(f"Revision dir: {config.revision_dir}")
135
- print(f"Shared dir: {config.shared_dir}")
136
-
137
- if args.validate:
138
- try:
139
- config.validate()
140
- print("\nValidation: PASSED")
141
- except ValueError as ee:
142
- print(f"\nValidation: FAILED - {ee}")
143
- return 1
144
-
145
- return 0
146
-
147
-
148
- def parse_args():
149
- import argparse
150
-
151
- parser = argparse.ArgumentParser(description="Demonstrate WriterConfig dataclass")
152
- parser.add_argument(
153
- "--dir",
154
- type=str,
155
- default="./my_paper",
156
- help="Project directory (default: ./my_paper)",
157
- )
158
- parser.add_argument(
159
- "--validate",
160
- action="store_true",
161
- help="Validate directory structure",
162
- )
163
-
164
- return parser.parse_args()
165
-
166
-
167
- if __name__ == "__main__":
168
- run_session()
169
-
170
-
171
- __all__ = ["WriterConfig"]
172
-
173
- # python -m scitex.writer._dataclasses.config._WriterConfig --dir ./my_paper --validate
174
-
175
- # EOF
@@ -1,9 +0,0 @@
1
- from ._WriterConfig import WriterConfig
2
- from ._CONSTANTS import DOC_TYPE_DIRS, DOC_TYPE_FLAGS, DOC_TYPE_PDFS
3
-
4
- __all__ = [
5
- "WriterConfig",
6
- "DOC_TYPE_DIRS",
7
- "DOC_TYPE_FLAGS",
8
- "DOC_TYPE_PDFS",
9
- ]
@@ -1,236 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-29 06:08:43 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/writer/dataclasses/_ManuscriptContents.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/writer/dataclasses/_ManuscriptContents.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
12
-
13
- """
14
- ManuscriptContents - dataclass for manuscript contents structure.
15
-
16
- Represents the 01_manuscript/contents/ directory structure with all files.
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 ManuscriptContents:
28
- """Contents subdirectory of manuscript (01_manuscript/contents/)."""
29
-
30
- root: Path
31
- git_root: Optional[Path] = None
32
-
33
- # Core sections
34
- abstract: DocumentSection = None
35
- introduction: DocumentSection = None
36
- methods: DocumentSection = None
37
- results: DocumentSection = None
38
- discussion: DocumentSection = None
39
-
40
- # Metadata
41
- title: DocumentSection = None
42
- authors: DocumentSection = None
43
- keywords: DocumentSection = None
44
- journal_name: DocumentSection = None
45
-
46
- # Optional sections
47
- graphical_abstract: DocumentSection = None
48
- highlights: DocumentSection = None
49
- data_availability: DocumentSection = None
50
- additional_info: DocumentSection = None
51
- wordcount: DocumentSection = None
52
-
53
- # Files/directories
54
- figures: Path = None
55
- tables: Path = None
56
- bibliography: DocumentSection = None
57
- latex_styles: Path = None
58
-
59
- def __post_init__(self):
60
- """Initialize all DocumentSection instances."""
61
- if self.abstract is None:
62
- self.abstract = DocumentSection(self.root / "abstract.tex", self.git_root)
63
- if self.introduction is None:
64
- self.introduction = DocumentSection(
65
- self.root / "introduction.tex", self.git_root
66
- )
67
- if self.methods is None:
68
- self.methods = DocumentSection(self.root / "methods.tex", self.git_root)
69
- if self.results is None:
70
- self.results = DocumentSection(self.root / "results.tex", self.git_root)
71
- if self.discussion is None:
72
- self.discussion = DocumentSection(
73
- self.root / "discussion.tex", self.git_root
74
- )
75
- if self.title is None:
76
- self.title = DocumentSection(self.root / "title.tex", self.git_root)
77
- if self.authors is None:
78
- self.authors = DocumentSection(self.root / "authors.tex", self.git_root)
79
- if self.keywords is None:
80
- self.keywords = DocumentSection(self.root / "keywords.tex", self.git_root)
81
- if self.journal_name is None:
82
- self.journal_name = DocumentSection(
83
- self.root / "journal_name.tex", self.git_root
84
- )
85
- if self.graphical_abstract is None:
86
- self.graphical_abstract = DocumentSection(
87
- self.root / "graphical_abstract.tex", self.git_root
88
- )
89
- if self.highlights is None:
90
- self.highlights = DocumentSection(
91
- self.root / "highlights.tex", self.git_root
92
- )
93
- if self.data_availability is None:
94
- self.data_availability = DocumentSection(
95
- self.root / "data_availability.tex", self.git_root
96
- )
97
- if self.additional_info is None:
98
- self.additional_info = DocumentSection(
99
- self.root / "additional_info.tex", self.git_root
100
- )
101
- if self.wordcount is None:
102
- self.wordcount = DocumentSection(self.root / "wordcount.tex", self.git_root)
103
- if self.figures is None:
104
- self.figures = self.root / "figures"
105
- if self.tables is None:
106
- self.tables = self.root / "tables"
107
- if self.bibliography is None:
108
- self.bibliography = DocumentSection(
109
- self.root / "bibliography.bib", self.git_root
110
- )
111
- if self.latex_styles is None:
112
- self.latex_styles = self.root / "latex_styles"
113
-
114
- def verify_structure(self) -> tuple[bool, list[str]]:
115
- """
116
- Verify manuscript structure has required files.
117
-
118
- Returns:
119
- (is_valid, list_of_missing_files_with_paths)
120
- """
121
- required = [
122
- ("abstract.tex", self.abstract),
123
- ("introduction.tex", self.introduction),
124
- ("methods.tex", self.methods),
125
- ("results.tex", self.results),
126
- ("discussion.tex", self.discussion),
127
- ]
128
-
129
- missing = []
130
- for name, section in required:
131
- if not section.path.exists():
132
- expected_path = (
133
- section.path.relative_to(self.git_root)
134
- if self.git_root
135
- else section.path
136
- )
137
- missing.append(f"{name} (expected at: {expected_path})")
138
-
139
- return len(missing) == 0, missing
140
-
141
-
142
- def run_session() -> None:
143
- """Initialize scitex framework, run main function, and cleanup."""
144
- global CONFIG, CC, sys, plt, rng
145
- import sys
146
- import matplotlib.pyplot as plt
147
- import scitex as stx
148
-
149
- args = parse_args()
150
-
151
- CONFIG, sys.stdout, sys.stderr, plt, CC, rng = stx.session.start(
152
- sys,
153
- plt,
154
- args=args,
155
- file=__FILE__,
156
- sdir_suffix=None,
157
- verbose=False,
158
- agg=True,
159
- )
160
-
161
- exit_status = main(args)
162
-
163
- stx.session.close(
164
- CONFIG,
165
- verbose=False,
166
- notify=False,
167
- message="",
168
- exit_status=exit_status,
169
- )
170
-
171
-
172
- def main(args):
173
- contents_path = Path(args.dir) / "01_manuscript" / "contents"
174
- git_root = Path(args.dir) if args.git_root else None
175
-
176
- contents = ManuscriptContents(
177
- root=contents_path,
178
- git_root=git_root,
179
- )
180
-
181
- print(f"Root: {contents.root}")
182
- print(f"Git root: {contents.git_root}")
183
- print(f"\nCore sections:")
184
- print(f" Abstract: {contents.abstract.path}")
185
- print(f" Introduction: {contents.introduction.path}")
186
- print(f" Methods: {contents.methods.path}")
187
- print(f" Results: {contents.results.path}")
188
- print(f" Discussion: {contents.discussion.path}")
189
-
190
- if args.verify:
191
- is_valid, missing = contents.verify_structure()
192
- if is_valid:
193
- print("\nStructure verification: PASSED")
194
- else:
195
- print(f"\nStructure verification: FAILED")
196
- print(f"Missing files: {', '.join(missing)}")
197
- return 1
198
-
199
- return 0
200
-
201
-
202
- def parse_args():
203
- import argparse
204
-
205
- parser = argparse.ArgumentParser(
206
- description="Demonstrate ManuscriptContents dataclass"
207
- )
208
- parser.add_argument(
209
- "--dir",
210
- type=str,
211
- default="./my_paper",
212
- help="Project directory (default: ./my_paper)",
213
- )
214
- parser.add_argument(
215
- "--git-root",
216
- action="store_true",
217
- help="Use project dir as git root",
218
- )
219
- parser.add_argument(
220
- "--verify",
221
- action="store_true",
222
- help="Verify structure has required files",
223
- )
224
-
225
- return parser.parse_args()
226
-
227
-
228
- if __name__ == "__main__":
229
- run_session()
230
-
231
-
232
- __all__ = ["ManuscriptContents"]
233
-
234
- # python -m scitex.writer._dataclasses.contents._ManuscriptContents --dir ./my_paper --verify
235
-
236
- # EOF