Class: Tabula::Line
Overview
Represents a line of text (a row of text chunks). Used for grouping text elements that share the same vertical position.
Constant Summary
Constants inherited from Rectangle
Rectangle::VERTICAL_COMPARISON_THRESHOLD
Instance Attribute Summary collapse
-
#chunks ⇒ Object
readonly
Returns the value of attribute chunks.
Attributes inherited from Rectangle
Instance Method Summary collapse
-
#add_chunk(chunk) ⇒ Object
Add a text chunk to this line.
-
#average_char_width ⇒ Float
Average character width in this line.
- #empty? ⇒ Boolean
-
#gap_positions(min_gap: nil) ⇒ Array<Float>
Find gap positions between chunks.
-
#in_gap?(x, min_gap: nil) ⇒ Boolean
Check if a position falls within a gap between chunks.
-
#initialize ⇒ Line
constructor
A new instance of Line.
- #inspect ⇒ Object
-
#ltr_dominant? ⇒ Boolean
Check if this line is LTR dominant.
-
#rtl_dominant? ⇒ Boolean
Check if this line is RTL dominant.
- #size ⇒ Object
-
#sorted_chunks ⇒ Array<TextChunk>
Get chunks sorted by horizontal position Respects RTL text direction when most chunks are RTL.
-
#text(separator: ' ') ⇒ String
Get the combined text of all chunks.
-
#text_elements ⇒ Array<TextElement>
Get text elements from all chunks.
- #to_s ⇒ Object
Methods inherited from Rectangle
#<=>, #==, #area, #bottom, #bottom=, bounding_box_of, #bounds, #center, #contains?, #contains_point?, #dup, from_bounds, from_points, #hash, #horizontal_overlap, #horizontally_overlaps?, #intersection, #intersects?, #merge, #merge!, #overlap_ratio, #points, #right, #right=, #vertical_overlap, #vertically_overlaps?, #x, #x=, #y, #y=
Constructor Details
#initialize ⇒ Line
Returns a new instance of Line.
9 10 11 12 13 |
# File 'lib/tabula/text/line.rb', line 9 def initialize super(0, 0, 0, 0) @chunks = [] @initialized = false end |
Instance Attribute Details
#chunks ⇒ Object (readonly)
Returns the value of attribute chunks.
7 8 9 |
# File 'lib/tabula/text/line.rb', line 7 def chunks @chunks end |
Instance Method Details
#add_chunk(chunk) ⇒ Object
Add a text chunk to this line
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/tabula/text/line.rb', line 17 def add_chunk(chunk) @chunks << chunk if @initialized merge!(chunk) else @top = chunk.top @left = chunk.left @width = chunk.width @height = chunk.height @initialized = true end self end |
#average_char_width ⇒ Float
Average character width in this line
71 72 73 74 75 76 77 |
# File 'lib/tabula/text/line.rb', line 71 def average_char_width elements = text_elements return 0.0 if elements.empty? total_width = elements.sum(&:width) total_width / elements.size end |
#empty? ⇒ Boolean
117 118 119 |
# File 'lib/tabula/text/line.rb', line 117 def empty? @chunks.empty? end |
#gap_positions(min_gap: nil) ⇒ Array<Float>
Find gap positions between chunks
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/tabula/text/line.rb', line 101 def gap_positions(min_gap: nil) min_gap ||= average_char_width * 2 gaps = [] sorted = sorted_chunks sorted.each_cons(2) do |left_chunk, right_chunk| gap_start = left_chunk.right gap_end = right_chunk.left gap_size = gap_end - gap_start gaps << ((gap_start + gap_end) / 2.0) if gap_size >= min_gap end gaps end |
#in_gap?(x, min_gap: nil) ⇒ Boolean
Check if a position falls within a gap between chunks
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/tabula/text/line.rb', line 83 def in_gap?(x, min_gap: nil) min_gap ||= average_char_width * 0.5 sorted = sorted_chunks sorted.each_cons(2) do |left_chunk, right_chunk| gap_start = left_chunk.right gap_end = right_chunk.left gap_size = gap_end - gap_start return true if x.between?(gap_start, gap_end) && gap_size >= min_gap end false end |
#inspect ⇒ Object
129 130 131 |
# File 'lib/tabula/text/line.rb', line 129 def inspect to_s end |
#ltr_dominant? ⇒ Boolean
Check if this line is LTR dominant
43 44 45 46 47 48 49 |
# File 'lib/tabula/text/line.rb', line 43 def ltr_dominant? return true if @chunks.empty? ltr_count = @chunks.count(&:ltr_dominant?) rtl_count = @chunks.count(&:rtl_dominant?) ltr_count >= rtl_count end |
#rtl_dominant? ⇒ Boolean
Check if this line is RTL dominant
52 53 54 |
# File 'lib/tabula/text/line.rb', line 52 def rtl_dominant? !ltr_dominant? end |
#size ⇒ Object
121 122 123 |
# File 'lib/tabula/text/line.rb', line 121 def size @chunks.size end |
#sorted_chunks ⇒ Array<TextChunk>
Get chunks sorted by horizontal position Respects RTL text direction when most chunks are RTL
34 35 36 37 38 39 40 |
# File 'lib/tabula/text/line.rb', line 34 def sorted_chunks if rtl_dominant? @chunks.sort_by(&:left).reverse else @chunks.sort_by(&:left) end end |
#text(separator: ' ') ⇒ String
Get the combined text of all chunks
59 60 61 |
# File 'lib/tabula/text/line.rb', line 59 def text(separator: ' ') sorted_chunks.map(&:text).join(separator) end |
#text_elements ⇒ Array<TextElement>
Get text elements from all chunks
65 66 67 |
# File 'lib/tabula/text/line.rb', line 65 def text_elements @chunks.flat_map(&:elements) end |
#to_s ⇒ Object
125 126 127 |
# File 'lib/tabula/text/line.rb', line 125 def to_s "Line[#{text.inspect}](#{left}, #{top}, #{width}, #{height})" end |