1 # Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are met:
5 # 1. Redistributions of source code must retain the above copyright notice,
6 # this list of conditions and the following disclaimer.
7 # 2. Redistributions in binary form must reproduce the above copyright notice,
8 # this list of conditions and the following disclaimer in the documentation
9 # and/or other materials provided with the distribution.
11 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
12 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
15 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
16 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
17 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
19 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
20 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 # POSSIBILITY OF SUCH DAMAGE.
26 # Methods for embedding location information in objects returned (or
27 # exceptions raised) from parse methods.
28 module LocationTracking
29 attr_reader :source_text
31 # For occasions where a single item must serve as a carrier for array-like
32 # information (that is, its own start, end and source_text, as well as the
33 # "outer" equivalents). This can happen where a single node appears in a
34 # list context surrounded only by skipped content.
35 attr_accessor :outer_start, :outer_end, :outer_source_text
37 def source_text=(string)
38 @source_text = string.to_s.clone
41 # Sets @column_start to col.
42 # Sets @column_start to 0 if passed nil (for ease of use, users of classes
43 # that mix-in this module don't have to worry about special casing nil
45 def column_start=(column_start)
46 @column_start = column_start.to_i
49 # Returns 0 if @column_start is nil (for ease of use, users of classes that
50 # mix-in this module don't have to worry about special casing nil values).
55 # Sets @line_start to line.
56 # Sets @line_start to 0 if passed nil (for ease of use, users of classes
57 # that mix-in this module don't have to worry about special casing nil
59 def line_start=(line_start)
60 @line_start = line_start.to_i
63 # Returns 0 if @line_start is nil (for ease of use, users of classes that
64 # mix-in this module don't have to worry about special casing nil values).
69 # Convenience method for getting both line_start and column_start at once.
71 [self.line_start, self.column_start]
74 # Convenience method for setting both line_start and column_start at once.
76 raise ArgumentError if array.nil?
77 raise ArgumentError if array.length != 2
78 self.line_start = array[0]
79 self.column_start = array[1]
82 def line_end=(line_end)
83 @line_end = line_end.to_i
90 def column_end=(column_end)
91 @column_end = column_end.to_i
98 # Convenience method for getting both line_end and column_end at once.
100 [self.line_end, self.column_end]
103 # Convenience method for setting both line_end and column_end at once.
105 raise ArgumentError if array.nil?
106 raise ArgumentError if array.length != 2
107 self.line_end = array[0]
108 self.column_end = array[1]
111 # Given another object that responds to column_end and line_end, returns
112 # true if the receiver is rightmost or equal.
113 # If the other object is farther to the right returns false.
115 if self.line_end > other.line_end
117 elsif other.line_end > self.line_end
119 elsif self.column_end >= other.column_end
125 end # module LocationTracking