3 # format-readme -- find and format a repository's readme blob
4 # Copyright (C) 2015 Kyle J. McKay. All rights reserved.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 # Usage: format-readme [-r <prefix> | -p <prefix> [ -i <imgprefix ] ]
22 # <path-to-repo.git> [<treeish>]
24 # With -r <prefix>, prefix all non-absolute URLs with <prefix>
26 # With -p <prefix>, prefix all non-aboslute URLs with <prefix>/<symlink-path>
27 # where <symlink-path> is the dirname portion of symlink if the selected readme
28 # is a symlink that needs to be followed. If it's not a symlink or its in the
29 # same directory, the "/<symlink-path>" is not added but <prefix> still is.
31 # With -i <imgprefix> use <imgprefix> instead of <prefix> when link is to
32 # an image. If -p was used it will include the path, if -r was used it won't.
40 if [ "$1" = "-r" -o "$1" = "-p" ]; then
42 [ "$1" != "-p" ] || addpath
=1
47 if [ "$1" = "-i" ]; then
55 [ -n "$projdir" -a -d "$projdir" ] ||
exit 2
56 cd "$projdir" ||
exit 2
58 gd
="$(git rev-parse --git-dir 2>&1)" ||
exit 2
61 tree
="$(git rev-parse --quiet --verify "$treeish"^{tree} 2>/dev/null)" ||
exit 2
63 # We prefer the first file or symlink we find with
64 # a supported extension and then we will follow it
65 # if it's a relative symlink with no '.' or '..' components.
66 # If we don't find a supported extension, we use just plain README
67 # which we assume to be plain text (and we will follow a symlink).
68 # We prefer a markdown extension over others and any extension
69 # other than plain text next followed by plain text and then no extension.
72 ! perl
-MPod::Html
-e 1 >/dev
/null
2>&1 || haspod
=1
79 while read -r mode
type hash name
; do
80 [ "$mode" = "100644" -o "$mode" = "100755" -o "$mode" = "120000" ] ||
continue
81 [ "$type" = "blob" ] ||
continue
84 readme.md|readme.markdown
)
85 if [ -n "$readmeext" ]; then
86 [ "$readmeextfmt" != "md" -o "$mode" != "120000" ] ||
continue
90 [ "$mode" != "120000" ] || readmeextlnk
=1
95 [ -n "$haspod" ] ||
continue
96 if [ -n "$readmeext" ]; then
97 [ "$readmeextfmt" != "md" ] ||
continue
98 [ "$readmeextfmt" = "txt" -o "$mode" != "120000" ] ||
continue
102 [ "$mode" != "120000" ] || readmeextlnk
=1
106 readme.txt|readme.text
)
107 if [ -n "$readmeext" ]; then
108 [ "$readmeextfmt" = "txt" -a "$mode" != "120000" ] ||
continue
112 [ "$mode" != "120000" ] || readmeextlnk
=1
117 [ -z "$readme" -o "$mode" != "120000" ] ||
continue
120 [ "$mode" != "120000" ] || readmelnk
=1
125 $(git ls-tree $tree | LC_ALL=C tr A-Z a-z)
127 if [ -n "$readme" -a -z "$readmeext" ]; then
129 readmeextlnk
="$readmelnk"
132 [ -n "$readmeext" ] ||
exit 1
133 if [ -n "$readmeextlnk" ]; then
134 rel
="$(git cat-file blob $readmeext 2>/dev/null)" ||
exit 1
135 case "$rel" in /*) exit 1; esac
136 case "/$rel/" in */..
/*|
*/.
/*) exit 1; esac
137 if [ -n "$addpath" ]; then
138 dir
="$(dirname "$rel")"
139 if [ "$dir" != "." ]; then
140 urlprefix
="${urlprefix%/}/$dir"
141 [ -z "$imgprefix" ] || imgprefix
="${imgprefix%/}/$dir"
144 read -r mode
type hash name
<<EOT
145 $(git ls-tree $tree -- "$rel")
147 [ "$mode" = "100644" -o "$mode" = "100755" ] ||
exit 1
148 [ "$type" = "blob" ] ||
exit 1
152 # Get up to the first 32K, but fail if it doesn't look like
155 contents
="$(git cat-file blob $readmeext | LC_ALL=C cut -b 1-32769 | perl -e '
159 binmode STDIN, ":perlio
" or exit 1
160 unless grep /^perlio$/, PerlIO::get_layers(STDIN);
161 exit 1 unless -T STDIN;
163 my $contents = <STDIN>;
164 exit 1 unless defined($contents) && length($contents) > 0 && length($contents)<= 32768;
167 ' 2>/dev/null)" ||
exit 1
170 case "$readmeextfmt" in
173 # Run Markdown.pl on it
175 if [ -n "$addprefix" ]; then
176 cmd
="$cmd -r \"$urlprefix\""
177 [ -z "$imgprefix" ] || cmd
="$cmd -i \"$imgprefix\""
179 printf '%s' "$contents" |
eval "$cmd 2>/dev/null"
184 # Run pod2html and extract the contents
186 if [ -n "$addprefix" -a -n "${urlprefix%/}" ]; then
187 arg
=", \"--htmlroot=${urlprefix%/}\""
189 printf '%s' "$contents" | \
190 perl
-MPod::Html
-e "pod2html \"--quiet\", \"--no-index\"$arg" 2>/dev
/null | \
195 my $contents = <STDIN>;
196 $contents =~ s,^.*<body[^>]*>\s*,,is;
197 $contents =~ s,\s*</body[^>]*>.*$,,is;
198 $contents =~ s,^.*<!--\s*INDEX\s+END\s*-->\s*,,is;
199 $contents =~ s,^\s*(?:<p>\s*</p>\s*)+,,is;
206 # It's a <pre> block but we need some escaping
207 printf '%s' '<pre class="plaintext">'
208 printf '%s' "$contents" | LC_ALL
=C
sed -e 's/&/\&/g' -e 's/</\</g'
209 printf '%s\n' '</pre>'