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
scitex/writer/README.md CHANGED
@@ -1,12 +1,12 @@
1
- <!-- ---
2
- !-- Timestamp: 2025-10-29 17:33:34
3
- !-- Author: ywatanabe
4
- !-- File: /home/ywatanabe/proj/scitex-python/src/scitex/writer/README.md
5
- !-- --- -->
6
-
7
1
  # SciTeX Writer
8
2
 
9
- Python interface for LaTeX manuscript compilation.
3
+ Thin wrapper delegating to [scitex-writer](https://github.com/ywatanabe1989/scitex-writer) package.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install scitex-writer
9
+ ```
10
10
 
11
11
  ## Usage
12
12
 
@@ -14,422 +14,38 @@ Python interface for LaTeX manuscript compilation.
14
14
  from scitex.writer import Writer
15
15
  from pathlib import Path
16
16
 
17
- # Standalone manuscript (isolated git repository - default)
17
+ # Create or attach to a writer project
18
18
  writer = Writer(Path("my_paper"))
19
19
 
20
- # # Project-integrated manuscript (use parent's git repository)
21
- # writer = Writer(Path("my_project/scitex/writer"), git_strategy='parent')
22
- #
23
- # # Clone specific branch of template
24
- # writer = Writer(Path("my_paper"), branch="develop")
25
- #
26
- # # No git (temporary work)
27
- # writer = Writer(Path("temp_work"), git_strategy=None)
28
-
29
- # Document operations (git-based version control)
30
- intro = writer.manuscript.contents.introduction
31
- lines = intro.read() # Read file (uses scitex.io or fallback to plain text)
32
- intro.write(lines + ["# New"]) # Write file
33
-
34
- intro.commit("Update intro") # Commit to git with message
35
- # intro.save() is not an alias - use commit() instead
36
-
37
- intro.history() # Show git log (returns list of commit messages)
38
- intro.diff() # Show uncommitted changes vs HEAD (returns diff string)
39
- intro.diff(ref="HEAD~1") # Show uncommitted changes vs previous commit
40
- intro.diff(ref="main") # Show uncommitted changes vs main branch
41
-
42
- intro.checkout("HEAD~1") # Restore from previous version
43
- intro.checkout("HEAD") # Restore from HEAD (returns bool: success)
44
-
45
- # Compilation
20
+ # Compile manuscript
46
21
  result = writer.compile_manuscript()
47
22
  if result.success:
48
- print(f"PDF: {result.output_pdf}")
49
-
50
- # Utilities
51
- pdf = writer.get_pdf()
52
- writer.watch()
53
- writer.delete()
54
- ```
55
-
56
- **Git Strategies:**
57
- - **`'child'` (default)**: Isolated git repository in project directory
58
- - Self-contained version history
59
- - Can use git directly in project directory
60
- - **`'parent'`**: Use existing parent git repository
61
- - Manuscript tracked in project's git repo
62
- - Better for code + paper reproducibility
63
- - **`None`**: Disable git (for temporary work)
64
-
65
- ## API Reference
66
-
67
- ### Writer Class
68
-
69
- ```python
70
- Writer(project_dir, name=None, git_strategy='child', branch=None)
71
-
72
- # Parameters:
73
- # - project_dir: Path to project directory
74
- # - name: Project name (optional, defaults to directory name)
75
- # - git_strategy: 'child' (default), 'parent', 'origin', or None
76
- # - branch: Specific branch of template to clone (optional)
77
-
78
- # Attributes:
79
- writer.project_dir # Path to project
80
- writer.project_name # Project name
81
- writer.git_root # Git repository root (if using git)
82
-
83
- # Document trees:
84
- writer.manuscript # ManuscriptTree with contents and sections
85
- writer.supplementary # SupplementaryTree
86
- writer.revision # RevisionTree
87
- writer.scripts # ScriptsTree with compilation and utility scripts
88
-
89
- # Methods:
90
- writer.compile_manuscript(timeout=300) # → CompilationResult
91
- writer.compile_supplementary(timeout=300) # → CompilationResult
92
- writer.compile_revision(track_changes=False) # → CompilationResult
93
- writer.watch(on_compile=None) # Auto-recompile on changes
94
- writer.get_pdf(doc_type='manuscript') # → Path or None
95
- writer.delete() # → bool
96
- ```
97
-
98
- ### DocumentSection Class
99
-
100
- All manuscript/supplementary/revision sections are DocumentSection instances:
101
-
102
- ```python
103
- section = writer.manuscript.contents.introduction # Example
104
-
105
- # Methods:
106
- section.read() # → content (str or list)
107
- section.write(content) # → bool
108
- section.commit(message) # → bool (git add + commit)
109
- section.history() # → List[str] (git log messages)
110
- section.diff(ref="HEAD") # → str (uncommitted changes vs ref, "" if none)
111
- section.diff_between(ref1, ref2) # → str (compare any two git states)
112
- section.checkout(ref="HEAD") # → bool (restore from git reference)
113
-
114
- # Attributes:
115
- section.path # → Path to file
116
- section.git_root # → Path to git root (if available)
117
- ```
118
-
119
- ### Available Sections
120
-
121
- **Manuscript Contents** (`writer.manuscript.contents.*`):
122
- - Core: abstract, introduction, methods, results, discussion
123
- - Metadata: title, authors, keywords, journal_name
124
- - Optional: graphical_abstract, highlights, data_availability, additional_info, wordcount
125
- - References: bibliography
126
- - Directories: figures/, tables/, latex_styles/
127
-
128
- **Supplementary & Revision**: Similar structure, customize as needed
129
-
130
- ## Usage Examples
131
-
132
- ### Basic Read/Write/Commit Workflow
133
-
134
- ```python
135
- intro = writer.manuscript.contents.introduction
136
-
137
- # 1. Read current content
138
- lines = intro.read()
139
-
140
- # 2. Modify and write
141
- lines.append("New paragraph...")
142
- intro.write(lines)
143
-
144
- # 3. Check what changed (returns "" if no changes, diff string if changed)
145
- changes = intro.diff()
146
- if changes:
147
- print("Changes detected:")
148
- print(changes)
149
-
150
- # 4. Commit when satisfied
151
- intro.commit("Added new paragraph")
152
- else:
153
- print("No changes to commit")
154
- ```
155
-
156
- ### Working with Git History
157
-
158
- ```python
159
- # View full version history
160
- history = intro.history()
161
- for commit in history:
162
- print(commit) # Output: "abc1234 Commit message"
163
-
164
- # Compare uncommitted changes against different versions
165
- diff_prev = intro.diff(ref="HEAD~1") # Uncommitted changes vs last commit
166
- diff_main = intro.diff(ref="main") # Uncommitted changes vs main branch
167
- diff_tag = intro.diff(ref="v1.0") # Uncommitted changes vs tag
168
-
169
- # Compare two arbitrary versions (no uncommitted changes needed)
170
- diff = intro.diff_between("v1.0", "v2.0") # Between tags
171
- diff = intro.diff_between("HEAD~2", "HEAD") # Between commits
172
- diff = intro.diff_between("main", "develop") # Between branches
173
-
174
- # Time-based comparisons with human-readable timestamps
175
- diff = intro.diff_between("1 week ago", "now") # Last week's changes
176
- diff = intro.diff_between("2 days ago", "HEAD") # Last 2 days
177
- diff = intro.diff_between("2025-10-20", "2025-10-28") # Between dates
178
-
179
- # Restore previous version
180
- intro.checkout("HEAD~1") # Restore to last commit
181
- intro.checkout("main") # Restore to main branch
182
-
183
- # After restore, commit if needed
184
- intro.commit("Reverted to previous version")
185
- ```
186
-
187
- ### Working with Scripts
188
-
189
- ```python
190
- # Access compilation scripts
191
- scripts = writer.scripts
192
-
193
- # View script paths
194
- compile_script = scripts.compile_manuscript.path
195
- watch_script = scripts.watch_compile.path
196
-
197
- # Read script content
198
- content = scripts.compile_manuscript.read()
199
-
200
- # Modify scripts (with git tracking)
201
- new_content = scripts.compile_manuscript.read()
202
- # ... modify content ...
203
- scripts.compile_manuscript.write(new_content)
204
- scripts.compile_manuscript.commit("Update compilation script")
205
-
206
- # View script history
207
- history = scripts.compile_manuscript.history()
208
- diff = scripts.compile_manuscript.diff()
209
- ```
210
-
211
- ### Typical Edit Workflow
212
-
213
- ```python
214
- # 1. Read current content
215
- content = intro.read()
216
-
217
- # 2. Make edits
218
- updated = content + "\n\nNew section..."
219
- intro.write(updated)
220
-
221
- # 3. Review changes
222
- print(intro.diff())
223
-
224
- # 4. Commit when satisfied
225
- if intro.diff():
226
- intro.commit("Add new section")
227
- else:
228
- print("No changes to commit")
229
-
230
- # 5. View history
231
- print(intro.history())
232
- ```
233
-
234
- ## CompilationResult
235
-
236
- ```python
237
- result.success # bool
238
- result.exit_code # int
239
- result.output_pdf # Path
240
- result.duration # float (seconds)
241
- result.errors # List[str]
242
- result.warnings # List[str]
243
- result.stdout # str
244
- result.stderr # str
245
- result.log_file # Path
246
- ```
247
-
248
- ## Project Structure
249
-
250
- Writer creates and manages the following directory structure:
251
-
252
- ```
253
- project_dir/
254
- ├── 01_manuscript/ # Main manuscript
255
- │ ├── abstract.tex
256
- │ ├── introduction.tex
257
- │ ├── methods.tex
258
- │ ├── results.tex
259
- │ ├── discussion.tex
260
- │ └── main.tex
261
- ├── 02_supplementary/ # Supplementary materials
262
- │ ├── figures/
263
- │ └── tables/
264
- ├── 03_revision/ # Revision/response documents
265
- └── .git/ # Git repository (if using 'child' or 'parent' strategy)
266
- ```
267
-
268
- ## Error Handling
269
-
270
- Writer handles errors gracefully with clear logging:
271
-
272
- ```python
273
- try:
274
- writer = Writer("/path/to/project")
275
- except RuntimeError as e:
276
- # Missing required directories (01_manuscript, 02_supplementary, 03_revision)
277
- print(f"Invalid project structure: {e}")
278
-
279
- try:
280
- result = writer.compile_manuscript()
281
- if not result.success:
282
- print(f"Compilation failed: {result.errors}")
283
- except Exception as e:
284
- print(f"Compilation error: {e}")
285
- ```
286
-
287
- **Common Issues:**
288
- - Invalid project structure: Ensure all 3 required directories exist
289
- - Git initialization failure: Check git installation and permissions
290
- - LaTeX compilation error: Check .tex files syntax and LaTeX installation
23
+ print(f"PDF created: {result.output_pdf}")
291
24
 
292
- ## Testing
293
-
294
- Run the comprehensive test suite:
295
-
296
- ```bash
297
- # Run all Writer tests
298
- python -m pytest src/scitex/writer/tests/test_writer_integration.py -v
25
+ # Compile supplementary
26
+ result = writer.compile_supplementary()
299
27
 
300
- # Run specific test class
301
- python -m pytest src/scitex/writer/tests/test_writer_integration.py::TestProjectAttachment -v
302
-
303
- # Run with coverage
304
- python -m pytest src/scitex/writer/tests/test_writer_integration.py --cov=scitex.writer
28
+ # Compile revision with change tracking
29
+ result = writer.compile_revision(track_changes=True)
305
30
  ```
306
31
 
307
- **Test Coverage:**
308
- - Project attachment and creation
309
- - Structure validation
310
- - Git strategy handling (child, parent, None)
311
- - Project name handling
312
- - Child git cleanup for parent strategy
32
+ ## Source of Truth
313
33
 
314
- ## Recent Improvements
34
+ The implementation lives in the `scitex-writer` package. This module (`scitex.writer`) simply re-exports from `scitex_writer`:
315
35
 
316
- ### 2025-10-29: Live Streaming & Timeout Support
36
+ - `Writer` - Main class for manuscript compilation
37
+ - `CompilationResult` - Compilation result dataclass
38
+ - `ManuscriptTree`, `SupplementaryTree`, `RevisionTree` - Document tree structures
39
+ - `bib`, `compile`, `figures`, `guidelines`, `project`, `prompts`, `tables` - Submodules
317
40
 
318
- **Live Output Streaming** - See compilation progress in real-time:
319
- - **Real-time output**: View LaTeX compilation output as it happens, not buffered until completion
320
- - **ANSI color preservation**: Color-coded messages (INFO, SUCC, ERRO, WARNING) display correctly
321
- - **Progress visibility**: Know exactly which step is running and how long it takes
322
- - **Immediate error detection**: Errors appear instantly instead of after full compilation
323
- - **Stdbuf integration**: Forces line-buffered output for shell scripts
41
+ ## Direct Import
324
42
 
325
- **Timeout Support**:
326
- - **Configurable timeouts**: Default 300s (5 minutes), customizable per compilation
327
- - **Graceful termination**: Process killed cleanly on timeout
328
- - **Clear timeout messages**: Explicit notification when compilation exceeds time limit
329
- - **Works with streaming**: Timeout checks happen during execution, not after
43
+ You can also import directly from scitex-writer:
330
44
 
331
- **Enhanced Compilation**:
332
45
  ```python
333
- # Compilation with default timeout (300s)
334
- result = writer.compile_manuscript()
335
-
336
- # Custom timeout
337
- result = writer.compile_manuscript(timeout=600) # 10 minutes
338
-
339
- # Watch real-time output with color coding:
340
- # INFO: Running compilation...
341
- # SUCC: All required tools available
342
- # INFO: Pass 1/3: Initial (3s)
343
- # SUCC: PDF ready (828K)
344
- ```
345
-
346
- **Implementation Details**:
347
- - Non-blocking I/O with `fcntl` for true streaming
348
- - Unbuffered subprocess execution (`bufsize=0`)
349
- - Environment variable propagation (`PYTHONUNBUFFERED=1`)
350
- - Progressive output reading without blocking
351
- - Separate stdout/stderr handling with immediate display
352
-
353
- **Test Coverage** - 64 comprehensive tests:
354
- - Real-time behavior verification (timing-based proofs)
355
- - ANSI color code preservation tests
356
- - Timeout during execution tests
357
- - Large output handling (100+ lines)
358
- - Stdbuf wrapper integration tests
359
- - Streaming vs buffered consistency tests
360
-
361
- **Benefits**:
362
- - 🔍 **Visibility**: See what's happening during long compilations (161s in example)
363
- - ⚡ **Responsiveness**: Decide to wait or interrupt based on live progress
364
- - 🎨 **Clarity**: Color-coded output for easy scanning
365
- - ⏱️ **Control**: Prevent runaway compilations with timeouts
366
- - 🐛 **Debugging**: Errors visible immediately with full context
367
-
368
- ### 2025-10-28: Enhanced Git Integration & Temporal Queries
369
-
370
- **Bug Fixes**:
371
- - Fixed incomplete initialization that left `git_root` uninitialized
372
- - Removed blocking debug code (`ipdb.set_trace()`)
373
- - Fixed return type annotation in `_attach_or_create_project()`
374
- - Improved error handling with proper logging throughout
375
-
376
- **New Features**:
377
- - **Structure Validation**: Automatically verifies project has required directories (01_manuscript, 02_supplementary, 03_revision) when attaching
378
- - **Child Git Cleanup**: Automatically removes project's `.git/` when using `'parent'` strategy and parent repo is found, preventing nested git issues
379
-
380
- **Enhanced Logging**:
381
- - Detailed initialization logs with project name, directory, and git strategy
382
- - Clear strategy selection and progression messages
383
- - Explicit error messages with full context
384
- - Success confirmations for key operations
385
-
386
- **Enhanced diff() Capability**:
387
- - **New `diff_between()` method** for comparing any two arbitrary git states
388
- - Compare commits: `diff_between("HEAD~2", "HEAD")`
389
- - Compare releases: `diff_between("v1.0", "v2.0")`
390
- - Compare branches: `diff_between("main", "develop")`
391
- - **Time-aware ref resolution**: `diff_between("1 week ago", "now")`
392
- - **Timestamp-based queries**: `diff_between("2025-10-20", "2025-10-28")`
393
- - Supports human-readable specifications without breaking git functionality
394
- - **Reference resolution** (`_resolve_ref()`) handles:
395
- - Standard git refs (HEAD, branches, tags, commit hashes)
396
- - Relative time: "2 days ago", "1 week ago", "24 hours ago"
397
- - Absolute dates: "2025-10-28", "2025-10-28 14:30"
398
- - Timestamp-based commit finding with `git log --before`
399
- - 15 new tests for diff_between functionality (all passing)
400
-
401
- **Comprehensive Testing**:
402
- - 99 tests covering all Writer and DocumentSection functionality
403
- - DocumentSection operations fully tested (read/write/commit/history/diff/diff_between/checkout)
404
- - End-to-end workflow testing (project creation → document editing → git operations)
405
- - Temporal queries and reference resolution tested
406
- - Error handling and edge cases covered
407
- - All tests passing ✅
408
-
409
- **Test Coverage**:
410
- - Writer initialization and configuration
411
- - Project creation and attachment
412
- - Git strategy handling (child, parent, None)
413
- - Document section operations (read, write, commit)
414
- - Git operations (history, diff, checkout)
415
- - Tree structure verification
416
- - Error handling
417
- - Live streaming infrastructure
418
- - Timeout handling
419
-
420
- **Run tests**:
421
- ```bash
422
- # Writer module tests
423
- pytest src/scitex/writer/tests/ -v
424
-
425
- # Shell/streaming infrastructure tests
426
- pytest tests/scitex/sh/ -v
46
+ from scitex_writer import Writer, CompilationResult
427
47
  ```
428
48
 
429
- ## Requirements
430
-
431
- - Python 3.8+
432
- - LaTeX distribution
433
- - Git (for version control)
49
+ ## Documentation
434
50
 
435
- <!-- EOF -->
51
+ See [scitex-writer documentation](https://github.com/ywatanabe1989/scitex-writer) for full API reference.
scitex/writer/__init__.py CHANGED
@@ -1,22 +1,62 @@
1
1
  #!/usr/bin/env python3
2
- """
3
- SciTeX Writer - Thin wrapper delegating to scitex-writer package.
2
+ # Timestamp: 2026-01-30
3
+ # File: src/scitex/writer/__init__.py
4
+
5
+ """SciTeX Writer - LaTeX manuscript compilation system.
6
+
7
+ This module provides a thin wrapper around scitex-writer, the core manuscript
8
+ compilation package. It uses scitex branding and environment variable prefixes.
9
+
10
+ Features
11
+ --------
12
+ - LaTeX manuscript compilation
13
+ - Supplementary materials compilation
14
+ - Revision response compilation with change tracking
15
+ - BibTeX management
16
+ - Figure/table management
17
+ - Writing guidelines
18
+
19
+ Usage
20
+ -----
21
+ import scitex as stx
4
22
 
5
- Single source of truth: scitex-writer package
6
- This module re-exports scitex-writer as-is, without modifications.
23
+ # Create or attach to a project
24
+ writer = stx.writer.Writer("my_paper")
7
25
 
8
- Install: pip install scitex-writer
26
+ # Compile manuscript
27
+ result = writer.compile_manuscript()
28
+ if result.success:
29
+ print(f"PDF created: {result.output_pdf}")
30
+
31
+ # Compile supplementary
32
+ result = writer.compile_supplementary()
33
+
34
+ # Compile revision with change tracking
35
+ result = writer.compile_revision(track_changes=True)
36
+
37
+ See Also
38
+ --------
39
+ - scitex-writer: https://github.com/ywatanabe1989/scitex-writer
40
+ - scitex: https://scitex.ai
9
41
  """
10
42
 
11
43
  import os as _os
12
44
 
13
- # Set branding environment variables BEFORE importing scitex-writer
45
+ # Set branding BEFORE importing scitex-writer
14
46
  _os.environ.setdefault("SCITEX_WRITER_BRAND", "scitex.writer")
15
47
  _os.environ.setdefault("SCITEX_WRITER_ALIAS", "sw")
16
48
 
17
- # Re-export from scitex-writer package (single source of truth)
49
+ # Check scitex-writer availability
18
50
  try:
19
- from scitex_writer import __version__ as writer_version
51
+ # Re-export main class and dataclasses
52
+ from scitex_writer import (
53
+ CompilationResult,
54
+ ManuscriptTree,
55
+ RevisionTree,
56
+ SupplementaryTree,
57
+ Writer,
58
+ )
59
+ from scitex_writer import __version__ as _writer_version
20
60
  from scitex_writer import (
21
61
  bib,
22
62
  compile,
@@ -27,11 +67,34 @@ try:
27
67
  tables,
28
68
  )
29
69
 
30
- HAS_WRITER_PKG = True
70
+ WRITER_AVAILABLE = True
71
+ __writer_version__ = _writer_version
31
72
 
32
73
  except ImportError:
33
- HAS_WRITER_PKG = False
34
- writer_version = None
74
+ WRITER_AVAILABLE = False
75
+ __writer_version__ = None
76
+
77
+ # Provide helpful error on access
78
+ class _WriterNotAvailable:
79
+ """Placeholder when scitex-writer is not installed."""
80
+
81
+ def __init__(self, *args, **kwargs):
82
+ raise ImportError(
83
+ "scitex-writer is required for scitex.writer. "
84
+ "Install with: pip install scitex-writer"
85
+ )
86
+
87
+ def __getattr__(self, name):
88
+ raise ImportError(
89
+ "scitex-writer is required for scitex.writer. "
90
+ "Install with: pip install scitex-writer"
91
+ )
92
+
93
+ Writer = _WriterNotAvailable
94
+ CompilationResult = _WriterNotAvailable
95
+ ManuscriptTree = _WriterNotAvailable
96
+ SupplementaryTree = _WriterNotAvailable
97
+ RevisionTree = _WriterNotAvailable
35
98
  bib = None
36
99
  compile = None
37
100
  figures = None
@@ -40,9 +103,31 @@ except ImportError:
40
103
  prompts = None
41
104
  tables = None
42
105
 
106
+
107
+ def has_writer() -> bool:
108
+ """Check if scitex-writer is available.
109
+
110
+ Returns
111
+ -------
112
+ bool
113
+ True if scitex-writer is installed and importable.
114
+ """
115
+ return WRITER_AVAILABLE
116
+
117
+
43
118
  __all__ = [
44
- "HAS_WRITER_PKG",
45
- "writer_version",
119
+ # Availability check
120
+ "WRITER_AVAILABLE",
121
+ "has_writer",
122
+ "__writer_version__",
123
+ # Main class
124
+ "Writer",
125
+ # Dataclasses
126
+ "CompilationResult",
127
+ "ManuscriptTree",
128
+ "SupplementaryTree",
129
+ "RevisionTree",
130
+ # Modules
46
131
  "bib",
47
132
  "compile",
48
133
  "figures",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scitex
3
- Version: 2.16.0
3
+ Version: 2.16.2
4
4
  Summary: A comprehensive Python library for scientific computing and data analysis
5
5
  Project-URL: Homepage, https://github.com/ywatanabe1989/scitex-python
6
6
  Project-URL: Documentation, https://scitex.readthedocs.io
@@ -62,6 +62,7 @@ Requires-Dist: catboost; extra == 'all'
62
62
  Requires-Dist: celery; extra == 'all'
63
63
  Requires-Dist: click; extra == 'all'
64
64
  Requires-Dist: crawl4ai; extra == 'all'
65
+ Requires-Dist: crossref-local; extra == 'all'
65
66
  Requires-Dist: csv2latex; extra == 'all'
66
67
  Requires-Dist: dearpygui; extra == 'all'
67
68
  Requires-Dist: einops; extra == 'all'
@@ -102,6 +103,7 @@ Requires-Dist: nest-asyncio; extra == 'all'
102
103
  Requires-Dist: numcodecs; extra == 'all'
103
104
  Requires-Dist: obspy; extra == 'all'
104
105
  Requires-Dist: openai; extra == 'all'
106
+ Requires-Dist: openalex-local; extra == 'all'
105
107
  Requires-Dist: opencv-python; extra == 'all'
106
108
  Requires-Dist: openpyxl; extra == 'all'
107
109
  Requires-Dist: optuna; extra == 'all'
@@ -140,6 +142,7 @@ Requires-Dist: scholarly; extra == 'all'
140
142
  Requires-Dist: scikit-image; extra == 'all'
141
143
  Requires-Dist: scikit-learn; extra == 'all'
142
144
  Requires-Dist: scipy; extra == 'all'
145
+ Requires-Dist: scitex-writer; extra == 'all'
143
146
  Requires-Dist: seaborn; extra == 'all'
144
147
  Requires-Dist: selenium; extra == 'all'
145
148
  Requires-Dist: sktime; extra == 'all'
@@ -382,12 +385,14 @@ Requires-Dist: aiohttp; extra == 'scholar'
382
385
  Requires-Dist: beautifulsoup4; extra == 'scholar'
383
386
  Requires-Dist: bibtexparser; extra == 'scholar'
384
387
  Requires-Dist: crawl4ai; extra == 'scholar'
388
+ Requires-Dist: crossref-local; extra == 'scholar'
385
389
  Requires-Dist: feedparser; extra == 'scholar'
386
390
  Requires-Dist: html2text; extra == 'scholar'
387
391
  Requires-Dist: httpx; extra == 'scholar'
388
392
  Requires-Dist: matplotlib; extra == 'scholar'
389
393
  Requires-Dist: natsort; extra == 'scholar'
390
394
  Requires-Dist: nest-asyncio; extra == 'scholar'
395
+ Requires-Dist: openalex-local; extra == 'scholar'
391
396
  Requires-Dist: openpyxl; extra == 'scholar'
392
397
  Requires-Dist: pdfplumber; extra == 'scholar'
393
398
  Requires-Dist: pillow; extra == 'scholar'