Recent

Author Topic: Pixie: A lightweight HTML/CSS rendering engine for Free Pascal and Lazarus 🌟  (Read 13168 times)

dsiders

  • Hero Member
  • *****
  • Posts: 1615
@dsiders,

Is it a pure md rendering engine or it does more than just render ?   The reason I ask is because, having something that is really lightweight would be very nice, i.e, just rendering and nothing else.

The demo certainly is lightweight. Direct to Canvas.

https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/components/markdown/README.md?ref_type=heads

440bx

  • Hero Member
  • *****
  • Posts: 6491
The demo certainly is lightweight. Direct to Canvas.
I'll check it out.  Thank you dsiders.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Retrofoxed

  • New member
  • *
  • Posts: 8
Actually that's an interesting idea to add MD support to Pixie in addition to HTML. The simplest but ugly way would be converting MD to HTML, but for best performance and compact size it would need to be a separate implementation. I'll have a look at that - shouldn't be too hard MD is a lot simpler.,

Retrofoxed

  • New member
  • *
  • Posts: 8
Adding Markdown rendering to Pixie — two approaches

We're considering Markdown rendering support in Pixie. There are two viable paths and they have very different tradeoffs. Looking for input on which way to go.

Option A — MD → HTML → existing HTML engine

Convert Markdown to HTML in a small new unit, then feed the output to TPixieHtmlView. The HTML/CSS engine handles everything else.

Pros
  • Minimal new code: just a CommonMark/GFM → HTML converter (~1-2k lines, mostly parser).
  • Full CommonMark + GFM compliance for free, including raw HTML passthrough (<kbd>, <details>, <img width="...">, <sub>, <div align="center"> — common in real-world READMEs).
  • MD extensions are trivial: footnotes become anchored sections, task lists become checkboxes, math becomes MathML or img tags, mermaid becomes <pre class="mermaid">. Renderer doesn't change.
  • Full CSS-based theming: users can override anything per-element.
  • PDF export, image loading, SVG embedding, text selection, clipboard, find-in-page, link hover, focus, accessibility — all inherited from the existing HtmlView.
  • Future-proof: new MD features = parser-only changes.

Cons
  • Brings the entire HTML engine (~60k lines) into any application that wants Markdown rendering.
  • Heavier runtime: HTML parser builds a DOM, CSS cascade computes styles, formatting contexts run, render tree builds — even for a one-paragraph chat message.
  • Higher memory footprint per document.
  • Pays for HTML quirks (margin collapse, float positioning, complex layout) even where not needed.
  • Wrong shape for embedded log viewers, chat bubbles, or anything where you want a fast, lean MD widget.

Option B — parallel MD-only renderer

A self-contained Markdown engine: own parser, own minimal node tree, own layout pass. Depends only on common/ (canvas, font descriptions, colours, types).

Pros
  • Order-of-magnitude smaller: estimated ~3-5k lines total (parser + layout + inline wrapper + components).
  • Depends only on common/ — apps that don't need HTML don't pay for HTML.
  • Single-pass parse, single-pass layout. No CSS cascade, no style invalidation, no formatting-context machinery.
  • Predictable performance and memory — well-suited to log viewers, chat UIs, in-app help, notes apps.
  • Simple theme record (fonts, colours, spacing) covers the common customisation cases without CSS.
  • Same TPixieCanvas abstraction means D2D / Cairo / CG / Qt / FMX / PDF backends all work.

Cons
  • No HTML passthrough. Real-world .md files use HTML constructs constantly (<kbd>, <details>/<summary>, <img width="...">, <sub>, <div align="center">, etc.). CommonMark explicitly allows this; a pure-MD renderer mis-renders these into literal text or has to silently strip them. This is the load-bearing tradeoff.
  • Every MD extension (footnotes, task lists, math, mermaid, definition lists, front-matter) requires parser + node + layout + theme changes. Closed system.
  • No per-element styling — theme is global. "This one heading in red" requires inventing a directive syntax.
  • We re-implement features the HtmlView already has: text selection across blocks, clipboard formatting, link hit-testing, find-in-page, keyboard navigation. Each is bounded but still ~300-500 lines.
  • PDF export needs to be wired up explicitly (uses the same canvas API, but it's not free).
  • Inline math is genuinely hard without a real typesetter — likely punt to "code block" rendering.
  • Two parallel rendering codebases to maintain long-term.

Comparison at a glance

DimensionOption A (MD → HTML)Option B (parallel)
New code added~1-2k lines~3-5k lines
Total engine cost~60k lines (HTML engine)~3-5k + common/
PerformanceHTML pipeline overheadSingle-pass, lean
Memory per docHigher (DOM + render tree + computed styles)Low (flat node tree)
CommonMark complianceFull, including raw HTMLMD subset, no HTML
GFM extensionsEasy to add (parser only)Each requires layout work
Custom stylingFull CSSFixed theme record
PDF exportFreeWire up via PdfCanvas
Selection / clipboard / linksInheritedReimplement
Best fitRender arbitrary README files, full-fidelity docsChat / log / notes / in-app help

The real decision

The choice is essentially:

  • A if the goal is "render arbitrary .md files, including ones from the wild" with full fidelity, and the engine size cost is acceptable.
  • B if the goal is "fast, lean MD widget for our own content" where we control the input and never need HTML escape hatches, and minimising dependency footprint matters.

I am leaning towards option A. Thoughts?

440bx

  • Hero Member
  • *****
  • Posts: 6491
I am leaning towards option A. Thoughts?
I do too.   I think option B should be considered if genuinely significant cons appear in option A, which I believe is unlikely, except possibly for performance in really low end machines.  Also, the work required is significantly less, which is something that should be taken into account.

IOW, the extra effort required to implement option B should be considered only if some deficiency in the implementation of Option A justifies it.  In addition to that, since a lot of md files use HTML elements, it is actually more likely to be Option B to have cons that justify going with Option A.

It's an Einstein problem, make the md viewer as lean as possible but no leaner and, removing HTML support may actually make it leaner than it should be in the practical world.


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

AlexTP

  • Hero Member
  • *****
  • Posts: 2709
    • UVviewsoft
I want the way B, please. The fastest reaction of MD control is wanted, when user changes the MD text in the editor.
« Last Edit: May 03, 2026, 09:30:23 am by AlexTP »

creaothceann

  • Sr. Member
  • ****
  • Posts: 361
I want the way B, please. The fastest reaction of MD control is wanted, when user changes the MD text in the editor.

A's speed may already be fast enough though, hard to say without knowing the size of your files.

AlexTP

  • Hero Member
  • *****
  • Posts: 2709
    • UVviewsoft
Size of files can be any average size of random MD files from the web, e.g. 10-30Kb.

Retrofoxed

  • New member
  • *
  • Posts: 8
MD view component has been implemented.

440bx

  • Hero Member
  • *****
  • Posts: 6491
Thank you @retrofoxed.  I most definitely plan to take it for an extended "walk" within the next few hours.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

AlexTP

  • Hero Member
  • *****
  • Posts: 2709
    • UVviewsoft
Great news. Thank you for MD component.

 

TinyPortal © 2005-2018