Module: Twitter::TwitterText::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 the text.
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 hit here"
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 85 86 87 88 89 |
# File 'lib/twitter-text/hit_highlighter.rb', line 21 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_codepoint_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_codepoint_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 |