Humus numericus

Aller au contenu | Aller au menu | Aller à la recherche

R, Spip et autres

Emacs, Gnus

Fil des billets

mardi 20 septembre 2011

el-get, un gestionnaire de script/package/extension pour Emacs

Un des aspects parfois fastidieux d'Emacs est la gestion de tous les scripts et extensions non inclus dans la distribution de base, qu'on récupère deci-delà et dont il faut gérer les version, les mises à jour, l'inclusion dans son .emacs, etc.

Pour remédier à ce problème, différents scripts existent, comme Auto Install, plutôt centré sur les scripts hébergés sur EmacsWiki, ELPA et l'extension package, et bien d'autres

Or je viens de découvrir grâce à un retweet de Julien Danjou un projet que je ne connaissais pas : el-get. Et il s'avère que ce système est tout simplement génial, et que j'y ai du coup migré dans la foulée la gestion de la totalité de mes scripts Emacs.

Pour le dire vite, el-get permet d'installer des scripts et extensions depuis quasiment toutes les sources imaginables (git, url, fichier, emacswiki, elpa, etc.), automatise leur installation, ajoute automatiquement les require et autres directives qui vont bien, et permet une mise à jour et une synchronisation très simple des extensions installées.

Installation

L'installation d'el-get se fait en ajoutant les lignes suivantes dans son .emacs et en les exécutant :

(add-to-list 'load-path "~/.emacs.d/el-get/el-get")

(unless (require 'el-get nil t)
  (url-retrieve
   "https://raw.github.com/dimitri/el-get/master/el-get-install.el"
   (lambda (s)
     (end-of-buffer)
     (eval-print-last-sexp))))

Ces instructions vérifient qu'el-get est déjà installé et, sinon, le télécharge via git et l'installe dans ~/.emacs.d/el-get/el-get.

Note : en cas de message d'erreur lié à la variable el-get-verbose, ajouter la ligne (setq el-get-verbose t) dans son .emacs peut suffire à résoudre le problème.

Utilisation interactive

el-get est fourni avec un certain nombre de «recettes» (recipes) qui décrivent l'installation d'un grand nombre d'extensions.

Imaginons que nous souhaitons installer rainbow-mode par exemple. Rien de plus simple. Il suffit de faire M-x el-get-install, de saisir rainbow-mode au prompt, et de laisser el-get faire le boulot, c'est à dire :

  • télécharger les fichiers nécessaires
  • les installer dans ~/.emacs/el-get
  • byte-compiler les fichiers
  • installer et exécuter automatiquement les require et autre autoloads nécessaires à l'utilisation de l'extension
  • et, en cadeau bonux, il fait tout ça de manière asynchrone (vous pouvez continuer à utiliser Emacs pendant ce temps) et vous prévient qu'il a fini avec une jolie notification !

Une fois l'opération effectuée, même pas besoin d'éditer son .emacs, l'extension est immédiatement disponible et un M-x rainbow-mode marche immédiatement.

Le plus fort, c'est que ça fonctionne pour des extensions de petite taille, mais aussi pour des mastodontes nécessitant dépendances et compilations, comme org-mode ou nXhtml !

Vous avez testé une extension et vous ne souhaitez pas la conserver ? Hop, el-get-remove. Vous souhaitez mettre à jour l'une d'entre elles ? Hop, el-get-update. Etc., etc.

Installation depuis EmacsWiki

Vous souhaitez installer un fichier hébergé sur EmacsWiki ? Pas de problème, il suffit de faire un petit M-x el-get-emacswiki-refresh, d'attendre la jolie notification, et à partir de là l'intégralité des fichiers hébergés sur EmacsWiki sont automatiquement disponibles et installables avec el-get-install !

Sauvegarde et synchronisation de la liste des extensions

Jusqu'à présent je gérais mes différents fichiers de configuration emacs dans un dépôt git, qui me permettait à la fois de garder l'historique et de synchroniser entre différentes machines. Là où ça devient plus compliqué, c'est quand on installe des extensions elles-mêmes sous git (problèmes de conflits pour des dépôts inclus dans des dépôts, même si git sait gérer ça très bien) ou sous d'autres gestionnaires de version.

el-get permet de gérer cela de manière très élégantes : il suffit de déclarer dans son .emacs la liste des extensions utilisées pour qu'elles soient automatiquement vérifiées au démarrage et installées si nécessaire.

Par exemple, voici ce que j'ai dans mon .emacs :

(setq my:el-get-packages
      '(xml-rpc-el
        yasnippet
        org-mode
        anything
        auto-dictionnary
        autopair
        calfw
        coffee-mode
        color-theme
        dired+
        edit-server
        fixme-mode
        flymake-ruby
        gist
        google-maps
        js2-mode
        nxhtml
        org2blog
        rainbow-mode
        r-autoyas
        rvm
        switch-window
        sr-speedbar
        typopunct
        ))

(el-get 'sync my:el-get-packages)

La variable my:el-get-packages contient la liste des extensions utilisées, et la fonction (el get 'sync) va automatiquement vérifier que toutes les extensions spécifiées sont installées sur le système. Et si ça n'est pas le cas, elle les installe.

Donc, plus besoin d'enregistrer les fichiers des extensions proprement dites dans le dépôt git de sa config emacs, il suffit de spécifier leur liste dans son .emacs et el-get se charge du reste.

Ajouter ses propres recettes

Il peut arriver qu'une extension ne soit disponible ni sur EmacsWiki ni parmi les recettes fournies. Dans ce cas il est possible et assez simple de créer sa propre recette.

Prenons par exemple le fichier pwsafe.el, qui est une interface entre Emacs et pwsafe. Celui-ci n'est disponible qu'en téléchargement direct depuis le site de son auteur.

La «recette» d'installation correspondante est très simple :

(:name pwsafe
       :description "Emacs interface to pwsafe, by Stefan Reichoer"
       :type http
       :url "http://www.xsteve.at/prg/emacs/pwsafe.el")

Dans le cas du thème color-theme-tangotango, hébergé sur GtiHub, c'est pas plus compliqué :

(:name color-theme-tangotango
       :description "Another color theme based on the Tango palette."
       :type git
       :url "https://github.com/juba/color-theme-tangotango.git")

Pour ajouter une recette à el-get, on peut l'ajouter directement dans son .emacs :

(setq my:el-get-packages
      '(xml-rpc-el
        yasnippet
        org-mode
        […]
        ))

(setq el-get-sources
        '((:name pwsafe
               :description "Emacs interface to pwsafe, by Stefan Reichoer"
               :type http
               :url "http://www.xsteve.at/prg/emacs/pwsafe.el")))

