Snail.Toolkit.Documents 0.1.0

dotnet add package Snail.Toolkit.Documents --version 0.1.0
                    
NuGet\Install-Package Snail.Toolkit.Documents -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Snail.Toolkit.Documents" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Snail.Toolkit.Documents" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Snail.Toolkit.Documents" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Snail.Toolkit.Documents --version 0.1.0
                    
#r "nuget: Snail.Toolkit.Documents, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Snail.Toolkit.Documents@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Snail.Toolkit.Documents&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Snail.Toolkit.Documents&version=0.1.0
                    
Install as a Cake Tool

Snail.Toolkit.Documents

Reads PDF, Word, Excel, PowerPoint, HTML, CSV, JSON, Markdown and text into one Markdown text, with its pages, headings and tables — in .NET, with no Office, no LibreOffice and no network.

var reading = await DocumentReader.Every.ReadAsync(File.OpenRead("invoice.pdf"), "invoice.pdf");

if (reading.TryGetDocument(out var document))
    Console.WriteLine(document.Text);
else
    Console.WriteLine($"{reading.Failure}: {reading.Reason}");

What it reads

Format Extensions Read as
Word .docx .docm headings, paragraphs, lists, tables, content controls
Excel .xlsx .xlsm .xls a part per sheet, its used cells one table under the letters of the columns and the numbers of the rows
PowerPoint .pptx .pptm a part per slide: its title, text, tables and the speaker's notes
PDF .pdf a part per page, its text layer in reading order; a page without one is marked as a scan
HTML .html .htm headings, paragraphs, lists, tables; scripts and styles left out
CSV .csv one table, the separator taken from the first line
TSV .tsv one table, split by tabs
JSON .json a list of flat records as a table, anything else as indented JSON
Markdown, text .md .markdown .txt .text .log as written

Text files are read as UTF-8, or by their byte order mark, and as Windows-1251 when they are not valid UTF-8 — the way a Russian Excel saves a CSV.

A document

Document is the whole text as Markdown and where everything in it stands: Parts (pages, sheets, slides, each with where its text starts and ends), Sections (each heading with the stretch of text it opens, to the next heading of its level or above) and Tables. The positions are offsets into Text, taken in the same pass that wrote it, so a page a caller finds in the outline is the page it reads.

A sheet's table keeps where its cells stood: Table.Addresses.At(row, column) is B7, and the Markdown shows it.

## Sheet 1: Invoices

|  | B | C | D |
| --- | --- | --- | --- |
| 2 | Number | Date | Sum |
| 3 | INV-7 | 2026-10-14 | 118000.5 |
| 5 | INV-8 |  | 42 |

Failures are answers

ReadAsync throws only when its caller cancels it. Every other way a file fails — including whatever a format's own library throws on a damaged one — comes back as a Reading with the reason in the reader's words:

ReadingFailure When
UnknownFormat no reader takes a file of this name
Damaged the file is damaged, or is not what its name says
Locked the file is protected by a password
TooLarge the file unpacks past ReadingLimits: 20 million characters, a million cells in one table, 256 MB unpacked or a hundred times its size for an Office file, or a workbook's styles past a million formats
TooSlow reading took longer than 30 seconds

The limits hold whatever the size of the file: a workbook of 11 kB can come to 98 million characters, and a zip of a few kilobytes to gigabytes. Each limit is stated with the file that found it in ReadingLimits.

Scanned pages

A PDF page without a text layer is a Part with IsScanned. Its picture is what a model that sees reads:

int[] scans = [.. document.Parts.Where(part => part.IsScanned).Select(part => part.Number)];
IReadOnlyList<ScannedPage> pages = ScannedPages.Pictures(File.OpenRead("scan.pdf"), scans);

Each page comes back as a PNG or a JPEG, or without a picture when no managed decoder opens it (fax and JBIG2 scans) or when it is past ReadingLimits.MostPicturePixels, fifty million pixels.

In a container

services.AddDocumentReading();   // every IFormatReader, and the DocumentReader over them

A program that reads fewer formats registers its own IFormatReaders and a DocumentReader over them.

The public API: docs/reference. Built on Snail.Sdk: the rules, the public API kept in src/PublicAPI.*.txt, validation against the last release, the shared workflows.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 150 10/23/2026