diff --git a/fconv b/fconv index 82f832b..bf6cfdd 100755 --- a/fconv +++ b/fconv @@ -1,133 +1,214 @@ #!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 - -function display_help() { - uecho "$scriptname: convertir des fichiers dans un autre encoding - -USAGE - $scriptname [-f src_enc] [ -t dest_enc] [/path/to/file] - -OPTIONS - -f from - Encoding source. Si n'est pas spécifié ou vaut 'detect', l'encoding est - autodétecté. - -t to - Encoding destination. Doit être spécifié. - Cas particulier: si to vaut 'lf' ou 'crlf', from est ignoré, et seuls - les caractères de fin de lignes sont convertis. - -N Ne pas optimiser le calcul de l'encoding. Cette option n'est valide que - si -f n'est pas spécifié. On assume que tous les noms de fichiers n'ont - pas le même encoding. L'encoding from est donc recalculé à chaque fois. - -r inverser from et to, qui doivent être tous les deux spécifiés." -} - -if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then - # créer les liens - scriptname="$(basename "$0")" - for destenc in latin1 utf8 lf crlf cr; do - ln -s "$scriptname" "${scriptname}2$destenc" - done - exit 0 -fi - source "$(dirname "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS -from=detect -case "${scriptname#fconv2}" in -utf8) to=utf-8;; -latin1) to=iso-8859-1;; -lf) to=lf;; -crlf) to=crlf;; -cr) to=cr;; -*) to=;; -esac -optimize=1 -parse_opts "${PRETTYOPTS[@]}" \ - --help '$exit_with display_help' \ - -f: from= \ - -t: to= \ - -N optimize= \ - -r reverse \ - @ args -- "$@" && set -- "${args[@]}" || die "$args" +function display_help() { + uecho "$scriptname: convertir le contenu d'un fichier -function dfconv() { - # $1 = répertoire dont les fichiers doivent être convertis - local srcdir="$1" files file - array_lsall files "$srcdir" - for file in "${files[@]}"; do - fconv "$file" - done +USAGE + $scriptname [options] file [cmds...] + +Une ou plusieurs commandes peuvent être spécifiées, séparées // +La command par défaut est 'lf' + +OPTIONS + -N, --detect-always + Pour la commande conv, ne pas optimiser le calcul de l'encoding. Cette + option n'est valide que si src_enc n'est pas spécifié. On assume que + tous les fichiers n'ont pas le même encoding: l'encoding src_enc est + donc recalculé à chaque fois. + -r, --reverse + Inverser src_enc et dest_enc, qui doivent être tous les deux spécifiés. + +COMMANDES + conv dest_enc [src_enc] + Convertir le fichier dans un autre encoding. + dest_enc est l'encoding destination. Il doit être spécifié. + src_enc est l'encoding source. S'il n'est pas spécifié ou vaut 'detect', + il est autodétecté. + utf8 [src_enc] + Equivalent à conv utf8 src_enc + latin1 [src_enc] + Equivalent à conv latin1 src_enc + lf + crlf + cr + Convertir respectivement les caractères de fin de ligne en LF, CR/LF ou CR + noaccents + Transformer caractères accentués en caractères non accentués" +} + +function detect_enc() { + if [ -f "$1" ]; then + "$scriptdir/lib/pywrapper" uencdetect.py -f "$1" + return $? + elif [ -d "$1" ]; then + local -a files + setx -a files=evalp find "$1" -type f // head -n1 + if [ ${#files[*]} -gt 0 ]; then + "$scriptdir/lib/pywrapper" uencdetect.py -f "${files[0]}" + return $? + fi + fi + echo Unknown +} + +function before_parse_cmd() { + case "$1" in + conv) + if [ -n "$OPTIMIZE_CONV" ]; then + local to="$2" + [ -n "$to" ] && setx CONV_TO=__norm_encoding "$to" + + local from="${3:-detect}" + if [ "$from" == "detect" ]; then + setx from=detect_enc "$FILE" + if [ "$from" == "Unknown" ]; then + echo "$FILE: Impossible de détecter l'encoding" + return 1 + fi + fi + [ -n "$from" ] && setx CONV_FROM=__norm_encoding "$from" + OPTIMIZE_CONV= + fi + ;; + noaccents|noa|fixchars) + export LANG=fr_FR.UTF-8 + ;; + esac +} + +function iconv_detect() { + local to="$1"; shift + local from + setx from=detect_enc "$FILE" + if [ "$from" == "Unknown" ]; then + cat + return 1 + else + if [ -n "$REVERSE_CONV" ]; then + local tmp="$to" + to="$from" + from="$tmp" + fi + iconv -f "$from" -t "$to" "$@" + return 0 + fi +} + +function parse_cmd() { + local cmd="$1"; shift + local -a args + case "$cmd" in + utf8) parse_cmd conv utf8 "$@";; + latin1) parse_cmd conv latin1 "$@";; + conv) + local to="$CONV_TO" from="$CONV_FROM" + [ -n "$to" ] || to="$1"; shift + [ -f "$from" ] || from="${1:-detect}"; shift + + if [ -z "$to" ]; then + echo "conv: vous devez spécifier l'encoding destination" + return 1 + fi + setx to=__norm_encoding "$to" + if [ "$from" == "detect" ]; then + qvals iconv_detect "$to" "$@" + else + setx from=__norm_encoding "$from" + if [ "$from" == "$to" ]; then + echo "Une conversion de $from à $to n'a pas de sens. Veuillez re-essayer avec -N si nécessaire." + return 1 + fi + if [ -n "$REVERSE_CONV" ]; then + local tmp="$to" + to="$from" + from="$tmp" + fi + qvals iconv -f "$from" -t "$to" "$@" + fi + ;; + lf) echo _nl2lf;; + crlf) echo _nl2crlf;; + cr) echo _nl2cr;; + noaccents|noa|fixchars) + echo _noaccents;; + *) + echo "$cmd: commande invalide" + return 1 + ;; + esac + return 0 } function ffconv() { - # $1 = fichier à renommer - local lfrom="$from" lto="$to" - local src="$1" + local tmp="$FILE.tmp.$$" + autoclean "$tmp" - if [ "$to" == "lf" ]; then - ebegin "$src" nl2lf "$src" - elif [ "$to" == "crlf" ]; then - ebegin "$src" nl2crlf "$src" - elif [ "$to" == "cr" ]; then - ebegin "$src" nl2cr "$src" - else - if [ "$lfrom" == "detect" ]; then - lfrom="$("$scriptdir/lib/pywrapper" uencdetect.py -f "$src")" - if [ "$lfrom" == "Unknown" ]; then - eerror "$(ppath "$src"): Impossible de déterminer l'encoding" - return 1 - fi - if [ -n "$optimize" ]; then - from="$(__norm_encoding "$lfrom")" - [ "$from" != "$to" ] && enote "Conversion $from --> $to" - fi - fi - if [ -n "$optimize" -a "$from" == "$to" ]; then - die "Une conversion de $from à $to n'a pas de sens. -Veuillez re-essayer avec -N si nécessaire." - fi - - if [ -n "$reverse" ]; then - local tmp="$lto" - lto="$lfrom" - lfrom="$tmp" - fi - - local tmp="$src.tmp.$$" - autoclean "$tmp" - ebegin "$src" - iconv -f "$lfrom" -t "$lto" "$src" >"$tmp" && - (cat "$tmp" >"$src"; edot) && - (rm "$tmp"; edot) - eend + ebegin "$FILE" + if eval "$CMD" <"$FILE" >"$tmp"; then + (cat "$tmp" >"$FILE"; edot $? "replace $FILE") fi + (rm "$tmp"; edot $? "remove temp") + eend } -function fconv() { - if [ -d "$1" ]; then - etitle "$(ppath "$1")" dfconv "$1" - elif [ -f "$1" ]; then - ffconv "$1" - else - eerror "$1: fichier introuvable ou invalide" - fi -} +OPTIMIZE_CONV=1 +REVERSE_CONV= +CONV_FROM= +CONV_TO= +parse_opts + "${PRETTYOPTS[@]}" \ + --help '$exit_with display_help' \ + -N,--detect-always OPTIMIZE_CONV= \ + -r,--reverse REVERSE_CONV=1 \ + @ args -- "$@" && set -- "${args[@]}" || die "$args" -[ -n "$to" ] || die "Il faut spécifier l'encoding de destination" -to="$(__norm_encoding "$to")" - -if [ -n "$*" ]; then - if [ "$to" == "lf" -o "$to" == "crlf" -o "$to" == "cr" ]; then - enote "Conversion [cr]lf --> $to" - fi - for src in "$@"; do - fconv "$src" - done -elif [ "$to" == "lf" ]; then - nl2lf -elif [ "$to" == "crlf" ]; then - nl2crlf -elif [ "$to" == "cr" ]; then - nl2cr +FILE="$1"; shift +[ "$FILE" == - ] && FILE=/dev/stdin +if [ "$FILE" != /dev/stdin ]; then + [ -e "$FILE" ] || die "$FILE: fichier introuvable" +fi + +[ $# -gt 0 ] || set -- lf # commande par défaut + +CMD= # la commande finale à lancer pour convertir le flux +while [ $# -gt 0 ]; do + args=() + while [ $# -gt 0 ]; do + arg="$1"; shift + if [ "$arg" == // ]; then + break + elif [ "${arg%//}" != "$arg" ]; then + local tmp="${arg%//}" + if [ -z "${tmp//\\/}" ]; then + arg="${arg#\\}" + fi + fi + args=("${args[@]}" "$arg") + done + + if [ ${#args[*]} -gt 0 ]; then + before_parse_cmd "${args[@]}" + setx cmd=parse_cmd "${args[@]}" || die "$cmd" + if [ "$FILE" == /dev/stdin ]; then + # pas de suivi pour /dev/stdin + CMD="${CMD:+$CMD | }$cmd" + else + CMD="${CMD:+$CMD | }($cmd; edot \$? $cmd)" + fi + fi +done + +if [ "$FILE" == /dev/stdin ]; then + eval "$CMD" +elif [ -f "$FILE" ]; then + ffconv +elif [ -d "$FILE" ]; then + setx -a files=find "$FILE" -type f + for FILE in "${files[@]}"; do + ffconv + done +else + die "$FILE: fichier invalide" fi diff --git a/lib/uinst/conf b/lib/uinst/conf index fa2bac2..7408223 100644 --- a/lib/uinst/conf +++ b/lib/uinst/conf @@ -25,7 +25,6 @@ for i in cg cgs; do ln -s compileAndGo "$i" done ./fnconv --nutools-makelinks -./fconv --nutools-makelinks ./uproject --nutools-makelinks ./woctl --nutools-makelinks ./dokuwiki --nutools-makelinks