Module: Twitter::HitHighlighter
- Extended by:
- HitHighlighter
- Included in:
- HitHighlighter
- Defined in:
- lib/twitter-text/hit_highlighter.rb
Overview
Module for doing “hit highlighting” on tweets that have been auto-linked already. Useful with the results returned from the Search API.
Constant Summary collapse
- DEFAULT_HIGHLIGHT_TAG =
Default Tag used for hit highlighting
"em"
Instance Method Summary collapse
-
#hit_highlight(text, hits = [], options = {}) ⇒ Object
Add tags around the
hits
provided in thetext
.
Instance Method Details
#hit_highlight(text, hits = [], options = {}) ⇒ Object
Add tags around the hits
provided in the text
. The hits
should be an array of (start, end) index pairs, relative to the original text, before auto-linking (but the text
may already be auto-linked if desired)
The tags can be overridden using the :tag
option. For example:
irb> hit_highlight("test hit here", [[5, 8]], :tag => 'strong')
=> "test <strong>hit</strong> here"
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/twitter-text/hit_highlighter.rb', line 16 def hit_highlight(text, hits = [], = {}) if hits.empty? return text end tag_name = [:tag] || DEFAULT_HIGHLIGHT_TAG = ["<" + tag_name + ">", "</" + tag_name + ">"] chunks = text.split(/[<>]/) result = [] chunk_index, chunk = 0, chunks[0] chunk_chars = chunk.to_s.to_char_a prev_chunks_len = 0 chunk_cursor = 0 start_in_chunk = false for hit, index in hits.flatten.each_with_index do tag = [index % 2] placed = false until chunk.nil? || hit < prev_chunks_len + chunk.length do result << chunk_chars[chunk_cursor..-1] if start_in_chunk && hit == prev_chunks_len + chunk_chars.length result << tag placed = true end # correctly handle highlights that end on the final character. if tag_text = chunks[chunk_index+1] result << "<#{tag_text}>" end prev_chunks_len += chunk_chars.length chunk_cursor = 0 chunk_index += 2 chunk = chunks[chunk_index] chunk_chars = chunk.to_s.to_char_a start_in_chunk = false end if !placed && !chunk.nil? hit_spot = hit - prev_chunks_len result << chunk_chars[chunk_cursor...hit_spot] << tag chunk_cursor = hit_spot if index % 2 == 0 start_in_chunk = true else start_in_chunk = false end placed = true end # ultimate fallback, hits that run off the end get a closing tag if !placed result << tag end end if chunk if chunk_cursor < chunk_chars.length result << chunk_chars[chunk_cursor..-1] end (chunk_index+1).upto(chunks.length-1).each do |i| result << (i.even? ? chunks[i] : "<#{chunks[i]}>") end end result.flatten.join end |