2 ポイント 投稿者 GN⁺ 2024-03-06 | 1件のコメント | WhatsAppで共有

Appleテキストエディタの技術的内部

  • TextView ベースのテキストエディタとしてのPaperの動作の詳細を扱う。
  • Paperは現在TextKit 1フレームワークを基盤に構築されており、TextKit 2でも概念、抽象化、原則は維持されるか、より良いAPIへと置き換えられている。

テキストビュー

  • TextView クラスはAppleテキストエディタにおけるテキスト編集処理の中核。
  • NSTextViewUITextView には違いがあるが、APIが似ているため、ひとつの TextView クラスとして扱う。
  • TextView はOSのリリースごとに複雑さが増している大規模コンポーネント。
  • Appleは TextView を複数のレイヤーに細分化し、テキスト編集体験を提供している。

NSTextStorage

  • 生のテキスト文字列を保存する。
  • テキスト範囲に割り当てられた属性(文字列-値のペア)を保存する。
  • テキストと属性の変更に関するイベントを発生させる。

NSTextContainer

  • テキスト記号(グリフ)を保持する領域の形状とサイズを定義する。

NSLayoutManager

  • NSTextStorage のテキスト文字列に適用された属性範囲を見て、グリフのサイズと間隔を計算する。
  • グリフをレイアウトし、テキストの各行がどこで始まりどこで終わるか、テキスト全体の高さを計算する。

TextView

  • NSLayoutManager によって生成されたグリフレイアウトを描画する。
  • ビューの高さをレイアウト済みテキストの現在の高さと同期する。
  • テキスト選択、キャレット、新たに挿入されたテキストに適用されるタイピング属性を管理する。

ScrollView

  • TextView の表示されている部分を表示する。
  • スクロール、スクロールバー、ズームを管理する。

属性

  • NSAttributedString はAppleフレームワークにおけるリッチテキスト編集の基盤。
  • 通常のテキスト文字列と、テキスト範囲に付与された属性(文字列-値のペア)で構成される。
  • 属性は主にスタイリング目的で使われるが、カスタムの文字列-値ペアを割り当てることに制限はない。

スタイリング

  • スタイリングとは、テキスト範囲に特別なフレームワーク定義属性を適用することを意味する。
  • Paperはメタ属性を使ってテキスト構造を識別したうえでスタイリングを適用する。
  • 属性は、ユーザー入力によって変更される NSTextStorageMarkdownテキスト と、ユーザーがメニュー項目、スライダー、ジェスチャーで調整する テキスト影響設定 と同期される。

パフォーマンス

  • メタ属性、レイアウト属性、装飾属性の分離は、特定のエディタ変更を高速に維持するのに役立つ。
  • タイピング速度はテキストエディタで最も重要なパフォーマンス要素。
  • Markdownの仕組みにより、テキスト変更は段落全体のスタイリングに影響を与えることがある。

メタ属性

  • ハイライト処理のロジック以外にも、メタ属性はテキスト構造を把握する必要があるさまざまな機能で重要な役割を果たす。

フォーマット用ショートカット

  • 選択されたMarkdownテキストのスタイルを切り替えるために必要な詳細情報を提供する。

章間移動

  • キャレット位置に対して相対的な見出しを見つけるのに役立つ。

アウトライン

  • すべての見出しを走査する機能に依存する。

章の並べ替え

  • アウトライン内で章を並べ替える機能を提供する。

フォーマット変換

  • MarkdownコンテンツをRTF、HTML、DOCXに変換するには構造を把握する必要がある。

テキストコンテナの数学

  • テキストコンテナでは、好ましい行長を維持することが最も重要なルール。
  • 見出しタグが通常のテキストフローの外に配置される場合のように、対称性を装う必要があることもある。

選択のアンカリング

  • テキスト選択には常にアンカーポイントがある。
  • Macではクリックしてドラッグしてテキストを選択し、iOSでは選択範囲の片端をドラッグできる。

選択親和性

  • テキスト編集には 選択親和性 という興味深い概念がある。
  • キャレットを矢印キーで移動すると単純に行が切り替わるが、ショートカットで行末へ移動すると同じ行に留まりつつ右側に付く。

Uniform Type Identifiers (UTIs)

  • アプリ間データ交換の基盤システムであるUTIについて議論する。
  • データ型が親データ型に conform to(継承)する階層システム。

ペーストボード

  • ペーストボードは、UTIがシリアライズ済みデータにマッピングされた辞書。
  • 単一の コピー 操作で、同じデータの複数の表現を同時に書き込む。
  • 公開UTIとプライベートUTIを扱うのは比較的簡単だが、Appleによって定義されていない広く受け入れられた形式を扱うのはより複雑。

まとめ

  • 最初の記事を確認すると、アプリと開発プロセスについてさらに多くの情報を得られる。

