##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Gestion de tiddlywiki ##@cooked nocomments ##@require base uprovide tiddlywiki urequire base function twget_version() { # lire le numéro de version dans le fichier $1 awk '/var[ \t]*version/ { match($0, /major: [0-9]*,/) major = substr($0, RSTART + 7, RLENGTH - 8) match($0, /minor: [0-9]*,/) minor = substr($0, RSTART + 7, RLENGTH - 8) match($0, /revision: [0-9]*,/) revision = substr($0, RSTART + 10, RLENGTH - 11) print major "." minor "." revision exit }' "$1" } function twdump_header() { # lire et afficher le contenu avant-storeArea du tiddlywiki $1 awk ' BEGIN { found = 0 } /
/ { found = 1; } found { print } ' "$1" } function twdump_storeArea() { # lire et afficher le storeArea dans le tiddlywiki $1 awk ' BEGIN { found = 0 } /
/ { found = 0; next } found { print } ' "$1" } function twreplace_storeArea() { # dans le tiddlywiki $1, remplacer le storeArea par le fichier $2 (par défaut, lu sur stdin) ( twdump_header "$1" if [ -z "$2" -o "$2" == "-" ]; then cat else cat "$2" fi twdump_footer "$1" ) >"$1.$$" /bin/mv "$1.$$" "$1" } function twupgrade() { # mettre à jour le tiddlywiki $1 sur la base du tiddlywiki plus récent $2 ( twdump_header "$2" twdump_storeArea "$1" twdump_footer "$2" ) >"$1.$$" /bin/mv "$1.$$" "$1" } TW_AWK_FUNCS=' function twdate_tid2time(tiddate, vs, y, m, d, H, M, time) { if (match(tiddate, /([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/, vs)) { y = vs[1] + 0; m = vs[2] + 0; d = vs[3] + 0 H = vs[4] + 0; M = vs[5] + 0 time = mktime(sprintf("%04i %02i %02i %02i %02i 00", y, m, d, H, M)) time = time + 4 * 60 * 60 # UTC --> GMT+4 return time } } function twdate_twp2time(twpdate, vs, y, m, d, H, M, time) { if (match(twpdate, /([0-9]+)\/([0-9]+)\/([0-9][0-9][0-9][0-9]) ([0-9]+)[:.]([0-9]+)$/, vs)) { y = vs[3] + 0; m = vs[2] + 0; d = vs[1] + 0 H = vs[4] + 0; M = vs[5] + 0 time = mktime(sprintf("%04i %02i %02i %02i %02i 00", y, m, d, H, M)) return time } } function twdate_curtwp(time, r) { if (!time) time = systime() # arrondir à la minute supérieur si nécessaire, pour éviter les problèmes de # mise à jour pour un fichier modifié plusieurs fois dans une même minute. r = time % 60 if (r != 0) time = time + 60 - r return strftime("%d/%m/%Y %H:%M", time) } function twdate_tid2twp(tiddate, vs, y, m, d, H, M, time) { time = twdate_tid2time(tiddate) if (time) return strftime("%d/%m/%Y %H:%M", time); } function twdate_curtid(time) { if (!time) time = systime() time = time - 4 * 60 * 60 # GMT+4 --> UTC return strftime("%Y%m%d%H%M", time) } function twdate_twp2tid(twpdate, vs, y, m, d, H, M, time) { time = twdate_twp2time(twpdate) if (time) { time = time - 4 * 60 * 60 # GMT+4 --> UTC return strftime("%Y%m%d%H%M", time) } } ' function twdate_curtwp() { # obtenir la date courante dans le format "dd/mm/YYYY HH:MM" exprimée dans # l'heure locale # $1 est éventuellement la date exprimée en nombre de secondes depuis # l'epoch, exprimée dans l'heure locale awkrun time="$1" "$TW_AWK_FUNCS"'BEGIN { print twdate_curtwp(time); }' } function twdate_tid2twp() { # Transformer $1, une date de la forme "YYYYmmddHHMM" exprimée dans le # timezone UTC en une chaine "dd/mm/YYYY HH:MM" exprimée dans l'heure locale # Si $1 n'est pas dans le bon format, ne rien afficher awkrun "$TW_AWK_FUNCS"'{ twdate = twdate_tid2twp($0); if (twdate) print twdate; }' <<<"$1" } function twdate_curtid() { # obtenir la date courante dans le format "YYYYmmddHHMM" exprimée dans le # timezone UTC # $1 est éventuellement la date exprimée en nombre de secondes depuis # l'epoch, exprimée dans l'heure locale awkrun time="$1" "$TW_AWK_FUNCS"'BEGIN { print twdate_curtid(time); }' } function twdate_twp2tid() { # Transformer $1, une date de la forme "dd/mm/YYYY HH:MM" exprimée en heure # locale en une chaine "YYYYmmddHHMM" exprimée dans le timezone UTC # Si $1 n'est pas dans le bon format, ne rien afficher awkrun "$TW_AWK_FUNCS"'{ tiddate = twdate_twp2tid($0); if (tiddate) print tiddate; }' <<<"$1" } function twdump_tiddlers() { # dumper les tiddlers du fichier $1 généré avec twdump_storeArea() sous # forme d'une liste d'appel de fonction '__tiddler_data title creator # modifier created modified tags changecount content' # Les arguments de la fonction sont les valeurs brutes du tiddler, qui ont # simplement été corrigées avec unquote_html() awkrun -f "$TW_AWK_FUNCS"' function parse_attrs() { title = "" creator = "" modifier = "" created = "" modified = "" tags = "" changecount = "" if (match($0, /title="([^"]*)"/, vs)) title = unquote_html(vs[1]) if (match($0, /creator="([^"]*)"/, vs)) creator = unquote_html(vs[1]) if (match($0, /modifier="([^"]*)"/, vs)) modifier = unquote_html(vs[1]) if (match($0, /created="([^"]*)"/, vs)) created = unquote_html(vs[1]) if (match($0, /modified="([^"]*)"/, vs)) modified = unquote_html(vs[1]) if (match($0, /tags="([^"]*)"/, vs)) tags = unquote_html(vs[1]) if (match($0, /changecount="([^"]*)"/, vs)) changecount = unquote_html(vs[1]) } function parse_content( found_pre, vs) { content = "" found_pre = 0 # Parser
 et éventuellement 
while (getline > 0) { if (match($0, /
(.*)<\/pre>$/, vs)) {
      content = unquote_html(vs[1])
      break
    } else if (match($0, /
(.*)$/, vs)) {
      found_pre = 1
      content = unquote_html(vs[1])
      break
    }
  }
  # Puis lire jusqu"à 
, le cas échéant if (found_pre) { found_pre = 0 while (getline > 0) { if (match($0, /^(.*)<\/pre>/, vs)) { found_pre = 1 content = content "\n" unquote_html(vs[1]) break } else { content = content "\n" unquote_html($0) } } } } function dump_tiddler() { print "__tiddler_data " quote_value(title) " " quote_value(creator) " " quote_value(modifier) " " quote_value(created) " " quote_value(modified) " " quote_value(tags) " " quote_value(changecount) " " quote_value(content) } BEGIN { parse = 0 } !parse && /
0) { content = content "\n" $0 }} gsub(/^[ \t\n]*/, "", content); gsub(/[ \t\n]*$/, "", content); print "__twpage_data " quote_value(title) " " quote_value(creator) " " quote_value(modifier) " " quote_value(created) " " quote_value(modified) " " quote_value(tags) " " quote_value(changecount) " " quote_value(content) }' <"$1" } function twwrite_tiddler() { # Ecrire sur STDOUT le tiddler correspondant aux paramètres sont spécifiés # sur la ligne de commande. Les arguments sont les valeurs brutes prises de # la twpage, telles qu'elles sont générées par twdump_twpage() awkrun -f title="$1" creator="$2" modifier="$3" created="$4" modified="$5" tags="$6" changecount="$7" content="$8" "$TW_AWK_FUNCS"'BEGIN { title = quote_html(title) creator = quote_html(creator) modifier = quote_html(modifier) created = quote_html(twdate_twp2tid(created)) modified = quote_html(twdate_twp2tid(modified)) tags = quote_html(tags) changecount = quote_html(changecount) content = quote_html(content) print "
" print "
" content "
" print "
" }' } function twcheck_twpage_modified() { # Vérifier si la twpage $1 peut être écrasée par un tiddler dont la date de # modification est $2, de format "YYYYmmddHHMM" exprimée dans le timezone # UTC # C'est le cas si le fichier $1 n'existe pas, ou a une date de modification # antérieure à $2 [ -f "$1" ] || return 0 local twpage="$1" othermodified="$2" ( function __twpage_data() { thismodified="$(twdate_twp2tid "$5")"; } eval "$(twdump_twpage "$twpage")" [ "$thismodified" -le "$othermodified" ] ) } function twcheck_twpage_newtwpage() { # Vérifier si la twpage $1 peut être écrasée par la twpage $2 # C'est le cas si le fichier $1 n'existe pas, ou a une date de modification # antérieure à $2 [ -f "$1" ] || return 0 local twpage="$1" othertwpage="$2" ( function __twpage_data() { thismodified="$(twdate_twp2tid "$5")"; } eval "$(twdump_twpage "$twpage")" function __twpage_data() { othermodified="$(twdate_twp2tid "$5")"; } eval "$(twdump_twpage "$othertwpage")" [ "$thismodified" -le "$othermodified" ] ) } TW_VERBOSE=1 function twwrite_twpage() { # Ecrire dans le répertoire courant le fichier correspondant au tiddler dont # les paramètres sont spécifiés sur la ligne de commande. Les arguments sont # les valeurs brutes prises du tiddler, telles qu'elles sont générées par # twdump_tiddlers() # Retourner 0 si le fichier a été écrasé, 1 s'il n'a pas été écrasé parce # qu'il n'a pas été modifié, 2 s'il n'a pas été écrasé parce qu'il est plus # récent. # Si TW_VERBOSE=1, afficher un message informatif lors de l'export local title="$1" creator="$2" modifier="$3" created="$4" modified="$5" tags="$6" changecount="$7" content="$8" # enlever les caractères problématiques dans le titre pour générer le nom de # fichier local twpage="$title.twp" twpage="${twpage//\//_}" twpage="${twpage//:/_}" local tmppage ac_set_tmpfile tmppage echo "# -*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # Pense-bête: # ''bold'' ==striked== __underline__ //italic// ^^super^^ ~~sub~~ # @@highlight@@ @@color:red;background-color:white; rouge sur noir@@ # ~NotAWikiWord [[force wikiword]] [[friendly name|WikiWord]] # [[external|http://site.com]] ---- {{monospace}} # !h1 !!h2 !!!h3 !!!!h4 !!!!!h5 # * dotlist ** sublist # numlist ## sublist # {{{ |caption|c [img[title|filename]] # pre text |!header|!header|h [img[filename]] # }}} |cell|cell| [img[title|filename][link]] # <<< |>|colspan| [img[filename][link]] # blockquote |rowspan|one| [img[filename]] # >quote1 |left| right| # >>quote2 |>| center | # >>>quote3 ##@creator: $creator ##@created: $(twdate_tid2twp "$created") ##@modifier: $modifier ##@changecount: $changecount ##@tags: $tags ##@title: $title $content" >"$tmppage" local status if [ ! -f "$twpage" ] || testdiff "$tmppage" "$twpage"; then if twcheck_twpage_modified "$twpage" "$modified"; then if [ -n "$TW_VERBOSE" ]; then if [ -f "$twpage" ]; then estepw "$twpage: fichier écrasé, parce qu'il est plus ancien" else estepi "$title: export" fi fi cat "$tmppage" >"$twpage" status=0 else if [ -n "$TW_VERBOSE" ]; then estepw "$twpage: fichier non écrasé car il est plus récent (utiliser -u)" fi status=2 fi else status=1 fi ac_clean "$tmppage" return $status } function export_to_twpages() { # Exporter tous les tiddlers du tiddlywiki $1 dans le répertoire $2 local wikifile="${1:-wiki.html}" wikidir="${2:-.}" local storeArea ac_set_tmpfile storeArea twdump_storeArea "$wikifile" >"$storeArea" function __tiddler_data() { twwrite_twpage "$@"; } local CWD="$(pwd)" cd "$wikidir" eval "$(twdump_tiddlers "$storeArea")" cd "$CWD" ac_clean "$storeArea" } function import_from_twpages() { # Remplacer les tiddlers du tiddlywiki $1 par les twpages du répertoire $2 local wikifile="${1:-wiki.html}" wikidir="${2:-.}" local storeArea ac_set_tmpfile storeArea echo "
" >"$storeArea" function __twpage_data() { twwrite_tiddler "$@" >>"$storeArea" } local -a twpages local twpage array_from_lines twpages "$(list_files "$wikidir" "*.twp" | csort)" for twpage in "${twpages[@]}"; do [ -n "$TW_VERBOSE" ] && estep "$twpage" eval "$(twdump_twpage "$wikidir/$twpage")" done echo "
" >>"$storeArea" twreplace_storeArea "$wikifile" "$storeArea" ac_clean "$storeArea" }