mirror of https://github.com/dyne/webnomad.git
368 lines
8.3 KiB
Bash
Executable File
368 lines
8.3 KiB
Bash
Executable File
#!/usr/bin/env zsh
|
||
#
|
||
# WebNomad, your slick and static website publisher
|
||
#
|
||
# Copyright (C) 2012-2013 Denis Roio <jaromil@dyne.org>
|
||
#
|
||
# This source code is free software; you can redistribute it and/or
|
||
# modify it under the terms of the GNU Public License as published by
|
||
# the Free Software Foundation; either version 3 of the License, or
|
||
# (at your option) any later version.
|
||
#
|
||
# This source code is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
# Please refer to the GNU Public License for more details.
|
||
#
|
||
# You should have received a copy of the GNU Public License along with
|
||
# this source code; if not, write to:
|
||
# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
|
||
SYS=`dirname $0`
|
||
source $SYS/utils
|
||
|
||
|
||
|
||
{ test -r config.zsh } || {
|
||
error "Directory not configured for WebNomad. First use /webnomad/init"
|
||
exit 1 }
|
||
|
||
|
||
####################################
|
||
|
||
source config.zsh
|
||
|
||
notice "Rendering $B $BRAND $r website"
|
||
act "Title: $B $TITLE $r"
|
||
|
||
typeset -a includejs
|
||
|
||
|
||
render_header() {
|
||
cat <<EOF
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>$TITLE</title>
|
||
<meta name="description" content="$DESCRIPTION" />
|
||
<meta name="keywords" content="$KEYWORDS" />
|
||
<meta charset="utf-8" />
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
<meta name="Generator" content="WebNomad $VERSION - http://dyne.org/software/webnomad" />
|
||
<meta name="MSSmartTagsPreventParsing" content="True" />
|
||
|
||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements
|
||
http://html5shim.googlecode.com/svn/trunk/html5.js -->
|
||
<!--[if lt IE 9]>
|
||
<script src="js/html5.js"></script>
|
||
<![endif]-->
|
||
|
||
<!-- Bootstrap -->
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<link href="css/bootstrap.min.css" rel="stylesheet" />
|
||
<link href="css/bootstrap-responsive.min.css" rel="stylesheet" />
|
||
|
||
EOF
|
||
{ test -r views/css/custom.css } && {
|
||
cat <<EOF
|
||
<link href="css/custom.css" rel="stylesheet" />
|
||
|
||
EOF
|
||
}
|
||
|
||
{ test "$1" = "" } || { echo "${@}"; echo }
|
||
|
||
cat tmpl/header.html
|
||
|
||
}
|
||
|
||
render_footer() {
|
||
cat tmpl/footer.html
|
||
|
||
cat <<EOF
|
||
</div><!--/.container-->
|
||
EOF
|
||
|
||
{ test "$1" = "" } || { echo "${@}"; echo }
|
||
|
||
for i in $includejs; do
|
||
echo "<script src=\"$i\"></script>"
|
||
done
|
||
|
||
cat <<EOF
|
||
</body>
|
||
</html>
|
||
EOF
|
||
}
|
||
|
||
render_html() {
|
||
|
||
|
||
#######################################
|
||
## we support the <markdown> tag inline
|
||
|
||
tmp="tmp.$RANDOM"
|
||
awk 'BEGIN { srand(); markdown=0; }
|
||
/^<markdown>/ { markdown=1; out="tmp.md" rand(); print out; next }
|
||
/^<\/markdown>/ { markdown=0; next }
|
||
{ if(markdown==1) { print $0 >out; next } else { print $0 } }
|
||
' > $tmp
|
||
|
||
# first pass marks the markdown parts and saves them separate
|
||
|
||
mds=(`find . -name 'tmp.md*'`)
|
||
{ test "${#mds}" = "0" } || {
|
||
# second pass substituted saved parts with rendered markdown
|
||
act -n "${#mds} markdown fields "
|
||
|
||
|
||
|
||
# check which markdown parser is available in PATH
|
||
command -v markdown > /dev/null
|
||
if [ "$?" = "0" ]; then parser=markdown
|
||
else command -v multimarkdown > /dev/null
|
||
if [ "$?" = "0"]; then parser=multimarkdown; fi
|
||
fi
|
||
|
||
for i in $mds; do
|
||
md=`basename $i`
|
||
newtemp="tmp.$RANDOM"
|
||
cat $tmp | awk '
|
||
/^'"$md"'/ { system("cat '"$md"' | '"$parser"'"); next }
|
||
{ print $0; }' > $newtemp
|
||
rm $tmp; tmp=$newtemp
|
||
done
|
||
}
|
||
|
||
cat $tmp
|
||
|
||
# clean up from temporary files
|
||
rm -f tmp.*
|
||
|
||
|
||
}
|
||
|
||
render_gallery() {
|
||
|
||
render_header
|
||
|
||
# close <head> with gallery specific styles
|
||
cat <<EOF >> $dst
|
||
<link rel="stylesheet" href="css/blueimp-gallery.min.css" />
|
||
|
||
</head> <!-- end of <head> -->
|
||
|
||
<body>
|
||
<div class="container">
|
||
EOF
|
||
|
||
# don't forget the navbar
|
||
cat tmpl/navbar.html
|
||
|
||
cat <<EOF
|
||
<!-- The Gallery as lightbox dialog, should be a child element of the document body -->
|
||
<div id="blueimp-gallery" class="blueimp-gallery">
|
||
<div class="slides"></div>
|
||
<h3 class="title"></h3>
|
||
<a class="prev">‹</a>
|
||
<a class="next">›</a>
|
||
<a class="close">×</a>
|
||
<a class="play-pause"></a>
|
||
<ol class="indicator"></ol>
|
||
</div>
|
||
|
||
EOF
|
||
|
||
# put a notice for non-javascript browsers
|
||
cat <<EOF
|
||
<noscript>
|
||
<p> </p>
|
||
<div class="alert">
|
||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||
<strong>Javascript missing</strong>.
|
||
You either have JavaScript turned off or your browser doesn't support JavaScript.
|
||
This website mostly consists of image galleries and needs JavaScript.
|
||
</div>
|
||
</noscript>
|
||
EOF
|
||
|
||
# if a file was specified as argument, include it
|
||
{ test -r "$1" } && { cat "$1" | render_html }
|
||
|
||
# generate the gallery's javascript
|
||
dst_js="js/temp-${RANDOM}-gallery.js"
|
||
|
||
cat <<EOF > pub/${dst_js}
|
||
var slides= [];
|
||
EOF
|
||
|
||
# parse gallery entries
|
||
pics=`grep -v '^#'`
|
||
for p in ${(f)pics}; do
|
||
file=${p[(ws: :)1]}
|
||
desc=`echo $p | awk '{ for(c=2;c<=NF;c++) printf("%s ",$c) }'`
|
||
cat << EOF >> pub/$dst_js
|
||
slides.push({
|
||
href: '${file}',
|
||
title: '${desc}'
|
||
});
|
||
EOF
|
||
done
|
||
|
||
cat <<EOF >> pub/$dst_js
|
||
|
||
function shuffle(array) {
|
||
var m = array.length, t, i;
|
||
|
||
// While there remain elements to shuffle…
|
||
while (m) {
|
||
|
||
// Pick a remaining element…
|
||
i = Math.floor(Math.random() * m--);
|
||
|
||
// And swap it with the current element.
|
||
t = array[m];
|
||
array[m] = array[i];
|
||
array[i] = t;
|
||
}
|
||
|
||
return array;
|
||
}
|
||
|
||
slides = shuffle(slides);
|
||
|
||
blueimp.Gallery(slides, {
|
||
container: '#blueimp-gallery',
|
||
carousel: true,
|
||
fullscreen: true,
|
||
closeOnEscape: true,
|
||
closeOnSwipeUpOrDown: true,
|
||
startSlideshow: true,
|
||
slideshowInterval: 4500,
|
||
});
|
||
EOF
|
||
# closeOnSlideClick: true,
|
||
|
||
includejs=(js/jquery.min.js)
|
||
includejs+=(js/bootstrap.min.js)
|
||
includejs+=(js/blueimp-gallery.min.js)
|
||
|
||
|
||
# not really needed
|
||
# includejs+=(js/blueimp-helper.js)
|
||
# includejs+=(js/blueimp-gallery-indicator.js)
|
||
# includejs+=(js/blueimp-gallery-fullscreen.js)
|
||
# includejs+=(js/jquery.blueimp-gallery.min.js)
|
||
|
||
includejs+=($dst_js)
|
||
|
||
render_footer
|
||
|
||
}
|
||
|
||
read_meta() {
|
||
tmp=`head -n 3 | awk '
|
||
!/^#/ { next }
|
||
/title/ { printf "title=\""; for(i=3;i<=NF;i++) printf "%s ", $i; printf "\";" }
|
||
/description/ { printf "description=\""; for(i=3;i<=NF;i++) printf "%s ", $i; printf "\";" }
|
||
/keywords/ { printf "keywords=\""; for(i=3;i<=NF;i++) printf "%s ", $i; printf "\";" }
|
||
'`
|
||
eval "$tmp"
|
||
}
|
||
|
||
|
||
{ test "$1" = "source" } && { return 0 }
|
||
|
||
|
||
# Main
|
||
|
||
mkdir -p pub
|
||
cat << EOF > pub/.htaccess
|
||
DirectoryIndex index index.html index.php
|
||
DefaultType text/html
|
||
EOF
|
||
|
||
act -n "Clean up all temp files ... "
|
||
temps=(`find pub -type f -name 'temp-*'`)
|
||
for t in $temps; do rm -f $t; done
|
||
print "done"
|
||
|
||
|
||
# render all HTML views
|
||
htmls=(`find views -type f -name '*.html'`)
|
||
for src in $htmls; do
|
||
|
||
# read meta commands
|
||
cat ${src} | read_meta
|
||
|
||
# compute destination file
|
||
dst="pub/`basename ${src%.*}`"
|
||
|
||
render_header > $dst
|
||
|
||
# close <head> as nothing else is needed
|
||
cat <<EOF >> $dst
|
||
</head> <!-- end of <head> -->
|
||
|
||
<body>
|
||
<div class="container">
|
||
EOF
|
||
|
||
# don't forget the navbar
|
||
cat tmpl/navbar.html >> $dst
|
||
|
||
cat <<EOF >> $dst
|
||
<p> </p>
|
||
<article>
|
||
EOF
|
||
|
||
# render html
|
||
act -n "Html rendering: $B $dst $r"
|
||
cat $src | render_html >> $dst
|
||
|
||
cat <<EOF >> $dst
|
||
</article>
|
||
<p> </p>
|
||
<p> </p>
|
||
|
||
EOF
|
||
|
||
includejs=(js/bootstrap.min.js)
|
||
render_footer >> $dst
|
||
|
||
act "done"
|
||
|
||
done
|
||
|
||
# render all image galleries
|
||
gals=(`find views -type f -name '*.gal'`)
|
||
for src in $gals; do
|
||
cat ${src} | read_meta
|
||
dst="pub/`basename ${src%.*}`"
|
||
act -n "Gallery rendering: $B $dst $r ... "
|
||
cat $src | render_gallery > $dst
|
||
print "done"
|
||
done
|
||
|
||
for m in `find views -mindepth 1 -type d `; do
|
||
act -n "publishing $B $m $r ... "
|
||
rsync -r $m pub/
|
||
print "done"
|
||
done
|
||
|
||
# if the whole website is a "slideshow" typology then we start with
|
||
# a full screen slideshow of all uploaded photos, cycling random every time.
|
||
# galleries are supported and can be linked in menu and pages.
|
||
{ test "$WEBSITE" = "slideshow" } && {
|
||
notice "Site is configured as slideshow"
|
||
# generate a list of all images (removing duplicates)
|
||
act "Indexing all images ... "
|
||
find pub -iname '*.jpg' | sed -e 's/^pub\///g' -e 's/^.\/pub\///g' -e "s@'@@g" | sort | uniq \
|
||
| render_gallery views/index.html > pub/index
|
||
}
|
||
|
||
|
||
notice "Website refreshed."
|
||
|
||
{ test "$DIR" = "." } || { sleep 10 }
|