GN⁺のコメント

  • この記事は、Appleプラットフォームにおける TextView ベースのテキストエディタの複雑な内部動作を詳しく説明しており、ソフトウェア開発者や関心のあるユーザーに興味深い情報を提供する。
  • テキストエディタのパフォーマンス最適化のためのアルゴリズムと属性管理の方法は、開発者が自らのアプリケーションを設計する際に参考にできる好例である。
  • テキストエディタの性能を高めるために使われた技術的アプローチは、他の開発者が類似の問題を解決する際に参考にできる有用な指針を提供する。
  • Markdownのようなテキストフォーマットを扱うアプリケーションを開発する際、UTIの理解はデータ交換と互換性のために重要である。
  • この記事はテキストエディタの内部構造への理解を深める助けになるが、実際にこの複雑さを管理することは開発者にとってかなりの挑戦になり得る。

1件のコメント

 
GN⁺ 2024-03-06
Hacker Newsのコメント
  • これは本当に素晴らしい記事だ。TextKitの基本的な入門資料として、https://www.objc.io に取って代わりそうだ。

    • このコメントは、この記事がTextKitの基本的な紹介として非常に有用だと評価している。
  • 編集トランザクションの外で行われる装飾的属性について少し混乱している。"そしてそれはトランザクションを認識しない。なぜならそれはNSTextStorageではなく、NSLayoutManager自体に存在するからだ" とある。だが、色のような装飾的属性は普通NSTextStorageに存在するはずだ! 著者は、Markdown文字に適用された色がNSLayoutManagerの一時的属性のサポート(通常はスペルミスの単語に色を付けるのに使われる)によって実現されていることを示唆しているのだろうか? だとしたら、その目的は何だろう?

    • コメント投稿者は、テキスト編集に関する技術的な詳細に混乱しており、装飾的属性がNSLayoutManagerとNSTextStorageの間でどのように扱われるのかという著者の説明に疑問を呈している。
  • 本当に素晴らしい記事だ(そして個人的にもタイムリーだ。今まさにNSTextViewを扱っている)。この情報はどうやって得たのか? 他人のコード? 苦労して得た経験? developer.apple.com?

    • コメント投稿者は、この記事が非常に有用だと評価し、著者がこうした知識をどのように得たのかを知りたがっている。
  • DOMドキュメントの時代に(例: notion、gitbook)、私はよく属性付き文字列を使ってテキストのパースや操作に魔法のようなことをしている。これはとてもエレガントな構造で、なぜこれほど知られていないのか理解できない。ちなみに記事は驚くほど素晴らしい。

    • コメント投稿者は、属性付き文字列を使うことがエレガントな方法だと考えており、この技術がもっと広く知られていない理由が理解できないと述べている。記事への称賛も添えている。
  • 以前、ゼロから独自のテキストエディタを書こうとしたことがあるが、そのときこういう資料があったなら本当にすごかっただろう。

    • コメント投稿者は、自分がテキストエディタを最初から作ろうとした経験に触れ、このような記事が当時あれば非常に役立っただろうと述べている。
  • 私は長い間Androidアプリ開発者だったので、Appleが物事にやや異なる、より慎重なアプローチをしているのを見るのは興味深かった。Androidでは、Layoutクラス(およびそのサブクラス)がレイアウトとレンダリングに関するすべてを処理し、TextViewが編集/選択ロジックの一部を実装する。EditTextとTextViewの唯一の違いは、EditTextがTextViewにすでに存在する編集機能を「有効化」することだ。このやや一体型のアプローチ(そして出来の悪いAPI)の問題は、アプリがテキストのレンダリング方法についてより多くの制御を必要とする場合、打つ手がないことだ。たとえば、レイアウト後に個々のグリフへアクセスしたい場合は? いや、無理だ。

    • コメント投稿者は、AndroidとAppleのテキストレンダリングおよび編集へのアプローチの違いを説明し、Androidではより細かな制御が必要なときに制約がある点を指摘している。
  • TextEditアプリはほぼ完全に単一のTextViewで構成されている。Windowsでの対応物はWordPadだと思う。これはRichEditコントロールをベースにしている。もう1つ面白い事実として、RTFは基本的にNSAttributedStringをシリアライズした形式だ。WindowsのRichEditコントロールにも同じことが当てはまる。実際にはWindows側の実装のほうが先だったようだ: https://en.wikipedia.org/wiki/Rich_Text_Format

    • コメント投稿者は、TextEditアプリがTextViewをベースにしており、RTF(Rich Text Format)がNSAttributedStringのシリアライズされた形式であることに言及している。また、Windowsで似た機能を持つRichEditコントロールのほうが先に登場した可能性があるとも述べている。
  • このアプリが本当に好きだ。obsidianや ia Writer を含む、他のすべてのMarkdownアプリを置き換えてしまった!

    • コメント投稿者は、このアプリがMarkdown作業向けの既存のすべてのアプリを置き換えたとして、非常に満足している。
  • ありがたいことに、少なくとも誰かは2024年になってもCocoaを使っている。

    • コメント投稿者は、今なおCocoaフレームワークを使っている開発者がいることに安堵を示している。
  • iOSコンポーネントについて、こういう文書がもっとあればいいのに!

    • コメント投稿者は、iOSコンポーネントに関するこの種の文書がもっと増えてほしいという希望を表している。