« アプリ一覧に戻る

コダマ (Kodama)

PowerPC Mac (Tiger) 向け ソース公開中

Mac OS X 10.4 Tiger を搭載したPowerPC Mac (G3/G4/G5) 向けの、超軽量3ペイン型Webリーダーです。現代のWebページはJavaScript・広告・巨大な画像だらけで、2000年代半ばのハードウェアではまともに開けません。コダマはそれらを一切読み込まず、libxml2でHTMLを解析して「見出し・本文・画像リンク」だけを抽出し、OS標準のCocoaコンポーネントに直接描画します。JavaScriptもCSSも実行しないため、 G3 450MHz機でも軽快に動作することを目標にしています。

Kodama.dmg をダウンロード
これまでのダウンロード数: 60
最終更新日: 2026-08-29(v0.2.1)
※ Tiger標準のSafari/curlは現代のHTTPS証明書を検証できないため、ここから直接ダウンロードできない場合があります。当サイトでは Aquafox(当サイトが日本語化パックを配布しているPowerPC向けブラウザ)をおすすめします。現代のHTTPSも普通に扱えます。難しい場合は、現代のMacで取得してからコピーするか、Tigerbrew/MacPorts経由の新しいcurlをご利用ください。

更新履歴

  • 2026-08-29 — v0.2.1: モダンHTTPS用のcurlをアプリに同梱したため、MacPorts / Tigerbrewによる外部curlの導入は不要になりました。特別な理由がなければv0.2.1をご利用ください。

機能

  • 左ペイン — 見出し(h1〜h3)の一覧。クリックで本文の該当箇所へジャンプ、または(見出しがリンクの場合は)別記事へ直接遷移します。
  • 中央ペイン — 記事本文。画像は[ 画像N を表示 ]というリンクに置き換わり、クリックした時だけ読み込みます。
  • 右ペイン — クリックした画像のプレビュー。普段は隠れている「隠れ3ペイン」方式で、狭い画面でも本文の表示領域を広く保てます。
  • アドレスバー下の折りたたみ式ブックマークバー。ブックマークごとの名前変更・削除にも対応。
  • 戻る/進む履歴。戻るボタンを右クリックすると訪問履歴の一覧からも直接ジャンプできます。
  • 日本語/英語のUI切り替え(実行中にその場で切り替え可能)。
  • アドレスバーにURLでない文字列を入力すると、DuckDuckGoのHTML版検索に問い合わせます。
  • ファイルダウンロード(.dmg/.zip/.pdf等)は実際のレスポンスヘッダから判定し、ページとして誤表示せず通常の保存ダイアログで保存します。

動作要件

  • Mac OS X 10.4 Tiger、PowerPC G3/G4/G5
  • v0.2.1からは、それ以外に何も要りません。TLS 1.2/1.3対応の新しいcurlをアプリ自体に同梱したため、 Tiger標準の古いシステムcurlは一切使いません。(以前のバージョンは Tigerbrew やMacPorts経由で別途curlを導入する必要がありましたが、今はその必要はありません。導入済みの場合は 引き続きそちらにフォールバックします。)

インストール手順

  1. Kodama.dmg をダウンロードして開きます。
  2. Kodama.app を、動かしたいPowerPC Macの/Applicationsなど好きな場所にドラッグします。
  3. これだけです。そのまま開いてブラウズを始められます。別途curlの導入は不要です。

既知の制限

  • HTMLフォーム(検索ボックス等)には対応していません。現状はアドレスバーの検索フォールバックのみが代替手段です。
  • サイトごとのナビゲーション除外は簡易的なヒューリスティックのため、レイアウトによっては広告・メニュー等が本文に混ざることがあります。

対応環境

動作環境PowerPC Mac / Mac OS X 10.4.11 (Tiger)
動作確認機種iBook G4

個人の趣味プロジェクトにつき無保証、MITライセンスです。詳しいソースコードはGitHubをご覧ください。

コダマの中身は、libxml2でHTMLを構造化するだけの軽量パーサーです。WebKitは使わず、JavaScriptも CSSも一切実行しません。目標は最初からG3 450MHzでも実用的に動くこと。ここでは実装のポイントと、実際のサイトで踏んだ地雷を紹介します。

なぜWebKitを使わないか

今どきのWebページはJS・広告・巨大な画像だらけで、G3世代のCPUではまともに描画できません。だからコダマは最初からWebKitを捨てて、libxml2でHTMLをパースし、見出し・本文・画像リンクだけを抜き出して Cocoaの標準部品に直接描画する設計にしました。JSもCSSも動かさないので、そもそも重くなりようがない、という考え方です。

Tigerの制約に何度もぶつかった

