Module: Emendate::SegmentSetEditable

Defined in:
lib/emendate/segment_set_editable.rb

Overview

Methods for manipulating the segments in a SegmentSet

Instance Method Summary collapse

Instance Method Details

#collapse_all_matching_type(type:, dir:, range: nil) ⇒ Object

Finds all segments of the given type and collapses each in the given direction

Parameters:

  • type (Symbol)
  • direction (:forward, :backward)
  • range (Range) (defaults to: nil)

    if given, only the Segments falling in this range will be collapsed



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/emendate/segment_set_editable.rb', line 56

def collapse_all_matching_type(type:, dir:, range: nil)
  when_type(type)
    .reverse_each do |seg|
      next if range && not_in_range?(seg, range)

      if is_first_seg?(seg)
        collapse_first_token if type == :comma
      elsif is_last_seg?(seg)
        collapse_last_token if type == :comma
      else
        collapse_segment(seg, dir)
      end
    end
  self
end

#collapse_enclosing_tokensObject

Collapses first and last tokens inward, keeping the types of the tokens each is collapsed into. Convenience method for collapsing extraneous parentheses, brackets, etc. around whole values.



111
112
113
114
# File 'lib/emendate/segment_set_editable.rb', line 111

def collapse_enclosing_tokens
  collapse_first_token
  collapse_last_token
end

#collapse_first_tokenObject

Derives a single token from the first and second tokens in the result, keeping the second token's type



98
99
100
# File 'lib/emendate/segment_set_editable.rb', line 98

def collapse_first_token
  collapse_token_pair_forward(segments[0], segments[1])
end

#collapse_last_tokenObject

Derives a single token from the last and next-to-last tokens in the result, keeping the next-to-last token's type



104
105
106
# File 'lib/emendate/segment_set_editable.rb', line 104

def collapse_last_token
  collapse_token_pair_backward(segments[-2], segments[-1])
end

#collapse_segment(seg, dir) ⇒ Object

Derive a single segment by collapsing the given segment into an adjacent segment

Parameters:

  • seg ({Segment})

    to collapse

  • dir (:forward, :backward)

    If :forward, the given segment is collapsed into the subsequent segment. The subsequent segment's type is retained in the new segment. If :backward, the given segment is collapsed into the previous segment. The previous segment's type is retained in the new segment.

Raises:



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/emendate/segment_set_editable.rb', line 82

def collapse_segment(seg, dir)
  test = :"#{dir}_collapsible?"
  raise Emendate::ImpossibleCollapseError.new(dir) unless send(test, seg)

  target = target_by_direction(seg, dir)
  sources = case dir
  when :forward then [seg, target]
  when :backward then [target, seg]
  else raise Emendate::Error, "dir must be :forward or :backward"
  end
  new = Emendate::Segment.new(type: target.type, sources: sources)
  replace_segments_with_new(segs: sources, new: new)
end

#collapse_segments_backward(ary) ⇒ Object

Derives a single token from 2 or more tokens, keeping the first token's type

Parameters:

  • ary (Array<Symbol>)


9
10
11
12
13
# File 'lib/emendate/segment_set_editable.rb', line 9

def collapse_segments_backward(ary)
  segs = extract(ary).segments
  derived = Emendate::Segment.new(type: segs.first.type, sources: segs)
  replace_segments_with_new(segs: segs, new: derived)
end

#collapse_segments_forward(ary) ⇒ Object

Derives a single token from 2 or more tokens, keeping the final token's type

Parameters:

  • ary (Array<Symbol>)


18
19
20
21
22
# File 'lib/emendate/segment_set_editable.rb', line 18

def collapse_segments_forward(ary)
  segs = extract(ary).segments
  derived = Emendate::Segment.new(type: segs.last.type, sources: segs)
  replace_segments_with_new(segs: segs, new: derived)
end

#collapse_token_pair(s1, s2, direction) ⇒ Object

Parameters:

  • s1 (Segment)

    first of pair

  • s2 (Segment)

    second of pair

  • direction (:forward, :backward)


39
40
41
42
43
44
45
46
47
48
# File 'lib/emendate/segment_set_editable.rb', line 39

def collapse_token_pair(s1, s2, direction)
  case direction
  when :forward
    collapse_token_pair_forward(s1, s2)
  when :backward
    collapse_token_pair_backward(s1, s2)
  else
    raise Emendate::Error, "Direction must be :forward or :backward"
  end
end

#collapse_token_pair_backward(s1, s2) ⇒ Object

derives a single token from two tokens, keeping the first token's type



25
26
27
28
# File 'lib/emendate/segment_set_editable.rb', line 25

