Skip to content

Releases: giordano137/MarkdownDocumentKit

v0.5.0 — real editable DOCX tables, written as OOXML by hand

Choose a tag to compare

@github-actions github-actions released this 24 Sep 19:02

v0.5.0 — real editable DOCX tables, written as OOXML by hand

WordDocumentExporter.export(blocks, title:) now produces .docx files whose
tables are actual Word tables — selectable, editable, resizable — instead of
the image AppKit's own .officeOpenXML writer produced. The reason it had to
be hand-written: asking AppKit for a table the "correct" way, via
NSTextTable/NSTextTableBlock, gets the structure silently dropped by that
specific writer. Confirmed it isn't the wrong way to ask by writing the same
attributed string to .rtf instead, where the table does come out real — it's
an .officeOpenXML-writer gap.

So each table is emitted as <w:tbl> XML by a new OOXMLTableWriter and spliced
into AppKit's own output at a placeholder paragraph, with MinimalZipArchive
(and CRC32) reading and rewriting the .docx container in place. Everything
that isn't a table still goes through AppKit's writer, which gets styling,
list numbering and the document skeleton right and would be a lot of surface
to reimplement for no gain. Verified against tools outside this codebase —
unzip plus XML well-formedness checks on word/document.xml, and opening the
result in a real word processor — since our own writer being validated
against our own reader proves nothing.

