[Hiki-dev:00538] 編集履歴にリンクを増やして欲しい

Back to archive index

Kouhei Sutou kou****@cozmi*****
2004年 6月 27日 (日) 23:14:23 JST


須藤です.

編集履歴関係のページにもっとリンクを増やして欲しいです.具体
的には以下のようなリンクが欲しいです.

== 編集履歴一覧ページ

  * 元のページへのリンク

== diffページ

  * 元のページへのリンク
  * 前後のリビジョンでのdiffを表示するページへのリンク
  * 現在のリビジョンのソースを表示するページへのリンク

最後のふたつがあると,編集履歴を順に追って行くときに編集履歴
ページに戻らなくてもよいのでだいぶ楽になります.

== ソース表示ページ

  * 元のページへのリンク


以上のようなリンクを作成するパッチを作成したので付けます.こ
のパッチを適用するとどうなるかというのは以下のページをみると
わかると思います.

  http://pub.cozmixng.org/~hiki/test/?c=history;p=FrontPage


Index: misc/plugin/history.rb
===================================================================
RCS file: /cvsroot/hiki/hiki/misc/plugin/history.rb,v
retrieving revision 1.5
diff -u -p -r1.5 history.rb
--- misc/plugin/history.rb	26 Jun 2004 14:25:14 -0000	1.5
+++ misc/plugin/history.rb	27 Jun 2004 14:07:02 -0000
@@ -108,6 +108,10 @@ module Hiki
       '現在のバージョンとの差分を見る'
     end
 
+    def history_view_this_version_src_label
+      'このバージョンのソースを見る'
+    end
+
     def history_backto_summary_label
       '編集履歴ページに戻る'
     end
@@ -152,15 +156,7 @@ module Hiki
       generate_page(data) # private method inherited from Command class
     end
 
-
-    public
-
-    # Output summary of change history
-    def history
-      unless history_repos_root then
-	return history_output(history_not_supported_label)
-      end
-
+    def revisions
       # make command string
       case history_repos_type
       when 'cvs'
@@ -168,30 +164,87 @@ module Hiki
       when 'svn'
 	hstcmd = "svn log #{@p.escape}"
       else
-	return history_output(history_not_supported_label)
+	raise
       end
-
+      
       # invoke external command
       cmdlog = history_exec_command(hstcmd)
-
+      
       # parse the result and make revisions array
-      revisions = Array::new()
+      parse_history(cmdlog)
+    end
+
+    def parse_history(cmdlog)
+      revs = Array::new()
+      diffrevs = ''
       case history_repos_type
       when 'cvs'
         cmdlog.split(/----------------------------/).each do |tmp|
 	  if /revision 1.(\d+?)\ndate: (.*?);  author: (?:.*?);  state: (?:.*?);(.*?)?\n(.*)/m =~ tmp then
-	    revisions << [$1.to_i, $2, $3, $4]
+	    revs << [$1.to_i, $2, $3, $4]
 	  end
 	end
       when 'svn'
-        diffrevs = ''
         cmdlog.split(/------------------------------------------------------------------------/).each do |tmp|
           if /(?:\D+)(\d+?)[\s:\|]+[(?:\s)*](?:.*?) \| (.*?) \| (.*?)\n(.*?)\n/m =~ tmp then
-	    revisions << [$1.to_i, $2, $3, $4]
+	    revs << [$1.to_i, $2, $3, $4]
             diffrevs << $1.to_i
 	  end
 	end
       end
+      [revs, diffrevs]
+    end
+
+    def recent_revs(revs, rev)
+      ind = revs.index(revs.assoc(rev)) || 0
+      prev_rev = revs[ind + 1]
+      prev2_rev = revs[ind + 2]
+      if ind - 1 >= 0
+	next_rev = revs[ind - 1]
+      else
+	next_rev = nil
+      end
+      [prev2_rev, prev_rev, revs[ind], next_rev]
+    end
+
+    def diff_link(rev1, rev2, rev_title1, rev_title2, link)
+      title = []
+      title << (rev_title1 || (rev1 and rev1[0]) || nil)
+      title << (rev_title2 || (rev2 and rev2[0]) || nil)
+      title = title.compact
+      title.reverse! unless rev2.nil?
+      title = title.join("<=>").escapeHTML
+      
+      do_link = (link and rev1)
+      
+      rv = "["
+      if do_link
+	rev_param = "r=#{rev1[0]}"
+	rev_param << ";r2=#{rev2[0]}" if rev2
+	rv << %Q[<a href="#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};#{rev_param}")}" title="#{title}">]
+      end
+      rv << title
+      if do_link
+	rv << "</a>"
+      end
+      rv << "]\n"
+      rv
+    end
+
+    public
+
+    # Output summary of change history
+    def history
+      unless history_repos_root then
+	return history_output(history_not_supported_label)
+      end
+
+      unless %w(cvs svn).include?(history_repos_type)
+	return history_output(history_not_supported_label)
+      end
+
+      # parse the result and make revisions array
+      revs, diffrevs = revisions
 
       # construct output sources
       if history_repos_type == 'svn' then
@@ -201,20 +254,22 @@ module Hiki
       #  sources << "<pre>\n"
       #  sources << cmdlog
       #  sources << "</pre>\n"
