[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

Column block scanning



大和です。

新機能の提案とその機能を実現するアルゴリズムの雛型の提案です。
うまく説明できるかな...


私はemacs-w3mでも特に目的の場所へいかに少ないキーストロークで
カーソルを移動させることができるかに関心があります。少ないキー
ストロークでカーソル移動を実現する方法の一つはweb pageに含まれ
る情報を利用することです。ここで情報とはweb pageのレイアウトの
ことをさします。

今回はレイアウトのうち特にコラムブロックに注目します。
コラムブロックとは互いに列方向独立した文章のかたまりです。
コラムブロックはバッファ縦方向に長く続きます。

http://slashdot.jp/を例に説明します。

----------------------------------------------------------------
        1                       2                             3
----------------------------------------------------------------
          共同開発支援システム -SORCEFORGE                                    

スラッシュドットジャパン   検閲  ハンドヘルド  プログラミング  ニュース  宇宙 
 About us             ● 焚書の標的になるハリー    日記も始めました!!         
 FAQ                     ・ポッター                スラッシュドットの正式運   
 プライバシー                                      用を開始しました。ぜひ、   
 トピック             Oliver による Tuesday        ユーザ登録をしてみてくだ   
 編集者紹介           November 20, @12:00AM の投   さい。登録しないと日記を   
 ユーザ設定           稿,                         含めて重要な幾つかの機能   
 古いストーリー       心の狭い大人達部門より.     が使えません。それが終わ   

...........................................................................
...........................................................................
...........................................................................

Geocrawler            みに、自分も映画を前に昨日   Xbox対抗でPS3発売前倒し    
Kuro5hin              から一巻を読んでたりする。   (29)                       
LinuxGram                                          無線LAN規格「802.11g」が   
OSDN.com              (もっと読む… | 27 コメン    IEEEで承認 (13)            
OSDN Japan            ト)                          「料理の鉄人」アメリカ版   
                                                   デビュー (15)              
                                                   さっそくXboxバラしました   
                      ● X'masプレゼントに新型     (19)                       
                         CLIE                                                 

----------------------------------------------------------------
http://slashdot.jp/には3つのコラムブロックがあります。
第1コラムブロックは, slashdot.jpのサイトに関連したのメタ情報が記載され
ています。第2コラムブロックは, このサイトのメインコンテンツである投稿
記事が記載されています。第3コラムブロック過去の記事と日記が記載されて
います。

emacs-w3mでこのコラムブロックを認識できるようにしてコラムブロック単位で
移動できては便利ではないでしょうか。あんまり便利じゃない?

コラムブロックを認識できると良いことは他にもあります。たとえば
縦scroll時に発生してしまう横方向のぶれ(意図せぬ横スクロール)をコラム
ブロックを使って固定できるかもしれません。emacs-w3mを使っていて不便な
ことの一つはある列にカーソルを置いてC-nやC-vなどweb pageを読み進める場合に、
page内に極端に短い行があり、もともと読み進めていた列からずれて、
縦のみでなく横方向にスクロールしてしまう場合です。ユーザが現在どの
コラムブロックを読んでいるかをemacs-w3mが認識することができれば、
そのコラムブロックが必ず表示されるように縦スクロールを制御できる
かもしれません。

さらにもし横方向の文章かたまり(ラインブロック)を認識することがで
きれば、コラムブロックとラインブロックを指定してweb pageの特定の
部分だけを抜きとってきたりすることができるかもしれません。

コラムブロックを認識するアルゴリズム:
まずページ内の各コラムごとに、コラム方向(縦方向に)空白以外の文字が何
文字含まれているかを数えます。空白以外の文字数が多いコラムは
コラムブロックの一部であり、少ないブロックはコラムブロックとコラムブロック
の境界となるコラムである。

コラム方向(縦方向に)空白以外の文字が何文字含まれているかを数えるコー
ドだけ書いてきました。

w3m-get-column-vectorは現在表示されているページの各columnに文字を
columnをインデックスとするベクトルを返します。

http://slashdot.jp/で実行してみました。

[24 32 24 33 26 36 26 32 21 18 14 11 9 8 7 5 4 5 5 3 6 2 
                                                       ;;;;;;;; 境界 
283 49 252 73 233 76 216 75 201 74 201 79 186 66 202 63 209 
80 193 76 184 63 175 53 168 5 4 3 4
                                  ;;;;;;;; 境界 
183 119 180 117 150 113 149 103 126 85 118 96 132 
81 109 77 99 63 88 51 66 33 44 7 2 0 0 0 0]

どこにももって行きようのない投稿になってしまいました。すいません。

;; w3m-block.el
;; Masatake YAMATO<jet@gyve.org>

;; Entry point
(defun w3m-get-column-vector ()
  (save-excursion
    (let* ((max-column (progn
			 (goto-char (point-min)) (end-of-line) (point)))
	   (column-vector (make-vector max-column 0))
	   (i 0)
	   chars)
      (while (< i max-column)
	(aset column-vector i 
	      (w3m-count-column-chars i))
	(setq i (1+ i)))
      column-vector)))
	
(defun w3m-count-column-chars (col)
  (save-excursion
    (goto-char (1+ col))
    (let (goal-column)
      (set-goal-column nil)
      (w3m-count-current-column-chars)
      )))

(defsubst w3m-char-is-in-text (c)
  (if (or (eq c ?\ ) (eq c nil) (eq c ?\n))
      nil
    t))

(defun w3m-count-current-column-chars ()
  (let ((chars 0))
    (condition-case nil
	(while t
	  (if (and (eq goal-column (current-column))
		   (w3m-char-is-in-text (char-after)))
	      (setq chars (1+ chars)))
	  (next-line 1))
      (error nil))
    chars))