Also in this release:

  • Task lists (- [ ] / - [x]) and footnotes ([^id] inline, [^id]: as a
    definition). Task lists get their own .taskListItem case rather than a new
    field on .listItem, so existing exhaustive switches keep compiling;
    footnote numbering follows GFM's first-reference-order convention.

  • Fixed a docx superscript bug this surfaced: AppKit's writer encodes a
    footnote reference's superscript as a raw <w:position> offset, which
    macOS's own Quick Look docx preview renders lowered instead of raised.
    WordDocumentExporter now substitutes the semantic
    <w:vertAlign w:val="superscript"/> that Word's own UI writes.

  • BREAKING (pre-1.0, see README's Versioning section): .codeBlock gained a
    language: String? field carrying the fence's info string. It was already
    parsed just to rule out ```mermaid and then discarded, leaving a consumer
    no way to tell Swift from Python from untagged. Not rendered as syntax
    highlighting — that stays out of scope with zero dependencies — this just
    stops losing the information.

  • Platform floor lowered to iOS 16+ / macOS 13+ (from iOS 17 / macOS 14).
    Nothing in the codebase needed the higher floor; verified by lowering
    Package.swift's platforms and rebuilding and retesting clean on both,
    then confirming the availability check itself still bites.

  • Opted into Swift Package Index DocC hosting via .spi.yml, and replaced the
    hand-maintained Swift/platform badges with SPI's own.

  • CONTRIBUTING.md now states the position on AI-assisted contributions —
    allowed, no disclosure required, the bar is architecture rather than
    syntax — and carries the iOS Simulator command, issue-first guidance for
    larger changes, and a release procedure that pushes main before tagging.
    The README now says outright that stars, issues and PRs are welcome, and
    names scope as the one filter.

v0.4.0 — DiagramRenderer: real Mermaid diagrams, theme-matched

Choose a tag to compare

@giordano137 giordano137 released this 22 Sep 19:10

v0.4.0 — DiagramRenderer: real Mermaid diagrams, theme-matched

A fenced ```mermaid block now becomes a .diagram(source:) block, rendered
through an injected DiagramRenderer exactly like .image already is
through ImageRenderer — a consumer typically backs it with a hidden
WKWebView running mermaid.js. No renderer, or one that can't parse a
given diagram, falls back to the raw Mermaid source shown as a code
block, same "show the source, don't fake it" reasoning
FormulaRenderer/ImageRenderer already use.

DiagramRenderer also receives a DiagramPalette (four colors: node
background/border, line color, text color) derived from the active
DocumentTheme, so a rendered diagram can match the rest of the document's
colors instead of a diagramming library's own unrelated stock theme.
Verified end-to-end with a real mermaid-cli-backed DiagramRenderer:
side-by-side renders of the same diagram showed the difference between
"looks bolted on" and "looks like one document."

Also in this release:

  • Fixed a real rendering bug: a multi-line code block showed a visible
    gap between every line instead of one continuous shaded block, caused
    by a paragraph style's spacing being applied per-line instead of once
    for the whole block. Found by actually generating a PDF with a YAML
    config example and looking at it.
  • Fixed a crash risk in DocumentTheme.calloutTint(for:) — it force-
    unwrapped a lookup that assumed every CalloutKind case had a matching
    default tint, an invariant the compiler never checked.
  • Added PDFRenderer test coverage for multi-page pagination and a table
    landing whole on one page rather than split across a page break —
    previously the riskiest, least-tested part of the package.
  • README overhaul: a Quick Start example right under the description
    (verified to actually compile — the version that shipped briefly
    didn't), a code example for each injected protocol, a real screenshot
    of rendered output, and a "Known limitations" section. The old
    phase-by-phase status writeup moved to ARCHITECTURE.md. Added
    CONTRIBUTING.md and a versioning policy note.

v0.3.0 — DocumentTheme: inject colors/font sizes/spacing

Choose a tag to compare

@giordano137 giordano137 released this 22 Sep 19:10

v0.3.0 — DocumentTheme: inject colors/font sizes/spacing

Every color, font size, and spacing constant DocumentRenderer/
TableRenderer used is now sourced from a DocumentTheme struct, passed
as an optional parameter defaulting to .default (reproduces v0.2.0's
hardcoded look exactly — zero change for an existing consumer).
Overriding one field, or one callout kind's colors, leaves everything
else at its default.

Deliberately does not cover font family (system-font variants only) —
see README's "Styling is injected too" section for why.

Verified end-to-end on both platforms: a custom theme rendered into a
real PDF (macOS) and a real iOS Simulator-rendered table PNG, both
opened and visually confirmed correct, not just asserted via isolated
attribute checks.

v0.2.0 — real iOS (UIKit) support, not just macOS (AppKit)

Choose a tag to compare

@giordano137 giordano137 released this 22 Sep 19:10

v0.2.0 — real iOS (UIKit) support, not just macOS (AppKit)

Every renderer (DocumentRenderer, TableRenderer, PDFRenderer,
TableAttachment, FormulaRenderer, ImageRenderer) now runs on both
platforms from one shared implementation, via PlatformTypes.swift's
typealiases and a handful of helpers for genuine AppKit/UIKit API
divergences. v0.1.0 declared .iOS(.v17) support in Package.swift without
actually providing it — this closes that gap for real.

Verified on iOS with an actual Simulator test run (not just
cross-compilation): the full test suite green via xcodebuild test
against an iOS Simulator destination, plus a real rendered table bitmap
saved from that same simulator process and opened directly to confirm
it isn't upside down.

CI now runs both a macOS job and an iOS Simulator job on every push/PR.

v0.1.0 — first tagged release

Choose a tag to compare

@giordano137 giordano137 released this 22 Sep 19:10

v0.1.0 — first tagged release

A native Swift package that parses Markdown into a structured document
model and renders it to PDF, DOCX, or a plain NSAttributedString, without
a browser engine or an external typesetting binary. Zero dependencies —
math and image rendering are injected via FormulaRenderer/ImageRenderer
protocols a consumer implements.

Included:

  • Block layout: headings, paragraphs (justified + hyphenated), lists,
    fenced code blocks, blockquotes
  • Tables: measured column widths, wrapped rows, real selectable text in
    PDF (not a flattened image), a bitmap fallback for DOCX
  • GFM alert callouts (> [!NOTE]/[!TIP]/[!WARNING]/[!IMPORTANT]) as
    tinted, rounded, accent-labeled boxes
  • LaTeX formulas (block [...]/$$...$$ and inline $...$/(...)),
    baseline-aligned so inline math flows with surrounding text
  • Images (alt) — data: URI sources decode with zero consumer
    code; local/remote sources go through an injected ImageRenderer
  • PDFRenderer: real multi-page PDF pagination via raw CoreText, no
    NSPrintOperation round trip

Not yet implemented: Mermaid diagrams (DiagramRenderer), rounded table
corners in PDF, a real (not image) DOCX table.