Skip to content

Commit 20a864c

Browse files
jnarebgitster
authored andcommitted
gitweb: Refactor diff body line classification
Simplify classification of diff line body in format_diff_line(), replacing two long if-elsif chains (one for ordinary diff and one for combined diff of a merge commit) with a single regexp match. Refactor this code into diff_line_class() function. While at it: * Fix an artifact in that $diff_class included leading space to be able to compose classes like this "class=\"diff$diff_class\"', even when $diff_class was an empty string. This made code unnecessary ugly: $diff_class is now just class name or an empty string. * Introduce "ctx" class for context lines ($diff_class was set to "" in this case before this commit). Idea and initial code by Junio C Hamano, polish and testing by Jakub Narebski. Inspired by patch adding side-by-side diff by Kato Kazuyoshi, which required $diff_class to be name of class without extra space. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent be3fa91 commit 20a864c

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

gitweb/gitweb.perl

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,40 +2225,47 @@ sub format_diff_cc_simplified {
22252225
return $result;
22262226
}
22272227

2228+
sub diff_line_class {
2229+
my ($line, $from, $to) = @_;
2230+
2231+
# ordinary diff
2232+
my $num_sign = 1;
2233+
# combined diff
2234+
if ($from && $to && ref($from->{'href'}) eq "ARRAY") {
2235+
$num_sign = scalar @{$from->{'href'}};
2236+
}
2237+
2238+
my @diff_line_classifier = (
2239+
{ regexp => qr/^\@\@{$num_sign} /, class => "chunk_header"},
2240+
{ regexp => qr/^\\/, class => "incomplete" },
2241+
{ regexp => qr/^ {$num_sign}/, class => "ctx" },
2242+
# classifier for context must come before classifier add/rem,
2243+
# or we would have to use more complicated regexp, for example
2244+
# qr/(?= {0,$m}\+)[+ ]{$num_sign}/, where $m = $num_sign - 1;
2245+
{ regexp => qr/^[+ ]{$num_sign}/, class => "add" },
2246+
{ regexp => qr/^[- ]{$num_sign}/, class => "rem" },
2247+
);
2248+
for my $clsfy (@diff_line_classifier) {
2249+
return $clsfy->{'class'}
2250+
if ($line =~ $clsfy->{'regexp'});
2251+
}
2252+
2253+
# fallback
2254+
return "";
2255+
}
2256+
22282257
# format patch (diff) line (not to be used for diff headers)
22292258
sub format_diff_line {
22302259
my $line = shift;
22312260
my ($from, $to) = @_;
2232-
my $diff_class = "";
22332261

2234-
chomp $line;
2262+
my $diff_class = diff_line_class($line, $from, $to);
2263+
my $diff_classes = "diff";
2264+
$diff_classes .= " $diff_class" if ($diff_class);
22352265

2236-
if ($from && $to && ref($from->{'href'}) eq "ARRAY") {
2237-
# combined diff
2238-
my $prefix = substr($line, 0, scalar @{$from->{'href'}});
2239-
if ($line =~ m/^\@{3}/) {
2240-
$diff_class = " chunk_header";
2241-
} elsif ($line =~ m/^\\/) {
2242-
$diff_class = " incomplete";
2243-
} elsif ($prefix =~ tr/+/+/) {
2244-
$diff_class = " add";
2245-
} elsif ($prefix =~ tr/-/-/) {
2246-
$diff_class = " rem";
2247-
}
2248-
} else {
2249-
# assume ordinary diff
2250-
my $char = substr($line, 0, 1);
2251-
if ($char eq '+') {
2252-
$diff_class = " add";
2253-
} elsif ($char eq '-') {
2254-
$diff_class = " rem";
2255-
} elsif ($char eq '@') {
2256-
$diff_class = " chunk_header";
2257-
} elsif ($char eq "\\") {
2258-
$diff_class = " incomplete";
2259-
}
2260-
}
2266+
chomp $line;
22612267
$line = untabify($line);
2268+
22622269
if ($from && $to && $line =~ m/^\@{2} /) {
22632270
my ($from_text, $from_start, $from_lines, $to_text, $to_start, $to_lines, $section) =
22642271
$line =~ m/^\@{2} (-(\d+)(?:,(\d+))?) (\+(\d+)(?:,(\d+))?) \@{2}(.*)$/;
@@ -2276,7 +2283,7 @@ sub format_diff_line {
22762283
}
22772284
$line = "<span class=\"chunk_info\">@@ $from_text $to_text @@</span>" .
22782285
"<span class=\"section\">" . esc_html($section, -nbsp=>1) . "</span>";
2279-
return "<div class=\"diff$diff_class\">$line</div>\n";
2286+
return "<div class=\"$diff_classes\">$line</div>\n";
22802287
} elsif ($from && $to && $line =~ m/^\@{3}/) {
22812288
my ($prefix, $ranges, $section) = $line =~ m/^(\@+) (.*?) \@+(.*)$/;
22822289
my (@from_text, @from_start, @from_nlines, $to_text, $to_start, $to_nlines);
@@ -2309,9 +2316,9 @@ sub format_diff_line {
23092316
}
23102317
$line .= " $prefix</span>" .
23112318
"<span class=\"section\">" . esc_html($section, -nbsp=>1) . "</span>";
2312-
return "<div class=\"diff$diff_class\">$line</div>\n";
2319+
return "<div class=\"$diff_classes\">$line</div>\n";
23132320
}
2314-
return "<div class=\"diff$diff_class\">" . esc_html($line, -nbsp=>1) . "</div>\n";
2321+
return "<div class=\"$diff_classes\">" . esc_html($line, -nbsp=>1) . "</div>\n";
23152322
}
23162323

23172324
# Generates undef or something like "_snapshot_" or "snapshot (_tbz2_ _zip_)",

0 commit comments

Comments
 (0)