282
'forks' => {
283
'override' => 0,
284
'default' => [0]},
285
+
286
+ # Allow gitweb scan project content tags described in ctags/
287
+ # of project repository, and display the popular Web 2.0-ish
288
+ # "tag cloud" near the project list. Note that this is something
289
+ # COMPLETELY different from the normal Git tags.
290
+
291
+ # gitweb by itself can show existing tags, but it does not handle
292
+ # tagging itself; you need an external application for that.
293
+ # For an example script, check Girocco's cgi/tagproj.cgi.
294
+ # You may want to install the HTML::TagCloud Perl module to get
295
+ # a pretty tag cloud instead of just a list of tags.
296
+
297
+ # To enable system wide have in $GITWEB_CONFIG
298
+ # $feature{'ctags'}{'default'} = ['path_to_tag_script'];
299
+ # Project specific override is not supported.
300
+ 'ctags' => {
301
+ 'override' => 0,
302
+ 'default' => [0]},
303
);
304
305
sub gitweb_check_feature {
1780
return $descr;
1781
}
1782
1783
+sub git_get_project_ctags {
1784
+ my $path = shift;
1785
+ my $ctags = {};
1786
+
1787
+ $git_dir = "$projectroot/$path";
1788
+ foreach (<$git_dir/ctags/*>) {
1789
+ open CT, $_ or next;
1790
+ my $val = <CT>;
1791
+ chomp $val;
1792
+ close CT;
1793
+ my $ctag = $_; $ctag =~ s#.*/##;
1794
+ $ctags->{$ctag} = $val;
1795
+ }
1796
+ $ctags;
1797
+}
1798
+
1799
+sub git_populate_project_tagcloud {
1800
+ my $ctags = shift;
1801
+
1802
+ # First, merge different-cased tags; tags vote on casing
1803
+ my %ctags_lc;
1804
+ foreach (keys %$ctags) {
1805
+ $ctags_lc{lc $_}->{count} += $ctags->{$_};
1806
+ if (not $ctags_lc{lc $_}->{topcount}
1807
+ or $ctags_lc{lc $_}->{topcount} < $ctags->{$_}) {
1808
+ $ctags_lc{lc $_}->{topcount} = $ctags->{$_};
1809
+ $ctags_lc{lc $_}->{topname} = $_;
1810
+ }
1811
+ }
1812
+
1813
+ my $cloud;
1814
+ if (eval { require HTML::TagCloud; 1; }) {
1815
+ $cloud = HTML::TagCloud->new;
1816
+ foreach (sort keys %ctags_lc) {
1817
+ # Pad the title with spaces so that the cloud looks
1818
+ # less crammed.
1819
+ my $title = $ctags_lc{$_}->{topname};
1820
+ $title =~ s/ / /g;
1821
+ $title =~ s/^/ /g;
1822
+ $title =~ s/$/ /g;
1823
+ $cloud->add($title, $home_link."?by_tag=".$_, $ctags_lc{$_}->{count});
1824
+ }
1825
+ } else {
1826
+ $cloud = \%ctags_lc;
1827
+ }
1828
+ $cloud;
1829
+}
1830
+
1831
+sub git_show_project_tagcloud {
1832
+ my ($cloud, $count) = @_;
1833
+ print STDERR ref($cloud)."..\n";
1834
+ if (ref $cloud eq 'HTML::TagCloud') {
1835
+ return $cloud->html_and_css($count);
1836
+ } else {
1837
+ my @tags = sort { $cloud->{$a}->{count} <=> $cloud->{$b}->{count} } keys %$cloud;
1838
+ return '<p align="center">' . join (', ', map {
1839
+ "<a href=\"$home_link?by_tag=$_\">$cloud->{$_}->{topname}</a>"
1840
+ } splice(@tags, 0, $count)) . '</p>';
1841
+ }
1842
+}
1843
+
1844
sub git_get_project_url_list {
1845
my $path = shift;
1846
3659
my ($projlist, $check_forks) = @_;
3660
my @projects;
3661
3662
+ my $show_ctags = gitweb_check_feature('ctags');
3663
PROJECT:
3664
foreach my $pr (@$projlist) {
3665
my (@activity) = git_get_last_activity($pr->{'path'});
3686
$pr->{'forks'} = 0;
3687
}
3688
}
3689
+ $show_ctags and $pr->{'ctags'} = git_get_project_ctags($pr->{'path'});
3690
push @projects, $pr;
3691
}
3692
3733
$from = 0 unless defined $from;
3734
$to = $#projects if (!defined $to || $#projects < $to);
3735
3736
+ my $show_ctags = gitweb_check_feature('ctags');
3737
+ if ($show_ctags) {
3738
+ my %ctags;
3739
+ foreach my $p (@projects) {
3740
+ foreach my $ct (keys %{$p->{'ctags'}}) {
3741
+ $ctags{$ct} += $p->{'ctags'}->{$ct};
3742
+ }
3743
+ }
3744
+ my $cloud = git_populate_project_tagcloud(\%ctags);
3745
+ print git_show_project_tagcloud($cloud, 64);
3746
+ }
3747
+
3748
print "<table class=\"project_list\">\n";
3749
unless ($no_header) {
3750
print "<tr>\n";
3763
"</tr>\n";
3764
}
3765
my $alternate = 1;
3766
+ my $tagfilter = $cgi->param('by_tag');
3767
for (my $i = $from; $i <= $to; $i++) {
3768
my $pr = $projects[$i];
3769
+ next if $tagfilter and $show_ctags and not grep { lc $_ eq lc $tagfilter } keys %{$pr->{'ctags'}};
3770
if ($alternate) {
3771
print "<tr class=\"dark\">\n";
3772
} else {
4188
print "<tr class=\"metadata_url\"><td>$url_tag</td><td>$git_url</td></tr>\n";
4189
$url_tag = "";
4190
}
4191
+
4192
+ # Tag cloud
4193
+ my $show_ctags = (gitweb_check_feature('ctags'))[0];
4194
+ if ($show_ctags) {
4195
+ my $ctags = git_get_project_ctags($project);
4196
+ my $cloud = git_populate_project_tagcloud($ctags);
4197
+ print "<tr id=\"metadata_ctags\"><td>Content tags:<br />";
4198
+ print "</td>\n<td>" unless %$ctags;
4199
+ print "<form action=\"$show_ctags\" method=\"post\"><input type=\"hidden\" name=\"p\" value=\"$project\" />Add: <input type=\"text\" name=\"t\" size=\"8\" /></form>";
4200
+ print "</td>\n<td>" if %$ctags;
4201
+ print git_show_project_tagcloud($cloud, 48);
4202
+ print "</td></tr>";
4203
+ }
4204
+
4205
print "</table>\n";
4206
4207
if (-s "$projectroot/$project/README.html") {