#! /bin/sh
#
# GenWeb.sh -Edouard.Thiel@lif.univ-mrs.fr - 07/12/2010
#
# Decoration de pages web statiques et insertion/modification de menus,
# en XHTML 1.0 avec CSS 2.1 et statistiques via Google analytics.
#
# This program is free software under the terms of the 
# GNU General Public License (GPL) version 3.


#------------------------------------------------------------------------------
# Configuration du script

# Ce fichier contient la description des menus, voir "mode d'emploi".
FichMenus="./menus.gweb"

# Mettre ici votre fichier favicon, ou ""
FavIcon="http://pageperso.lif.univ-mrs.fr/~edouard.thiel/favicon.ico"

# Mettre ici votre fichier de style css, ou ""
StyleCSS="styleET.css"

# Mettre ici votre propre numero pour Google analytics, ou ""
GoogleUA="UA-9220198-1"

# Pour faire apparaitre "Page in XHTML 1.0 strict and CSS 2.1" en bas
# de la page ; mettre "true" ou "false"
Validator="true"

# Parametres pour la recopie sur un serveur distant
rep_src="$HOME/public_html"
rep_dest="public_html"
user_dest="Edouard.Thiel@saphir2.lidil.univ-mrs.fr"


#------------------------------------------------------------------------------
# MODE D'EMPLOI :
#
# 1) Ecrire des pages web sans menus, par exemple le fichier "un.html" :
#
#    <html>
#    <head><title>Titre Un</title></head>
#    <body>
#      <h1>Bonjour</h1>
#      <p>Ceci est du texte</p>
#    </body>
#    </html>
#
# 2) Ecrire le menu general dans un fichier "menus.gweb" :
#
#    <MENU>
#     <TITRE> TITRE="Navigation" 
#     <ITEM> URL="un.html" NAME="Fichier Un" 
#     <ITEM> URL="http://www.linuxfr.org" NAME="LinuxFR"
#    </MENU>
#
# 3) De'corer tous les fichiers mentionne's par une URL relative dans le fichier
#    "menus.gweb" (les URL absolues ne sont pas traite'es) :
#
#    ./GenWeb.sh --genall
#
# On peut voir le resultat avec un editeur de texte ou un browser.
# Le fichier de style (ici styleET.css) doit etre dans le repertoire racine.
# Par la suite,
#  - si on modifie le body de un.html, il n'y a pas besoin de rappeler GenWeb.sh
#  - si on modifie menus.gweb, refaire le point 3)
#
# Comment ca marche ? Le script insere la balise speciale :
#   <!-- gweb-content --> ... <!-- /gweb-content -->
# autour du corps du texte. Si cette balise n'est pas trouvee, c'est une version 
# sans decoration. Le script cherche donc le titre dans le head et le corps entre
# les balises speciales, ou a defaut entre les balises du body, puis reecrit
# tout : l'entete, le menu, le corps puis le footer.
#
# On peut utiliser, et c'est meme conseille', le fichier de style styleET.css ;
# s'inspirer de mes pages existantes comme exemple.
# Pour tester la validite' du fichier genere', cliquer en bas a droite sur
# le lien "xhtml".
#
# Pour decorer une page sans qu'elle apparaisse dans un menu, mettre 
# <ITEM-NODIST> dans menus.gweb. 
#
# Pour voir les options du script, taper : ./GenWeb.sh --help


#------------------------------------------------------------------------------
# Commandes utiles
#------------------------------------------------------------------------------

# Copie le fichier
#
# Usage : CopieFi source dest

CopieFi () {
    if ! cp -f "$1" "$2" ; then
        echo "Erreur, copie impossible de $1 dans $2" 1>&2
        exit 1
    fi
}


# Supprime le fichier
#
# Usage : SupprFi fich

SupprFi () {
    if ! rm -f "$1" ; then
        echo "Erreur, suppression impossible de $2" 1>&2
        exit 1
    fi
}


# De'truit et recre'e le fichier
#
# Usage : Recree fich

ReCree () {
    if [ -f "$1" ]; then
        rm -f "$1"
    fi
    echo "MAJ de $1 ..."
    touch "$1"
}


# Re'ussi si le fichier existe
#
# Usage : TestFi fich

