Skip to content

Commit

Permalink
Spellchecking on preview for most contents
Browse files Browse the repository at this point in the history
  • Loading branch information
nono committed Apr 3, 2011
1 parent f266d51 commit d047109
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 55 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ gem "devise", "~>1.2"
gem "french_rails", "~>0.2"
gem "friendly_id", "~>3.1"
gem "haml", "~>3.0"
gem "html_spellchecker", "~>0.1"
gem "html_truncator", "~>0.2"
gem "htmlentities", "~>4.2"
gem "jammit", "~>0.5"
Expand Down
10 changes: 9 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ GEM
railties (>= 3.0.0)
faker (0.9.5)
i18n (~> 0.4)
ffi (1.0.7)
rake (>= 0.8.7)
french_rails (0.2.6)
rails (~> 3.0.0)
friendly_id (3.2.1.1)
Expand All @@ -86,9 +88,14 @@ GEM
railties (~> 3.0)
highline (1.6.1)
hiredis (0.3.1)
html_spellchecker (0.1.0)
hunspell-ffi (= 0.1.3.alpha2)
nokogiri (~> 1.4)
html_truncator (0.2.1)
nokogiri (~> 1.4)
htmlentities (4.3.0)
hunspell-ffi (0.1.3.alpha2)
ffi (~> 1.0.7)
i18n (0.5.0)
jammit (0.6.0)
closure-compiler (>= 0.1.0)
Expand Down Expand Up @@ -173,7 +180,7 @@ GEM
thor (0.14.6)
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.25)
tzinfo (0.3.26)
unicorn (3.5.0)
kgio (~> 2.3)
rack
Expand Down Expand Up @@ -207,6 +214,7 @@ DEPENDENCIES
haml (~> 3.0)
haml-rails
hiredis (~> 0.3)
html_spellchecker (~> 0.1)
html_truncator (~> 0.2)
htmlentities (~> 4.2)
jammit (~> 0.5)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ LinuxFr.org on a Debian box.
# aptitude install ruby1.9.1-full
# aptitude install mysql-server mysql-client libmysql++-dev
# aptitude install build-essential libxslt1-dev libxml2-dev
# aptitude install imagemagick
# aptitude install imagemagick hunspell hunspell-fr

2) Install some gems:

Expand Down
7 changes: 7 additions & 0 deletions app/helpers/content_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module ContentHelper

def spellcheck(html)
HTML_Spellchecker.french.spellcheck(html).html_safe
end

end
6 changes: 0 additions & 6 deletions app/helpers/node_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ def tags_for(node)
end
end

def editable_field(record, field)
value = record.send(field)
obj = ActionController::RecordIdentifier.singular_class_name(record)
content_tag(:span, value, :class => 'rest_in_place', :"data-attribute" => field, :"data-object" => obj)
end

def link_to_content(content)
link_to content.title, path_for_content(content)
end
Expand Down
6 changes: 6 additions & 0 deletions app/stylesheets/RonRonnement.scss
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,12 @@ ul.poll {
}
}

.misspelled {
color: inherit;
background-color: inherit;
border-bottom: 1px dashed red;
}

