-
Notifications
You must be signed in to change notification settings - Fork 0
Promises
These are the properties the project holds itself to. Each one is enforced by a test that fails the build, not by convention — a promise nobody has fired a shot at is a comment rather than a defence.
src/n8PDF carries zero PackageReference entries, and LibraryInvariantTests fails the build if that ever changes. The only things it builds on are the base class library's System.IO.Compression (the DOCX container, and Flate for PDF streams) and System.Xml.Linq. Everything domain-specific is the project's own:
- OPC relationships and content types
- WordprocessingML semantics and the style cascade
- TrueType/OpenType/CFF parsing, metrics, shaping (OpenType and Apple AAT state tables), and subsetting
- The Unicode bidirectional algorithm and its generated tables
- PNG, GIF, BMP, TIFF, EMF/EMF+ and JPEG decoding — including progressive and arithmetic JPEG, fax-encoded TIFF strips, and 16-bit and CMYK samples
- Text measurement, line breaking (the Unicode algorithm, plus Liang's hyphenation patterns), pagination
- The PDF writer, including Type0/CIDFontType2 embedding with
ToUnicodemaps
What follows from this: no supply chain beyond the .NET runtime itself, no transitive advisories, no version conflicts in a consumer's dependency graph, and no behavior that changes because a package updated. A task that seems to need a package needs a conversation instead.
Eight public types (The API). PublicApiTests writes the surface out in full and fails on anything that grows it. A published version is a promise about every public name in it; keeping the surface small is what lets the internals — 170+ types of parser, cascade, font engine, layout and writer — keep improving without breaking anyone.
Directory.Build.props sets TreatWarningsAsErrors for every project and every build, so the build that introduces a warning is the build that fails — not the next push to CI. (NuGet audit warnings are the one exception, in the test project only: they report what is known about a package today rather than anything about this code.)
- The build is deterministic: the same input builds the same assembly, whoever builds it.
- The output is deterministic: with
CreationDateleft null, converting the same document twice produces identical bytes. That is not a nicety — it is what makes golden-trace comparison possible (Validation).
A release is cut by pushing a tag (git tag v1.0.1 && git push origin v1.0.1). The workflow builds at the version the tag names, runs the same tests every push runs, packs the library with its symbols and documentation, and writes a GitHub release. The tag is the only place a version is written down, and LibraryInvariantTests checks a package cannot disagree with the tag it was cut at.
GenerateDocumentationFile is on: what a rule is and where it was measured from is written on the types that carry it, and that goes into a consumer's editor with the package. Symbols ship alongside (snupkg) so a stack trace through the converter is readable.
MIT. The one piece of third-party data (not code) is Liang's hyphenation patterns, as TeX has distributed them since 1990, turned into generated source; their license asks that the copyright notice be preserved, and the generated source carries it.
Fidelity numbers ("agrees with Word to within 0.72pt") are measurements of the current suite, not API guarantees — they are held by tests and reported honestly in Matching Word, and they improve or are explained, never quietly regressed.
Using n8PDF
What it does
How it works
Contributing