onedocumentDocs
onedocument docs
Everything about OneDocument: getting started, the notes for documents, workbooks and presentations, templates and operations, sanitizing and redaction, rendering, coming from another library, and the project’s own 1.0 results.
Start
Getting startedInstall OneDocument 1.0.0 for .NET 10, read a Word document, convert it to PDF, read and recalculate an Excel workbook, and use the onedocument command-line tool. Every sample on this page was run on the 1.0.0 packages from NuGet and shows its real output. The program makes…OverviewOneDocument is a clean-room document processor for net10.0 that depends only on the .NET base class library and other Recursive AI libraries. It is NativeAOT-, trim- and browser-WebAssembly-friendly: no reflection, no native code, no System.Xml in the document path.All notesNormative notes on how OneDocument behaves, one page per area. The code's XML documentation states the details of each type; these pages state the rules, the sources they come from and the deviations. Start with contracts.md and defects.md.Contracts and the format registryThe contracts every layer of OneDocument is written against. They live in the core package (RecursiveAI.OneDocument). This note states the behaviour; the XML documentation on each type states the details.NativeAOT, WebAssembly and mobileOneDocument targets net10.0 and runs the same code on the desktop runtime, under NativeAOT, in browser WebAssembly, in an iOS simulator and in an Android emulator. One set of smoke checks (smoke/shared) is compiled into the NativeAOT app (smoke/aot), the browser app…
Coming from another library
Which page to readThese pages map the common tasks of seven libraries to OneDocument, call by call. They are written from each library's published API documentation. OneDocument has no compatibility layer and no shim: the pages are a map, and the code on the right is ordinary OneDocument.From the Open XML SDKThe Open XML SDK gives you the packages, parts and a typed class per schema element: WordprocessingDocument, SpreadsheetDocument, PresentationDocument, OpenXmlElement and its subclasses, OpenXmlReader / OpenXmlWriter for streaming. OneDocument has two ways to work at that…From ClosedXMLClosedXML edits workbooks through XLWorkbook, IXLWorksheet, IXLCell and IXLRange; ClosedXML.Report fills templates. OneDocument's equivalents are Workbook, Worksheet, Cell, Spreadsheet and Template. Read README.md first for what is true on every page.From EPPlusEPPlus 4.x edits workbooks through ExcelPackage, ExcelWorkbook, ExcelWorksheet and ExcelRange. OneDocument's workbook is Workbook / Worksheet / Cell. (Later EPPlus versions have a different licence and are not covered.) Read README.md first for what is true on every page.From NPOINPOI has three families that matter here: XSSF* (OOXML workbooks), HSSF* (legacy .xls) and XWPF* (Word documents). OneDocument has one model per kind (Workbook, Document, Presentation) that opens whichever file format holds it. Read README.md first for what is true on every page.From MiniExcelMiniExcel moves rows of data and dictionaries in and out of XLSX and CSV with static methods and fills workbook templates. OneDocument has the same one-call shape for typed rows (Spreadsheet.Read / Write), a forward-only cursor for the lowest-level streaming, the full…From ShapeCrawlerShapeCrawler edits PowerPoint files through a presentation object with slides and shapes. OneDocument's Presentation is the same idea on a lossless model, with templating and PDF output, and it reads legacy .ppt. The names below follow ShapeCrawler's published documentation…From Xceed DocXDocX loads a Word document with DocX.Load, exposes Paragraphs, Tables, InsertParagraph, ReplaceText and AddTable, and saves. OneDocument's Document covers the same ground on the lossless model, and adds templating, conversion and rendering. Read README.md first for what is…
Word-processing documents
Authoring contentThe hub types add content through small calls that write through the markup tree and the generated views. Everything else in the part stays as it was: unknown elements, attributes, prefixes, mc:AlternateContent and extLst keep their place, and the parts an authoring call does…Styles and numberingHow the document hub resolves formatting and list labels. References are to ECMA-376 Part 1 (5th edition) unless noted. Where Word's behaviour is not settled by the text, the rule below is what the hub does today and the item is marked to check against Word.Tables, sections, headers and footersHow the document hub reads and edits them. References are to ECMA-376 Part 1 (5th edition) unless noted. Items marked to check against Word are what the hub does today where the text leaves the answer open.Fields, notes and commentsHow the document hub reads and edits fields, footnotes and endnotes, and comments. The model holds codes and cached results; evaluating a field that needs layout (page numbers, tables of contents) is not done here.Content controlsDocument.ContentControls() enumerates every w:sdt of the main part and of its headers, footers, footnotes and endnotes in document order (a control before the controls nested in it). BlockContentControl.Control and InlineContentControl.Control reach the same model from the…Text boxes, stories and propertiesDocument.TextBoxes() lists the text boxes of every story (body, headers and footers, footnotes, endnotes, comments); BlockContainer.TextBoxes() and Paragraph.TextBoxes() list the ones anchored in one container or paragraph. A TextBox is a BlockContainer over one…Tracked changesThis note states what the revision model (RecursiveAI.OneDocument.Documents.Revisions) does. The XML documentation on each type states the details. Section numbers are ECMA-376 Part 1 (5th edition) unless noted.Word binary (.doc)RecursiveAI.OneDocument.Doc.Binary (package .Documents) reads Word 97, 2000, 2002, 2003, 2007, 2010 and 2013 binary documents, Word 6.0 and Word 95 documents, and files that were saved incrementally ("fast saved"). Reading only: DOC writing is not planned for 1.0. A DOC…RTFRTF is read into and written from the word-processing hub (Document). The format has no part structure to keep byte-for-byte, so the lossless layer is a group tree of the file, and the hub is the WordprocessingML model: a document read from RTF is a WordprocessingML package…Word and Excel 2003 XMLBoth formats are read-only. A file opens as a Document or a Workbook by conversion: the reader turns the 2003 file into an in-memory OOXML package (DOCX or XLSX) on the markup layer and the hub wraps that package like any other. What the hub then holds saves as DOCX or XLSX…HTMLHTML reads into the word-processing hub and the hub writes it back. Both directions report what they could not carry.MarkdownCommonMark 0.31.2 with the GitHub Flavored Markdown extensions, into and out of the document hub, and out of workbooks and presentations.OpenDocument text (ODT)OpenDocument files have a native layer in the core package (RecursiveAI.OneDocument.Odf) that the text, spreadsheet and presentation units share, and a conversion into and out of the word-processing hub in .Documents. This note covers both; spreadsheets and presentations add…
Workbooks
The workbook modelRecursiveAI.OneDocument.Spreadsheets holds the SpreadsheetML hub: Workbook, Worksheet, Cell, the cell store and the shared string table. This note states what they do; the XML documentation on each type gives the details. Defect codes are in defects.md (prefix xlsx.).Styles, tables and namesRecursiveAI.OneDocument.Spreadsheets models the rest of the workbook around the cells (ECMA-376 Part 1 §18). Every model is a view over the part's markup tree: what the model does not read (extension lists, unknown attributes and elements, attribute order, prefixes) stays…Streaming rowsRecursiveAI.OneDocument.Spreadsheets.Streaming reads and writes XLSX, XLSM and Flat OPC workbooks as a forward-only stream of rows and cells, beside the workbook hub (spreadsheets.md), not through it. Use it when the sheet is larger than you want in memory or when you only…Rows of plain objectsSpreadsheet.Read and Spreadsheet.Write move rows of plain classes, structs and records to and from XLSX, CSV and TSV in one call. They sit on the streaming cursors (spreadsheets-streaming.md) and the CSV layer (csv.md), so memory stays constant however many rows there are.…RecalculationNamespace RecursiveAI.OneDocument.Spreadsheets.Calc, in the .Spreadsheets package, over the evaluator in calc.md. Entry points: Workbook.Recalculate, Workbook.RecalculateAll, Cell.SetDynamicArrayFormula, and onedocument recalc.Pivot tablesNamespace RecursiveAI.OneDocument.Spreadsheets.Pivots, in the .Spreadsheets package. Entry points: Workbook.PivotCaches, Worksheet.PivotTables, PivotTable.Refresh, Workbook.RefreshPivots, and GETPIVOTDATA in formulas. Sources: ECMA-376 Part 1 §18.10 (pivotCacheDefinition…Formulas and the evaluatorNamespace RecursiveAI.OneDocument.Calc in the core package. This page is the contract the function families, the workbook binding, recalculation and the template engine build on. Excel is the specification for anything the text below does not settle; rules settled by a run…FunctionsThe functions registered by FunctionRegistry.CreateDefault() for these four families, written from Microsoft's per-function reference pages. Columns: status is docs when the behaviour follows the reference page and its examples (covered by FunctionFamilyTests), pending when…Number formatsNormative notes for RecursiveAI.OneDocument.NumberFormats: Excel's number-format code language as one shared service, and the date-serial rules it and the workbook need. The calc engine's TEXT and VALUE, cell rendering, text export and templates all call it, so a value reads…CSV and TSVDelimited text is a native layer of RecursiveAI.OneDocument.Spreadsheets (namespace RecursiveAI.OneDocument.Spreadsheets.Csv): a streaming reader, a value parser, a streaming writer, and a bridge to the workbook model. The rules below are RFC 4180 (§2, definitions of the…Binary workbooks (.xlsb)RecursiveAI.OneDocument.Xlsb (in the spreadsheets package) reads and writes the Excel binary workbook ([MS-XLSB]). The format is an OPC package whose parts hold records instead of XML. Workbook.Open finds it from the content (the workbook part's content type), shows it…Legacy workbooks (.xls)RecursiveAI.OneDocument.Spreadsheets.Biff reads Excel 2.0 to 2003 workbooks and converts them to the SpreadsheetML hub (Workbook). Reading follows [MS-XLS] (BIFF8); the layouts of BIFF2 to BIFF5 are not in that specification and are read from the files themselves (see "What…OpenDocument spreadsheets (ODS)ODS, OTS and flat FODS (OpenDocument 1.2 and 1.3) read into the workbook hub and write back out, with a loss report each way. The package layer (OdfPackage, odf.md) does the zip, manifest and flat-file work; this page covers the spreadsheet conversion in…
Presentations
The presentation modelRecursiveAI.OneDocument.Presentations holds Presentation, Slide, SlideLayout, SlideMaster, NotesSlide, NotesMaster, Shape, TextBody/Paragraph/Run and Table. It is a set of views over the lazy markup tree of each part; nothing is copied out of the part buffers. The XML…PowerPoint binary (.ppt)Presentation.Open, Office.Open, Office.ExtractText and Office.Convert read PowerPoint binary presentations. The file is read at record level (RecursiveAI.OneDocument.Ppt.Binary, on the shared OfficeArt reader in officeart.md), converted to PresentationML in memory, and the…OpenDocument presentations (ODP)Presentation.Open accepts ODP, OTP and flat FODP by content (the mimetype entry or office:mimetype), never the extension. The file is converted to an in-memory PPTX package, and the hub wraps it like any PPTX; Presentation.Format stays Odp, Otp or Fodp, and…
Templates and operations
TemplatesNamespace RecursiveAI.OneDocument.Templating in the core package. This page states the template syntax, the extensions to Excel formula syntax, how the engine reads data, the contract a document binder implements, and the defect codes (the full catalogue is in defects.md).…Word templatesNamespace RecursiveAI.OneDocument.Documents.Templating in the documents package. The engine, syntax, data model and defect codes are in templating.md; this page states how the document binder reads a document, what the blocks repeat, and what the data-fed tags insert.Workbook templatesXlsxTemplateBinder.Render(workbook, data, options, xlsxOptions) (namespace RecursiveAI.OneDocument.Spreadsheets.Templating) renders a workbook template with the engine described in templating.md. The workbook is edited in place and comes back as the result; sheets with no tag…Presentation templatesNamespace RecursiveAI.OneDocument.Presentations.Templating in the presentations package. PresentationTemplate.Render(presentation, data, options) fills a template presentation in place; Validate checks it without data; Render(Stream template, data, Stream output) opens…Mail mergeDocument.MailMerge(data, options) runs Word's mail merge on a main document: the merge fields are replaced by their results for each record, the mailMerge connection is removed, and the output is a new document per record or one document holding every record. The data is read…Merge, append and splitOperations that combine documents, cut them apart, and store layout-time field results in the file. They edit the hub (the markup of the parts they change); parts they do not change stay as stored, and edited parts keep their unknown markup, prefixes, mc: blocks and extLst.…Find and replaceSearch and replace over the text of a document, a workbook or a presentation, as the reader sees it. The same matcher serves the three kinds (RecursiveAI.OneDocument.Operations: SearchOptions, TextSearch, ReplaceReport); each kind walks its own text.ProtectionEditing restrictions and the passwords that lift them, for the three kinds. Read, set, verify and remove.
Hidden content and security
Inspect and sanitizeOffice.Inspect(path) reports what a file holds that a reader does not see; Office.Sanitize(input, output) removes it into a new file and proves the result is clean. Inspector and Sanitizer (namespace RecursiveAI.OneDocument.Inspection) take streams, an open package and the…Sanitizer review (the project’s own)The project's own review (not an external audit) of Inspector and Sanitizer (docs/sanitize.md): for every category inspection reports, does it find every instance, and does sanitising remove every instance it says it removed? The checks are committed as tests…RedactionTrue redaction removes content from the file, not from the view. OfficeFile.Redact(plan, path) (and Office.Redact(source, destination, plan)) takes a RedactionPlan of matches (a literal or a regular expression) and regions (paragraphs, cell ranges, shapes, slides), writes a…Redaction review (the project’s own)The project's own review (not an external audit) of Office.Redact / OfficeFile.Redact. The question: after a match or region is redacted, can the removed text be recovered from the output file by any means? The method was to list every place a string can live from the format…VBA projectsVBA is data here: it is read, listed, extracted and removed. It is never compiled, interpreted or run, the p-code is never decoded, and no password is cracked. Namespace RecursiveAI.OneDocument.Vba (core). Specification: Office VBA File Format Structure ([MS-OVBA]); where the…Encrypted filesPassword-protected files open when the caller supplies OpenContext.Password (Document.Open, Workbook.Open, Presentation.Open, Office.Open). Without a password, or with a wrong one, the reader raises OfficeEncryptedException (encryption.password-required /…OLE objectsHow the legacy formats' document properties and embedded objects are read, written and carried into the hub. Namespace RecursiveAI.OneDocument.Ole (core). Specifications: [MS-OLEPS] (property set data structures), [MS-OSHARED] §2.3.3.2 (the Summary Information, Document…Accessibility checkingDocument.CheckAccessibility(), Workbook.CheckAccessibility(), Presentation.CheckAccessibility() and the one-liner Office.CheckAccessibility(path) check a file against Office's published accessibility rules and return an AccessibilityReport. Checking reads the model and edits…
Rendering
Layout and PDFWorkbooks print through their own pagination and cell layout: see spreadsheet-rendering.md. They share the paint contract, fonts and PDF/PNG output below; RenderingFormats.Register installs one handler per format that dispatches on the kind of file.Tables in layoutHow LayoutEngine lays out and paints Word tables. It builds on the layout tree and paint contract in layout.md and on the logical table model in docx-tables-sections.md (grid, spans, vertical merges, resolved table-style regions). References are to ECMA-376 Part 1 unless…Floating objectsHow anchored objects are positioned and how text goes round them. Code: Layout/Floats/, with hooks in the paragraph formatter, the page flow and the painter. DrawingML painting itself is in drawingml-rendering.md.Page fields and tables of contentsFields that depend on pages, and the table of contents, index and table of authorities, are resolved while a document is laid out (LayoutEngine.Layout, so also DocumentRenderer, Office.Convert and document.SaveAs("x.pdf")). The document is only read: results go to the pages…Printing workbooksHow OneDocument prints a workbook the way Excel does: which cells land on which page, how a cell's text is formed and placed, and what is painted. Package RecursiveAI.OneDocument.Rendering, namespace RecursiveAI.OneDocument.Rendering.Spreadsheets. References are to ECMA-376…Slides to PDF and imagesHow a presentation becomes PDF and PNG pages. Namespace RecursiveAI.OneDocument.Rendering.Presentations, in the RecursiveAI.OneDocument.Rendering package. The hub it reads is described in presentations.md, the shape painter in drawingml-rendering.md, the shared paint contract…Page images and SVGPageExporter writes the pages of a document, workbook or presentation as PNG, JPEG, TIFF, WebP or SVG. Pages are laid out once (the layout of each kind is described in layout.md, spreadsheet-rendering.md and presentation-rendering.md), painted into a OneRender display list…Shapes and picturesHow shapes, pictures and groups are painted. One painter serves Word drawings, slide shapes and worksheet drawings: RecursiveAI.OneDocument.Rendering.Drawing.DrawingPainter. It reads the shape elements (wps:wsp, p:sp, p:cxnSp, pic:pic, p:pic, wpg:wgp, p:grpSp) and never asks…ChartsHow OneDocument reads, lays out and paints charts. Namespace RecursiveAI.OneDocument.Charts in RecursiveAI.OneDocument.Rendering (src/OneDocument.Rendering/Charts/). References are to ECMA-376 Part 1 §21.2 (DrawingML charts) and [MS-ODRAWXML] (chartex) unless noted.SmartArtHow OneDocument paints SmartArt diagrams in Word, PowerPoint and Excel drawings. Namespace RecursiveAI.OneDocument.Rendering.SmartArt (src/OneDocument.Rendering/SmartArt/). A diagram is a graphic frame (dgm:relIds) that points at four parts, plus an optional fifth that Office…EquationsOffice Math (OMML, ECMA-376 Part 1 §22.1) is read into a typed tree, laid out with a TeX-style box layout driven by the math font's OpenType MATH table, and painted with the paragraph it sits in. The tree is a view over the markup (nothing is rewritten); the layout is a…EMF and WMF picturesHow OneDocument draws embedded Windows metafiles. Namespace RecursiveAI.OneDocument.Rendering.Metafiles, package RecursiveAI.OneDocument.Rendering. The interpreter is OneImage's (RecursiveAI.OneImage.Metafile: it reads the file and plays it as a stream of device-independent…
File internals
Packages and compound filesHow RecursiveAI.OneDocument.Packaging reads and writes the containers under every format. Defect codes are in defects.md; limits in contracts.md.The markup treeThis note states the behaviour of the XML layer (RecursiveAI.OneDocument.Markup.Xml and RecursiveAI.OneDocument.Markup). The XML documentation on each type states the details.OfficeArtRecursiveAI.OneDocument.OfficeArt reads the drawing layer ([MS-ODRAW]) that the binary Word, Excel and PowerPoint formats share. It is a record-level reader: it finds, bounds and decodes records and leaves their host-specific meaning to the format that embeds them.Text extractionOoxmlTextExtractor (namespace RecursiveAI.OneDocument.TextExtraction) extracts the text of word-processing, spreadsheet and presentation packages by streaming the parts that hold text from an OpcPackage (zip or Flat OPC). It reads tokens from the markup reader and builds…Defect codesA defect's Code is a stable, lower-case, dot-separated identifier: .. The first segment names the layer that found it. A code is never reused for another meaning. Each layer adds its codes here when it adds the check; the tests of that layer assert them.
Results
The 1.0 gatesWhat was run over the public corpus before 1.0, with the numbers and an explanation for every difference. The runs are one pass each, driven by tools/gate/gate.sh (stages), the probes under tools/, and the pinned oracles (LibreOffice 26.8.2.2, Jing 20241231 with the ODF 1.3…Checks against OfficeWhat desktop Word, Excel and PowerPoint did with OneDocument's output, and what OneDocument got wrong or right against them. The oracle drives the applications through COM from a scheduled task in a signed-in user session (tools/office-oracle); only files we generated were…FuzzingThe 1.0 fuzz campaign: every target in fuzz/run.sh for 600 s under libFuzzer with SharpFuzz instrumentation (the library assemblies and OneArchive), one process and one core per target, seeded from each target's WriteSeeds corpus. How to run and add targets: fuzz/README.md.ChangelogAll notable changes are listed here. The format follows Keep a Changelog and the project follows Semantic Versioning.