TestFi () {
    if [ ! -f "$1" ]; then
        echo "Erreur, fichier $1 absent"
        exit 1
    fi
}


# Re'ussi si le fichier a l'extension
#
# TestExt fich.ext fich ext

TestExt () {
    if [ "$1" != "$2.$3" -a "./$1" != "$2.$3" ]; then
        echo "Erreur, extension .$3 attendue" 1>&2
        exit 1
    fi
}


# Re'ussi si le nombre d'arguments est suffisant
#
# Usage : TestArgc $# n

TestArgc () {
    if [ "$1" -lt "$2" ]; then
        echo "Erreur, nombre d'arguments insuffisant" 1>&2
        exit 1
    fi
}


# Calcul du chemin inverse
#
# Usage : RevPath path

# ATTENTION :
# - ne marche pas en cas de .. ; il faudrait enlever un ..

RevPath () {
    echo "$1" | 
    tr '/' '\n' | 
    while read a ; do
        if [ "$a" != "." ]; then
            echo -n "../"
        fi
    done
}


#------------------------------------------------------------------------------
# Reque^tes sur un fichier .html
#------------------------------------------------------------------------------

# Affiche le texte du champ LABEL1 ... LABEL2 dans fich.html
#
# Usage : EchoLab LABEL1 LABEL2 fich.html

EchoLab () {
    gawk -v IGNORECASE=1 -v LINT=0 \
        "/$1/,/$2/{ 
            a=\$0 
            sub(\".*$1\",\"\",a)
            sub(\"$2.*\",\"\",a)
            print a 
        }" "$3" 2> /dev/null
}

# version avec gensub: commande spe'cifique a` gawk
#     awk -v IGNORECASE=1 -v LINT=1 \
#         "/$1/,/$2/{ \
#             a=\$0 ; \
#             if (match(a,\"$1\")) \
#                 a=gensub(\".*$1\",\"\",1,a) ; \
#             if (match(a,\"$2\")) \
#                 a=gensub(\"$2.*\",\"\",1,a) ; \
#             print a \
#         }" "$3"


EchoTitre () {
    EchoLab "<title>" "<\/title>" "$1"
}

EchoContent () {
    if grep -q "gweb-content" "$1" ; then
        EchoLab "<!-- gweb-content -->" "<!-- \/gweb-content -->" "$1"
    else
        EchoLab "<body[^>]*>" "<\/body>" "$1"
    fi
}


#------------------------------------------------------------------------------
# Ge'ne'ration d'une page html
#
# Usage : GenPage fich.html path
#------------------------------------------------------------------------------

GenPage () {

FichC="$1.bak"

CopieFi "$1" "$FichC"
ReCree "$1"

cat >> "$1" << FINCAT
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>`EchoTitre "$FichC"`</title>
FINCAT

if [ -n "$FavIcon" ]; then
cat >> "$1" << FINCAT
  <link rel="icon" href="$FavIcon" type="image/x-icon" />
FINCAT
fi

cat >> "$1" << FINCAT
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
FINCAT

if [ -n "$StyleCSS" ]; then
cat >> "$1" << FINCAT
  <link rel="stylesheet" type="text/css" href="`RevPath $2`$StyleCSS" />
FINCAT
fi

cat >> "$1" << FINCAT
</head>
<body>

<div id="box-menu1">
`GenMenu "$1" "$2"`
</div> <!-- box-menu1 -->

<div id="box-main">
<!-- gweb-content -->`EchoContent "$FichC"`

<!-- /gweb-content -->
</div> <!-- box-main -->

<div id="box-footer">
FINCAT

if [ "$Validator" = "true" ]; then
cat >> "$1" << FINCAT
  Page in
  <a href="http://validator.w3.org/check?uri=referer">XHTML 1.0 strict</a> and
  <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS 2.1</a> &nbsp;-&nbsp;
FINCAT
fi

cat >> "$1" << FINCAT
  generated `LANG=C date "+%d %b %Y"` by 
  <a href="http://pageperso.lif.univ-mrs.fr/~edouard.thiel/GenWeb.sh">GenWeb.sh</a>
</div> <!-- box-footer -->

FINCAT

if [ -n "$GoogleUA" ]; then
cat >> "$1" << FINCAT
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("$GoogleUA");
pageTracker._trackPageview();
} catch(err) {}</script>

FINCAT
fi

cat >> "$1" << FINCAT
</body>
</html>
FINCAT

}


