@@ -85,31 +85,29 @@ def convert(content)
8585 # Applies regexp handling to +text+ and returns an array of [text, converted?] pairs.
8686
8787 def apply_regexp_handling ( text )
88- output = [ ]
89- start = 0
90- loop do
91- pos = text . size
92- matched_name = matched_text = nil
93- @markup . regexp_handlings . each do |pattern , name |
94- m = text . match ( pattern , start )
95- next unless m
88+ matched = [ ]
89+ @markup . regexp_handlings . each_with_index do |( pattern , name ) , priority |
90+ text . scan ( pattern ) do
91+ m = Regexp . last_match
9692 idx = m [ 1 ] ? 1 : 0
97- if m . begin ( idx ) < pos
98- pos = m . begin ( idx )
99- matched_text = m [ idx ]
100- matched_name = name
101- end
102- end
103- output << [ text [ start ...pos ] , false ] if pos > start
104- if matched_name
105- handled = public_send ( :"handle_regexp_#{ matched_name } " , matched_text )
106- output << [ handled , true ]
107- start = pos + matched_text . size
108- else
109- start = pos
93+ matched << [ m . begin ( idx ) , m . end ( idx ) , m [ idx ] , name , priority ]
11094 end
111- break if pos == text . size
11295 end
96+ # If the start positions are the same, prefer the one with higher priority (registered earlier one)
97+ matched . sort_by! { |beg_pos , _ , _ , _ , priority | [ beg_pos , priority ] }
98+
99+ pos = 0
100+ output = [ ]
101+ matched . each do |beg_pos , end_pos , s , name |
102+ next if beg_pos < pos
103+
104+ output << [ text [ pos ...beg_pos ] , false ] if beg_pos != pos
105+ handled = public_send ( :"handle_regexp_#{ name } " , s )
106+ output << [ handled , true ]
107+ pos = end_pos
108+ end
109+
110+ output << [ text [ pos ..] , false ] if pos < text . size
113111 output
114112 end
115113
0 commit comments