using OfficeIMO.Drawing; using OfficeIMO.Html; using OfficeIMO.Html.Pdf; namespace OfficeIMO.Examples.Html { internal static partial class Html { public static void Example_HtmlManagedRendererGallery(string folderPath, bool openPdf) { Console.WriteLine("[*] Managed HTML renderer gallery: one source to interactive PDF, PNG, and SVG"); const string html = """

OfficeIMO managed document renderer

One authored document.
Four dependable outputs.

AngleSharp parsing, bounded document layout, searchable vector output, and native form fields—without a browser process.

PDF · PNG · SVGSame parsed source and policy
CascadeLayers + nesting
LayoutGrid + subgrid
PaintCSS Color 4
OutputReal AcroForms

Render pipeline

One managed scene keeps output adapters thin.

Validated
01 / PARSEHTML + CSS

AngleSharp, layers, nesting, media and container queries.

02 / LAYOUTDocument scene

Paged grid, subgrid, typography, counters, SVG and MathML.

03 / EXPORTPortable output

Searchable PDF, vector SVG, PNG and native form fields.

Container-aware composition

This pair becomes two columns only when its own container has room, not merely when the page is wide.

Bounded by design

Resource limits, deterministic fallbacks, structured diagnostics, and no script execution are part of the rendering contract.

MathML → OfficeMathE=mc2

Generated from a runnable OfficeIMO example. The downloadable PDF, PNG, SVG, and HTML source are produced together and hashed in the website evidence manifest.

"""; var options = new HtmlToPdfOptions { PageSize = OfficePageSizes.A4.Landscape(), Margins = HtmlRenderMargins.All(18D), BackgroundColor = OfficeColor.White, Scale = 1D, ConicGradientQualitySegments = 72 }; options.UseTextHyphenationLexicon(new OfficeTextHyphenationLexicon(new[] { "Do-nau-dampf-schiff-fahrts-ge-sell-schafts-ka-pi-tän" }, minimumPrefixLength: 2, minimumSuffixLength: 2)); string htmlPath = Path.Combine(folderPath, "HtmlManagedRendererGallery.html"); string pdfPath = Path.Combine(folderPath, "HtmlManagedRendererGallery.pdf"); string pngPath = Path.Combine(folderPath, "HtmlManagedRendererGallery.png"); string svgPath = Path.Combine(folderPath, "HtmlManagedRendererGallery.svg"); HtmlConversionDocument document = HtmlConversionDocument.Parse(html); HtmlRenderDocument rendered = HtmlRenderEngine.Render(document, options); HtmlDiagnostic[] fidelityDiagnostics = rendered.Diagnostics .Where(diagnostic => diagnostic.Severity != HtmlDiagnosticSeverity.Info) .ToArray(); if (fidelityDiagnostics.Length > 0) { throw new InvalidOperationException("Managed renderer gallery emitted fidelity diagnostics: " + string.Join("; ", fidelityDiagnostics.Select(diagnostic => diagnostic.Code + " (" + diagnostic.Source + ": " + diagnostic.Detail + ")"))); } bool hasHyphenationProof = rendered.Pages .SelectMany(page => EnumerateManagedRendererGalleryVisuals(page.Scene)) .OfType() .Any(text => text.Text.StartsWith("Donaudampf", StringComparison.Ordinal) && text.Text.EndsWith("-", StringComparison.Ordinal)); if (!hasHyphenationProof) { throw new InvalidOperationException("Managed renderer gallery expected the German proof word to use the configured automatic hyphenation lexicon."); } File.WriteAllText(htmlPath, html); document.SaveAsPdf(pdfPath, options); document.ToImage(options) .AsPng() .OnFileConflict(OfficeImageExportFileConflictPolicy.Replace) .Save(pngPath); document.ToImage(options) .AsSvg() .OnFileConflict(OfficeImageExportFileConflictPolicy.Replace) .Save(svgPath); byte[] pdf = File.ReadAllBytes(pdfPath); int formFieldCount = global::OfficeIMO.Pdf.PdfDocument.Load(pdf).Inspect().FormFieldCount; if (formFieldCount < 4) { throw new InvalidOperationException($"Managed renderer gallery expected at least four PDF fields but found {formFieldCount}."); } Console.WriteLine($" HTML: {htmlPath}"); Console.WriteLine($" PDF: {pdfPath} ({formFieldCount} interactive fields)"); Console.WriteLine($" PNG: {pngPath}"); Console.WriteLine($" SVG: {svgPath}"); if (openPdf) { System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(pdfPath) { UseShellExecute = true }); } } private static IEnumerable EnumerateManagedRendererGalleryVisuals(IEnumerable visuals) { foreach (HtmlRenderVisual visual in visuals) { yield return visual; IEnumerable? children = visual is HtmlRenderClipGroup clip ? clip.Visuals : visual is HtmlRenderPathClipGroup pathClip ? pathClip.Visuals : visual is HtmlRenderEffectGroup effect ? effect.Visuals : visual is HtmlRenderSemanticGroup semantic ? semantic.Visuals : visual is HtmlRenderLogicalTextGroup logical ? logical.Visuals : visual is HtmlRenderFormField form ? form.Visuals : null; if (children == null) continue; foreach (HtmlRenderVisual child in EnumerateManagedRendererGalleryVisuals(children)) yield return child; } } } }