]> gitweb.ps.run Git - flakes/blob - patches/gitweb.patch
add stackoverflow link
[flakes] / patches / gitweb.patch
1 # https://stackoverflow.com/questions/8321649/gitweb-how-to-display-markdown-file-in-html-format-automatically-like-github
2 --- gitweb.cgi.orig     2020-10-06 10:13:45.621810025 +0100
3 +++ gitweb.cgi  2020-10-06 10:08:21.651823286 +0100
4 @@ -18,9 +18,10 @@
5  use Encode;
6  use Fcntl ':mode';
7  use File::Find qw();
8 -use File::Basename qw(basename);
9 +use File::Basename qw(basename dirname);
10  use Time::HiRes qw(gettimeofday tv_interval);
11  use Digest::MD5 qw(md5_hex);
12 +use File::Spec; # hack
13  
14  binmode STDOUT, ':utf8';
15  
16 @@ -6644,6 +6645,20 @@
17                 print "\n</div>\n"; # class="readme"
18         }
19  
20 +       # hack
21 +       if (!$prevent_xss) {
22 +               $file_name = "README.md";
23 +               my $proj_head_hash = git_get_head_hash($project);
24 +               my $readme_blob_hash = git_get_hash_by_path($proj_head_hash, "README.md", "blob");
25
26 +               if ($readme_blob_hash) { # if README.md exists
27 +                       print "<div class=\"header\">$file_name</div>\n";
28 +                       print "<div class=\"readme page_body\">"; # TODO find/create a better CSS class than page_body
29 +                       print get_markdown($file_name, $readme_blob_hash);
30 +                       print "</div>";
31 +               }
32 +       }
33 +
34         # we need to request one more than 16 (0..15) to check if
35         # those 16 are all
36         my @commitlist = $head ? parse_commits($head, 17) : ();
37 @@ -7117,6 +7132,9 @@
38         my $syntax = guess_file_syntax($highlight, $file_name);
39         $fd = run_highlighter($fd, $highlight, $syntax);
40  
41 +       # hack
42 +       my $ismarkdown = ($file_name =~ /md$/);
43 +
44         git_header_html(undef, $expires);
45         my $formats_nav = '';
46         if (defined $hash_base && (my %co = parse_commit($hash_base))) {
47 @@ -7160,6 +7178,10 @@
48                       esc_attr(href(action=>"blob_plain", hash=>$hash,
49                            hash_base=>$hash_base, file_name=>$file_name)) .
50                       qq!" />\n!;
51 +       } elsif ($ismarkdown) {
52 +               print qq!<div class="readme page_body">\n!;
53 +               print get_markdown($file_name, $hash);
54 +               print qq!</div>\n!; #  $cmd_markdownify
55         } else {
56                 my $nr;
57                 while (my $line = <$fd>) {
58 @@ -7177,6 +7199,79 @@
59         git_footer_html();
60  }
61  
62 +# hack
63 +sub get_norm_rel_path { # http://www.perlmonks.org/bare/?node_id=11907
64 +   my $unnormpath = shift;
65 +   while ($unnormpath =~ m!/\.!) {
66 +       $unnormpath =~ s!/[^\/]+/\.\.!!;
67 +       # print "Path is now -+$unnormpath+-\n";
68 +   }
69 +   return $unnormpath;
70 +}
71 +sub get_markdown {
72 +   my $tfilename = shift;
73 +   my $thash = shift;
74 +   my $rethtmlstr = "";
75 +   use open ":encoding(utf8)"; # needed to have utf8 survive through the shell pipe
76 +   my $cmd_markdownify = $GIT . " " . git_cmd() . " cat-file blob " . $thash . " | perl -e 'my \$str = do { local \$/; <STDIN> }; \$str =~ s/<!--.*?--\s*>//gs; print \$str;' | markdown |";
77 +   open (FOO, $cmd_markdownify) or die_error(500, "Open git-cat-file blob '$thash' failed");
78 +   while (<FOO>) {
79 +       if ($_ =~ /(<img[^>]src=")(.*?)"/) {
80 +           my $origcut = "".$2;
81 +           my $testcut = "".$2;
82 +           my $is_anchor = ($testcut =~ /^#/);
83 +           my $is_absolute = ($testcut =~ /^http/);
84 +           my $is_relative_up = ($testcut =~ /^\.\./);
85 +           my $is_local_link = ((!$is_anchor) and (!$is_absolute));
86 +           my $tdir = dirname($tfilename);
87 +           my $is_tdir_proper = (($tdir ne "") and ($tdir ne "."));
88 +           #print "XX: $origcut ($is_anchor, $is_absolute - $is_local_link) ($is_relative_up, $is_tdir_proper, $tdir, $tfilename)\n"; # dbg
89 +           if ($is_local_link) {
90 +               if ($is_relative_up) { # normalize
91 +                   if ($is_tdir_proper) {
92 +                       # cheat with absolute path here:
93 +                       my $resolved = get_norm_rel_path( File::Spec->rel2abs ("$origcut", "/$tdir" ) );
94 +                       $resolved = substr $resolved, 1;
95 +                       #print "YY: $resolved\n";
96 +                       $_ =~ s!(<img[^>]src=")(.*?)"!$1?p=$project;a=blob_plain;f=$resolved"!gi;
97 +                   }
98 +               } else {
99 +                   $_ =~ s!(<img[^>]src=")(.*?)"!$1?p=$project;a=blob_plain;f=$2"!gi;
100 +                   #print "ZZ: $_\n";
101 +               }
102 +           }
103 +       }
104 +       if ($_ =~ /(<a[^>]href=")(.*?)"/) {
105 +           my $origcut = "".$2;
106 +           my $testcut = "".$2;
107 +           my $is_anchor = ($testcut =~ /^#/);
108 +           my $is_absolute = ($testcut =~ /^http/);
109 +           my $is_relative_up = ($testcut =~ /^\.\./);
110 +           my $is_local_link = ((!$is_anchor) and (!$is_absolute));
111 +           my $tdir = dirname($tfilename);
112 +           my $is_tdir_proper = (($tdir ne "") and ($tdir ne "."));
113 +           #print "XX: $origcut ($is_anchor, $is_absolute - $is_local_link) ($is_relative_up, $is_tdir_proper, $tdir, $tfilename)\n"; # dbg
114 +           if ($is_local_link) {
115 +               if ($is_relative_up) { # normalize
116 +                   if ($is_tdir_proper) {
117 +                       # cheat with absolute path here:
118 +                       my $resolved = get_norm_rel_path( File::Spec->rel2abs ("$origcut", "/$tdir" ) );
119 +                       $resolved = substr $resolved, 1;
120 +                       #print "YY: $resolved\n";
121 +                       $_ =~ s!(<a[^>]href=")(.*?)"!$1?p=$project;a=blob;f=$resolved"!gi;
122 +                   }
123 +               } else {
124 +                   $_ =~ s!(<a[^>]href=")(.*?)"!$1?p=$project;a=blob;f=$2"!gi;
125 +                   #print "ZZ: $_\n";
126 +               }
127 +           }
128 +       }
129 +       $rethtmlstr .= $_;
130 +   }
131 +   close(FOO);
132 +   return $rethtmlstr;
133 +}
134 +
135  sub git_tree {
136         if (!defined $hash_base) {
137                 $hash_base = "HEAD";
138