+      sources << @plugin.hiki_anchor(@p.escape, @plugin.page_name(@p))
+      sources << "\n<br>\n"
       sources << "\n<table border=\"1\">\n"
       if****@conf*****['history.hidelog']
 	sources << " <tr><th>#{history_th_label[0].escapeHTML}</th><th>#{history_th_label[1].escapeHTML}</th><th>#{history_th_label[2].escapeHTML}</th><th>#{history_th_label[3].escapeHTML}</th></tr>\n"
       else
 	sources << " <tr><th rowspan=\"2\">#{history_th_label[0].escapeHTML}</th><th>#{history_th_label[1].escapeHTML}</th><th>#{history_th_label[2].escapeHTML}</th><th>#{history_th_label[3].escapeHTML}</th></tr><tr><th colspan=\"3\">#{history_th_label[4].escapeHTML}</th></tr>\n"
       end
-      revisions.each do |rev,time,changes,log|
+      revs.each do |rev,time,changes,log|
 	#    time << " GMT"
         op = "[<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_src;p=#{@p.escape};r=#{rev}")}\">View</a> this version] "
 	op << "[Diff to "
         case history_repos_type
         when 'cvs'
-          op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev}")}\">current</a>" unless revisions.size == rev
-	op << " | " unless (revisions.size == rev || rev == 1)
+          op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev}")}\">current</a>" unless revs.size == rev
+	op << " | " unless (revs.size == rev || rev == 1)
           op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev};r2=#{rev-1}")}\">previous</a>" unless rev == 1
         when 'svn'
           op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev}")}\">current</a>" unless prevdiff == 1
@@ -263,7 +318,9 @@ module Hiki
       # construct output sources
       sources = ''
       sources << "<div class=\"section\">\n"
-      sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{r}")}\">#{history_diffto_current_label.escapeHTML}</a><br>\n"
+      sources << @plugin.hiki_anchor(@p.escape, @plugin.page_name(@p))
+      sources << "\n<br>\n"
+      sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{r.escapeHTML}")}\">#{history_diffto_current_label.escapeHTML}</a><br>\n"
       sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('history', "p=#{@p.escape}")}\">#{history_backto_summary_label.escapeHTML}</a><br>\n"
       sources << "</div>\n"
       sources << "<pre class=\"diff\">\n"
@@ -279,6 +336,10 @@ module Hiki
 	return history_output(history_not_supported_label)
       end
 
+      unless %w(cvs svn).include?(history_repos_type)
+	return history_output(history_not_supported_label)
+      end
+
       # make command string
       r =****@cgi*****['r'][0] || '1'
       r2 =****@cgi*****['r2'][0]
@@ -295,15 +356,40 @@ module Hiki
 	return history_output(history_not_supported_label)
       end
 
+      # parse the result and make revisions array
+      revs, diffrevs = revisions
+			
+      prev2_rev, prev_rev, curr_rev, next_rev = recent_revs(revs, r.to_i)
+      last_rev = revs[0]
+
       # invoke external command
       cmdlog = history_exec_command(hstcmd)
-      cmdlog.gsub!(/(?:.*?)---/m, '---') # Get rid of header
+      cmdlog.gsub!(/\A(?:.*?)---/m, '---') # Get rid of header
       cmdlog = "*** no diff ***" if cmdlog.empty?
 
       # construct output sources
       sources = ''
       sources << "<div class=\"section\">\n"
+      sources << @plugin.hiki_anchor(@p.escape, @plugin.page_name(@p))
+      sources << "<br>\n"
+      sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_src;p=#{@p.escape};r=#{curr_rev[0]}")}\">#{history_view_this_version_src_label.escapeHTML}</a><br>\n" if curr_rev
       sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('history', "p=#{@p.escape}")}\">#{history_backto_summary_label.escapeHTML}</a><br>\n"
+      sources << "\n"
+
+      if prev_rev
+	do_link = (last_rev and prev_rev and last_rev[0] != prev_rev[0])
+	sources << diff_link(prev_rev, nil, nil, "HEAD", do_link)
+      end
+      if prev_rev and prev2_rev
+	sources << diff_link(prev_rev, prev2_rev, nil, nil, true)
+      end
+      sources << diff_link(curr_rev, r2.nil? ? nil : prev_rev, nil, nil, false)
+      if next_rev
+	sources << diff_link(next_rev, curr_rev, nil, nil, true)
+      end
+      do_link = (r2 and last_rev and last_rev[0] != curr_rev[0])
+      sources << diff_link(curr_rev, nil, nil, "HEAD", do_link)
+
       sources << "</div>\n<br>\n"
       sources << "<span class=\"add_line\">#{history_add_line_label.escapeHTML}</span><br>\n"
       sources << "<span class=\"del_line\">#{history_delete_line_label.escapeHTML}</span><br>\n"
@@ -311,16 +397,21 @@ module Hiki
 #     sources << cmdlog.escapeHTML
       diffsrc = cmdlog.escapeHTML
       cmdlog = nil
-      diffsrc.each do |tmp|
-        if /^[\+\-].*/m =~ tmp then
-          if /^\+.*/m =~ tmp then
-            tmp = "<span class=\"add_line\">#{tmp}<\/span>"
-          elsif
-            tmp = "<span class=\"del_line\">#{tmp}<\/span>"
+      diffsrc.each_with_index do |line, i|
+        if /^([\+\-]).*/m =~ line then
+	  added = $1 == '+'
+	  if i < 2 then
+	    mark, page_name, other = line.split(/ /, 3)
+	    line = "#{mark} #{page_name.unescape} #{other}"
+	  end
+          if added then
+            line = "<span class=\"add_line\">#{line}<\/span>"
+          else
+            line = "<span class=\"del_line\">#{line}<\/span>"
           end
         end
-        if /^[^\\].*/m =~ tmp then
-          sources << "#{tmp}"
+        if /^[^\\].*/m =~ line then
+          sources << "#{line}"
         end
       end
       sources << "</pre>\n"




Hiki-dev メーリングリストの案内
Back to archive index