summaryrefslogtreecommitdiffstats
path: root/app/models/wiki_page.rb
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2007-12-20 19:10:24 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2007-12-20 19:10:24 +0000
commit31c6ebb31046470d41a625195662dfccdff116c4 (patch)
treeab099bc278f30009158a7afe93a1ca46e9594ef9 /app/models/wiki_page.rb
parent3d5381b24bb488e4e9edd5a9eec2ba8be4de5c63 (diff)
downloadredmine-31c6ebb31046470d41a625195662dfccdff116c4.tar.gz
redmine-31c6ebb31046470d41a625195662dfccdff116c4.zip
Added wiki annotate view. It's accessible for each version from the page history view.
Slight style change: pre-wrap added on file/diff contents. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1020 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models/wiki_page.rb')
-rw-r--r--app/models/wiki_page.rb45
1 files changed, 45 insertions, 0 deletions
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index cbca4fd68..8ce71cb80 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -16,6 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'diff'
+require 'enumerator'
class WikiPage < ActiveRecord::Base
belongs_to :wiki
@@ -87,6 +88,12 @@ class WikiPage < ActiveRecord::Base
(content_to && content_from) ? WikiDiff.new(content_to, content_from) : nil
end
+ def annotate(version=nil)
+ version = version ? version.to_i : self.content.version
+ c = content.versions.find_by_version(version)
+ c ? WikiAnnotate.new(c) : nil
+ end
+
def self.pretty_title(str)
(str && str.is_a?(String)) ? str.tr('_', ' ') : str
end
@@ -113,3 +120,41 @@ class WikiDiff
@diff = words_from.diff @words
end
end
+
+class WikiAnnotate
+ attr_reader :lines, :content
+
+ def initialize(content)
+ @content = content
+ current = content
+ current_lines = current.text.split(/\r?\n/)
+ @lines = current_lines.collect {|t| [nil, nil, t]}
+ positions = []
+ current_lines.size.times {|i| positions << i}
+ while (current.previous)
+ d = current.previous.text.split(/\r?\n/).diff(current.text.split(/\r?\n/)).diffs.flatten
+ d.each_slice(3) do |s|
+ sign, line = s[0], s[1]
+ if sign == '+' && positions[line] && positions[line] != -1
+ if @lines[positions[line]][0].nil?
+ @lines[positions[line]][0] = current.version
+ @lines[positions[line]][1] = current.author
+ end
+ end
+ end
+ d.each_slice(3) do |s|
+ sign, line = s[0], s[1]
+ if sign == '-'
+ positions.insert(line, -1)
+ else
+ positions[line] = nil
+ end
+ end
+ positions.compact!
+ # Stop if every line is annotated
+ break unless @lines.detect { |line| line[0].nil? }
+ current = current.previous
+ end
+ @lines.each { |line| line[0] ||= current.version }
+ end
+end