書式がない

「ページの編集に必要な前提知識を限りなくゼロに近づけたい」という目標のもと、SocieWikiは、Wikiのくせに書式というものがない。フラットなテキストファイルとして編集し、それが同じように表示される。

単純にすべてを<pre>で囲うようなことはせず、改行を<br>に、空白を &nbsp; かつ monospace となるようにレンダリングしている。

日本語の文章もプログラムのコード片もパッチも、なるべく自然に見やすく表示できるようにという試行錯誤からきた妥協点だ。

すべてオートリンク

前述の書式がないことにも関連しているが、SocieWikiは、ページへのリンクを明示的に指定するルールが存在しない。

WikiName,BracketNameなどの特殊な記法を使わなくても、文中にページ名が出現するとそれを自動的にリンクにする。

差分の表示

SocieWikiではページを普通に閲覧するモードで、常に前回との差分を表示している。

コミュニティを運営するためのWikiとして、ユーザー登録制というシステムを採用している以上、ビジターは不特定多数の「一見さん」よりも、いつも来る「常連さん」である確率が圧倒的に高いだろう、と踏んでいる。

そして、いつも来る人は、ページが更新されているとまず「どこが書き換わったのだろう」と差分表示をクリックすることが経験的に分かっている。

となれば、わざわざ「差分表示」なんていうモードを設けないで、最初から差分を見せてしまったほうが親切だろう、と判断した。

といっても、削除された行まで表示すると文書として見難くなってしまうので、前回の版になかった行(一部が書き直された行&新しく追加された行)に、 <ins>タグを付加して表示している。

  • <ins>がどのように表示されるかはスタイルシート次第だが、たいていは、背景色が少し変わっていたり、アンダーラインが引かれたりしている。(SocieWikiは、テーマ選択機能によってCSSをユーザーごとに切り替えられる)

表示時に毎回旧版との比較を行うのは効率が悪いので、ページを編集して保存するタイミングで比較して、差分情報をキャッシュしている。

比較するロジックも、普通のWikiエンジンではLCSとかのdiffアルゴリズムを使って正確に差分を計算したりしているが、SocieWikiでは思いっきり手を抜いている。

具体的なコードは下記の通り。

  1. function computeDifference($new, $old) {
  2. $newArray = explode("\n", Formatter::normalizeLineBreak($new));
  3. $oldArray = explode("\n", Formatter::normalizeLineBreak($old));
  4. $diff = array_diff($newArray, $oldArray);
  5. return $diff;
  6. }

なにをしているかというと、PHPの標準関数 array_diff() を使って「旧版には存在せず新版にだけ存在する要素(=行)」を調べている。 array_diff() は位置や重複を考慮せず、要素の存在の有無だけを調べるため、この方法には下記のような欠陥がある。

  • 単に行の順序を入れ替えたりしただけでは変更として検知できない。
  • 同じ文字列で構成される行が複数あると、増えたり減ったりしてもわからない。

このロジックがプログラムのソースコードの比較には向いていないのは確かだが(*)、人間が読むテキストの更新状況をざっと把握するという目的にはあまり困らない。

  • 例えばブロックを閉じる“}”だけの行が増えたり減ったりしても分からない