git clone https://orangeshoelaces.net/git/git3html.git
Author: Vasilii Kolobkov on 01/13/2019
Committer: Vasilii Kolobkov on 01/13/2019
Have a second take on traversing repository tree
Also:
- update html escaping to work in attribute ctx as well as in text
- provision an isbinary function hailing from libgit2
git3html | 113 ++++++--
1 file changed, 85 insertions(+), 28 deletions(-)
diff --git a/git3html b/git3html
index e580830..de74a3a 100755
--- a/git3html
+++ b/git3html
@@ -16,11 +16,15 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -eu
+ht="$(printf '\t')"
# ........ functions ........
escape() {
- sed 's,&,\&,g; s,<,\<,g; s,>,\>,g'
+ # assume the input is in utf8
+ # \302\240 is U+00A0 or in utf8
+ sed "s,&,\&,g; s,$(printf '\302\240'),\ ,g; \
+ s,\",\",g; s,<,\<,g; s,>,\>,g"
}
parent() {
@@ -31,6 +35,31 @@ parent() {
fi
}
+# snatched from libgit2
+isbinary() {
+ od -A n -N 256 -t u1 | awk -f '
+ {
+ for(i=1; i <= NF; ++i) {
+ c=$i
+ if ((c > 31 && c != 127) || c == 8 || c == 27 || c == 12) {
+ # BS, ESC, FF and anything over US excluding DEL is printable
+ ++printable
+ } else if (c == 0) {
+ null=1
+ exit
+ } else if (c < 9 || c > 13) {
+ # everything else, sans [:space:] is not
+ ++nonprintable
+ }
+ }
+ }
+
+ END {
+ if (null) print "y"
+ else print (printable / 128 < nonprintable) ? "y" : "n"
+ }'
+}
+
g() {
git --git-dir="$repodir" "$@"
}
@@ -48,11 +77,17 @@ defaultname() {
fi | sed 's/\.git$//'
}
-header() {
+header() (
+ title="$1"
+ toroot="$2"
+
cat <<-END
<!doctype html>
<html>
<head>
+ END
+ echo "<title>$(echo "$title" | escape)</title>"
+ cat <<-END
</head>
<body>
<header>
@@ -62,15 +97,15 @@ header() {
<nav>
<ul>
END
- echo "<li><a href=\"${1%/}/readme.html\">Readme</a></li>"
- echo "<li><a href=\"${1%/}/log.html\">Log</a></li>"
- echo "<li><a href=\"${1%/}/files.html\">Files</a></li>"
+ echo "<li><a href=\"${toroot%/}/readme.html\">Readme</a></li>"
+ echo "<li><a href=\"${toroot%/}/log.html\">Log</a></li>"
+ echo "<li><a href=\"${toroot%/}/files.html\">Files</a></li>"
cat <<-END
</ul>
</nav>
</header>
END
-}
+)
footer() {
cat <<-END
@@ -80,7 +115,7 @@ footer() {
}
readme() (
- header '.'
+ header "${projname} readme" '.'
root=$(tmrc)
echo '<pre>'
g ls-tree --name-only "$root" | grep '^README*' | while read -r readme; do
@@ -90,28 +125,50 @@ readme() (
footer
)
+dirent() {
+ printf "<li><pre><code>d--------- <a href=\"%s\">%s</a></code></pre></li>\n" \
+ "$(echo "$2" | escape)" "$(echo "$1" | escape)"
+}
+
+blobent() {
+ printf "<li><pre><code>f--------- <a href=\"%s\">%s</code></pre></a></li>\n" \
+ "$(echo "$2" | escape)" "$(echo "$1" | escape)"
+}
+
files() (
- root="$1"
- outdir="$2"
- rootreldir="$3"
-
- header "$rootreldir"
- g ls-tree "$root" | awk '$2 == "tree"' | while read d; do
- droot="$(echo "$d" | awk '{ print $3 }')"
- dname="$(echo "$d" | awk '{ print $4 }')"
- doutdir="${outdir%/}/$dname"
- if [ ! -d "$doutdir" ]; then
- mkdir "$doutdir"
+ tree="$1"
+ name="$2"
+ outdir="$3"
+ relbaseoutdir="$4" # these two are
+ relparidx="$5" # relative to outdir
+ reppath="$6"
+
+ {
+ header "${reppath}:" "$relbaseoutdir"
+ echo '<ul>'
+ if [ -n "$relparidx" ]; then
+ dirent '..' "$relparidx"
fi
- files "$droot" "$doutdir" "$(parent "$rootreldir")" > "${doutdir%/}/files.html"
- echo "<li><a href=\"$dname/files.html\">$(echo "$dname" | escape)</a></li>"
- done
-
- g ls-tree "$root" | awk '$2 == "blob"' | while read f; do
- fname="$(echo "$f" | awk '{ print $4 }')"
- echo "<li><a href=\"$fname.html\">$(echo "$fname" | escape)</a></li>"
- done
- footer
+ g ls-tree "$tree" | awk '$2 == "tree"' | while read rec; do
+ subtree="$(echo "$rec" | awk '{ print $3 }')"
+ stname="$(echo "$rec" | cut -d "$ht" -f2)"
+ stoutdir="${outdir%/}/${name}"
+ if [ ! -d "$stoutdir" ]; then
+ mkdir "$stoutdir"
+ fi
+
+ files "$subtree" "$stname" "${stoutdir}" "$(parent "${relbaseoutdir}")" \
+ "../${name}.html" "${reppath%/}/${stname}"
+
+ dirent "${stname}" "${name}/${stname}.html"
+ done
+ g ls-tree "$tree" | awk '$2 == "blob"' | while read rec; do
+ bname="$(echo "$rec" | cut -d "$ht" -f2)"
+ blobent "$bname" "${name}/${bname}.html"
+ done
+ echo '</ul>'
+ footer
+ } > "${outdir%/}/${name}.html"
)
# ........ driver ........
@@ -154,4 +211,4 @@ fi
readme > "${htmldir%/}/readme.html"
#log
-files "$(tmrc)" "$htmldir" '.' > "${htmldir%/}/files.html"
+files "$(tmrc)" 'files' "$htmldir" '.' '' '/'