Skip to content

DTCoreText 2.1.0

Latest

Choose a tag to compare

@odrobnik odrobnik released this 13 Jun 06:50

DTCoreText 2.1.0 is the first feature release built on the Swift 2.0 foundation — and it's a big one. It brings full HTML table support, real CSS floats, native iOS 27 TextKit bridging, CSS border-spacing, and a dependency graph trimmed from five packages down to one.

That's ~8,600 lines of new code across 5 pull requests since 2.0.0.

✨ Highlights

  • 📊 HTML tables — a full NSTextTable-compatible model with real grid layout, drawing, and HTML round-trip
  • 🌊 CSS float: left/right for images and blocks, with text wrapping and clear
  • 🍏 iOS 27 ready — tables and text blocks bridge to the native UIKit NSTextTable classes and lay out in TextKit
  • 🎯 CSS border-spacing on tables, with full round-trip support
  • 📦 One dependency instead of five — DTCoreText now depends only on XMLKit

📊 HTML Table Support (#1318)

DTCoreText now renders HTML tables end to end — parsing, grid layout, drawing, and HTML round-trip — built on a model that mirrors the NSTextBlock / NSTextTable / NSTextTableBlock API so it can hand off to the native classes on iOS 27 (see below).

  • Parsing of table, tr, td, th, thead, tbody, tfoot, caption, and col/colgroup, producing the same structure as the native macOS HTML importer.
  • Real grid layout: automatic column sizing, explicit and percentage widths, colspan/rowspan, vertical alignment with true first-baseline support, justified cell text, and recursively nested tables.
  • Styling: per-edge borders (solid / dashed / dotted / double), background colors on table, row and cell, cellpadding/cellspacing, border-collapse, empty-cells, table-layout, and the width / min-width / max-width family.
  • Pagination: tables in finite-height frames break row by row across pages.
  • Round-trip & SwiftUI: HTMLWriter emits <table> markup with colspan/rowspan, and tables survive conversion through AttributedString and back — still laying out as a grid.

🌊 CSS Floats (#1319)

float is now a real layout feature instead of a parsed-but-ignored property.

  • Floated images sit at the left or right content edge, with paragraph text wrapping around them and reflowing to full width below.
  • Floated blocks (div, span, even table) become shrink-to-fit or fixed-width columns — including their backgrounds, padding, and nested content.
  • clear: left/right/both pushes content below earlier floats. Several floats stack side by side and wrap down as space runs out, and a float that doesn't fit moves whole to the next page in paginated frames.
  • Round-trips through HTMLWriter (floated images, floated blocks with width, and clear).

🍏 Native iOS 27 Bridging (#1320)

The table model was designed from day one to swap to the native UIKit classes shipping in the iOS 27 SDK — and that handoff is now wired up and verified end to end on the iOS 27 simulator.

  • TextBlockConverter bridges DT text blocks to native NSTextBlock / NSTextTable / NSTextTableBlock on iOS, tvOS, visionOS and Mac Catalyst (gated @available(iOS 27.0, *)), preserving shared table identity across paragraphs.
  • DTCoreText output can be handed straight to a TextKit view on iOS 27, which lays the tables out natively.
  • Xcode 27 compatibility: the existing macOS code now builds against the Xcode 27 SDK changes (text-block enum raw-type change, soft-deprecated edge accessors). Builds clean on both Xcode 26 and 27.
  • Drive-by tvOS build fix.

🎯 CSS border-spacing (#1321)

border-spacing is now honored on tables (one- and two-value forms) with browser-correct precedence — border-collapse: collapse forces zero, CSS border-spacing beats the legacy cellspacing attribute — and it survives a full HTML → attributed string → HTML round-trip. Previously any spacing was silently lost on a round-trip.

📦 Leaner Dependencies (#1322)

The resolved dependency graph shrinks from five packages to one: just XMLKit 1.0.1.

  • The HTMLParser module was extracted from SwiftText into its own XMLKit package (with full git history); DTCoreText now depends on it directly, semver-pinned (from: 1.0.1). This drops SwiftText, swift-markdown and swift-cmark from the graph.
  • The swift-docc-plugin dependency was removed — Swift Package Index auto-injects it for hosted docs and Xcode builds the .docc catalog natively. This also removes SymbolKit and swift-argument-parser.
  • No source changesimport HTMLParser resolves to the identical module; only Package.swift/Package.resolved change.

✅ Compatibility

  • Requirements: iOS 16+, macOS 13+, tvOS 16+ · Swift 6.1 · Xcode 26 (also builds on the Xcode 27 beta).
  • Source-compatible with 2.0.0. Swift Package Manager consumers pick up the new XMLKit dependency automatically on resolve.
  • Floats behavioral note: rendering a DTCoreText string in a plain NSTextView/UITextView shows floated images inline — the wrap happens in DTCoreText's own layout engine.

⚠️ Known Limitations

  • Tables: no full min/max-content width negotiation, no RTL column mirroring, table content bypasses numberOfLines truncation, and 3D border styles render as solid.
  • Floats: floats inside table cells are ignored, and a frame of unknown width disables floats.

Full Changelog: 2.0.0...2.1.0