gitweb: Introduce esc_html_match_hl and esc_html_hl_regions
The esc_html_match_hl() subroutine added in this commit will be used to highlight *all* matches of given regexp, using 'match' class. Ultimately it is to be used in all match highlighting, starting with project search, which does not have it yet. It uses the esc_html_hl_regions() subroutine, which is meant to highlight in a given string a list of regions (given as a list of [ beg, end ] pairs of positions in string), using HTML <span> element with given class. It could probably be used in other places that do highlighting of part of ready line, like highlighting of changes in a diff (diff refinement highlighting). Implementation and enhancement notes: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Currently esc_html_hl_regions() subroutine doesn't accept any parameters, like esc_html() does. We might want for example to pass nbsp=>1 to it. It can easily be done with the following code: my %opts = grep { ref($_) ne "ARRAY" } @sel; @sel = grep { ref($_) eq "ARRAY" } @sel; This allow adding parameters after or before regions, e.g.: esc_html_hl_regions("foo bar", "mark", [ 0, 3 ], -nbsp => 1); * esc_html_hl_regions() escapes like esc_html(); if we wanted to highlight with esc_path(), we could pass subroutine reference to now named esc_gen_hl_regions(). esc_html_hl_regions("foo bar", "mark", \&esc_path, [ 0, 3 ]); Note that this way we can handle -nbsp=>1 case automatically, e.g. esc_html_hl_regions("foo bar", "mark", sub { esc_html(@_, -nbsp=>1) }, [ 0, 3 ]); * Alternate solution for highlighting region of a string would be to use the idea that strings are to be HTML-escaped, and references to scalars are HTML (like in the idea for generic committags). This would require modifying gitweb code or esc_html to get list of fragments, e.g.: esc_html(\'<span class="mark">', 'foo', \'</span>', ' bar', { -nbsp => 1 }); or esc_html([\'<span class="mark">', 'foo', \'</span>', ' bar'], -nbsp=>1); esc_html_match_hl() could be then simple wrapper around "match formatter", e.g. esc_html([ render_match_hl($str, $regexp) ], -nbsp=>1); Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
07b257f940
commit
337da8d2b0
@ -1715,6 +1715,47 @@ sub chop_and_escape_str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Highlight selected fragments of string, using given CSS class,
|
||||||
|
# and escape HTML. It is assumed that fragments do not overlap.
|
||||||
|
# Regions are passed as list of pairs (array references).
|
||||||
|
#
|
||||||
|
# Example: esc_html_hl_regions("foobar", "mark", [ 0, 3 ]) returns
|
||||||
|
# '<span class="mark">foo</span>bar'
|
||||||
|
sub esc_html_hl_regions {
|
||||||
|
my ($str, $css_class, @sel) = @_;
|
||||||
|
return esc_html($str) unless @sel;
|
||||||
|
|
||||||
|
my $out = '';
|
||||||
|
my $pos = 0;
|
||||||
|
|
||||||
|
for my $s (@sel) {
|
||||||
|
$out .= esc_html(substr($str, $pos, $s->[0] - $pos))
|
||||||
|
if ($s->[0] - $pos > 0);
|
||||||
|
$out .= $cgi->span({-class => $css_class},
|
||||||
|
esc_html(substr($str, $s->[0], $s->[1] - $s->[0])));
|
||||||
|
|
||||||
|
$pos = $s->[1];
|
||||||
|
}
|
||||||
|
$out .= esc_html(substr($str, $pos))
|
||||||
|
if ($pos < length($str));
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
# highlight match (if any), and escape HTML
|
||||||
|
sub esc_html_match_hl {
|
||||||
|
my ($str, $regexp) = @_;
|
||||||
|
return esc_html($str) unless defined $regexp;
|
||||||
|
|
||||||
|
my @matches;
|
||||||
|
while ($str =~ /$regexp/g) {
|
||||||
|
push @matches, [$-[0], $+[0]];
|
||||||
|
}
|
||||||
|
return esc_html($str) unless @matches;
|
||||||
|
|
||||||
|
return esc_html_hl_regions($str, 'match', @matches);
|
||||||
|
}
|
||||||
|
|
||||||
## ----------------------------------------------------------------------
|
## ----------------------------------------------------------------------
|
||||||
## functions returning short strings
|
## functions returning short strings
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user