def collapse_token_pair_backward(s1, s2)
  new = Emendate::Segment.new(type: s1.type, sources: [s1, s2])
  replace_segments_with_new(segs: [s1, s2], new: new)
end

#collapse_token_pair_forward(s1, s2) ⇒ Object

derives a single token from two tokens, keeping the second token's type



31
32
33
34
# File 'lib/emendate/segment_set_editable.rb', line 31

def collapse_token_pair_forward(s1, s2)
  new = Emendate::Segment.new(type: s2.type, sources: [s1, s2])
  replace_segments_with_new(segs: [s1, s2], new: new)
end

#insert_dummy_after_segment(seg, dummytype) ⇒ Object

Parameters:

  • seg (Emendate::Segment)
  • dummytype (Symbol)


182
183
184
185
# File 'lib/emendate/segment_set_editable.rb', line 182

def insert_dummy_after_segment(seg, dummytype)
  newsegment = Emendate::Segment.new(type: dummytype)
  insert_segment_after_segment(seg, newsegment)
end

#insert_segment_after_segment(seg, newseg) ⇒ Object

Parameters:

  • seg (Emendate::Segment)
  • newseg (Emendate::Segment)


170
171
172
# File 'lib/emendate/segment_set_editable.rb', line 170

def insert_segment_after_segment(seg, newseg)
  insert(ins_pt(seg), newseg)
end

#insert_segment_before_segment(seg, newseg) ⇒ Object

Parameters:

  • seg (Emendate::Segment)
  • newseg (Emendate::Segment)


176
177
178
# File 'lib/emendate/segment_set_editable.rb', line 176

def insert_segment_before_segment(seg, newseg)
  insert(ins_pt(seg, :prev), newseg)
end

#replace_segments_with_new(segs:, new:) ⇒ Object

Parameters:

  • segs (Array<Emendate::Segment>)

    to replace

  • new (Emendate::Segment)

    replacement



135
136
137
138
# File 'lib/emendate/segment_set_editable.rb', line 135

def replace_segments_with_new(segs:, new:)
  insert(ins_pt(segs[-1]), new)
  segs.each { |segment| delete(segment) }
end

#replace_segments_with_new_segment_set(segs:, new:) ⇒ Object

Parameters:

  • segs (Array<Emendate::Segment>)

    to replace

  • new (Emendate::SegmentSet)

    replacement



142
143
144
145
146
# File 'lib/emendate/segment_set_editable.rb', line 142

def replace_segments_with_new_segment_set(segs:, new:)
  insert(ins_pt(segs[-1]), *new.segments)
  segs.each { |segment| delete(segment) }
  new.warnings.each { |warn| add_warning(warn) }
end

#replace_segs_with_new_type(segs:, type:) ⇒ Object

Parameters:

  • segs (Array<Emendate::Segment>)
  • date_part_type (Symbol)


127
128
129
130
131
# File 'lib/emendate/segment_set_editable.rb', line 127

def replace_segs_with_new_type(segs:, type:)
  new = Emendate::Segment.new(type: type, sources: segs)
  insert(ins_pt(segs[0]), new)
  segs.each { |x| delete(x) }
end

#replace_segtypes_with_new_type(old:, new:) ⇒ Object

Parameters:

  • old (Array<Symbol>)

    of segments to replace

  • new (Symbol)

    for new derived replacement



118
119
120
121
122
123
# File 'lib/emendate/segment_set_editable.rb', line 118

def replace_segtypes_with_new_type(old:, new:)
  segs = extract(old)
  newsegment = Emendate::Segment.new(type: new, sources: segs)
  insert(ins_pt(segs[0]), newsegment)
  segs.each { |segment| delete(segment) }
end

#replace_x_with_date_part_type(x:, date_part_type:) ⇒ Object

Parameters:

  • x (Emendate::Segment)
  • date_part_type (Symbol)


164
165
166
# File 'lib/emendate/segment_set_editable.rb', line 164

def replace_x_with_date_part_type(x:, date_part_type:)
  replace_segs_with_new_type(segs: [x], type: date_part_type)
end

#replace_x_with_derived_new_type(x:, type:) ⇒ Object

Parameters:

  • x (Segment)

    to replace

  • type (Symbol)

    type of the new segment



150
151
152
153
# File 'lib/emendate/segment_set_editable.rb', line 150

def replace_x_with_derived_new_type(x:, type:)
  newsegment = Emendate::Segment.new(type: type, sources: [x])
  replace_x_with_new(x: x, new: newsegment)
end

#replace_x_with_new(x:, new:) ⇒ Object

Parameters:

  • x (Segment)
  • new (Segment)


157
158
159
160
# File 'lib/emendate/segment_set_editable.rb', line 157

def replace_x_with_new(x:, new:)
  insert(ins_pt(x), new)
  delete(x)
end