From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>, Jakub Narebski <jnareb@gmail.com>
Subject: [PATCHv4 4/4] gitweb: Highlight matched part of shortened project description
Date: Mon, 27 Feb 2012 02:55:22 +0100 [thread overview]
Message-ID: <1330307722-25351-5-git-send-email-jnareb@gmail.com> (raw)
In-Reply-To: <1330307722-25351-1-git-send-email-jnareb@gmail.com>
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 <jnareb@gmail.com>
---
It was marked as RFC, because I am not sure if it is right way to
highlight match in shortened string, or if we better use full string,
or full string if match is in chopped part.
Changes from v3:
* The relation between esc_html_match_hl() and esc_html_match_hl_chopped()
got changed; instead of esc_html_match_hl() being wrapper and
esc_html_match_hl_chopped() doing all the work, common part is
refactored into matchpos_list(), and both esc_html_match_hl* are
kept separate. It results in a bit of code duplication, but
hopefully it also makes code more clear (it is e.g. less nested).
* Brings back -title that was removed in previous commit, to show full
description on mouseover (partial revert of previous commit).
Changes from v2:
* Harden esc_html_match_hl_chopped() against calling with both
$chopped and $regexp undefined (even though it wouldn't happen
with current code).
* esc_html_match_hl_chopped() uses now esc_html_hl_regions(),
like esc_html_match_hl() used to do.
Changes from v1:
* Instead of esc_html_match_hl_chopped() duplicating much od code in
esc_html_match_hl(), make esc_html_match_hl() call the *_chopped()
one with $chopped set to undef.
Now managing highlighting of $chopped part is just a matter of
adjusting and filtering @matches to apply to $chopped rather than
original $str where match was performed.
As a side issue when match span past chop point current code uses
one selection <span class+match">foo... </span> and not two
<span class="match">foo</span><span class="match">... </span>
gitweb/gitweb.perl | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 03a8dd9..1fc5361 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1742,20 +1742,61 @@ sub esc_html_hl_regions {
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) = @_;
- return esc_html($str) unless defined $regexp;
+ return unless (defined $str && defined $regexp);
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);
}
+
+# 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
@@ -5412,9 +5453,10 @@ sub git_project_list_rows {
"</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
- ? 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";
--
1.7.9
prev parent reply other threads:[~2012-02-27 1:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-27 1:55 [PATCHv3 0/4] gitweb: Match highlighting in project search Jakub Narebski
2012-02-27 1:55 ` [PATCHv3 1/4] gitweb: Introduce esc_html_match_hl and esc_html_hl_regions Jakub Narebski
2012-02-27 1:55 ` [PATCHv3 2/4] gitweb: Highlight matched part of project name when searching projects Jakub Narebski
2012-02-27 1:55 ` [PATCHv3 3/4] gitweb: Highlight matched part of project description " Jakub Narebski
2012-02-27 1:55 ` Jakub Narebski [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1330307722-25351-5-git-send-email-jnareb@gmail.com \
--to=jnareb@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).