## Implement manuscript subpackage in notio: schema, assembly, render, figures,
Implement manuscript subpackage in notio: schema, assembly, render, figures, validate¶
Implement the manuscript subpackage at packages/notio/src/notio/manuscript/.
Prerequisites¶
- Read the design spec at
docs/explanation/manuscript-design-spec.md(written by prior task) — it has the full architecture. - Read existing notio code:
packages/notio/src/notio/core.py,query.py,config.py,mcp/server.py. - Read figio schema:
packages/figio/src/figio/schema.py(for FigureSpec/caption structure). - Read pixecog's manuscript audit:
worklog_read_file(project_id="pixecog", path="docs/how-to/doc/manuscript-system-audit.md").
Deliverables¶
1. manuscript/__init__.py¶
Public API exports: init_manuscript, list_manuscripts, manuscript_status, assemble, render, validate_manuscript, ManuscriptSpec
2. manuscript/schema.py¶
Pydantic models:
- SectionRef(order: int, path: str, title: str)
- FigureBinding(figure_id: str, spec_path: str, caption_override: str | None)
- RenderConfig(pdf_engine: str = "xelatex", csl: str = "", bibliography: str = "", extra_args: list[str] = [])
- ManuscriptSpec(name: str, title: str, authors: list[str], sections: list[SectionRef], figures: list[FigureBinding], render: RenderConfig, output_dir: str = "_build")
- from_yaml(path) / to_yaml(path) class methods
3. manuscript/assembly.py¶
assemble(root: Path, spec: ManuscriptSpec) -> str- Read each section file in order
- Prepend YAML metadata block (title, author, date)
- Insert
\newpagebetween sections (configurable) - Resolve figure references:
{fig:figure_id}→{#fig:id} - Write assembled output to
<output_dir>/md/<name>-assembled.md - Return the assembled text
4. manuscript/render.py¶
render(root: Path, spec: ManuscriptSpec, format: str = "pdf") -> RenderResult- Run assembly first if assembled file doesn't exist or is stale
- Build pandoc command:
pandoc <assembled.md> --citeproc --bibliography=<bib> --csl=<csl> --pdf-engine=<engine> -o <output> - Format support: pdf, latex, md (gfm, no citeproc), html
- subprocess.run with capture of stderr for warnings
- Return RenderResult(success: bool, output_path: Path, warnings: list[str], stderr: str)
5. manuscript/figures.py¶
extract_caption(spec_path: Path) -> str | None— read figio FigureSpec YAML, find caption annotation, return textresolve_figure_paths(root: Path, bindings: list[FigureBinding]) -> dict[str, Path]— map figure_id to built SVG/PDF pathinsert_figure_markdown(figure_id: str, caption: str, path: Path) -> str— return{#fig:id}markdown
6. manuscript/validate.py¶
validate_manuscript(root: Path, spec: ManuscriptSpec) -> ValidationResult- Check all section files exist
- Check order field has no gaps/duplicates
- Scan sections for
[@citekey]patterns, verify each exists in bibliography .bib file - Check figure bindings have corresponding figio spec files
- Check pandoc is in PATH
- Return ValidationResult(valid: bool, errors: list[str], warnings: list[str])
7. Extend notio/core.py¶
- Add a
sectionnote type to DEFAULT_CONFIG with template includingorderandmanuscriptfields - Section template:
--- title: ${title} order: ${order} series: manuscript-${manuscript} manuscript: ${manuscript} date: ${date} ---
8. Extend notio/config.py¶
- Add
[manuscript]section support in notio.toml parsing - Fields: default_csl, default_engine, bib_path, output_dir
9. manuscript/init.py (or in init)¶
init_manuscript(root: Path, name: str, template: str = "generic") -> ManuscriptSpec- Create
docs/manuscript/<name>/directory - Create
manuscript.ymlwith defaults - Create starter sections: 00-cover.md, 01-abstract.md, 02-introduction.md, 03-methods.md, 04-results.md, 05-discussion.md, 06-conclusions.md
- Each section created as a notio note with appropriate frontmatter
10. Tests¶
tests/test_manuscript_schema.py— ManuscriptSpec YAML round-triptests/test_manuscript_assembly.py— section ordering and concatenation (use tmp_path, no pandoc needed)tests/test_manuscript_validate.py— validation logic with fixture sections
Notes¶
- Keep pandoc as an optional system dependency — render functions should check for it and raise clear errors.
- Don't modify notio's existing tests — add new test files.
- Use pathlib throughout, not os.path.
- Section files live at
docs/manuscript/<name>/sections/NN-slug.md(not in docs/log/ like regular notes). - The
sectionnote type in notio.toml uses a customnote_dirpointing to manuscript directories, not the default docs/log/section/ path.
Related Notes¶
- [[task-arash-20260331-175617-644481.md]] — Design spec task for manuscript as a notio subpackage — direct prerequisite
- [[task-arash-20260331-175313-566067.md]] — manuscripto architecture and API surface design — closely related design work
- [[task-arash-20260331-175439-058148.md]] — Parallel implementation task for manuscripto core: assembly, render, notio section type
- [[task-arash-20260331-175356-958039.md]] — Scaffolding manuscripto package — prerequisite infrastructure
- [[task-arash-20260331-175508-399347.md]] — Registering manuscripto in projio MCP/submodule — downstream integration step
Batch Result¶
- status: done
- batch queue_id:
3e973e87bee2 - session:
f9189029-1adf-43a6-aa5f-93edf57dfe17 - batch duration: 494.6s