Obtaining a DocumentReader
Call GetContentReader() on the DocumentController:
DocumentReader reader = controller.GetContentReader();
Note
DocumentReader is a lightweight wrapper around the live TextDocument. Do not hold a reference
across editing operations if you need a stable snapshot; create a new reader after edits.
API
| Member | Return Type | Description |
|---|---|---|
| Document | TextDocument | The underlying RTK TextDocument (advanced use) |
| GetContent() | IEnumerable<ContentBlock> | Yields one ContentBlock per paragraph |
| GetStyles() | IEnumerable<StyleInfo> | Yields unique styles used in the document |
Iterating Content
GetContent() yields one ContentBlock per paragraph.
Each block contains a list of ContentRun objects — the individual styled text segments (or inline images).
var reader = controller.GetContentReader();
foreach (var block in reader.GetContent())
{
// Paragraph-level properties
TextAlignment? align = block.Alignment;
ListType? list = block.ListType;
int? level = block.ListLevel;
float? indent = block.BlockIndent;
float? spacing = block.LineSpacing;
foreach (var run in block.Runs)
{
if (run.IsImage)
{
// Inline image run
byte[] png = run.ImageData;
float w = run.ImageWidth;
float h = run.ImageHeight;
}
else
{
// Text run
string text = run.Text; // Never contains U+2029
IStyle style = run.Style; // Fully merged — safe to read directly
bool bold = style.FontWeight >= 700;
}
}
}
Paragraph Separator
The underlying text engine uses U+2029 (PARAGRAPH SEPARATOR) internally.
DocumentReader strips this character before exposing ContentRun.Text —
you will never see it in exported content.
Building a Custom Exporter
Implement the ExporterBase abstract class from ParentElement.RichText.Export, then use DocumentReader in your implementation:
public class MarkdownExporter : ExporterBase
{
private readonly DocumentReader _reader;
public MarkdownExporter(DocumentReader reader) => _reader = reader;
public override async Task ExportAsync(Stream stream)
{
await using var writer = new StreamWriter(stream);
foreach (var block in _reader.GetContent())
{
if (block.ListType == ListType.Bullet)
await writer.WriteAsync("- ");
foreach (var run in block.Runs)
{
if (!run.IsImage)
await writer.WriteAsync(run.Text);
}
await writer.WriteLineAsync();
}
}
public override async Task ExportAsync(string filePath)
{
await using var fs = File.OpenWrite(filePath);
await ExportAsync(fs);
}
}