(setq my-packages
      (append
       my:el-get-packages
       (mapcar 'el-get-source-name el-get-sources)))

(el-get 'sync my-packages)

Aller plus loin

Pour avoir un aperçu plus complet des fonctionnalités d'el-get, l'idéal est de consulter le README sur GitHub.

jeudi 15 septembre 2011

Une fonction Emacs qu'elle est utile

Un des trucs que j'adore sous org-mode, c'est la possibilité de déplacer des éléments (items de listes, titres, sections, etc.) avec M-haut et M-bas.

J'ai réalisé ce matin que je passais quand même un certain temps, lors de l'édition de fichiers, à enchaîner les C-k et C-y pour déplacer des lignes entières. Ça serait-y pas plus pratique de pouvoir utiliser M-haut et M-bas partout pour déplacer les lignes de la même manière que sous org-mode ?

Un petit tour sur EmacsWiki, et voilà :

(defun move-line (n)
  "Move the current line up or down by N lines."
  (interactive "p")
  (setq col (current-column))
  (beginning-of-line) (setq start (point))
  (end-of-line) (forward-char) (setq end (point))
  (let ((line-text (delete-and-extract-region start end)))
    (forward-line n)
    (insert line-text)
    ;; restore point to original column in moved line
    (forward-line -1)
    (forward-char col)))

(defun move-line-up (n)
  "Move the current line up by N lines."
  (interactive "p")
  (move-line (if (null n) -1 (- n))))

(defun move-line-down (n)
  "Move the current line down by N lines."
  (interactive "p")
  (move-line (if (null n) 1 n)))

(global-set-key (kbd "M-<up>") 'move-line-up)
(global-set-key (kbd "M-<down>") 'move-line-down)

On rajoute ça à son .emacs, et boudiou que c'est pratique !

lundi 3 janvier 2011

How to post on a dotclear blog with org-mode

I just discovered a very great tool called org2blog that allows to post articles to a Wordpress blog directly from Emacs’ org-mode :

https://github.com/punchagan/org2blog

You just have to set up org2blog with the xmlrpc interface of your blog, and then you can create a new org-mode buffer which will be automatically exported to html and then published to your blog.

Some very great features :

  • HTML export, source code highlighting, org-babel, etc. are fully supported out of the box !
  • you can use an existing org-mode buffer or create a new one to post your article
  • thanks to the embedded post id in the org-mode buffer, you can edit and update an already posted article
  • categories and tags are supported as CATEGORY and TAGS buffer properties, and it even features autocompletion !

You can even post some images directly form your org-file :

/public/_____________20110104_org2mode.jpg

And, finally, I also discovered that org2blog fully supports Dotclear via it’s xml-rpc interface. So I think I know how I will post content on this blog now.

And, finally, just a little proof that org-babel works :

x <- rnorm(100)
summary(x)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.9840 -0.5460  0.1608  0.1768  0.8476  2.2070 

lundi 12 juillet 2010

Updated tangotango emacs color theme

EDIT : This post is now quite deprecated. Installation instructions and new versions are posted on the github project page.

I just updated my original ”tangotango” emacs color theme, based on the tango palette colors. I’ve tweaked some details and moved the source code to github. Here are updated installation instructions and screenshots :

Installation instructions

  1. Download and install the color-theme emacs package either via your linux distribution or via the source tarball
  2. Download and install color-theme-tangotango.el from github
  3. Make sure that both color-theme.el and color-theme-tangotango.el are in your load path

There are several ways to load the tangotango color theme from your .emacs, as documented on emacswiki. The way I currently use should work for a daemonized emacs and allows the selection of different themes for GUI or console based frames :

(require 'color-theme)
(setq color-theme-load-all-themes nil)

(require 'color-theme-tangotango)

;; select theme - first list element is for windowing system, second is for console/terminal
;; Source : http://www.emacswiki.org/emacs/ColorTheme#toc9
(setq color-theme-choices 
      '(color-theme-tangotango color-theme-tangotango))

;; default-start
(funcall (lambda (cols)
    	   (let ((color-theme-is-global nil))
    	     (eval 
    	      (append '(if (window-system))
    		      (mapcar (lambda (x) (cons x nil)) 
    			      cols)))))
    	 color-theme-choices)

;; test for each additional frame or console
(require 'cl)
(fset 'test-win-sys 
      (funcall (lambda (cols)
    		 (lexical-let ((cols cols))
    		   (lambda (frame)
    		     (let ((color-theme-is-global nil))
		       ;; must be current for local ctheme
		       (select-frame frame)
		       ;; test winsystem
		       (eval 
			(append '(if (window-system frame)) 
				(mapcar (lambda (x) (cons x nil)) 
					cols)))))))
    	       color-theme-choices ))
;; hook on after-make-frame-functions
(add-hook 'after-make-frame-functions 'test-win-sys)

(color-theme-tangotango)

Note that I also had to add a (color-theme-tangotango) line at the end of my .gnus file in order to apply the color theme to Gnus.

Screenshots

Here is a screenshot of the color theme with an emacs-lisp file :

tangotango_elisp.png

One with a Gnus summary and article buffers :

tangotango_gnus.png

And one with an org-mode buffer :

tangotango_org.png

mercredi 10 février 2010

Tangotango dark emacs color theme

UPDATE : This entry is deprecated ! Source code has been moved to Github and installation instructions have been rewritten.

I always have used the default Emacs color theme, with a white background. Recently I wanted to switch to a dark background but didn’t find a color scheme taht I’d like enough to use, so Is tarted to create one myself. In fact I started with the tango color theme on EmacsWiki, modified a bit, and added some faces to support gnus and org-mode as I use them a lot.

The result is a color theme named tangotango whose code is the following :

(defun color-theme-tangotango ()
  "A color theme based on Tango Palette."
  (interactive)
  (color-theme-install
   '(color-theme-tango
     ((background-color . "#2e3436")
      (background-mode . dark)
      (border-color . "#888a85")
      (cursor-color . "#fce94f")
      (foreground-color . "#eeeeec")
      (mouse-color . "#8ae234"))
     ((help-highlight-face . underline)
      (ibuffer-dired-buffer-face . font-lock-function-name-face)
      (ibuffer-help-buffer-face . font-lock-comment-face)
      (ibuffer-hidden-buffer-face . font-lock-warning-face)
      (ibuffer-occur-match-face . font-lock-warning-face)
      (ibuffer-read-only-buffer-face . font-lock-type-face)
      (ibuffer-special-buffer-face . font-lock-keyword-face)
      (ibuffer-title-face . font-lock-type-face))
     (highlight ((t (:background "brown4" :foreground nil))))
     (border ((t (:background "#888a85"))))
     (fringe ((t (:background "grey10"))))
     (mode-line ((t (:foreground "#bbbbbc" :background "#222222" :box (:line-width 1 :color nil :style released-button)))))
     (mode-line-inactive ((t (:foreground "#bbbbbc" :background "#555753"))))
     (mode-line-buffer-id ((t (:bold t :foreground "orange" :background nil))))
     (region ((t (:background "dark slate blue"))))
     (link ((t (:underline t :foreground "dodger blue"))))
     (custom-link ((t (:inherit 'link))))
     (match ((t (:bold t :background "#e9b96e" :foreground "#2e3436"))))
     (tool-tips ((t (:inherit 'variable-pitch :foreground "black" :background "lightyellow"))))
     (tooltip ((t (:inherit 'variable-pitch :foreground "black" :background "lightyellow"))))
     (bold ((t (:bold t :underline nil :background nil))))
     (italic ((t (:italic t :underline nil :background nil))))
     (font-lock-builtin-face ((t (:foreground "#729fcf"))))
     (font-lock-comment-face ((t (:foreground "#888a85"))))
     (font-lock-constant-face ((t (:foreground "#8ae234"))))
     (font-lock-doc-face ((t (:foreground "#888a85"))))
     (font-lock-keyword-face ((t (:foreground "#729fcf" :bold t))))
     (font-lock-string-face ((t (:foreground "#ad7fa8" :italic t))))
     (font-lock-type-face ((t (:foreground "#8ae234" :bold t))))
     (font-lock-variable-name-face ((t (:foreground "tomato"))))
     (font-lock-warning-face ((t (:bold t :foreground "#f57900"))))
     (font-lock-function-name-face ((t (:foreground "#edd400" :bold t))))
     (comint-highlight-input ((t (:italic t :bold t))))
     (comint-highlight-prompt ((t (:foreground "#8ae234"))))
     (isearch ((t (:background "#f57900" :foreground "#2e3436"))))
     (isearch-lazy-highlight-face ((t (:foreground "#2e3436" :background "#e9b96e"))))
     (show-paren-match-face ((t (:foreground "#2e3436" :background "#73d216"))))
     (show-paren-mismatch-face ((t (:background "#ad7fa8" :foreground "#2e3436"))))
     (minibuffer-prompt ((t (:foreground "#729fcf" :bold t))))
     (info-xref ((t (:foreground "#729fcf"))))
     (info-xref-visited ((t (:foreground "#ad7fa8"))))
     (diary-face ((t (:bold t :foreground "IndianRed"))))
     (eshell-ls-clutter-face ((t (:bold t :foreground "DimGray"))))
     (eshell-ls-executable-face ((t (:bold t :foreground "Coral"))))
     (eshell-ls-missing-face ((t (:bold t :foreground "black"))))
     (eshell-ls-special-face ((t (:bold t :foreground "Gold"))))
     (eshell-ls-symlink-face ((t (:bold t :foreground "White"))))
     (widget-button ((t (:bold t))))
     (widget-mouse-face ((t (:bold t :foreground "white" :background "brown4"))))
     (widget-field ((t (:foreground "orange" :background "gray30"))))
     (widget-single-line-field ((t (:foreground "orange" :background "gray30"))))
     (custom-group-tag ((t (:bold t :foreground "#edd400" :height 1.3))))
     (custom-variable-tag ((t (:bold t :foreground "#edd400" :height 1.1))))
     (custom-face-tag ((t (:bold t :foreground "#edd400" :height 1.1))))
     (custom-state-face ((t (:foreground "#729fcf"))))
     (custom-button  ((t (:box (:line-width 1 :style released-button) :background "grey50" :foreground "black"))))
     (custom-variable-button ((t (:inherit 'custom-button))))
     (custom-button-mouse  ((t (:inherit 'custom-button :background "grey60"))))
     (custom-button-unraised  ((t (:background "grey50" :foreground "black"))))
     (custom-button-mouse-unraised  ((t (:inherit 'custom-button-unraised :background "grey60"))))
     (custom-button-pressed  ((t (:inherit 'custom-button :box (:style pressed-button)))))
     (custom-button-mouse-pressed-unraised  ((t (:inherit 'custom-button-unraised :background "grey60"))))
     (custom-documentation ((t (:italic t))))
     (message-cited-text ((t (:foreground "#edd400")))) 
     (gnus-cite-face-1 ((t (:foreground "#ad7fa8"))))
     (gnus-cite-face-2 ((t (:foreground "sienna4"))))
     (gnus-cite-face-3 ((t (:foreground "khaki4"))))
     (gnus-cite-face-4 ((t (:foreground "PaleTurquoise4"))))
     (gnus-group-mail-1-empty-face ((t (:foreground "light cyan"))))
     (gnus-group-mail-1-face ((t (:bold t :foreground "light cyan"))))
     (gnus-group-mail-2-empty-face ((t (:foreground "turquoise"))))
     (gnus-group-mail-2-face ((t (:bold t :foreground "turquoise"))))
     (gnus-group-mail-3-empty-face ((t (:foreground "#729fcf"))))
     (gnus-group-mail-3-face ((t (:bold t :foreground "#edd400"))))
     (gnus-group-mail-low-empty-face ((t (:foreground "dodger blue"))))
     (gnus-group-mail-low-face ((t (:bold t :foreground "dodger blue"))))
     (gnus-group-news-1-empty-face ((t (:foreground "light cyan"))))
     (gnus-group-news-1-face ((t (:bold t :foreground "light cyan"))))
     (gnus-group-news-2-empty-face ((t (:foreground "turquoise"))))
     (gnus-group-news-2-face ((t (:bold t :foreground "turquoise"))))
     (gnus-group-news-3-empty-face ((t (:foreground "#729fcf"))))
     (gnus-group-news-3-face ((t (:bold t :foreground "#edd400"))))
     (gnus-group-news-low-empty-face ((t (:foreground "dodger blue"))))
     (gnus-group-news-low-face ((t (:bold t :foreground "dodger blue"))))
     (gnus-header-name-face ((t (:bold t :foreground "#729fcf"))))
     (gnus-header-from ((t (:bold t :foreground "#edd400"))))
     (gnus-header-subject ((t (:foreground "#edd400"))))
     (gnus-header-content ((t (:italic t :foreground "#8ae234"))))
     (gnus-header-newsgroups-face ((t (:italic t :bold t :foreground "LightSkyBlue3"))))
     (gnus-signature-face ((t (:italic t :foreground "dark grey"))))
     (gnus-summary-cancelled-face ((t (:background "black" :foreground "yellow"))))
     (gnus-summary-high-ancient-face ((t (:bold t :foreground "rotal blue"))))
     (gnus-summary-high-read-face ((t (:bold t :foreground "lime green"))))
     (gnus-summary-high-ticked-face ((t (:bold t :foreground "tomato"))))
     (gnus-summary-high-unread-face ((t (:bold t :foreground "white"))))
     (gnus-summary-low-ancient-face ((t (:italic t :foreground "lime green"))))
     (gnus-summary-low-read-face ((t (:italic t :foreground "royal blue"))))
     (gnus-summary-low-ticked-face ((t (:italic t :foreground "dark red"))))
     (gnus-summary-low-unread-face ((t (:italic t :foreground "white"))))
     (gnus-summary-normal-ancient-face ((t (:foreground "royal blue"))))
     (gnus-summary-normal-read-face ((t (:foreground "lime green"))))
     (gnus-summary-normal-ticked-face ((t (:foreground "indian red"))))
     (gnus-summary-normal-unread-face ((t (:foreground "white"))))
     (gnus-summary-selected ((t (:background "brown4" :foreground "white"))))
     (message-header-name-face ((t (:foreground "tomato"))))
     (message-header-newsgroups-face ((t (:italic t :bold t :foreground "LightSkyBlue3"))))
     (message-header-other-face ((t (:foreground "LightSkyBlue3"))))
     (message-header-xheader-face ((t (:foreground "DodgerBlue3"))))
     (message-header-subject ((t (:foreground "white"))))
     (message-header-to ((t (:foreground "white"))))
     (message-header-cc ((t (:foreground "white"))))
     (org-hide ((t (:foreground "#2e3436"))))
     (org-level-1 ((t (:bold t :foreground "dodger blue" :height 1.5))))
     (org-level-2 ((t (:bold t :foreground "#6ac214" :height 1.2))))
     (org-level-3 ((t (:bold t :foreground "#edd400" :height 1.1))))
     (org-level-4 ((t (:bold t :foreground "tomato" :height 1.0))))
     (org-date ((t (:underline t :foreground "magenta3"))))
     (org-footnote  ((t (:underline t :foreground "magenta3"))))
     (org-link ((t (:foreground "skyblue2" :background "#2e3436"))))
     (org-special-keyword ((t (:foreground "brown"))))
     (org-verbatim ((t (:foreground "#eeeeec" :underline t :slant italic))))
     (org-block ((t (:foreground "#bbbbbc"))))
     (org-quote ((t (:inherit org-block :slant italic))))
     (org-verse ((t (:inherit org-block :slant italic))))
     (org-todo ((t (:bold t :foreground "Red"))))
     (org-done ((t (:bold t :foreground "ForestGreen"))))
     (anything-header ((t (:bold t :background "grey15" :foreground "#edd400"))))
)))

Obviously you need to install and configure the color-theme Emacs extension to use it. You will find instructions on the dedicated EmacsWiki page. The setup I use is the following :

(require 'color-theme)
(color-theme-initialize)
(setq color-theme-is-global t)
(setq color-theme-is-cumulative t)
(setq color-theme-load-all-themes nil)

(color-theme-tangotango)

(add-hook 'message-mode-hook 'color-theme-tangotango)
(add-hook 'gnus-article-mode-hook 'color-theme-tangotango)

(add-hook 'after-make-frame-functions
	  (lambda (frame)
	    (set-variable 'color-theme-is-global nil)
	    (select-frame frame)
	    (if window-system
		(color-theme-tangotango)
	      (color-theme-tty-dark))))

Here is a screenshot of the color theme with an emacs-lisp file :

tangotango_elisp.png

One with a Gnus summary and article buffers :

tangotango_gnus.png

And one with an org-mode buffer :

tangotango_org.png

Feel free to give any feedback !

mercredi 5 avril 2006

Textile mode

Youpi, youpla, je viens de créer mon premier major mode pour Emacs. C'est un mode visant à faciliter l'écriture de document suivant la syntaxe de balisage Textile.

Pour l'instant il ne fait pas grand-chose, c'est à dire seulement de la coloration syntaxique, et il est en version vraiment alpha, pas plus testée que ça. N'hésitez pas à me faire remonter tout bug ou commentaire.

La dernière version du script peut être téléchargée là :

http://svn.nozav.org/scripts/elisp/textile-mode/textile-mode.el

Pour plus d'informations sur Textile, vous pouvez consulter :

samedi 7 janvier 2006

erc2html

Je viens de pondre un tout petit script en Ruby qui me permet de transformer un log de discussion IRC enregistré sous ERC (Emacs Relay Chat) en fichier HTML pour publication. Le script supprime les sauts de ligne superflus, supprime les messages serveur et colorise deux trois bricoles. C'est loin d'être parfait, mais si ça peut être utile à quelqu'un...

require "cgi"

str = IO.read("/home/julien/lautre_20060107.log.txt")

titre = "Titre de la page"
charset = "UTF-8"

head = <<EOL
<html>
<head>
<title>#{titre}</title>
<meta http-equiv="Content-Type" content="text/html; charset=#{charset}" />
<style type="text/css">
 * {font-family: monospace;}
 .nick {font-weight: bold; color: #A00;}
 .ref {font-style: italic; color: #090;}
 .timestamp {color: #AAA;}
 .me {color: #00B;}
</style>
</head>
<body>
<h1>#{titre}</h1>
<p>
EOL

foot = <<EOL
</p>
</body>
</html>
EOL

str.gsub!(/^ERC>.*$/n, "")
str.gsub!(/
\s+/n, " ")
str.gsub!(/[\d\d:\d\d]/) { |s| "
"+s+"
"}
str.gsub!(/\s+$/n, "")
str.gsub!(/^\*\*\* .*$/n, "")
5.times {str.gsub!(/
\s*
/n, "
")}

str = CGI::escapeHTML(str)
str.gsub!(/^&lt;.*?&gt;/n) {|s| '<span class="nick">'+s+'</span>'}
str.gsub!(/(<\/span>) (\w+\s?:)/n) {|s| $1+' <span class="ref">'+$2+'</span>'}
str.gsub!(/[\d\d:\d\d]/) { |s| '<span class="timestamp">'+s+'</span>'}
str.gsub!(/^\* .*$/n) {|s| '<span class="me">'+s+'</span>'}
str.gsub!(/
/, "<br />
")

str = head + str
str = str + foot

puts str

jeudi 21 octobre 2004

Utiliser Mozilla Firefox pour ouvrir les liens sous Emacs/Gnus

La commande utilisée sous Emacs (et donc sous Gnus) pour ouvrir et afficher le contenu d'url contenues dans des documents ou des mails est à définir sous la forme d'une fonction à rattacher à la fonction browse-url-browser-function. Il existe un cetain nombre de fonctions par défaut, mais aucune pour Mozilla Firefox (en tous cas pour ma version d'Emacs, la 21.3.1). Grâce à EmacsWiki et à Google Groups, j'ai pu bricoler une fonction qui permet d'ouvrir le lien dans un nouveau tab si une instance de Firefox tourne déjà, et de lancer le navigateur sinon.

A priori ça fonctionne pour Firefox 0.9 et au-delà. Voici le code à rajouter dans votre .emacs :

(defun browse-url-firefox-new-tab (url &optional new-window)
  "Open URL in a new tab in Firefox."
  (interactive (browse-url-interactive-arg "URL: "))
  (let ((cmd (shell-command-to-string
              (concat "mozilla-firefox -a firefox -remote 'openURL("
                        url ",new-tab)' > /dev/null"))))
    (unless (string= "" cmd)
      (message "Starting Firefox...")
      (start-process (concat "firefox " url) nil "/bin/sh" "-c" 
               (concat "mozilla-firefox " url "|| true"))
      (message "Starting Firefox...done"))))
(setq browse-url-browser-function 'browse-url-firefox-new-tab)

Lire des fils RSS avec Gnus

Gnus (le lecteur de news mail et autres sous Emacs) sait tout faire, ça n'est pas nouveau. Il sait aussi lire des fils d'informations au format XML-RSS, mais la marche à suivre indiquée dans la documentation ne fonctionne pas chez moi. Celle-ci suggère de créer un nouveau groupe à l'aide des touches G R, mais chez moi ça débouche sur un message d'erreur :

No such newsgroup: nnrss:xxxxxxxxxx

Une autre méthode qui semble fonctionner est de créer le groupe dans un premier temps à l'aide de G m, de choisir un nom et indiquer nnrss comme 'From method'. Ensuite, à la première ouverture du nouveau groupe, Gnus vous demandera l'url du fichier RSS, et le tour est joué !