#------------------------------------------------------------------------------
# Ge'ne'ration des menu
#
# Usage : GenMenu fich.html path
#------------------------------------------------------------------------------

GenMenu () {

    F="$1"
    P="$2"
    R=`RevPath "$P"`

    cat $FichMenus |
    while read A B ; do
    
        if [ "$A" = "<MENU>" ]; then
            echo "  <dl class=\"sub-menu1\">" 
        fi
        
        if [ "$A" = "<TITRE>" ]; then
            eval $B
            echo "    <dt>$TITRE</dt>" 
        fi
        
        if [ "$A" = "<ITEM>" ]; then
            eval $B
            
            if [ `echo "$URL" | cut -c 1-1` = '/' -o \
                `echo "$URL" | cut -c 1-7` = 'http://' ]; then
                # Chemin absolu ou http://
                echo "    <dd><a href=\"$URL\">$NAME</a></dd>" 
            else
                # Chemin inverse
                echo "    <dd><a href=\"$R$URL\">$NAME</a></dd>" 
            fi
        fi
            
        if [ "$A" = "</MENU>" ]; then
            echo "  </dl>" 
            echo "" 
        fi

    done
}


#------------------------------------------------------------------------------
# Usage : AffiUsage
#------------------------------------------------------------------------------

AffiUsage () {

    echo "USAGE: $0 <commandes>"
    echo "    --help                 affiche cette aide"
    echo "    --clean                supprime tous les fichiers.html.bak"
    echo "    --revert               remplace les .html par les .html.bak"
    echo "    --gen fich.html        regenere fich.html"
    echo "    --genall               regenere tous les fichiers de menus.gweb"
    echo "    --majall               met a jour le site distant"
}


#------------------------------------------------------------------------------
#                       D E B U T   D U   S C R I P T
#------------------------------------------------------------------------------


if ! gawk --version 1> /dev/null 2>&1 ; then 
    echo "ERREUR: gawk n'est pas installe'" 1>&2
    exit 1
fi

if [ $# -lt 1 ]; then
    AffiUsage 1>&2
    exit 1 
fi

# De'codage de la ligne de commande

while [ "$1x" != "x" ]; do
    case "$1" in
    '--help')
        AffiUsage 1>&2
        exit 1
        ;;

    '--clean')
        for i in *.html.bak */*.html.bak */*/*.html.bak ; do
            rm -f "$i"
        done
        shift 1
        ;;

    '--revert')
        for i in *.html */*.html */*/*.html ; do
            if [ -f "$i.bak" ]; then
                mv -f "$i.bak" "$i"
           fi
        done
        shift 1
        ;;

    '--gen')
        TestArgc $# 2
        F=`basename "$2" .html`
        P=`dirname "$2"`
        TestExt "$2" "$P/$F" "html"
        TestFi "$2"
        GenPage "$2" "$P"
        shift 2
        ;;

    '--genall')
        cat $FichMenus |
        while read A B ; do
            if [ "$A" = "<ITEM>" -o "$A" = "ITEM-NODISP" ]; then
                eval $B
                if [ `echo "$URL" | cut -c 1-1` = '/' -o \
                     `echo "$URL" | cut -c 1-7` = 'http://' ]
                then
                    echo "Ignore $URL"
                else
                    F=`basename "$URL" .html`
                    P=`dirname "$URL"`
                    TestExt "$URL" "$P/$F" "html"
                    TestFi "$URL"
                    GenPage "$URL" "$P"
                fi
            fi
        done
        shift 1
        ;;

    '--majall')
        echo
        echo "*** MISE A JOUR DE $user_dest:$rep_dest/ ***"
        echo
        # -i to output a change-summary for all updates
        # -q to suppress non-error messages
        rsync -rLpEi "$rep_src/" "$user_dest:$rep_dest/" 
        shift 1
        ;;

    *)
        echo "Erreur de syntaxe : $1" 1>&2
        echo "Pour avoir de l'aide tapez : $0 --help" 1>&2
        exit 1
        ;;

    esac
done

# Fin succe`s
exit 0


