Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: a0632f3aae
Fetching contributors…

Cannot retrieve contributors at this time

executable file 156 lines (141 sloc) 4.045 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
#!/bin/bash

# Generate the bookmarks.html file based on the JavaScript files.

# Escape special HTML chars.
escape_html () {
regex='s/&/\&amp;/g; s/"/\&quot;/g; s/</\&lt;/g; s/>/\&gt;/g;';
if [ $# -eq 0 ]; then
sed "$regex";
else
sed "$regex" <<< "$@";
fi;
}

# URL-encode the given string.
url_encode () {
if [ $# -eq 0 ]; then
perl -MURI::Escape -ne 'print uri_escape($_)';
else
perl -MURI::Escape -ne 'print uri_escape($_)' <<< "$@";
fi;
}

# Loop through *.js in the given directory and recurse for its subdirectories.
process_dir () {
echo "Now processing directory \"$1\"…" 1>&2;

# Start the bookmarks folder.
if [ -f "$1/README" ]; then
title="$(escape_html <<< "$(head -n 1 "$1/README")")";
description="$(escape_html <<< "$(tail -n +3 "$1/README")")";
else
title="$(escape_html "$(basename "$1")")";
description="$(escape_html "${1:2}")";
[ "$title" = "$description" ] && description=;
fi;
if [ "$1" = '.' ]; then
description="$description"$'\n\n'"These bookmarks were exported on $(date +'%a, %Y/%m/%d %T %z').";
fi;
cat <<-EOD
<DT><H3>$title</H3>
<DD><P>$description</P>
<DL><P>
EOD

shopt -s nullglob;
GLOBIGNORE='./jslint*:./.git/';
for file in "$1"/*/ "$1"/*.js; do
# Recurse for directories, and indent the output.
if [ -d "$file" ]; then
[ -L "${file%/}" ] || process_dir "${file%/}" | sed $'s/^\([[:space:]]*\)</\\1\t</';
continue;
fi;

# Use git log to find the timestamps for the initial and last commits.
unset add_date last_modified;
while read timestamp subject; do
[ -z "$last_modified" -a "${subject:0:1}" != '*' ] && last_modified="$timestamp";
add_date="$timestamp";
done < <(git log --follow --pretty='tformat:%at %s' "$file");

# Get the bookmarklet's description, title and keyword.
unset description title keyword;
is_in_docblock=0;
while read -r line; do
if [ "$line" = '/**' ]; then
is_in_docblock=1;
continue;
elif [ "$line" = '*/' ]; then
is_in_docblock=0;
elif [[ "$line" =~ ^\(function\ (.+)\( ]]; then
keyword="${BASH_REMATCH[1]}";
break;
fi;
if [[ "$line" =~ ^\*\ @([a-z]*)\ (.*) ]]; then
tag="${BASH_REMATCH[1]}";
content="${BASH_REMATCH[2]}";
case "$tag" in
'title')
title="$content";;
'keyword')
keyword="$content";;
esac;
continue;
fi;
if [ $is_in_docblock -eq 1 ]; then
description+=("${line:2}");
fi;
done < "$file";

# Trim blank lines from the start and end of the description.
if [ "${description[0]}" = '' ]; then
unset description[0];
fi;
for ((i = ${#description[@]} - 1; i >= 0; i--)); do
if [ "${description[$i]}" = '' ]; then
unset description[$i];
fi;
done;
description="$(IFS=$'\n'; echo "${description[*]}")";

# Output the current bookmarklet.
cat <<-EOD
<DT><A HREF="javascript:$(perl -p -e 's/\\$//g; s/[\n\t]//g' "$file" | perl -p -e 's@/\*\*? .*? \*/@@g' | url_encode | sed 's/%25s/%s/g')" ADD_DATE="$(escape_html "$add_date")" LAST_MODIFIED="$(escape_html "$last_modified")" SHORTCUTURL="$(escape_html "$keyword")">$(escape_html "$title")</A>
<DD><P>$(escape_html "$description")</P></DD>
EOD
done;

# End the bookmarks folder.
cat <<-EOD
</DL>
EOD
}

# Export our bookmarks.html.
{
# Output the preamble.
cat <<EOD
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<STYLE>
html {
max-width: 60em;
margin: auto;
font-family: "Calibri", sans-serif;
}
dd > p {
margin-top: 0;
white-space: pre-wrap;
line-height: 1.5;
}
a[shortcuturl]::after {
content: " (keyword: " attr(shortcuturl) ")";
display: inline-block;
margin-left: 1em;
font-family: "Consolas", monospace;
}
</STYLE>
<H1>Bookmarks Menu</H1>

<DL>
EOD

# Recursively process this directory and its subdirectories.
process_dir .;

# Wrap it up for the common good.
cat <<EOD
</DD>
</DL>
EOD
} > bookmarks.html;
Something went wrong with that request. Please try again.