Lire ses mangas dans Emacs

(Nhat Minh Lê (rz0) @ 2009-09-15 23:31:51)

Pom pom pom pom, voici l’histoire de comment je me suis retrouvé à lire mes scans de mangas dans Emacs. Dernièrement, j’ai mis à jour libjpeg et, manque de chance, il a fallu que mon logiciel de visionnement d’images se fâche avec sa nouvelle bibliothèque de support. Bref, GQview, depuis, n’affiche plus correctement certains fichiers JPEG, ce qui est fort dérangeant…

C’est vraiment dommage car j’avais pris un peu de temps pour patcher celui-ci afin de rendre la lecture de mangas, comics, et autres documents linéaires composés d’images successives, plus agréable. Le patch était très simple : il modifiait le comportement de la touche d’espacement pour ajouter au défilement vertical le passage au fichier suivant lorsque l’image venait buter contre le bord de la fenêtre. En d’autres termes, il devenait possible de lire page après page, linéairement, en appuyant de manière répétée sur la seule touche espace. Une telle fonctionnalité m’est devenue indispensable, et je ne la trouve, à mon grand étonnement, nulle part…

Puisque mon GQview est devenu, pour l’heure, inutilisable, j’ai donc songé à recréer cette fonction ailleurs. C’est ainsi que j’ai décidé de recoder cette petite routine dans Emacs, et de la greffer à l’image-mode, qui, sans être bien sophistiqué, a l’avantage d’encore fonctionner correctement. Je vous présente donc le résultat de ma (fin de) soirée :

(defun my-image-next-by-number ()
  (interactive)
  (let ((file-name (buffer-file-name))
        base num suffix
        num-width fmt)
    (unless (string-match
             "^\\(.*[^0-9-]\\)?\\(?:[0-9]+-\\)?\\([0-9]+\\)\\(\\.[^.]+\\)?$"
             file-name)
      (error "Improper file name"))
    (setq base (match-string 1 file-name))
    (setq num (match-string 2 file-name))
    (setq suffix (match-string 3 file-name))
    (setq num-width (length num))
    (setq fmt (format "%%s%%0%dd%%s" num-width))
    (setq num (1+ (string-to-number num)))
    (setq file-name (format fmt base num suffix))
    (unless (file-exists-p file-name)
      (setq fmt (format "%%s%%0%dd-*%%s" num-width))
      (setq file-name (format fmt base num suffix))
      (setq file-name (file-expand-wildcards file-name))
      (if file-name
          (setq file-name (car file-name))
        (error "No more files")))
    (find-alternate-file file-name)))
(defun my-image-scroll-up-or-next-by-number ()
  (interactive)
  (let* ((image (image-get-display-property))
         (edges (window-inside-edges))
         (win-height (- (nth 3 edges) (nth 1 edges)))
         (img-height (ceiling (cdr (image-size image)))))
    (if (< (+ win-height (window-vscroll nil t))
           img-height)
        (image-scroll-up)
      (my-image-next-by-number))))
(define-key image-mode-map (kbd "SPC")
  'my-image-scroll-up-or-next-by-number)

Le code n’est pas très joli mais il semble fonctionner pour moi. Et je peux à nouveau être flemmard et lire avec un seul doigt !

La fonction de recherche du fichier suivant est spécifique à mes lectures : elle considère des fichiers à suffixe numérique croissant (ou éventuellement composé de deux nombres séparés par un tiret, pour les pages groupées).