debian-mirror-gitlab/lib/gitlab/diff/rendered/notebook/diff_file_helper.rb
2022-07-29 14:03:07 +02:00

108 lines
3.7 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Diff
module Rendered
module Notebook
module DiffFileHelper
require 'set'
EMBEDDED_IMAGE_PATTERN = ' ![](data:image'
def strip_diff_frontmatter(diff_content)
diff_content.scan(/.*\n/)[2..]&.join('') if diff_content.present?
end
# line_positions_at_source_diff: given the transformed lines,
# what are the correct values for old_pos and new_pos?
#
# Example:
#
# Original
# from | to
# A | A
# B | D
# C | E
# F | F
#
# Original Diff
# A A
# - B
# - C
# + D
# + E
# F F
#
# Transformed
# from | to
# A | A
# C | D
# B | J
# L | E
# K | K
# F | F
#
# Transformed diff | transf old, new | OG old_pos, new_pos |
# A A | 1, 1 | 1, 1 |
# -C | 2, 2 | 3, 2 |
# -B | 3, 2 | 2, 2 |
# -L | 4, 2 | 0, 0 |
# + D | 5, 2 | 4, 2 |
# + J | 5, 3 | 0, 0 |
# + E | 5, 4 | 4, 3 |
# K K | 5, 5 | 0, 0 |
# F F | 6, 6 | 4, 4 |
def line_positions_at_source_diff(lines, blocks)
last_mapped_old_pos = 0
last_mapped_new_pos = 0
lines.reverse_each.map do |line|
old_pos = source_line_from_block(line.old_pos, blocks[:from])
new_pos = source_line_from_block(line.new_pos, blocks[:to])
old_has_no_mapping = old_pos == 0
new_has_no_mapping = new_pos == 0
next [0, 0] if old_has_no_mapping && (new_has_no_mapping || line.type == 'old')
next [0, 0] if new_has_no_mapping && line.type == 'new'
new_pos = last_mapped_new_pos if new_has_no_mapping && line.type == 'old'
old_pos = last_mapped_old_pos if old_has_no_mapping && line.type == 'new'
last_mapped_old_pos = old_pos
last_mapped_new_pos = new_pos
[old_pos, new_pos]
end.reverse
end
def lines_in_source_diff(source_diff_lines, is_deleted_file, is_added_file)
{
from: is_added_file ? Set[] : source_diff_lines.map {|l| l.old_pos}.to_set,
to: is_deleted_file ? Set[] : source_diff_lines.map {|l| l.new_pos}.to_set
}
end
def source_line_from_block(transformed_line, transformed_blocks)
# Blocks are the lines returned from the library and are a hash with {text:, source_line:}
# Blocks source_line are 0 indexed
return 0 if transformed_blocks.empty?
line_in_source = transformed_blocks[transformed_line - 1][:source_line]
return 0 unless line_in_source.present?
line_in_source + 1
end
def image_as_rich_text(line_text)
return unless line_text[1..].starts_with?(EMBEDDED_IMAGE_PATTERN)
image_body = line_text[1..].delete_prefix(EMBEDDED_IMAGE_PATTERN).delete_suffix(')')
"<img src=\"data:image#{CGI.escapeHTML(image_body)}\">".html_safe
end
end
end
end
end
end