.anchor {
color: #aaa;
&:hover {
Expand Down
2 changes: 1 addition & 1 deletion app/views/comments/_preview.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
%figure.image
= avatar_url(current_user)
.content
= preview.body
= spellcheck(preview.body)
- if current_user.signature.present? && !current_account.try(:hide_signature?)
%p.signature
= current_user.signature
Expand Down
2 changes: 1 addition & 1 deletion app/views/diaries/_preview.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
- c.title = "Journal : #{preview.title}"
- c.title = "#{link_to "Journal", "/journaux"} #{link_to preview.title, "#"}".html_safe
- c.image = avatar_url(current_user)
- c.body = preview.body
- c.body = spellcheck(preview.body)
4 changes: 2 additions & 2 deletions app/views/news/_preview.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- c.meta = news_posted_by(preview)
- c.image = link_to(image_tag(preview.section.image, :alt => preview.section.title), preview.section)
- c.body = capture do
= preview.body
= spellcheck(preview.body)
%ul
= render preview.links
= preview.second_part
= spellcheck(preview.second_part)
2 changes: 1 addition & 1 deletion app/views/posts/_preview.html.haml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
= article_for preview do |c|
- c.title = "#{link_to("Forum #{preview.forum.title}", preview.forum) if preview.forum} #{link_to preview.title, [preview.forum, preview]}".html_safe
- c.body = preview.body
- c.body = spellcheck(preview.body)
2 changes: 1 addition & 1 deletion app/views/search/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
%div
%h2 Résultats
- @results.each do |result|
= highlight(render(result), @query, :highlighter => '<mark>\1</mark>').html_safe
= highlight(render(result), @query, :highlighter => '<mark class="highlight">\1</mark>').html_safe
- paginate @results
2 changes: 1 addition & 1 deletion app/views/trackers/_preview.html.haml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
= article_for preview do |c|
- c.title = "#{link_to "Suivi - #{preview.category_title}", "/suivi"} #{link_to preview.title, preview}".html_safe
- c.body = preview.body
- c.body = spellcheck(preview.body)
2 changes: 1 addition & 1 deletion app/views/wiki_pages/_preview.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= article_for preview do |c|
- c.meta = ""
- c.title = "#{link_to "Wiki", "/wiki"} #{h preview.title}".html_safe
- c.body = preview.body
- c.body = spellcheck(preview.body)
6 changes: 3 additions & 3 deletions config/initializers/require_libs.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "friendly_id/active_record"
require "digest/md5"
require "not"
require "htmldiff"
require "ar_base_ext"
require "not"
require "friendly_id/active_record"
require "babosa_ext"
require "digest/md5"
72 changes: 36 additions & 36 deletions lib/htmldiff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ class Match
def end_in_old
self.start_in_old + self.size
end

def end_in_new
self.start_in_new + self.size
end
end

Operation = Struct.new(:action, :start_in_old, :end_in_old, :start_in_new, :end_in_new)

class DiffBuilder
Expand Down Expand Up @@ -42,17 +42,17 @@ def index_new_words
def operations
position_in_old = position_in_new = 0
operations = []

matches = matching_blocks
# an empty match at the end forces the loop below to handle the unmatched tails
# I'm sure it can be done more gracefully, but not at 23:52
matches << Match.new(@old_words.length, @new_words.length, 0)

matches.each_with_index do |match, i|
match_starts_at_current_position_in_old = (position_in_old == match.start_in_old)
match_starts_at_current_position_in_new = (position_in_new == match.start_in_new)
action_upto_match_positions =

action_upto_match_positions =
case [match_starts_at_current_position_in_old, match_starts_at_current_position_in_new]
when [false, false]
:replace
Expand All @@ -66,23 +66,23 @@ def operations
end

if action_upto_match_positions != :none
operation_upto_match_positions =
Operation.new(action_upto_match_positions,
position_in_old, match.start_in_old,
operation_upto_match_positions =
Operation.new(action_upto_match_positions,
position_in_old, match.start_in_old,
position_in_new, match.start_in_new)
operations << operation_upto_match_positions
end
if match.size != 0
match_operation = Operation.new(:equal,
match.start_in_old, match.end_in_old,
match_operation = Operation.new(:equal,
match.start_in_old, match.end_in_old,
match.start_in_new, match.end_in_new)
operations << match_operation
end

position_in_old = match.end_in_old
position_in_new = match.end_in_new
end

operations
end

Expand All @@ -97,7 +97,7 @@ def recursively_find_matching_blocks(start_in_old, end_in_old, start_in_new, end
if match
if start_in_old < match.start_in_old and start_in_new < match.start_in_new
recursively_find_matching_blocks(
start_in_old, match.start_in_old, start_in_new, match.start_in_new, matching_blocks)
start_in_old, match.start_in_old, start_in_new, match.start_in_new, matching_blocks)
end
matching_blocks << match
if match.end_in_old < end_in_old and match.end_in_new < end_in_new
Expand All @@ -112,9 +112,9 @@ def find_match(start_in_old, end_in_old, start_in_new, end_in_new)
best_match_in_old = start_in_old
best_match_in_new = start_in_new
best_match_size = 0

match_length_at = Hash.new { |h, index| h[index] = 0 }

start_in_old.upto(end_in_old - 1) do |index_in_old|

new_match_length_at = Hash.new { |h, index| h[index] = 0 }
Expand Down Expand Up @@ -144,8 +144,8 @@ def find_match(start_in_old, end_in_old, start_in_new, end_in_new)
end

def add_matching_words_left(match_in_old, match_in_new, match_size, start_in_old, start_in_new)
while match_in_old > start_in_old and
match_in_new > start_in_new and
while match_in_old > start_in_old and
match_in_new > start_in_new and
@old_words[match_in_old - 1] == @new_words[match_in_new - 1]
match_in_old -= 1
match_in_new -= 1
Expand All @@ -155,14 +155,14 @@ def add_matching_words_left(match_in_old, match_in_new, match_size, start_in_old
end

def add_matching_words_right(match_in_old, match_in_new, match_size, end_in_old, end_in_new)
while match_in_old + match_size < end_in_old and
while match_in_old + match_size < end_in_old and
match_in_new + match_size < end_in_new and
@old_words[match_in_old + match_size] == @new_words[match_in_new + match_size]
match_size += 1
end
[match_in_old, match_in_new, match_size]
end

VALID_METHODS = [:replace, :insert, :delete, :equal]

def perform_operation(operation)
Expand All @@ -174,20 +174,20 @@ def replace(operation)
delete(operation, 'diffmod')
insert(operation, 'diffmod')
end

def insert(operation, tagclass = 'diffins')
insert_tag('ins', tagclass, @new_words[operation.start_in_new...operation.end_in_new])
end

def delete(operation, tagclass = 'diffdel')
insert_tag('del', tagclass, @old_words[operation.start_in_old...operation.end_in_old])
end

def equal(operation)
# no tags to insert, simply copy the matching words from one of the versions
@content += @new_words[operation.start_in_new...operation.end_in_new]
end

def opening_tag?(item)
item =~ %r!^\s*<[^>]+>\s*$!
end
Expand All @@ -202,7 +202,7 @@ def tag?(item)

def extract_consecutive_words(words, &condition)
index_of_first_tag = nil
words.each_with_index do |word, i|
words.each_with_index do |word, i|
if !condition.call(word)
index_of_first_tag = i
break
Expand All @@ -215,15 +215,15 @@ def extract_consecutive_words(words, &condition)
end
end

# This method encloses words within a specified tag (ins or del), and adds this into @content,
# with a twist: if there are words contain tags, it actually creates multiple ins or del,
# This method encloses words within a specified tag (ins or del), and adds this into @content,
# with a twist: if there are words contain tags, it actually creates multiple ins or del,
# so that they don't include any ins or del. This handles cases like
# old: '<p>a</p>'
# new: '<p>ab</p><p>c</b>'
# diff result: '<p>a<ins>b</ins></p><p><ins>c</ins></p>'
# this still doesn't guarantee valid HTML (hint: think about diffing a text containing ins or
# del tags), but handles correctly more cases than the earlier version.
#
#
# P.S.: Spare a thought for people who write HTML browsers. They live in this ... every day.

def insert_tag(tagname, cssclass, words)
Expand All @@ -244,33 +244,33 @@ def wrap_text(text, tagname, cssclass)
def explode(sequence)
sequence.is_a?(String) ? sequence.split(//) : sequence
end

def end_of_tag?(char)
char == '>'
end

def start_of_tag?(char)
char == '<'
end

def whitespace?(char)
char =~ /\s/
end

def convert_html_to_list_of_words(x, use_brackets = false)
mode = :char
current_word = ''
words = []

explode(x).each do |char|
case mode
when :tag
if end_of_tag? char
current_word << (use_brackets ? ']' : '>')
words << current_word
current_word = ''
if whitespace?(char)
mode = :whitespace
if whitespace?(char)
mode = :whitespace
else
mode = :char
end
Expand Down Expand Up @@ -301,7 +301,7 @@ def convert_html_to_list_of_words(x, use_brackets = false)
current_word = char
mode = :char
end
else
else
raise "Unknown mode #{mode.inspect}"
end
end
Expand All @@ -310,7 +310,7 @@ def convert_html_to_list_of_words(x, use_brackets = false)
end

end # of class Diff Builder

def self.diff(a, b)
DiffBuilder.new(a, b).build
end
Expand Down
5 changes: 5 additions & 0 deletions public/stylesheets/RonRonnement.css
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,11 @@ ul.poll li meter::-webkit-meter-horizontal-suboptimal-value,
ul.poll li meter::-webkit-meter-horizontal-even-less-good-value {
background: rgba(76, 87, 95, 0.33); }

.misspelled {
color: inherit;
background-color: inherit;
border-bottom: 1px dashed red; }

.anchor {
color: #aaa; }
.anchor:hover {
Expand Down

0 comments on commit d047109

Please sign in to comment.