]> Lady’s Gitweb - Gitweb/commitdiff
gitweb: Highlight matched part of shortened project description
authorJakub Narebski <redacted>
Mon, 27 Feb 2012 01:55:22 +0000 (02:55 +0100)
committerLady <redacted>
Mon, 6 Apr 2026 04:51:32 +0000 (00:51 -0400)
Previous commit make gitweb use esc_html_match_hl() to mark match in
the _whole_ description of a project when searching projects.

This commit makes gitweb highlight match in _shortened_ description,
based on match in whole description, using esc_html_match_hl_chopped()
subroutine.

If match is in removed (chopped) part, even partially, then trailing
"... " is highlighted.

Signed-off-by: Jakub Narebski <redacted>
Signed-off-by: Junio C Hamano <redacted>
gitweb.perl

index 56588a722bdf597fbebdde88abd538ef8efb41b61d02f4c545a983832c9f14a7..eac264c266909b25af34b696623410bb4d623aea484edb554d895a5509c1a4fb 100755 (executable)
@@ -1743,20 +1743,61 @@ sub esc_html_hl_regions {
        return $out;
 }
 
        return $out;
 }
 
-# highlight match (if any), and escape HTML
-sub esc_html_match_hl {
+# return positions of beginning and end of each match
+sub matchpos_list {
        my ($str, $regexp) = @_;
        my ($str, $regexp) = @_;
-       return esc_html($str) unless defined $regexp;
+       return unless (defined $str && defined $regexp);
 
        my @matches;
        while ($str =~ /$regexp/g) {
                push @matches, [$-[0], $+[0]];
        }
 
        my @matches;
        while ($str =~ /$regexp/g) {
                push @matches, [$-[0], $+[0]];
        }
+       return @matches;
+}
+
+# highlight match (if any), and escape HTML
+sub esc_html_match_hl {
+       my ($str, $regexp) = @_;
+       return esc_html($str) unless defined $regexp;
+
+       my @matches = matchpos_list($str, $regexp);
        return esc_html($str) unless @matches;
 
        return esc_html_hl_regions($str, 'match', @matches);
 }
 
        return esc_html($str) unless @matches;
 
        return esc_html_hl_regions($str, 'match', @matches);
 }
 
+
+# highlight match (if any) of shortened string, and escape HTML
+sub esc_html_match_hl_chopped {
+       my ($str, $chopped, $regexp) = @_;
+       return esc_html_match_hl($str, $regexp) unless defined $chopped;
+
+       my @matches = matchpos_list($str, $regexp);
+       return esc_html($chopped) unless @matches;
+
+       # filter matches so that we mark chopped string
+       my $tail = "... "; # see chop_str
+       unless ($chopped =~ s/\Q$tail\E$//) {
+               $tail = '';
+       }
+       my $chop_len = length($chopped);
+       my $tail_len = length($tail);
+       my @filtered;
+
+       for my $m (@matches) {
+               if ($m->[0] > $chop_len) {
+                       push @filtered, [ $chop_len, $chop_len + $tail_len ] if ($tail_len > 0);
+                       last;
+               } elsif ($m->[1] > $chop_len) {
+                       push @filtered, [ $m->[0], $chop_len + $tail_len ];
+                       last;
+               }
+               push @filtered, $m;
+       }
+
+       return esc_html_hl_regions($chopped . $tail, 'match', @filtered);
+}
+
 ## ----------------------------------------------------------------------
 ## functions returning short strings
 
 ## ----------------------------------------------------------------------
 ## functions returning short strings
 
@@ -5406,9 +5447,10 @@ sub git_project_list_rows {
                      "</td>\n" .
                      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
                                        -class => "list",
                      "</td>\n" .
                      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
                                        -class => "list",
-                                       $search_regexp ? () : -title => $pr->{'descr_long'}},
+                                       -title => $pr->{'descr_long'}},
                                        $search_regexp
                                        $search_regexp
-                                       ? esc_html_match_hl($pr->{'descr_long'}, $search_regexp)
+                                       ? esc_html_match_hl_chopped($pr->{'descr_long'},
+                                                                   $pr->{'descr'}, $search_regexp)
                                        : esc_html($pr->{'descr'})) .
                      "</td>\n" .
                      "<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
                                        : esc_html($pr->{'descr'})) .
                      "</td>\n" .
                      "<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
This page took 0.297664 seconds and 4 git commands to generate.