X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FViewDiff.pm;h=6a60d0dca63450926f9a3c57bd0c1a9aa991509d;hb=a27717d1717b6fdf69e9472e8e9f61b2bbaeb5e7;hp=b7dab81946efe9372fa0a433740d1bd331b206a1;hpb=bbfa42a9ea55b7057c7a6b632f090763c9e7c655;p=public-inbox.git diff --git a/lib/PublicInbox/ViewDiff.pm b/lib/PublicInbox/ViewDiff.pm index b7dab819..6a60d0dc 100644 --- a/lib/PublicInbox/ViewDiff.pm +++ b/lib/PublicInbox/ViewDiff.pm @@ -12,7 +12,7 @@ use warnings; use base qw(Exporter); our @EXPORT_OK = qw(flush_diff); use URI::Escape qw(uri_escape_utf8); -use PublicInbox::Hval qw(ascii_html to_attr from_attr); +use PublicInbox::Hval qw(ascii_html to_attr); use PublicInbox::Git qw(git_unquote); # keep track of state so we can avoid redundant HTML tags for @@ -38,13 +38,10 @@ sub UNSAFE () { "^A-Za-z0-9\-\._~/" } my $OID_NULL = '0{7,40}'; my $OID_BLOB = '[a-f0-9]{7,40}'; -my $PATH_A = '"?a/.+|/dev/null'; -my $PATH_B = '"?b/.+|/dev/null'; +my $PATH_X = '"?[^/]+/.+|/dev/null'; -sub to_html ($$) { - $_[0]->linkify_1($_[1]); - $_[0]->linkify_2(ascii_html($_[1])); -} +# cf. git diff.c :: get_compact_summary +my $DIFFSTAT_COMMENT = qr/\((?:new|gone|(?:(?:new|mode) [\+\-][lx]))\)/; # link to line numbers in blobs sub diff_hunk ($$$$) { @@ -89,7 +86,7 @@ sub anchor0 ($$$$$) { # So only do best-effort handling of renames for common cases; # which works well in practice. If projects put "=>", or trailing # spaces in filenames, oh well :P - $fn =~ s/ +\z//s; + $fn =~ s/(?: *$DIFFSTAT_COMMENT)? *\z//so; $fn =~ s/{(?:.+) => (.+)}/$1/ or $fn =~ s/.* => (.+)/$1/; $fn = git_unquote($fn); @@ -101,9 +98,10 @@ sub anchor0 ($$$$$) { if (my $attr = to_attr($ctx->{-apfx}.$fn)) { $ctx->{-anchors}->{$attr} = 1; + my $spaces = ($orig =~ s/( +)\z//) ? $1 : ''; $$dst .= " " . - ascii_html($orig) . ''. - to_html($linkify, $rest); + ascii_html($orig) . '' . $spaces . + $linkify->to_html($rest); return 1; } undef; @@ -112,7 +110,7 @@ sub anchor0 ($$$$$) { sub anchor1 ($$$$$) { my ($dst, $ctx, $linkify, $pb, $s) = @_; my $attr = to_attr($ctx->{-apfx}.$pb) or return; - my $line = to_html($linkify, $s); + my $line = $linkify->to_html($s); my $ok = delete $ctx->{-anchors}->{$attr}; @@ -154,12 +152,12 @@ sub flush_diff ($$$) { } elsif ($state2class[$state]) { to_state($dst, $state, DSTATE_CTX); } - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } elsif ($s =~ /^-- $/) { # email signature begins $state == DSTATE_INIT or to_state($dst, $state, DSTATE_INIT); $$dst .= $s; - } elsif ($s =~ m!^diff --git ($PATH_A) ($PATH_B)$!o) { + } elsif ($s =~ m!^diff --git ($PATH_X) ($PATH_X)$!o) { my ($pa, $pb) = ($1, $2); if ($state != DSTATE_HEAD) { to_state($dst, $state, DSTATE_HEAD); @@ -174,53 +172,53 @@ sub flush_diff ($$$) { uri_escape_utf8($pa, UNSAFE); } anchor1($dst, $ctx, $linkify, $pb, $s) and next; - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } elsif ($s =~ s/^(index $OID_NULL\.\.)($OID_BLOB)\b//o) { $$dst .= $1 . oid($dctx, $spfx, $2); $dctx = { Q => '' }; - $$dst .= to_html($linkify, $s) ; + $$dst .= $linkify->to_html($s) ; } elsif ($s =~ s/^index ($OID_BLOB)(\.\.$OID_NULL)\b//o) { $$dst .= 'index ' . oid($dctx, $spfx, $1) . $2; $dctx = { Q => '' }; - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } elsif ($s =~ /^index ($OID_BLOB)\.\.($OID_BLOB)/o) { $dctx->{oid_a} = $1; $dctx->{oid_b} = $2; - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } elsif ($s =~ s/^@@ (\S+) (\S+) @@//) { $$dst .= '' if $state2class[$state]; $$dst .= qq(); $$dst .= diff_hunk($dctx, $spfx, $1, $2); $$dst .= ''; $state = DSTATE_CTX; - $$dst .= to_html($linkify, $s); - } elsif ($s =~ m!^--- (?:$PATH_A)!o || - $s =~ m!^\+{3} (?:$PATH_B)!o) { + $$dst .= $linkify->to_html($s); + } elsif ($s =~ m!^--- (?:$PATH_X)!o || + $s =~ m!^\+{3} (?:$PATH_X)!o) { # color only (no oid link) if missing dctx->{oid_*} $state <= DSTATE_STAT and to_state($dst, $state, DSTATE_HEAD); - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } elsif ($s =~ /^\+/) { if ($state != DSTATE_ADD && $state > DSTATE_STAT) { to_state($dst, $state, DSTATE_ADD); } - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } elsif ($s =~ /^-/) { if ($state != DSTATE_DEL && $state > DSTATE_STAT) { to_state($dst, $state, DSTATE_DEL); } - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); # ignore the following lines in headers: } elsif ($s =~ /^(?:dis)similarity index/ || $s =~ /^(?:old|new) mode/ || $s =~ /^(?:deleted|new) file mode/ || $s =~ /^(?:copy|rename) (?:from|to) / || $s =~ /^(?:dis)?similarity index /) { - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } else { $state <= DSTATE_STAT or to_state($dst, $state, DSTATE_INIT); - $$dst .= to_html($linkify, $s); + $$dst .= $linkify->to_html($s); } } @$diff = ();