Add a link box
[git/dscho.git] / upload.sh
blob0c27aabe04e702c2f31c0d48faa0ed95710d8ca6
1 #!/bin/sh
3 # This is a simple script that will produce my blog on repo.or.cz
5 # The idea is to have source-<timestamp>.txt files as input, having the
6 # stories, and this script turning them into nice HTML, committing
7 # everything, and then pushing it to my repository.
9 # The blog will then be served using gitweb.
11 # To make it easier on me, if a file "source.txt" exists, it is
12 # automatically renamed using the current timestamp.
14 # TODO: generate an RSS feed, too
15 # TODO: have a configurable maximum number of entries per page, and links
16 # to older pages
18 # make sure we're in the correct working directory
19 cd "$(dirname "$0")"
21 GITWEBURL="$(git config gitweb.url)"
22 test -z "$GITWEBURL" && {
23 echo "Please set gitweb.url in the Git config first!" >&2
24 exit 1
27 URLPREFIX="$(dirname "$GITWEBURL")"/
28 REMOTEREPOSITORY="$(basename "$GITWEBURL")"
29 BRANCH=blog
30 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$BRANCH;f="
31 CSS=blog.css
32 NEW=new
33 OUTPUT=index.html
34 TEST=test.html
35 TITLE="Dscho's blog"
37 LC_ALL=C
38 export LC_ALL
40 move_new_entry_back () {
41 test -f source-$now.txt &&
42 mv source-$now.txt $NEW &&
43 git rm --cached -f source-$now.txt
46 die () {
47 move_new_entry_back
48 echo "$*" >&2
49 exit 1
52 nth () {
53 # add illogical suffix
54 case "$1" in
55 *1?|*[04-9]) echo "$1th";;
56 *1) echo "$1st";;
57 *2) echo "$1nd";;
58 *3) echo "$1rd";;
59 esac
62 make_chinese_hour () {
63 case $1 in
64 23|00) echo Rat;;
65 01|02) echo Buffalo;;
66 03|04) echo Tiger;;
67 05|06) echo Rabbit;;
68 07|08) echo Dragon;;
69 09|10) echo Snake;;
70 11|12) echo Horse;;
71 13|14) echo Goat;;
72 15|16) echo Monkey;;
73 17|18) echo Rooster;;
74 19|20) echo Dog;;
75 21|22) echo Pig;;
76 esac
79 digit_to_roman () {
80 case $1 in
81 1) echo $2;;
82 2) echo $2$2;;
83 3) echo $2$2$2;;
84 4) echo $2$3;;
85 5) echo $3;;
86 6) echo $3$2;;
87 7) echo $3$2$2;;
88 8) echo $3$2$2$2;;
89 9) echo $2$4;;
90 esac
93 make_roman_number () {
94 case $1 in
95 '') ;;
96 ?) digit_to_roman $1 I V X;;
97 ??) echo $(digit_to_roman ${1%?} X L C)$(make_roman_number ${1#?});;
98 ???) echo $(digit_to_roman ${1%??} C D M)$(make_roman_number ${1#?});;
99 ????) echo $(digit_to_roman ${1%???} M)$(make_roman_number ${1#?});;
100 esac
103 make_date () {
104 printf "%s, %s of %s, Anno Domini %s, at the hour of the %s\n" \
105 $(date +%A -d @$1) \
106 $(nth $(date +%e -d @$1)) \
107 $(date +%B -d @$1) \
108 $(make_roman_number $(date +%Y -d @$1)) \
109 $(make_chinese_hour $(date +%H -d @$1))
112 # make an argument for sed, to replace $1..$1 by <$2>..</$2>
113 markup_substitution () {
114 case "$1" in
115 ?) echo "s/$1\\([^$1]*\\)$1/<$2>\\\\1<\/$2>/g";;
117 tmp="[^${1%?}]*"
118 tmp2="\\|${1%?}[^${1#?}]$tmp"
119 tmp3="\\($tmp\\($tmp2\\($tmp2\\($tmp2\\)\\)\\)\\)"
120 echo "s/$1$tmp3$1/<$2>\\\\1<\/$2>/g"
122 esac
125 # transform markup in stdin to HTML
126 markup () {
127 image_pattern="\\[\\[Image:\([^]]*\)"
128 image_pattern2="$image_pattern\(\\|[^\]]*\)\?\]\]"
129 sed -e 's!^$!</p><p>!' \
130 -e 's!IMHO!in my humble opinion!g' \
131 -e 's!BTW!By the way,!g' \
132 -e 's!repo.or.cz!<a href=http://&>&</a>!g' \
133 -e 's!:-)!\&#x263a;!g' \
134 -e "s!$image_pattern2!<center><img src=$URL\1></center>!g" \
135 -e 's!<bash>!<table\
136 border=1 bgcolor=black style="color:#ffffff;">\
137 <tr><td bgcolor=lightblue colspan=3>\
138 \&nbsp;\
139 </td></tr>\
140 <tr><td>\
141 <table cellspacing=5 border=0>\
142 <tr><td>\
143 <pre>!' \
144 -e 's!</bash>! </pre>\
145 </td></tr>\
146 </table>\
147 </td></tr>\
148 </table>!' \
149 -e "$(markup_substitution "''" i)" \
150 -e "$(markup_substitution "_" u)"
153 # make HTML page
154 make_html () {
155 cat << EOF
156 <html>
157 <head>
158 <title>$TITLE</title>
159 <meta http-equiv="Content-Type"
160 content="text/html; charset=UTF-8"/>
161 <link rel="stylesheet" type="text/css" href="$URL$CSS">
162 </head>
163 <body>
164 <div class=content>
165 <h1>$TITLE</h1>
167 indent='\t\t\t'
169 # make toc
170 toc_width=400px
171 toc_style="position:absolute;top:50px;left:810px;width=$toc_width"
173 echo "<div style=\"$toc_style\">"
174 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
175 echo "<tr><th>Table of contents:</th></tr>"
176 echo "<tr><td>"
177 echo '<p><ol>'
178 for file in $(ls -r source-*.txt)
180 basename=${file%.txt}
181 timestamp=${basename#source-}
182 date="$(date +"%d %b %Y" -d @$timestamp)"
183 title="$(sed 1q < $file | markup)"
184 echo "<li><a href=#$timestamp>$date $title</a>"
185 done
186 echo '</ol></p>'
187 echo '</td></tr></table>'
188 test -f links.html && {
189 echo "<br>"
190 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
191 echo "<tr><th>Links:</th></tr>"
192 echo "<tr><td>"
193 cat links.html
194 echo "</td></tr></table>"
196 echo '</div>'
197 } | sed -s "s/^/$indent/"
200 # timestamps will not need padding to sort correctly, for some time...
201 for file in $(ls -r source-*.txt)
203 basename=${file%.txt}
204 timestamp=${basename#source-}
205 echo "<h6>$(make_date $timestamp)</h6>"
206 echo "<a name=$timestamp>"
207 echo "<h2>$(sed 1q < $file | markup)</h2>"
208 echo ""
209 echo "<p>"
210 sed 1d < $file | markup
211 echo "</p>"
212 done |
213 sed -e "s/^./$indent&/" \
214 -e "/<pre>/,/<\/pre>/s/^$indent//"
216 cat << EOF
217 </div>
218 </body>
219 </html>
223 # never, ever have spaces in the file names
224 commit_new_images () {
225 images=
226 for image in $(cat source-* |
227 tr ' ]|' '\n' |
228 sed -n 's/.*\[\[Image://p' |
229 sort |
230 uniq)
232 git add $image || die "Could not git add image $image"
233 images="$images $image"
234 done
236 git update-index --refresh &&
237 git diff-files --quiet -- $images &&
238 git diff --cached --quiet HEAD -- $images ||
239 git commit -s -m "Commit some images on $(make_date $now)" $images
243 # parse command line option
244 case "$1" in
245 *dry*) DRYRUN=1; shift;;
246 *show*) firefox "$(pwd)"/$TEST; exit;;
247 *remote*) firefox $URLPREFIX$URL$OUTPUT; exit;;
248 esac
250 test "$#" = 0 ||
251 die "Usage: $0 [--dry-run]"
253 # make sure we're on the correct branch
254 test refs/heads/$BRANCH = $(git symbolic-ref HEAD) ||
255 die "Not on branch $BRANCH"
257 # make sure there are no uncommitted changes
258 git update-index --refresh &&
259 git diff-files --quiet ||
260 die "Have unstaged changes!"
262 # rename the new blog entry if it exists
263 now=$(date +%s)
264 test ! -f $NEW || {
265 mv -i $NEW source-$now.txt &&
266 git add source-$now.txt
267 } ||
268 die "Could not rename source.txt"
270 # commit the images that are referenced and not yet committed
271 test ! -z "$DRYRUN" ||
272 commit_new_images ||
273 die "Could not commit new images"
275 # to find the images reliably, we have to use the commit name, not the branch
276 # we use the latest commit touching an image file.
277 IMAGEFILES="$(git ls-files |
278 grep -v '\.\(css\|html\|gitignore\|in\|sh\|txt\)$')"
279 REV=$(git rev-list -1 HEAD -- $IMAGEFILES)
280 test -z "$REV" && REV=$BRANCH
281 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$REV;f="
283 # Rewrite the URL in the .css file if we're not running dry
284 if test -z "$DRYRUN"
285 then
286 # rewrite URLs
287 sed -e "s/url(/&$URL/g" < $CSS.in > $CSS &&
288 git add $CSS ||
289 die "Rewriting $CSS failed"
290 else
291 OUTPUT=$TEST
292 CSS=$CSS.in
293 URL=
296 make_html > $OUTPUT || die "Could not write $OUTPUT"
298 test ! -z "$DRYRUN" && {
299 move_new_entry_back
300 exit
303 git add $OUTPUT &&
304 git commit -s -m "Update $(make_date $now)" &&
305 git push origin +$BRANCH