Recursive AI

Changelog

All onedocument docs

All notable changes are listed here. The format follows Keep a Changelog and the project follows Semantic Versioning.

[Unreleased]

[1.0.0] - 2026-11-06

Read, write, calculate, template and render Word, Excel and PowerPoint documents (OOXML, legacy binary, RTF, ODF) in pure .NET. Not affiliated with Microsoft.

First release. OneDocument is a clean-room document processor for net10.0 on the .NET base class library and other Recursive AI libraries; it is NativeAOT-, trim- and browser-WebAssembly-friendly.

Highlights:

  • Lossless models (Document, Workbook, Presentation) over the file's own markup: parts you do not edit are written back byte-identical, and edits keep unknown markup in order.
  • Formats: OOXML (Transitional, Strict, macro-enabled, templates, Flat OPC), XLSB, BIFF8 XLS, RTF, CSV/TSV, ODF and flat ODF are read and written; DOC, PPT, BIFF2 to BIFF5 and the 2003 XML formats are read; HTML and Markdown are imported and exported; encrypted files open with a password.
  • A calculation engine with Excel's semantics (dynamic arrays and spill, LET/LAMBDA, structured and 3D references, iterative calculation, data tables, Goal Seek, pivot refresh, multi-threaded recalculation) and Excel's number-format language as a shared service.
  • One template engine across Word, Excel and PowerPoint files, plus mail merge and content-control binding.
  • Rendering to tagged PDF (PDF/UA-1, PDF/A-2a), PNG, JPEG, TIFF, WebP and SVG, with a public layout tree.
  • Operations: merge, append, split, find and replace, revisions, field and table-of-contents update, protection, inspect and sanitise, true redaction verified by re-extraction, accessibility checking, VBA read, extract and remove.
  • Generated, zero-copy typed views over every pinned ECMA-376 and Microsoft extension schema (RecursiveAI.OneDocument.Schema).
  • The onedocument tool: detect, extract, recalc, template, render, convert, inspect, sanitize.

Known limitations (the support table in the README has the numbers and every gap):

  • RecursiveAI.OneDocument.Cryptography (signatures, Agile OOXML and ODF encryption on write) has no content yet and is not in RecursiveAI.OneDocument.All; it follows in a 1.x release.
  • Browser WebAssembly has no Aes or MD5: opening Agile or Standard encrypted OOXML and RC4-MD5 files there raises OfficeUnsupportedException.
  • Formula text is en-US and invariant only; localized function names are not supported.
  • DOC and PPT are read-only. XOR-obfuscated BIFF8 workbooks are unconfirmed against Excel.
  • Agreement with the Accessibility Checker and with some Document Inspector categories could not be measured (Office has no automation for them).
  • PDF/A-2a output fails one veraPDF rule in some files (a private-use character without ActualText).
  • There is no forward cursor for ODS (it reads through the model).

