Files
MD-to-Prrint/scripts/md_to_print_gui.sh
syoul 6285840eb2 Correction conversion Markdown: format explicite et dialogue options impression
- Ajout --from=markdown et --to=pdf pour conversion explicite
- Ajout --standalone pour document complet
- Correction dialogue options impression (suppression --set-value)
- Ajout logs débogage pour diagnostic
- Support preview et print avec dialogue options
- Correction gestion orientation CUPS (pas de conflit PDF/CUPS)
- Suppression fit-to-page problématique
2025-12-25 17:56:21 +01:00

508 lines
16 KiB
Bash
Executable File

#!/bin/bash
# Wrapper GUI pour MD_to_Print avec support sélection multiple
# Usage: md_to_print_gui.sh --print|--convert|--preview fichier1.md [fichier2.md ...]
set -euo pipefail
# Couleurs
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Variables
ACTION=""
USE_DOCKER=false
FILES=()
SCRIPT_DIR=""
# Fonction de notification
notify() {
local level="$1"
shift
local message="$*"
local icon=""
local urgency="normal"
case "$level" in
info)
icon="dialog-information"
urgency="low"
;;
success)
icon="dialog-information"
urgency="normal"
;;
warning)
icon="dialog-warning"
urgency="normal"
;;
error)
icon="dialog-error"
urgency="critical"
;;
esac
if command -v notify-send &> /dev/null; then
notify-send -u "$urgency" -i "$icon" "MD_to_Print" "$message" 2>/dev/null || true
fi
}
# Fonction pour afficher le dialogue d'options d'impression
show_print_options() {
if ! command -v zenity &> /dev/null; then
# Fallback si zenity n'est pas disponible
return 1
fi
# Récupérer la liste des imprimantes
local printers="Par défaut"
if command -v lpstat &> /dev/null; then
local printer_list=$(lpstat -p 2>/dev/null | grep -E "^printer" | awk '{print $2}' | tr '\n' '|')
if [ -n "$printer_list" ]; then
printers="${printer_list%|}|Par défaut"
fi
fi
# Dialogue zenity avec formulaire (forcer DISPLAY et mode synchrone)
echo "DEBUG show_print_options: Tentative d'affichage avec DISPLAY=${DISPLAY}" >> /tmp/md_to_print_debug.log
local result
# Utiliser dbus-launch si nécessaire pour les applications GUI depuis un contexte non-GUI
if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && command -v dbus-launch &> /dev/null; then
eval $(dbus-launch --sh-syntax)
fi
result=$(DISPLAY="${DISPLAY}" zenity --forms \
--title "Options d'impression MD_to_Print" \
--text "Configurez les options d'impression" \
--add-combo "Imprimante" \
--combo-values "$printers" \
--add-combo "Recto-verso" \
--combo-values "none|simplex|duplex" \
--add-entry "Nombre de copies (1-10)" \
--add-combo "Couleur" \
--combo-values "Non|Oui" \
--add-combo "Qualité" \
--combo-values "draft|normal|high" \
--add-combo "Orientation" \
--combo-values "portrait|landscape" \
2>&1)
local zenity_exit=$?
echo "DEBUG show_print_options: zenity_exit=$zenity_exit, result=$result" >> /tmp/md_to_print_debug.log
# Code 1 = utilisateur a annulé (normal)
# Code 0 = OK
# Autre = erreur
if [ $zenity_exit -eq 1 ]; then
# Utilisateur a annulé
echo "DEBUG: Utilisateur a annulé le dialogue" >> /tmp/md_to_print_debug.log
return 1
elif [ $zenity_exit -ne 0 ]; then
# Erreur d'exécution
echo "Erreur zenity (code $zenity_exit): $result" >> /tmp/md_to_print_zenity_error.log
echo "DEBUG: Erreur zenity (code $zenity_exit): $result" >> /tmp/md_to_print_debug.log
return 1
fi
if [ -z "$result" ]; then
echo "DEBUG: Résultat vide" >> /tmp/md_to_print_debug.log
return 1 # Pas de résultat
fi
echo "DEBUG: Dialogue réussi, résultat: $result" >> /tmp/md_to_print_debug.log
# Parser les résultats (zenity forms retourne les valeurs séparées par |)
IFS='|' read -r selected_printer duplex_mode copies color quality orientation <<< "$result"
# Valider et formater les options (déclarer comme globale)
declare -ga PRINT_OPTS=()
if [ -n "$selected_printer" ] && [ "$selected_printer" != "Par défaut" ] && [ "$selected_printer" != "" ]; then
PRINT_OPTS+=(--printer "$selected_printer")
fi
if [ -n "$duplex_mode" ] && [ "$duplex_mode" != "none" ]; then
PRINT_OPTS+=(--duplex "$duplex_mode")
fi
if [ -n "$copies" ] && [[ "$copies" =~ ^[0-9]+$ ]] && [ "$copies" -ge 1 ] && [ "$copies" -le 10 ]; then
PRINT_OPTS+=(--copies "$copies")
fi
if [ "$color" = "Oui" ]; then
PRINT_OPTS+=(--color)
fi
if [ -n "$quality" ] && [ "$quality" != "normal" ]; then
PRINT_OPTS+=(--quality "$quality")
fi
if [ -n "$orientation" ] && [ "$orientation" != "portrait" ]; then
PRINT_OPTS+=(--orientation "$orientation")
fi
return 0
}
# Fonction d'aide
show_help() {
cat << EOF
MD_to_Print - Wrapper GUI
Usage: $0 --print|--convert|--preview [--docker] fichier1.md [fichier2.md ...]
OPTIONS:
--print Conversion + Impression (avec dialogue d'options)
--convert Conversion uniquement (sans impression)
--preview Prévisualisation avant impression
--docker Forcer l'utilisation de Docker
--help Afficher cette aide
EXEMPLES:
$0 --print document.md
$0 --convert fichier1.md fichier2.md
$0 --preview document.md --docker
EOF
}
# Détection du script principal
detect_script() {
# Chercher md_to_print.sh dans le PATH
if command -v md_to_print.sh &> /dev/null; then
SCRIPT_DIR="$(dirname "$(command -v md_to_print.sh)")"
return 0
fi
# Chercher dans le répertoire parent
local current_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local parent_dir="$(dirname "$current_dir")"
if [ -f "$parent_dir/md_to_print.sh" ]; then
SCRIPT_DIR="$parent_dir"
return 0
fi
return 1
}
# Détection automatique Docker vs Local
detect_mode() {
# Si flag --docker explicite
if [ "$USE_DOCKER" = true ]; then
return 0
fi
# Vérifier si script local existe
if detect_script; then
USE_DOCKER=false
return 0
fi
# Vérifier si Docker est disponible
if command -v docker &> /dev/null; then
if docker images md-to-print:latest --format "{{.Repository}}:{{.Tag}}" 2>/dev/null | grep -q "md-to-print:latest"; then
USE_DOCKER=true
notify info "Utilisation Docker (dépendances locales non disponibles)"
return 0
fi
fi
# Aucune option disponible
return 1
}
# Parsing des arguments
while [[ $# -gt 0 ]]; do
case $1 in
--print|--convert|--preview)
ACTION="${1#--}"
shift
;;
--docker)
USE_DOCKER=true
shift
;;
--help|-h)
show_help
exit 0
;;
-*)
echo "Option inconnue: $1" >&2
show_help
exit 1
;;
*)
if [ -f "$1" ]; then
FILES+=("$1")
else
echo "Fichier introuvable: $1" >&2
exit 1
fi
shift
;;
esac
done
# Vérification des arguments
if [ -z "$ACTION" ]; then
echo "Erreur: Action non spécifiée (--print, --convert, ou --preview)" >&2
show_help
exit 1
fi
if [ ${#FILES[@]} -eq 0 ]; then
echo "Erreur: Aucun fichier spécifié" >&2
show_help
exit 1
fi
# Filtrer seulement les fichiers markdown
MD_FILES=()
for file in "${FILES[@]}"; do
if [[ "$file" =~ \.(md|markdown)$ ]]; then
MD_FILES+=("$file")
fi
done
if [ ${#MD_FILES[@]} -eq 0 ]; then
notify error "Aucun fichier Markdown trouvé dans la sélection"
exit 1
fi
# Détection du mode d'exécution
if ! detect_mode; then
if command -v zenity &> /dev/null; then
if zenity --question --text "Aucune installation locale trouvée.\n\nInstaller les dépendances localement ou utiliser Docker?" --title "MD_to_Print" --ok-label "Installer" --cancel-label "Docker"; then
if detect_script && [ -f "$SCRIPT_DIR/md_to_print.sh" ]; then
notify info "Installation des dépendances..."
"$SCRIPT_DIR/md_to_print.sh" --install-deps || {
notify error "Échec de l'installation des dépendances"
exit 1
}
USE_DOCKER=false
else
notify error "Script md_to_print.sh introuvable"
exit 1
fi
else
USE_DOCKER=true
fi
else
echo "Erreur: Aucune installation trouvée. Installez md_to_print.sh ou Docker." >&2
exit 1
fi
fi
# Confirmation pour plusieurs fichiers
if [ ${#MD_FILES[@]} -gt 1 ]; then
count=${#MD_FILES[@]}
if command -v zenity &> /dev/null; then
if ! zenity --question --text "Traiter $count fichiers?\n\n${MD_FILES[*]}" --title "MD_to_Print" --ok-label "Continuer" --cancel-label "Annuler"; then
exit 0
fi
else
echo "Traitement de $count fichiers..."
read -p "Continuer? (o/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Oo]$ ]]; then
exit 0
fi
fi
fi
# Afficher le dialogue d'options d'impression AVANT le traitement si action print et un seul fichier
# (doit être fait depuis l'hôte, pas dans Docker)
PRINT_OPTS=()
# S'assurer que DISPLAY est défini (nécessaire quand appelé depuis Caja Actions)
if [ -z "${DISPLAY:-}" ]; then
# Essayer de trouver DISPLAY depuis l'environnement utilisateur
if [ -f "$HOME/.Xauthority" ] && [ -S "/tmp/.X11-unix/X0" ]; then
export DISPLAY=":0"
elif [ -S "/tmp/.X11-unix/X0" ]; then
export DISPLAY=":0"
fi
# Dernière tentative : utiliser la valeur par défaut
if [ -z "${DISPLAY:-}" ]; then
export DISPLAY=":0"
fi
fi
# Logs de débogage
echo "DEBUG: ACTION=$ACTION" >> /tmp/md_to_print_debug.log
echo "DEBUG: DISPLAY=${DISPLAY:-}" >> /tmp/md_to_print_debug.log
echo "DEBUG: zenity disponible: $(command -v zenity 2>&1)" >> /tmp/md_to_print_debug.log
echo "DEBUG: Nombre de fichiers: ${#MD_FILES[@]}" >> /tmp/md_to_print_debug.log
# Afficher le dialogue d'options pour print ET preview (si un seul fichier)
if [ \( "$ACTION" = "print" -o "$ACTION" = "preview" \) ] && command -v zenity &> /dev/null && [ ${#MD_FILES[@]} -eq 1 ]; then
echo "DEBUG: Conditions remplies, tentative d'affichage du dialogue" >> /tmp/md_to_print_debug.log
# Toujours essayer d'afficher le dialogue pour print et preview
if show_print_options; then
echo "DEBUG: Dialogue OK, options: ${PRINT_OPTS[*]}" >> /tmp/md_to_print_debug.log
notify info "Options sélectionnées: ${PRINT_OPTS[*]}"
else
echo "DEBUG: Dialogue échoué ou annulé" >> /tmp/md_to_print_debug.log
notify info "Utilisation des options par défaut"
fi
else
echo "DEBUG: Conditions non remplies - ACTION=$ACTION, zenity=$(command -v zenity), fichiers=${#MD_FILES[@]}" >> /tmp/md_to_print_debug.log
fi
# Notification de début
notify info "Traitement de ${#MD_FILES[@]} fichier(s)..."
# Traitement des fichiers
SUCCESS_COUNT=0
ERROR_COUNT=0
ERROR_FILES=()
for file in "${MD_FILES[@]}"; do
file_name="$(basename "$file")"
notify info "Traitement: $file_name"
if [ "$USE_DOCKER" = true ]; then
# Utilisation Docker
file_dir="$(dirname "$(realpath "$file")")"
file_base="$(basename "$file")"
output_dir="$HOME/MD_to_print_output"
mkdir -p "$output_dir"
# Construire les arguments Docker
docker_args=()
if [ "$ACTION" = "convert" ]; then
docker_args+=(--convert-only)
elif [ "$ACTION" = "preview" ]; then
# Pour "preview", utiliser les options déjà récupérées avant la boucle
if [ ${#PRINT_OPTS[@]} -gt 0 ]; then
docker_args+=("${PRINT_OPTS[@]}")
fi
docker_args+=(--preview --keep-pdf)
else
# Pour "print", utiliser les options déjà récupérées avant la boucle
if [ ${#PRINT_OPTS[@]} -gt 0 ]; then
docker_args+=("${PRINT_OPTS[@]}")
fi
# On garde le PDF après impression
docker_args+=(--keep-pdf)
fi
if docker run --rm \
-v "$file_dir:/workspace/documents:ro" \
-v "$output_dir:/workspace/output" \
-v "$HOME/MD_to_print/logs:/workspace/logs" \
--network host \
${DISPLAY:+-e DISPLAY="$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix:ro} \
${CUPS_SOCKET:+-v /var/run/cups:/var/run/cups:ro} \
md-to-print:latest \
"/workspace/documents/$file_base" \
"${docker_args[@]}" \
> /tmp/md_to_print_docker.log 2>&1; then
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
# Pour preview, ouvrir le PDF depuis l'hôte après conversion
if [ "$ACTION" = "preview" ]; then
pdf_file="$output_dir/${file_base%.*}.pdf"
if [ -f "$pdf_file" ]; then
if command -v evince &> /dev/null; then
evince "$pdf_file" 2>/dev/null &
elif command -v xdg-open &> /dev/null; then
xdg-open "$pdf_file" 2>/dev/null &
else
notify warn "Aucun visualiseur PDF trouvé pour prévisualisation"
fi
fi
fi
notify success "$file_name traité"
else
ERROR_COUNT=$((ERROR_COUNT + 1))
ERROR_FILES+=("$file_name")
notify error "✗ Erreur: $file_name"
fi
else
# Utilisation locale
script_path=""
if [ -n "$SCRIPT_DIR" ]; then
script_path="$SCRIPT_DIR/md_to_print.sh"
else
script_path="md_to_print.sh"
fi
cmd_args=("$file")
case "$ACTION" in
print)
# Pour print, utiliser les options déjà récupérées avant la boucle
if [ ${#PRINT_OPTS[@]} -gt 0 ]; then
cmd_args+=("${PRINT_OPTS[@]}")
fi
# On garde le PDF après impression
cmd_args+=(--keep-pdf)
;;
convert)
# Pour convert, conversion uniquement sans impression
cmd_args+=(--convert-only)
;;
preview)
# Pour preview, utiliser les options déjà récupérées avant la boucle
if [ ${#PRINT_OPTS[@]} -gt 0 ]; then
cmd_args+=("${PRINT_OPTS[@]}")
fi
cmd_args+=(--preview --keep-pdf)
;;
esac
if "$script_path" "${cmd_args[@]}" > /tmp/md_to_print.log 2>&1; then
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
# Pour preview, ouvrir le PDF depuis l'hôte après conversion
if [ "$ACTION" = "preview" ]; then
# Chercher le PDF dans le répertoire de sortie
pdf_file=""
if [ -f "${file%.*}.pdf" ]; then
pdf_file="${file%.*}.pdf"
elif [ -f "$HOME/MD_to_print_output/$(basename "${file%.*}.pdf")" ]; then
pdf_file="$HOME/MD_to_print_output/$(basename "${file%.*}.pdf")"
elif [ -f "./output/$(basename "${file%.*}.pdf")" ]; then
pdf_file="./output/$(basename "${file%.*}.pdf")"
fi
if [ -n "$pdf_file" ] && [ -f "$pdf_file" ]; then
if command -v evince &> /dev/null; then
evince "$pdf_file" 2>/dev/null &
elif command -v xdg-open &> /dev/null; then
xdg-open "$pdf_file" 2>/dev/null &
else
notify warn "Aucun visualiseur PDF trouvé pour prévisualisation"
fi
fi
fi
notify success "$file_name traité"
else
ERROR_COUNT=$((ERROR_COUNT + 1))
ERROR_FILES+=("$file_name")
notify error "✗ Erreur: $file_name"
fi
fi
done
# Résumé final
if [ $ERROR_COUNT -eq 0 ]; then
notify success "Tous les fichiers ont été traités avec succès ($SUCCESS_COUNT fichier(s))"
exit 0
else
summary="Terminé: $SUCCESS_COUNT succès, $ERROR_COUNT erreur(s)"
if [ ${#ERROR_FILES[@]} -gt 0 ]; then
summary="$summary\n\nErreurs:\n${ERROR_FILES[*]}"
fi
notify error "$summary"
exit 1
fi