最初のパーサー(HTMLParserEngine)を作った段階から、実機検証だけでいくつも古い環境特有の壁に当たりました。使っているlibxml2(2.6.16)にはHTML_PARSE_RECOVER定数が無い、Foundation(10.4)には componentsSeparatedByCharactersInSet:が無くてNSScannerベースで書き直す必要がある、といった具合です。一番厄介だったのはgcc 4.0.0のObjective-C文字列リテラル(@"...")で、日本語などのマルチバイト文字を含む@""リテラルが正しくエンコードされず文字化けするというバグ。何度も踏んだので、Cの生リテラル+stringWithUTF8String:経由で文字列を作るPWRJPStrというマクロを用意して、以降のUI文字列は全部これ経由にしました。

blocksもGCDも無い時代の非同期通信

TigerにはGCDもblocksも無いので、curlを非同期で呼ぶだけでも一苦労でした。 NSTaskDidTerminateNotificationとNSFileHandleReadCompletionNotificationを両方待ち合わせる形で CurlTaskRunnerというクラスを実装し、結果はdelegateで通知する昔ながらの作りにしています。実機では Tigerbrew経由のポータブルcurl(7.58.0+OpenSSL 1.0.2l)でHTTPS取得に成功し、TLS1.2/1.3のハンドシェイク回避というこのアプリの核心部分を実証できました。

curlを「必須」から「同梱」にした

v0.2までのTigerbrew/MacPorts必須という要件は機能はしてたんですが、どちらも入ってない素のTiger環境だと それだけで詰んでしまう問題がありました。実際にPower Mac G4にv0.2を入れた利用者がまさにこれに遭遇して 発覚しました。v0.2.1では、静的リンクしたPPC版curl 8.9.1(LibreSSL 3.8.4)と最新の cacert.pemを、そのままKodama.app/Contents/Resourcesに同梱するようにしました。 CurlTaskRunnerのパス検出は、まずこの同梱版を最優先で探しに行き、無ければ従来通りの 探索順(/opt/local/usr/local/binPATH上のポータブルcurl)に フォールバックします。--cacertオプションは、実際に動いているのが同梱版のcurlの時だけ 渡すようにしていて、システムに入ってるcurlにフォールバックした場合は、そちらが元々信頼してるCAストアを 上書きせずそのまま尊重するようにしています。

「隠れ3ペイン」の実装

右ペイン(画像プレビュー)は普段は幅0で隠れていて、画像リンクをクリックした時だけ広がる作りです。ところがTiger(10.4)のNSSplitViewにはsetPosition:ofDividerAtIndex:というメソッドが無く、今どきのやり方が使えません。splitView:resizeSubviewsWithOldSize:の中でサブビューのframeを自分で計算する、昔ながらのやり方で折りたたみ/展開を実装しています。

実サイトとの終わらないいたちごっこ

ここが一番時間を食ったところかもしれません。

Shift_JISの文字化け。 libxml2(2.6.16)のエンコーディング自動検出があてにならず、 charset=shift_jisを宣言している実サイト(ITmedia等)で文字化けが起きました。htmlReadMemoryにNULLを渡して自動検出任せにするのをやめ、HTML先頭のmeta charset宣言を自前で読み取って明示的にエンコーディングを渡すように変更して直しました。
JSコードが本文に漏れる。 同じlibxml2がscriptタグの中身をHTML5仕様通りの生テキストとして扱ってくれず、JSのテンプレートリテラルの中に書かれたタグっぽい文字列(FNNニュース等で発生)を見て「scriptの外に出た」と誤認識し、JSコードがそのまま本文として表示されてしまう不具合がありました。パーサーに渡す前の生バイト列の段階でscript/styleの中身を確実に取り除く前処理を追加して解消しています。
グローバルメニューが本文に混入。 FNNニュースのような実サイトで、divで組まれたグローバルメニュー(class="m-gnav"等)が実際のnavタグではないため本文冒頭に丸ごと入ってきてしまう問題がありました。class/id名に「gnav」のような特徴的な語を含む要素を除外するヒューリスティックを追加しましたが、「nav」や「header」のような一般的すぎる語は記事本文側のクラス名を誤って除外してしまう恐れがあったので避け、誤検知の少ない具体的な語(gnav/globalnav/breadcrumb/pankuzu/drawer/ hamburger)だけに絞っています。

日英切り替えの落とし穴

英語に切り替えてもウィンドウタイトルだけ「コダマ」のまま、Editメニューの項目も日本語のまま、という報告がありました。調べたら、ウィンドウタイトルの一部が「コダマ」という文字列を決め打ちで作っていて、言語切り替えの仕組みを経由していなかったのが原因。Editメニューの各項目もローカル変数のまま作っていたため、切り替え対象のリストに単純に入れ忘れていました。両方修正して、実機で全項目が切り替わることを確認しています。ちなみにメニューバー左端のアプリ名は、OSがCFBundleName から強制的に表示する部分で実行中は切り替えられないため、日本語話者以外にも読めるよう最初から「Kodama」というラテン文字表記にしています。「コダマ」というアイデンティティ自体は、ウィンドウタイトルやAboutパネル、この配布サイトの方には残しています。

今後

フォーム未対応(検索ボックスなど)は、現状アドレスバーのDuckDuckGo検索フォールバックだけで凌いでいるので、ここは引き続き検討中です。

ソースコードはGitHubにあります。