Repository navigation
4.0.0
3.0.0 以降に溜まっていた実バグの修正と、公開 API の全面的な見直しをまとめたメジャー。
要点: ①表示されているリンクと実際に開く先が違う等の実バグを 13 件修正 ②ライブ
プレビューの O(n²) を線形化(1 万行で 16.3 秒 → 0.12 秒)③配線されていない公開 API を
全廃 ④外部デザインシステムへの必須依存を解消し、既定でダークモードに追従 ⑤約束を
黙って別の挙動にすり替える経路を塞ぐ ⑥エディタの拡張点を公開。
移行の要点は下の「破壊的変更」に項目ごとの 移行 として書いてある。
修正
MarkdownEditorController.canUndo/canRedoが SwiftUI を更新しなかったのを修正。
UndoManagerを読む計算プロパティなのにobjectWillChangeを流していなかったため、
利用者が自作した「元に戻す」ボタンが永久に無効のままだった。undo 通知を購読して
publish する。購読先のobjectを絞らないのは、NSTextView.undoManagerが
レスポンダチェーン経由で解決されbind(_:)の時点ではまだnilだから- コードブロックの中身が数式に置換される不具合を修正。
~~~フェンス・4 スペースの
インデントコード・$が先行する場合のインラインコードスパンが、いずれも数式スキャナの
保護対象から漏れていた(~~~python\ncost = $5$\n~~~の中身がcost = 0になっていた) - CRLF 改行のソースで、行末まで伸びるトークン(見出し本文・コードブロック)の範囲に
\rが 1 コードユニット含まれ、ハイライトが行末まで伸びていたのを修正 - インデントされた閉じフェンス(リスト項目内など)を認識できず、以降のドキュメント全体が
コードとして着色され続けていたのを修正
破壊的変更
-
配線されていない公開 API を全廃した。 いずれも本体レンダリング経路からの参照が
0 件で、Catalog のデモとテストだけが参照していた。- Style プロトコル 5 系統(
HeadingStyle/CodeBlockStyle/TableStyle/
LinkStyle/AsideStyle)と既定実装 17 型を削除。
移行: 見た目の調整はMarkdownPalette/MarkdownMetrics/MarkdownTypeScale
で行う(下記「テーマ」参照) MarkdownRenderingOptionsをrenderMath1 フィールドに縮小。他 7 つと
.compact/.plainTextを削除。移行: 該当する代替は無い。画像の抑止は
.markdownImagePolicy(.bundleOnly)が近いEditorHistory/MarkdownEditorEngineを削除。undo/redo はシステムの
UndoManagerが担っており二重実装だった。移行: 不要(既に UndoManager 経由)MathBlockView/CodeBlockView/MermaidDiagramView/AdaptiveMermaidView/
MermaidFallbackViewを削除。移行:MarkdownViewを使うMathRenderer.displayMath(_:)要件を削除。移行: ディスプレイ数式は
MarkdownAttachmentRendering.renderedImage(for:theme:)で描く
- Style プロトコル 5 系統(
-
外部デザインシステムへの必須依存を外した。
SwiftMarkdownView/SwiftMarkdownEditorはswift-design-systemを
リンクしなくなった。色・寸法・文字サイズはMarkdownPalette/
MarkdownMetrics/MarkdownTypeScaleとして自前で抽象化してある- 既定パレットがシステムの意味色になり、ライト/ダークに自動追従する。
従来の既定はLightColorPalette()固定でcolorSchemeを見ておらず、
素で使うとダークモードで文字が読めなかった。README の回避手順は不要になった - 移行:
.markdownTheme(themeProvider)を使っていた場合は
SwiftMarkdownViewDesignSystemproduct を依存に追加して import する。
呼び出し自体は変わらない。エディタはSwiftMarkdownEditorDesignSystemの
.markdownEditorDesignSystemTheme() - 移行:
MarkdownEditorTheme.fromDesignSystem(palette:)は
SwiftMarkdownEditorDesignSystemへ移動した
-
MathRendererの要件を 1 本にまとめた。
inlineMath(_:palette:)とinlineMath(_:fontSize:palette:)の 2 本立てをやめ、
inlineMath(_:fontSize:textColor:)だけにした。旧デフォルト実装は fontSize を
破棄しており、同梱のLaTeXMathRendererは両方実装していたため、
サードパーティ実装でのみ数式のサイズが周囲に追従しないという出方をしていた。
移行:paletteの代わりに解決済みのtextColorを受け取る。fontSizeが
nilのときは実装側の既定サイズを使う -
MathRendererがMarkdownAttachmentRenderingを継承するようになった。
従来は無関係な 2 プロトコルをMarkdownView内のas?で繋いでおり、
自作MathRendererを注入しても無言で無視され、数式が$latex$のまま
表示された。移行:renderedImage(for:theme:)を実装する。組版しないなら
nilを返せば読み取り可能なテキストに落ちる -
MermaidScriptSource.inlineが実際に機能するようになった。
従来は.urlと.localFileしか解釈せず、それ以外は無条件で CDN に落ちていた。
オフライン動作のつもりで.inlineを選んだ利用者のアプリから、気づかないまま
外部通信が飛んでいた。 あわせて.localFileも、file URL を<script src>に
渡す実装(WebView の origin からは読めない)から、中身を読み込んで埋め込む方式に
改めた。読み込めない場合はログを出して描画しない — CDN には落ちない -
MarkdownAttachmentRenderingがSendableを要求するようになった。
戻り値のMarkdownRenderedImageが@unchecked Sendableを名乗る一方、
生成側に並行性の契約が無かった -
SyntaxHighlighterの失敗を握り潰さなくなった。
try?で捨てていたため、doc がスローを約束しているのに利用者は自作ハイライターの
失敗を「なぜか色が付かない」としてしか観測できなかった。今は理由をログに出す
(描画自体は素のコードで続行する) -
実装詳細の再輸出をやめた。
import SwiftMarkdownViewから見えていた
MarkdownAttributedBuilder/MarkdownCodeHighlighting/MarkdownCodeRegion/
MarkdownSyntaxHighlighting/MarkdownImageRequest/MarkdownImageAttachments/
MarkdownBlockDecorationとNSAttributedString.Key拡張をpackageに降格した。
引き続き見えるのはMarkdownTextTheme/MarkdownAttachment/
MarkdownRenderedImage/MarkdownAttachmentRenderingの 4 型で、いずれも
自作アタッチメントレンダラを書くのに必要 -
BundledMermaidScriptProviderを failable にした。 リソースが見つからない場合は
nilを返す。従来はデバッグビルドでassertionFailureを出しつつ、リリースでは
無言で CDN にフォールバックしていた。移行:if letか??で受ける。
bundle/filenameプロパティは解決済みのurlに置き換わった// 見つからなければ Mermaid を描画しない if let provider = BundledMermaidScriptProvider() { view.markdownMermaidScriptProvider(provider) } // 明示的に CDN へ倒す判断も、利用者が書く let provider = BundledMermaidScriptProvider() ?? CDNMermaidScriptProvider()
-
グローバル定数
defaultMermaidScriptProviderを削除した。
移行:.markdownMermaidScriptProvider(.cdn)を使う。あわせて同 modifier の
引数をany MermaidScriptProviderからsome MermaidScriptProviderに変えた
(実存パラメータだと先頭ドット構文の推論が効かないため) -
旧 modifier 名の deprecated エイリアスを削除した。
syntaxHighlighter/mermaidScriptProvider/mathRendererの 3 件。
移行:markdownprefix 付きの名前に置き換える
(残り 3 件のheadingStyle/codeBlockStyle/asideStyleは本体ごと廃止済み) -
MarkdownEditorControllerのコマンド名を実挙動に合わせた。 いずれも
適用済みなら解除する toggle なのに、toggleHeading/toggleQuoteだけが
toggle を名乗っていた。移行:bold()→toggleBold()italic()→toggleItalic()code()→toggleInlineCode()strikethrough()→toggleStrikethrough()bulletList()→toggleBulletList()wrap(_:)→toggleWrap(_:)linePrefix(_:)→toggleLinePrefix(_:)
-
エディタ 4 ターゲットの公開面を確定した。
SwiftMarkdownEditorCore/
Rules/TextKitは.libraryproduct として宣言されていなかったが、
SwiftPM は依存グラフ内の全ターゲットをモジュール検索パスに載せるため、
外部から import できてしまっていた(実測で確認)。つまり利用者は未文書な
挙動に依存し、こちらは何が契約かを決めていない状態だった。import SwiftMarkdownEditor1 つで、init の引数型(InputRuleProcessor)も
テーマ型(MarkdownEditorTheme)も独自コマンドの部品(EditTransform/
MarkdownFormatting)も届くよう再輸出した- 契約でないものは
packageに降格:LineIndex/InlineSpan/
InlineSpanParser/StyleRun/LivePreviewStyler - 移行: 3 ターゲットを個別に import していた場合は
import SwiftMarkdownEditorだけで足りる
-
MarkdownTokenizerとMathScannerの公開面を狭めた。MarkdownTokenizer.isInsideFencedCode(_:offset:)は public のまま。独自InputRuleが
コードブロック内でオートフォーマットを抑えるのに要る(同梱のListContinuationRuleが実例)MarkdownTokenizer.tokenize(_:)/fencedCodeRanges(_:)とMathScanner全体は
packageへ。いずれも呼び出し元がパッケージ内のハイライタ・前処理だけだった- 移行: 該当する外部ユースケースは想定していない。トークン列を直接扱う必要が
生じた場合は issue で相談してほしい
-
PlatformColor/PlatformFontの二重定義を解消した。
MarkdownAttributedKitとSwiftMarkdownEditorTextKitが同名の public typealias を
別々に宣言しており、両方を import した利用者のスコープで曖昧になっていた。
定義はMarkdownPlatformターゲット 1 か所に集約した。移行: 型は同一
(UIColor/NSColor)なので通常は変更不要 -
画像の読み込みに
MarkdownImagePolicyを導入し、既定でローカルファイルシステムへの
アクセスを行わなくなった。の source はドキュメント由来の文字列で、
LLM 出力やユーザー投稿の場合がある。従来はfile:URL と裸のファイルパスを無条件に
開いていたため、描画するだけでアプリのファイルを読みにいく指定が成立していた。- 既定(
.default): リモート(http/https)とバンドルリソース名のみ .bundleOnly: ネットワークも使わない.trustedDocument: 従来どおりローカルファイルを許可- 設定は
.markdownImagePolicy(_:)で行う
- 既定(
-
あわせてリモート取得にサイズ上限(既定 10 MB)とタイムアウト(既定 15 秒)を追加し、
失敗をtry?で握りつぶすのをやめてログに理由を出すようにした -
BundledMermaidScriptProviderはバンドルにスクリプトが無い場合、デバッグビルドで
assertionFailureを発生させる。従来は無言で CDN にフォールバックしており、
オフライン動作を期待した利用者のアプリから気づかないまま外部通信が発生していた
追加
-
MarkdownPalette/MarkdownMetrics/MarkdownTypeScaleと、それぞれの
既定実装・環境値・View modifier。外部依存なしで見た目を差し替えられる:struct BrandPalette: MarkdownPalette { var text: Color { .primary } var secondaryText: Color { .secondary } var heading: Color { .indigo } var link: Color { .blue } var codeBackground: Color { Color.gray.opacity(0.12) } var rule: Color { Color.gray.opacity(0.4) } } MarkdownView(source).markdownPalette(BrandPalette())
-
SwiftMarkdownViewDesignSystem/SwiftMarkdownEditorDesignSystemproduct。
swift-design-systemのトークンを上記の抽象へ写すブリッジ -
MarkdownEditorThemeの環境値と.markdownEditorTheme(_:)modifier -
macOS の検索バーについて、ホストアプリ側で
.commands { TextEditingCommands() }が
要ることを README とソースコメントに明記した。エディタはusesFindBarを有効にしているが、
⌘F はアプリの Edit メニュー経由で届き、SwiftUI の既定メニューには Find が含まれない。
宣言しないと検索バーは出てこない(実機で確認) -
エディタの拡張点を公開した。 差別化の中核でありながら、テーマ以外は
ほぼ差し替え不能だった:MarkdownEditorToolbarItem— ツールバーを項目の配列で構成する。既定は
.standard。label(読み上げ名)は省略できず、keyを与えると
ショートカットも付く。ショートカットは項目定義から供給されるので、
ツールバーを差し替えても失われない。空配列を渡すとツールバーを表示しないMarkdownFormattingToolbarを public 化。自前のモード UI と組み合わせられるMarkdownEditorController.state/apply(_:)を public 化。これで
MarkdownFormattingの純関数と組み合わせて任意コマンドが書ける。従来は
applyもreadStateも private で、現在のテキストと選択を読むことすら
できなかったMarkdownEditor(controller:)でコントローラを注入できる。外部から
プログラム的にコマンドを送れるMarkdownEditor(text:mode:...)でモードをBindingとして外に出せる
MarkdownEditor( text: $text, mode: $mode, toolbar: [ .bold, .italic, .separator, .item(icon: "highlighter", label: "マーカー", key: "h") { controller in guard let state = controller.state else { return } controller.apply(MarkdownFormatting.wrap( text: state.text, selection: state.selection, delimiter: "==" )) } ], controller: controller )
-
MarkdownContent(blocks:)を public 化。MarkdownView.init(_ content:)の doc は
「レンダリング前にコンテンツを加工したい場合に使用する」と書いていたが、
ブロック配列から組み直す入口が internal で実行不可能だった
変更
- View modifier の命名を
markdownprefix に統一した。Viewの extension は
グローバル名前空間で、headingStyleやcodeBlockStyleのような一般名は利用者の
アプリや他ライブラリと衝突しうる。旧名は deprecated エイリアスとして残しており、
Xcode の Fix-it で移行できる(削除は次のメジャー)syntaxHighlighter→markdownSyntaxHighlightermathRenderer→markdownMathRenderermermaidScriptProvider→markdownMermaidScriptProvider
- tvOS / watchOS のプラットフォーム宣言を削除。依存パッケージが iOS / macOS しか
宣言しておらず、実際には解決・ビルドできなかった - デモ画面を
SwiftMarkdownViewCatalogとして別 product に分離。本体を import しても
カタログ画面が補完候補に出なくなる