def resolve_replace2(prev_item, replace, next_item, junk=[]): items_actual = replace.items_actual i = 0 phrases = [] # For a replace, distinguish between (sub)phrases that could be rearranged # and that couldn't be rearranged. # (simplified) example: Let 'items_actual' = "foo bar baz boo" and say the # phrase "bar baz" could be rearranged and the phrase "boo" could be # rearranged (to another position). # So, compute the phrases ["foo", "bar baz", "boo"]. while i < len(items_actual): item = items_actual[i] if item.run: rearr = Rearr() while i < len(items_actual) and items_actual[i].run and items_actual[i].run == item.run: rearr.append(items_actual[i]) i += 1 phrases.append(rearr) else: repl = Repl() while i < len(items_actual) and not items_actual[i].run: repl.append(items_actual[i]) i += 1 phrases.append(repl) # Setup the diff.Replace and diff.Rearrange objects. result = [] current_rearrange = None current_replace = None last_rearrange = None for i in range(0, len(phrases)): prev_phrase = phrases[i - 1] if i > 0 else None phrase = phrases[i] next_phrase = phrases[i + 1] if i < len(phrases) - 1 else None if isinstance(phrase, Repl): # Process the phrases that couldn't be rearranged: if prev_phrase: # prev_phrase is definitely a rearrange! # Check if the rearrange position of prev phrase is followed by # a junk item. last_target_item = prev_phrase[-1].match next_target_item = last_target_item.next if util.ignore_item(next_target_item, junk): continue elif next_phrase: # next_phrase is definitely a rearrange! # Check if the rearrange position of prev phrase is preceded by # a junk item. first_target_item = next_phrase[0].match prev_target_item = first_target_item.prev if util.ignore_item(prev_target_item, junk): continue # Create new replace (consider remaining target items!). if not current_replace: current_replace = diff.Replace([], [], 0, 0) result.append(current_replace) current_replace.items_actual.extend(phrase) current_rearrange = None elif isinstance(phrase, Rearr): # Rearrange if not current_rearrange: current_rearrange = Rearrange() current_rearrange.items_actual.extend(phrase) # TODO: Which target items? current_rearrange.items_target.extend([x.match for x in phrase]) #current_rearrange.run = item.run result.append(current_rearrange) else: if last_rearrange: xxx = last_rearrange[-1].match while True: if xxx and util.ignore_item(xxx.next, junk): xxx = xxx.next else: break if xxx and xxx == phrase[0].match.prev: # Append current_rearrange.items_actual.extend(phrase) # TODO: Which target items? current_rearrange.items_target.extend([x.match for x in phrase]) else: current_rearrange = Rearrange() current_rearrange.items_actual.extend(phrase) # TODO: Which target items? current_rearrange.items_target.extend([x.match for x in phrase]) #current_rearrange.run = item.run result.append(current_rearrange) last_rearrange = phrase # Don't forget remaining target items. x = [y for y in replace.items_target if not y.match] if x: if not current_replace: current_replace = diff.Replace([], [], 0, 0) result.append(current_replace) current_replace.items_target.extend(replace.items_target) return result
def resolve_replace(prev_item, replace, next_item, junk=[]): """ Resolves the given replace to a sequence of diff.Replace and rearrange.Rearrange objects. """ # __________________________________________________________________________ # Identify the items that couldn't be rearranged and all items that could # be rearranged in any run. The result is a list of all "unrearranged" # items and a list of list of all rearranged items. # # simplified example: # Let items_actual = "foo bar baz boo far faz" and lets say "bar baz" and # "boo far" could be rearranged to (different) positions. We compute: # # unrearranged_items = ["foo", "faz"] and # rearranged_items_lists = [["bar", "baz"], ["boo", "far"]] i = 0 unrearranged_items = [] rearranged_items_lists = [] while i < len(replace.items_actual): item = replace.items_actual[i] if item.run: # The item has a run and thus could be rearranged. Proceed as long # next items belongs to the same run. rearranged_items = [item] while i + 1 < len(replace.items_actual): next_item = replace.items_actual[i + 1] # Abort if next item has no run or belongs to another run. if not next_item.run or next_item.run != item.run: break rearranged_items.append(next_item) i += 1 # Append the rearranged items to result if it is non-empty. if rearranged_items: rearranged_items_lists.append(rearranged_items) else: # The item has no run and thus couldn't be rearranged. Add it to # unrearranged items. unrearranged_items.append(item) i += 1 # __________________________________________________________________________ # Split the (unmatched) target items into sequences of junk and non-junk # items. # # simplified example: # Let items_target = "foo bar JUNK1 baz JUNK2" with junk words "JUNK1" and # "JUNK2". We compute: # # junk_target_items = ["JUNK1", "JUNK2"] and # non_junk_target_items = ["foo", "bar", "baz"] # Obtain all unmatched target items. unmatched_target_items = [x for x in replace.items_target if not x.match] junk_target_items = [] non_junk_target_items = [] for i in range(0, len(unmatched_target_items)): item = unmatched_target_items[i] if util.ignore_item(item, junk): # The item is a junk item. junk_target_items.append(item) else: # The item is not a junk item. non_junk_target_items.append(item) # __________________________________________________________________________ # Setup the sequence of diff.Replace and rearrange.Rearrange objects. result = [] if not junk_target_items: # There are no junk items. So create a single replace object with the # unrearranged_items as actual items and the non_junk_target_items as # the target items. replace = diff.Replace([], [], 0, 0) replace.items_actual.extend(unrearranged_items) replace.items_target.extend(non_junk_target_items) result.append(replace) else: # There is at least one junk item. We will assign each unrearranged # actual item to a junk item. Because the junk items will be ignored # from further process, we can ignore all unrearranged items. for i in range(0, len(junk_target_items)): replace = diff.Replace([], [], 0, 0) replace.items_target.append(junk_target_items[i]) result.append(replace) # Create a single replace object that considers the remaining non junk # target items. if non_junk_target_items: replace = diff.Replace([], [], 0, 0) replace.items_target.extend(non_junk_target_items) result.append(replace) # Iterate through the rearranged lists and setup the rearrange.Rearrange # objects. for i in range(0, len(rearranged_items_lists)): rearrange_items = rearranged_items_lists[i] rearrange = Rearrange() rearrange.items_actual.extend(rearrange_items) # Setup the target items (that are the matched items). rearrange.items_target.extend([x.match for x in rearrange_items]) result.append(rearrange) return result