Bonjour à tous
La photocopie d'un document recto-verso avec un scanner uniquement recto nécessite une manipulation fastidieuse.
Le script ci-dessous réinsère dans les rectos les versos obtenus par le retournement du document dans le bac d'alimentation automatique. Il utilise
yad pour l'interface graphique
pdftk pour le traitement du pdf.
#!/bin/bash
function Initialisations () {
# rvc (rectos versos concaténés) : les versos viennent à la suite des rectos dans un fichier unique
# sinon les rectos sont dans un fichier et les versos dans un autre fichier ; aucun test n'est effectué sur le nombre de pages
# de ces deux fichiers
rvc=true
# pri (premier recto inclus) : le recto de la première feuille doit être inclus dans le document final
# sinon, la première page du document final est le verso de la première feuille
pri=true
# rpr (réorientation pages rectos) les pages rectos sont à l'endroit et ne doivent par être retournées de 180°
rpr=
# dvi (dernier verso inclus) : le verso de la dernière feuille doit être inclus dans le document final
dvi=true
# rpv (réorientation pages versos) les pages versos sont à l'endroit et ne doivent par être retournées de 180°
rpv=
# opt (options) le script est exécuté à partir d'une ligne de commande, par exemple à partir d'un lanceur par "glisser/déposer"
# du fichier à traiter, ceci pour permettre l'exécution sans interface graphique (le binaire de yad n'est pas dans le dépot)
opt=false
return 0
}
function LesOptions () {
# sera intégré dans la prochaine version, si elle voit le jour
:
}
function Ressources () {
############################################################
# vérification présence des ressources nécessaires
###########################################################
which zenity > /dev/null && zenity=true || zenity=false ;
which pdftk > /dev/null && pdftk=true || pdftk=false ;
which yad > /dev/null && yad=true && zenity=false || yad=false ;
! ${yad} && ${pdftk} && Msg_Err e=130 ;
${yad} && ! ${pdftk} && Msg_Err e=131 ;
! ${yad} && ! ${pdftk} && Msg_Err e=132 ;
}
function Msg_Err () {
# le premier paramètre est une instruction «e=num», ce qui facilite la recherche de l'instruction
# qui décèle une erreur dont on connait le numéro
local e
function yad_err_msg () {
local msg="${1}"
yad --text-info --title="${titre}" --button="Erreur ${e}:1" \
--text-align=center \
--width=500 \
--text="${msg}" --sticky --center
}
function zen_err_msg () {
local msg="${1}"
zenity --error --text="${msg}" --title="${titre}" --width=350 --height=60 --no-wrap ;
}
function echo_err_msg () {
local msg="${1}" ;
echo "${titre}" 1>/dev/stderr ;
echo "${msg}" 1>/dev/stderr ;
}
eval ${1} ;
case "${e}" in
0) msg="Le fichier\n\"${2}\"\na été correctement créé." ;;
128) msg="Vous n'avez spécifié aucun fichier à traiter." ;;
129) msg="Le fichier \"${2}\" n'est pas un fichier pdf ou ne peut pas être lu." ;
msg="${msg}\nPdftk a indiqué\n${3}" ;;
130) msg="Yad - Yet another display https://sourceforge.net/projects/yad-dialog/ - est indispensable pour utiliser ce script." ;;
131) msg="Pdftk - Pdf tool kit - est indispensable pour utiliser ce script." ;;
132) msg="Yad et Pdftk sont indispensables pour utiliser ce script." ;;
133) msg="Le traitement a échoué.\nPdftk a indiqué\n${2}" ;;
esac ;
titre="Ordonnancement de photocopie : erreur n° ${e}" ;
[[ $((${e})) -gt 127 ]] && msg="${msg}\n Arrêt immédiat."
${yad} && yad_err_msg "${msg}" ;
! ${yad} && ${zenity} && zen_err_msg "${msg}" ;
! ${yad} && ! ${zenity} && echo_err_msg "${msg}" ;
[[ $((${e})) -lt 127 ]] && return $((${e})) || exit $((${e}-127)) ;
}
function TestPdf () {
local pdf="${1}" ;
pdftk "${pdf}" dump_data 1> /tmp/pdftk.txt 2>/tmp/pdftk.err ;
[[ $((${?})) -ne 0 ]] && Msg_Err e=129 "${pdf}" "$(cat /tmp/pdftk.err)" ;
}
function NbPagesPdf () {
local pdf="${1}"
pdftk "${pdf}" dump_data 2>/tmp/pdftk.err | grep NumberOfPages | grep -o -E "[[:digit:]]+$" ;
}
function Ordonnance_pri () {
#####################################################################################
#
# Cette fonction est appelée lorsque le premier recto est inclus dans le document final (situation la plus fréquente)
#
######################################################################################
# la variable dpe (dernière page exclue) vaut 1 si le verso de la dernière feuille du paquet doit être écarté du document final
# le document final contient alors un nombre impair de pages ; cependant, dpe ne doit pas être utilisée si la dernière feuille du paquet
# a été retirée avant de photocopier les versos
local impaires="${1}" paires="${2}" toutes="${1}"
if ${rvc} ; then
np=$(NbPagesPdf "${toutes}") ;
di=$(((${np}+1)/2)) ;
dp=$((${di}+1+${dpe})) ;
else
di=$(NbPagesPdf "${impaires}") ;
dp=$((1+${dpe})) ;
fi
pdftk A="${impaires}" B="${paires}" shuffle A1-${di}${rpr} Bend-${dp}${rpv} output ${trv} keep_first_id 2>/tmp/pdftk.err ;
[[ $((${?})) -ne 0 ]] && Msg_Err e=133 "$(cat /tmp/pdftk.err)" ;
}
function Ordonnance_pre () {
#####################################################################################
#
# Cette fonction est appelée lorsque le premier recto est exclu du document final (situation la moins fréquente)
#
######################################################################################
# la variable dpe (dernière page exclue) vaut 1 si le verso de la dernière feuille du paquet doit être écarté du document final
# le document final contient alors un nombre pair de pages ; cependant, dpe ne doit pas être utilisée si la dernière feuille du paquet
# a été retirée avant de photocopier les versos
local paires="${1}" impaires="${2}" toutes="${1}"
if ${rvc} ; then
np=$(NbPagesPdf "${toutes}") ;
dp=$(((${np}+1)/2)) ;
di=$((${dp}+1+${dpe})) ;
pi=${np} ;
else
dp=$(NbPagesPdf "${paires}") ;
di=$((1+${dpe})) ;
pi=$(NbPagesPdf "${impaires}") ;
fi
pdftk A="${impaires}" B="${paires}" shuffle A${pi}-${di}${rpv} B2-${dp}${rpr} output ${trv} keep_first_id 2>/tmp/pdftk.err ;
[[ $((${?})) -ne 0 ]] && Msg_Err e=133 "$(cat /tmp/pdftk.err)" ;
}
function LireParams () {
function yad_form () {
titre="Les rectos et les versos peuvent être contenus dans un fichier unique (1) ou dans deux fichiers séparés,"
titre="${titre} l'un pour les rectos (1), l'autre pour les versos (2). Les versos sont dans l'ordre inverse des pages."
titre="${titre}\nLa possibilité de retourner les pages qui sont éventuellement à l'envers s'applique séparément pour les rectos et"
titre="${titre} les versos, même lorsque toutes les pages sont dans le même fichier."
yad --form --title="Choix du fichier à réordonner" --button="gtk-ok:0" --button=Annuler:1 \
--width=900 \
--text="${titre}" --always-print-result --sticky --center \
--field="Fichier des rectos ou des rectos et des versos (1):SFL" \
--field="Ne pas inclure le premier recto (la première page de la photocopie est le premier verso):CHK" \
--field="Les pages rectos sont à l'envers et doivent être retournées:CHK" \
--field="Fichier des versos, si rectos et versos séparés (2):SFL" \
--field="Ne pas inclure le dernier verso:CHK" \
--field="Les pages versos sont à l'envers et doivent être retournées:CHK" \
--field="Si aucun fichier n'est spécifié ci-dessous, le fichier des rectos est écrasé:LBL" \
--field="Fichier à créer (3):SFL" \
"" "" "" "" "" "" "" ""
}
params=$(yad_form) ;
[ "${?}" != "0" ] && exit 1 ;
pdf_recto=$(echo "${params}" | cut -d "|" -f 1) ;
[ -z "${pdf_recto}" ] && Msg_Err e=128 ;
nbr=$(NbPagesPdf "${pdf_recto}")
pdf_verso=$(echo "${params}" | cut -d "|" -f 4) ;
[ -n "${pdf_verso}" ] && rvc=false && nbv=$(NbPagesPdf "${pdf_verso}") || pdf_verso="${pdf_recto}" && nbv=nbr ;
pdf_cree=$(echo "${params}" | cut -d "|" -f 8) ;
[ -z "${pdf_cree}" ] && pdf_cree="${pdf_recto}" ;
[[ "$(echo "${params}" | cut -d "|" -f 2)" = "TRUE" ]] && pri=false ;
[[ "$(echo "${params}" | cut -d "|" -f 3)" = "TRUE" ]] && rpr=down ;
[[ "$(echo "${params}" | cut -d "|" -f 5)" = "TRUE" ]] && dvi=false ;
[[ "$(echo "${params}" | cut -d "|" -f 6)" = "TRUE" ]] && rpv=down ;
}
function Traitement () {
${dvi} && dpe=0 || dpe=1 ;
# trv="$(mktemp --suffix=".pdf" --tmpdir="$(dirname "${pdf_cree}")")" ;
trv="$(mktemp)" ;
${pri} && rslt="$(Ordonnance_pri "${pdf_recto}" "${pdf_verso}")" ;
! ${pri} && rslt="$(Ordonnance_pre "${pdf_recto}" "${pdf_verso}")" ;
cp -fT "${trv}" "${pdf_cree}" && rm "${trv}"
Msg_Err e=0 "${pdf_cree}"
return 0
}
function Principale () {
Initialisations
LesOptions
Ressources
! ${opt} && LireParams
Traitement
}
Principale
Arbiel