Problem
Every reader and writer module exposes a different function name and return shape, making the library harder to learn and use consistently.
| Module |
Entry function |
Returns |
DOCX.Reader |
open!/1 → convert!/1 → close!/1 |
Bare struct (raises) |
Tiptap.Reader |
convert/1 |
{:ok, spec} | {:error, ...} |
HTML.Writer |
convert/1 |
String.t() (bare, no error path) |
EPUB.Writer |
convert!/1 / convert!/2 |
Mixed (see #19) |
Tiptap.Writer |
convert/1 |
{:ok, element} | {:error, ...} |
BlockNote.Writer |
write/1 |
{:ok, content} | {:error, ...} |
Validation.Writer |
validate/1 |
[Finding.t()] (bare list) |
Specific inconsistencies
BlockNote.Writer.write/1 uses write while all other writers use convert
HTML.Writer.convert/1 returns a bare string with no error tuple — no way to handle conversion failures
DOCX.Reader requires a 3-step open/convert/close lifecycle; Tiptap.Reader is a single convert/1 call
Validation.Writer — the module is named "Writer" but the public function is validate/1, which is semantically correct but structurally confusing given the module hierarchy
Proposal
Standardize on:
convert/1 → {:ok, result} | {:error, reason} (all readers and writers)
convert!/1 → result or raises (convenience bang variant)
- DOCX Reader: provide a single-call
convert/1 that handles the open/convert/close lifecycle internally, keeping the granular API available for advanced use
Files
lib/docspec/core/blocknote/writer.ex
lib/docspec/core/html/writer.ex
lib/docspec/core/epub/writer.ex
lib/docspec/core/tiptap/reader.ex
lib/docspec/core/tiptap/writer.ex
lib/docspec/core/docx/reader.ex
lib/docspec/core/validation/writer.ex
Notes
This is a breaking change. Consider whether Validation.Writer should be renamed to DocSpec.Core.Validation since it doesn't "write" output.
Problem
Every reader and writer module exposes a different function name and return shape, making the library harder to learn and use consistently.
DOCX.Readeropen!/1→convert!/1→close!/1Tiptap.Readerconvert/1{:ok, spec} | {:error, ...}HTML.Writerconvert/1String.t()(bare, no error path)EPUB.Writerconvert!/1/convert!/2Tiptap.Writerconvert/1{:ok, element} | {:error, ...}BlockNote.Writerwrite/1{:ok, content} | {:error, ...}Validation.Writervalidate/1[Finding.t()](bare list)Specific inconsistencies
BlockNote.Writer.write/1useswritewhile all other writers useconvertHTML.Writer.convert/1returns a bare string with no error tuple — no way to handle conversion failuresDOCX.Readerrequires a 3-step open/convert/close lifecycle;Tiptap.Readeris a singleconvert/1callValidation.Writer— the module is named "Writer" but the public function isvalidate/1, which is semantically correct but structurally confusing given the module hierarchyProposal
Standardize on:
convert/1→{:ok, result} | {:error, reason}(all readers and writers)convert!/1→resultor raises (convenience bang variant)convert/1that handles the open/convert/close lifecycle internally, keeping the granular API available for advanced useFiles
lib/docspec/core/blocknote/writer.exlib/docspec/core/html/writer.exlib/docspec/core/epub/writer.exlib/docspec/core/tiptap/reader.exlib/docspec/core/tiptap/writer.exlib/docspec/core/docx/reader.exlib/docspec/core/validation/writer.exNotes
This is a breaking change. Consider whether
Validation.Writershould be renamed toDocSpec.Core.Validationsince it doesn't "write" output.