fconv accepte une liste de commandes

This commit is contained in:
Jephte CLAIN 2014-10-12 21:51:38 +04:00
parent b03c78b639
commit 9ee74697e0
2 changed files with 199 additions and 119 deletions

317
fconv
View File

@ -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

View File

@ -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