Details

  • Tagged output gains the structure roles Note (footnote and endnote bodies; Div under PDF/UA-1 until the PDF writer writes /ID on Note), Reference (note marks and the result of REF, PAGEREF and NOTEREF fields), TOC and TOCI (paragraphs in the TOC1 to TOC9 styles) and Formula (equations), and artifacts carry their kind (header, footer, watermark, repeated table header row, line numbers, note separators). SVG pages size their scopes from layer bounds.

  • Presentation reports conversion the way Document does: ImportLoss (PowerPoint 97-2003 and OpenDocument sources) and SourceFormat; Workbook and Presentation report ExportLoss for every lossy export, Markdown included.

  • Forward cursors for binary workbooks. XlsStreamReader and XlsSheetCursor read .xls files (BIFF8, and BIFF2 to BIFF5) row by row from the file without building the workbook: cached formula results, shared strings, dates through the number-format service and the 1900 and 1904 date systems, password-protected files decrypted as the model path does. XlsbStreamReader and XlsbSheetCursor (already present) now build each shared string once and read records faster. All three cursors have the same members, Spreadsheet.Read<T>, Spreadsheet.ReadRows and Office.ExtractText read .xls and .xlsb through them, and Office.ExtractText now supports .xls (BIFF2 to BIFF8) and .xlsb without building the model. Part streams of a compound file can seek. New defect codes xls.stream-row-order and xls.stream-cell-order; fuzz targets xlscursor and xlsbcursor. See docs/spreadsheets-streaming.md.

  • Page export (PageExporter, PageExportOptions, PageSelection, PageImageFormat): every page, or a chosen range, of a document, workbook or presentation as PNG, JPEG, TIFF (one multi-page file), WebP or SVG, at a dpi or a pixel size, through OneRender's image backend and OneImage's encoders; SaveAs and Office.Convert pick the format by extension. RecursiveAI.OneDocument.Rendering.Svg.SvgWriter writes a display list as SVG 1.1 (gradients, clips, groups with blend modes, filters, one-layer masks, images, borders, shadows, glyph runs as text or outlines, semantic tags as roles, labels and links; what SVG cannot express is embedded as an image by a caller-supplied rasterizer); it depends only on OneRender's display-list types. onedocument render takes the new formats, --pages, --dpi, --width, --height, --quality and --svg-glyphs. See docs/rendering-export.md.

  • Fixes found while hardening. A default password (VelvetSweatshop, PowerPoint's read-only password) is tried only when the caller gives none, never after a wrong one. RC4 CryptoAPI files whose header clears fDocProps keep their document properties in an EncryptedSummary stream, which the XLS, DOC and PPT readers now decrypt (BinaryRc4Encryption.TryReadEncryptedSummary). InMemoryPackage.WriteTo/SaveAs write an Open Packaging Conventions zip that opens again (it wrote a private listing that did not). XLSB sheets no longer put the elements after the hyperlinks inside hyperlinks. Document.TextBoxes no longer serves a cached box whose content was replaced, and a box met through a link chain keeps its alternate copy. The command-line tool prints no dangling "at" for a defect without a location. Schema validation of written files treats two known gaps between the Transitional schemas and what Excel and PowerPoint write (xml:space on the spreadsheet t, the integer a:buSzPct) as such, in tools/validate. The tool defaults for oracle and cache locations are now ~/.onedocument. See docs/contracts.md for how formats get registered.

  • Find and replace and protection. Document.Find/Replace, Workbook.Find/Replace and Presentation.Find/Replace search the text a reader sees (documents across runs, hyperlinks, bookmarks, field results, content controls and other authors' insertions; workbook cells with rich text kept and formulas replaced only when the new text parses; presentation paragraphs across runs) with literal, whole-word, case and regular-expression modes (SearchOptions, TextSearch; timeout from OfficeLimits.RegexMatchTimeoutMilliseconds, linear-time engine where the pattern allows), keep the formatting of the first matched run, and return a ReplaceReport of located replacements and issues; documents can replace as tracked w:del/w:ins. Protection is read, set, verified and removed with the hashes the formats define (PasswordVerifier, SHA-512 by default, seeded salt; Word 2007 and Excel 16-bit hashes read): Document.Protection, WriteProtection and editing exceptions, Worksheet.Protection with protected ranges, Workbook.Protection and FileSharing, Presentation.Protection. Deleting text right after an anchored drawing, text box or note reference as a tracked change no longer deletes the object. See docs/operations-find-replace.md and docs/protection.md; tools/FindReplaceProbe checks replacement over a directory.

  • True redaction: OfficeFile.Redact and Office.Redact remove literal or regular-expression matches (across runs, in field codes and results, comments, notes, headers, text boxes, alt text, link targets, names, properties, custom XML, chart caches and embedded chart workbooks, SmartArt, speaker notes, layouts, shared strings, formulas and cached values, pivot caches and external-link caches) and regions (paragraphs, cell ranges, shapes, slides) from all three kinds, write a new OOXML file (legacy and other inputs are redacted through the hub), then re-open it and search every entry, decompressed, for survivors; RedactionReport lists what was removed, what could not be (typed gaps) and whether the output verified. See docs/redaction.md.

  • Inspect and sanitise (RecursiveAI.OneDocument.Inspection, docs/sanitize.md): Office.Inspect(path) reports the hidden data and personal information of a document, workbook or presentation by category (comments, revisions, properties, personal information, custom XML, headers and footers, hidden text, hidden and off-slide shapes, hidden rows, columns, sheets and slides, notes, ink, macros, external links, add-ins, thumbnails and more) with counts and locations; Office.Sanitize(input, output) and Sanitizer remove the categories the caller selects into a new file, report what was removed and what stays and why, inspect the written file again and refuse to write it if a removed category is not empty. Legacy and RTF files are inspected and sanitised through the hub and written as OOXML. CLI: onedocument inspect and onedocument sanitize.

  • Markdown read and write: RecursiveAI.OneDocument.Documents.Markdown has a CommonMark 0.31.2 parser with the GitHub Flavored Markdown extensions (tables, task lists, strike-through, extended autolinks, footnotes) whose time is linear in the input and whose nesting follows OfficeLimits.MaxRecursionDepth; all 652 CommonMark examples and the 28 GFM extension examples pass. Document.OpenMarkdown, ParseMarkdown, Document.Open(path, OfficeFormat.Markdown), Office.Open(path, OfficeFormat.Markdown) and Office.Convert from a .md name read Markdown into the document model (headings, lists with start numbers, quotes, code, tables with alignment, links, footnotes, front matter as properties; pictures from data: addresses or an opt-in MarkdownImportOptions.ImageResolver); Document.ToMarkdown, WriteMarkdown and SaveAs("x.md") write GFM, with MarkdownExportOptions.ImageSink for pictures; Document.ImportLoss and ExportLoss list what did not map. Workbook.ToMarkdown writes a table per sheet with displayed values and Presentation.ToMarkdown a section per slide with its notes. The template markdown tag now uses the same parser. See docs/markdown.md; new defect codes markdown.*; fuzz targets markdown and markdownparse.

  • HTML import and export: Document.FromHtml and Document.Open (by content) read a page with OneHtml's parser and cascade into the word-processing hub (computed styles to paragraph and character formatting and to named styles, headings, nested and numbered lists, tables with spans, header rows, widths, borders and shading, links and anchors, data-URI pictures, preformatted text, quotes, rules, page-break CSS, direction and language). The import is sanitised by default: scripts, event handlers, script-capable link targets, forms, frames, objects and external images never reach the model, and each is a LossReport item and an html.dropped defect; HtmlImportOptions carries the one switch that keeps inert text and an image resolver. Document.ToHtml, SaveAsHtml and SaveAs("x.html") write a self-contained HTML5 page or fragment (styles as classes, lists, tables, linked end notes, pictures as data URIs or through a caller's sink); Workbook.ToHtml and Presentation.ToHtml write tables and per-slide sections. The template engine's html tag now runs on the same importer. See docs/html.md.

  • VBA projects as data (RecursiveAI.OneDocument.Vba, docs/vba.md): VbaProject.Open finds the project in any OOXML package, a DOC (Macros), an XLS (_VBA_PROJECT_CUR) or a PPT and lists its modules with kind and source text, references, project information, protection (CMG/DPB/GC reported, never opened), signature streams (located, not verified) and a p-code flag ("source and p-code may disagree"); modules export as .bas/.cls/.frm. VbaRemoval.Remove writes a copy without the project (DOCM to DOCX, XLSM to XLSX, PPTM to PPTX and the template and slide-show kinds; DOC, XLS and PPT stay in their format) and returns a report of what was removed and what was left; Document, Workbook and Presentation have GetVbaProject() and RemoveVbaProject(). Nothing is run and the p-code is never decoded. vba.* defects are in docs/defects.md. Saving a Word macro-enabled template now writes the content type Word uses (macroEnabledTemplate).

  • RTF 1.9.1 read and write: RecursiveAI.OneDocument.Rtf (core) has the tokenizer, a lossless group tree (RtfTree), RtfWriter, the rtf.* defects and the mail-body layer (RTF to HTML and text, HTML and text encapsulation, compressed RTF); .Documents converts RTF to and from the word-processing model. Document.Open finds RTF by content, SaveAs("x.rtf"), Office.ExtractText and Office.Convert work in both directions, Document.ImportLoss and ExportLoss list what each direction could not carry, and RTF saved without an edit keeps its bytes. See docs/rtf.md.

  • Legacy Excel workbooks (RecursiveAI.OneDocument.Spreadsheets.Biff): Workbook.Open, Office.Open, Office.ExtractText and Office.Convert read BIFF2 to BIFF8 files (a Workbook or Book stream in a compound file, or a bare BIFF stream) into the spreadsheet hub: cells, cached formula results, shared, array and data-table formulas, styles, names, merges, rows and columns, views, hyperlinks, comments, data validation, conditional formats, page setup, protection and pictures. BiffRecordSet keeps every record; PtgDecoder/PtgEncoder turn formula tokens into the public formula tree and back; XlsConverter and Workbook.ImportLoss report what the hub cannot carry. Encrypted files raise the encrypted exception. New defect codes biff.*; fuzz targets xls and ptg; tools/XlsProbe reads a directory of files. See docs/xls.md.

  • Office 2003 XML: Document.Open, Workbook.Open, Office.Open, Office.ExtractText and Office.Convert read Word 2003 XML (WordprocessingML 2003: styles, lists, sections with headers and footers, tables, fields, hyperlinks, bookmarks, footnotes and endnotes, comments, tracked insertions and deletions, pictures and text boxes, properties) and Excel 2003 XML (SpreadsheetML 2003: sheets with index gaps, spans and merges, every data type and rich text, R1C1 formulas through the public formula AST, array formulas, styles with inheritance, names, comments, hyperlinks, conditional formats, data validation, panes and page setup, properties) by converting them into the DOCX and XLSX hubs; Document.ImportLoss and Workbook.ImportLoss list what did not map, and repairs are wml2003.* and sml2003.* defects. WordMl2003 and SpreadsheetMl2003 are the entry points. Reading only. See docs/xml-2003.md.

  • SmartArt in rendering: RecursiveAI.OneDocument.Rendering.SmartArt paints diagram frames in Word, PowerPoint and Excel drawings (DrawingContext.DiagramPainter, DiagramHost.CreatePainter). The drawing Office stores with a diagram is painted as ordinary shapes with their text; when it is missing or stale, or on request (DiagramRegeneration), the layout definition of ECMA-376 Part 1 §21.4 is run against the data model (lin, snake, cycle, pyra, composite, hierRoot/hierChild, conn, sp, tx; constraints, forEach/choose over the axes, colour and style definitions, text fitting) and its shapes are painted the same way. DiagramHost.Find, Generate and ReadStored inspect diagrams. See docs/smartart.md. Slides and worksheet drawings install the same painter, so a diagram without a usable stored drawing is regenerated there too (PresentationRenderOptions.Diagrams, SheetRenderOptions.Diagrams).

  • Word binary files (DOC) are read: RecursiveAI.OneDocument.Doc.Binary (DocFile, DocFib, PieceTable, PropertyRuns, Prl, SprmReader, DocReader, DocStyleSheet, DocLists, DocTextExtractor) reads Word 97 to 2013 files, fast-saved files and Word 6.0/95 files, and Document.Open, Office.Open, Office.Convert and Office.ExtractText accept them by content. A DOC is converted into the WordprocessingML model (text, character, paragraph, table and section formatting, styles, lists, fields, bookmarks, notes, comments, headers and footers, tracked changes, inline and floating pictures); Document.SourceFormat and Document.ImportLoss say what it was and what the model could not hold. Text extraction reads the piece table without building the model. Encrypted files raise OfficeEncryptedException. Reading only. See docs/doc.md; new defect codes doc.*.

  • PowerPoint 97-2003 files (.ppt): Presentation.Open, Office.Open, Office.ExtractText and Office.Convert read them. RecursiveAI.OneDocument.Ppt.Binary reads the Current User and PowerPoint Document streams at record level (user-edit chain and persist directory with the last edit winning, masters, slides, notes, handout, text and style runs, rulers, fields, comments, hyperlinks, transitions) and converts them to PresentationML with a loss report (Presentation.ImportLoss, also defects with record offsets); encrypted files raise the encryption exception. RecursiveAI.OneDocument.OfficeArt is the shared record-level reader for the drawing layer (records, shapes and groups, property tables, the BLIP store and pictures). FormatSniffer classifies compound files with a damaged allocation table by retrying in recovery mode. See docs/ppt.md and docs/officeart.md.

  • Fields in layout: page-dependent fields (PAGE, NUMPAGES, SECTIONPAGES, SECTION, PAGEREF, NOTEREF, REF, STYLEREF, SEQ) are computed from the pages in headers, footers and the body, with the \*, \# and \@ switches; table of contents, index and table of authorities are built (TOC, INDEX/XE, TOA/TA, TC) in a private copy of the document, and layout runs again with the facts of the pass before until they settle (LayoutOptions.MaxFieldPasses, LayoutDocument.FieldPasses, note layout.fields-unsettled). LayoutOptions.UpdateFields (and w:updateFields in a file) also computes dates, document properties, IF, = (on the calc engine, with table references), SYMBOL and QUOTE; LayoutOptions.Clock supplies DATE and TIME. See docs/layout-fields.md.

  • Footnotes and endnotes in layout: reference marks numbered per footnotePr/endnotePr (format, start, restart each section or page, custom marks), footnotes at the bottom of their page or column (or beneath the text) behind the separator, notes taking space from the body, the reference-line rule, long notes split with the continuation separator and notice, endnotes at the end of the section or document; LayoutPage.NoteBlocks, LayoutNoteBlock, LayoutNoteRole. See docs/layout.md.

  • Equations (Office Math): RecursiveAI.OneDocument.Equations reads every OMML object into a typed tree (OmmlReader, MathNode, MathSettings for m:mathPr) and writes UnicodeMath-style linear text (MathLinearizer), which Office.ExtractText now returns for equations in Word and PowerPoint text. Rendering lays them out with the font's OpenType MATH table (MathLayouter, MathTable; Noto Sans Math stands in for Cambria Math) inline and as display math with justification and breaking at operators, paints them in the layout (LayoutRunKind.Math, LayoutRun.Math) and tags each as a figure with the linear text as alternative text. See docs/math-layout.md.

  • Spreadsheet print rendering (RecursiveAI.OneDocument.Rendering.Spreadsheets): WorkbookRenderer lays out and paints worksheets as Excel prints them (print areas and titles, paper, margins, scale and fit-to-page, manual and automatic breaks, page order, centring, hidden rows and columns, headers and footers with their codes, gridlines and headings), with cell text from the number-format service (####, fill, colours), alignment, indent, wrap, shrink, rotation, overflow, merges, fonts, fills, all border styles, rich text and conditional formats (rule formats, colour scales, data bars with negative axis, icon sets as vector paths); tagged as tables; drawing anchors resolved to page boxes for the drawing and chart painters. Workbook.SaveAs("x.pdf") and Office.Convert("in.xlsx", "out.pdf") write PDF and PNG. Hub additions: Worksheet.LayoutMarkup, Worksheet.TryGetSharedStringIndex, SharedStringTable.GetItemXml, Workbook.EvaluateFormula. See docs/spreadsheet-rendering.md.

  • Rendering presentations (PresentationRenderer, PresentationRenderOptions): slides compose their background, master and layout graphics and own shapes in z-order with placeholder inheritance of position, geometry, fill, line and text style; text bodies are laid out by OneDocument's own text layout (insets, anchors, vertical text, columns, wrap none, rotation and upright, levels 1 to 9, bullets and automatic numbers with restarts, indents, tab stops, line and paragraph spacing, justification, bidirectional text, fields, hyperlinks), with autofit as stored, computed in PowerPoint's steps, or by resizing the shape; tables with table styles, merged cells, borders and margins; charts, saved SmartArt drawings and object previews; hidden slides skipped unless asked; notes pages and handouts; tagged PDF (headings, lists, tables, figures with alternative text, artifacts) and PNG; equations in slide text laid out inline; Office.Convert("deck.pptx", "deck.pdf"), presentation.SaveAs and onedocument render for documents, workbooks and presentations. The shape painter gained hooks for placeholders, frames and tags, and DrawBackground. See docs/presentation-rendering.md; the generated decks in testdata/slides are inputs for the PowerPoint layout differential.

  • Metafiles in rendering: PictureHook and MetafilePainter draw embedded EMF, EMF+ and WMF pictures as vector content in the display list (paths, strokes, hatch, pattern, gradient and texture brushes, clips, bitmaps, gradients, text and EMF+ strings as glyph runs), sniffing the bytes when the media type is missing; pictures the display list cannot express (raster operations, triangle gradients, union clips) are drawn as one bitmap, with defects naming the reason. OneImage packages move to 1.11.0-preview.2. See docs/metafiles.md.

  • Rendering (RecursiveAI.OneDocument.Rendering): the text-layout core for paragraphs and lines (shaping through OneFont, UAX #14 breaking, tabs and leaders, indents, alignment and justification, bidirectional lines, Word line heights, list labels, borders and shading, widow/orphan, keep-with-next, keep-lines, page breaks over a single column per section), a public layout tree (LayoutDocument > pages > paragraphs > lines > runs with positions and text ranges), a font provider with Office-to-open-font substitution notes and embedded-font de-obfuscation, and painting into OneRender's display list with semantic tags. Document.SaveAs writes .pdf (tagged; PDF/UA-1 and PDF/A profiles) and .png; Office.Convert and the onedocument render/convert commands use it. Tables, headers and footers, columns, floating objects, notes and fields are reported as layout.* notes and come later. See docs/layout.md. render.failed is the new defect code for output failures.

  • Calculation of what-if features: iterative calculation (calcPr iterate, iterateCount, iterateDelta; Workbook.SetIterativeCalculation), data tables (one- and two-variable, calculated in an overlay so the grid is never touched), Workbook.GoalSeek, external links (Workbook.ExternalLinks; references read the file's cached values, or live workbooks through an opt-in IExternalWorkbookResolver, with refreshed values saved back), and WEBSERVICE/FILTERXML through an opt-in IWebServiceResolver. Nothing is opened or fetched unless the caller supplies a resolver.

  • Word mail merge: Document.MailMerge (MERGEFIELD with \b, \f, \#, \@, \*, IF, NEXT, NEXTIF, SKIPIF, MERGEREC, MERGESEQ, SET, ASK, FILLIN, REF; a document per record or all records in one with section breaks; the mailMerge connection is removed and never opened). See docs/mail-merge.md.

  • Content-control data binding: Document.BindContentControls, RefreshContentControls, PushContentControls for text, rich text, date, check box, drop-down, combo box and repeating sections; the binding XPath subset now covers //, ., .., last(), comparisons, name() and string functions.

  • The Office statics work with no registration call: each kind package compiles a module initializer into the referencing C# project (no reflection; NativeAOT and trimming keep only the referenced kinds). Register stays public and may be called any number of times; OneDocumentAutoRegister=false opts out.

  • Text boxes as block containers: Document.TextBoxes(), BlockContainer.TextBoxes(), Paragraph.TextBoxes(), TextBox (DrawingML and VML, the copy in mc:Fallback kept equal on commit, linked chains), and Document.WrapParagraph. Tracked changes and edits work on their paragraphs.

  • Document properties: Document.Properties with core, extended and custom properties (RecursiveAI.OneDocument.Properties), created on first write, untouched when not edited, no clock reads.

  • List labels for every story as Word counts them: NumberingDefinitions.LabelStories(); DocumentText.ListLabels now covers headers, footers, notes, comments and text boxes.

  • The presentation hub (RecursiveAI.OneDocument.Presentations): Presentation over PPTX, PPTM, POTX, PPSX and Flat OPC (Transitional and Strict) with masters, layouts, slides, notes, shapes, text, tables and comments; placeholder inheritance from master to slide; add, delete, duplicate and move slides, text and table-cell edits. Generated PresentationML and PowerPoint-extension views in .Schema.

  • The presentation template binder (PresentationTemplate.Render/Validate in RecursiveAI.OneDocument.Presentations.Templating): tags in shapes, placeholders, groups, table cells and notes bind across split runs; blocks repeat paragraphs, table rows, shapes or whole slides (cloned with their notes) by where their tags stand or by scope=; a shape holding only a false block is removed; {% image %} replaces a shape with a picture keeping its geometry; hyperlink targets bind per copy. A 23-template golden corpus lives under testdata/templates/pptx. See docs/templating-pptx.md.

  • The document template binder (Template.Render/Template.Validate in the core package, RecursiveAI.OneDocument.Documents.Templating, CLI onedocument template): tags in every story bind across runs; for/if blocks repeat paragraphs, table rows, tables and sections with list numbering, bookmark, comment, note, picture and paragraph ids kept unique; {% image %}, link(), {% html %} and {% markdown %} insert pictures, hyperlinks and formatted content. See docs/templating-docx.md.

  • Fixed: a package whose main part is typed only by a Default content type for xml is recognised and opens.

  • The workbook template binder carries more than cells: chart series references and cached points, pivot cache sources (refreshOnLoad), conditional-format and validation rule formulas, copies of a sheet block with their tables, conditional formats, validations, page setup, comments and drawings; tags in comments, header and footer strings and text boxes; {% image %} pictures anchored at their cell; and XlsxTemplateBinder.Validate. Table columns take the rendered header text. New defect template.image-invalid.

Foundations

  • The word-processing hub: styles with inheritance, numbering and list labels, tables with a logical cell model and edits, sections, headers and footers, fields, footnotes and endnotes, comments with replies, revisions (read, accept, reject, author) and content controls with custom XML bindings.
  • Generated typed views of the WordprocessingML elements over the markup tree (RecursiveAI.OneDocument.Schema).
  • OOXML text extraction for documents, workbooks and presentations, with located, normalized text.
  • OPC packages on zip and Flat OPC with untouched parts copied raw; compound-file access.
  • A span-based UTF-8 XML tokenizer and writer, and a lazy, lossless markup tree.
  • The onedocument tool (detect, extract).
  • Document on the word-processing hub: Open (sniffs content), Create, atomic Save, SaveAs by extension or format (DOCX, DOCM, DOTX, DOTM, Flat OPC), Paragraphs, Tables, Paragraph.SetText, Body.AddParagraph; DocumentFormats.Register.
  • Core contracts: byte sources, resource limits, typed defects and exceptions, content-based format identification, the format registry, the part/package abstraction with atomic save, and the shared base of the document types.