Emacs i formatowanie kodów źródłowych
Ten blog jest częściowo techniczny; blog anglojęzyczny jest techniczny praktycznie całkowicie. Często (częstawo?) potrzebuję wklejać w tekst (edytowany jedynie słusznym edytorem w jedynie słusznym języku znaczników) fragmenty kodu źródłowego. Jest parę rozwiązań, które mogę zastosować na blogaskach; oczywiście wszystkie kiepskie.
Można przeładować HTML-owy tag <pre>, za pomocą JavaScriptu albo pług-inów systemu blogowego. Drugie rozwiązanie może ma jakiś sens na Wordpressie, ale na Joggasku jest niemożliwe; JavaScript—fajnie, w większości przypadków działa, ale oskryptowywać się dla takiej pierdółki? HTML i CSS są całkowicie zdolne do pokazania ładnie sformatowanego i pokolorowanego kodu, bez uciekania się do pomocy skryptów. No i żaden skrypt w pehapie czy żawaskrypcie nie pokoloruje mi składni tak ładnie jak mój Emacs ;)
Emacs, z dodatkiem htmlize.el, potrafi zakodować bufor lub jego fragment do postaci pliku HTML, z zachowaniem kolorowania. Jeśli ustawimy zmienną htmlize-output-type na 'inline-css, to generowany jest HTML zdatny do przeklejenia prosto do pisanego kodu, ze stylami w formie <span style="…">. Dwa problemy: generowany jest cały HTML (z nagłówkiem itd), a kolor tła jest ustawiany w tagu body, a nie pre, co powoduje, że trzeba go przekleić. Zwykle robiłem to ręcznie, ale potrzebując przegenerować wszystkie przykłady potrzebne w drugiej części tutoriala Yaclml, wymiękłem.
Po pewnym czasie…
(require 'htmlize) (defun jph/strip-htmlized-buffer () "Strip htmlized buffer to <pre> tag, copying style attribute from <body> to <pre>." (interactive) (goto-char (point-min)) (re-search-forward "<body\\( style=[^>]*\\)>") (let ((style (match-string 1))) (search-forward "<pre") (insert style) (delete-region (point-min) (line-beginning-position)) (search-forward "</pre>") (delete-region (point) (point-max)) (insert "\n"))) (defun jph/htmlize-fragment (prefix) "Replace fragment of current buffer with htmlized file. Text between comments <!-- htmlize filename --> and <!-- end htmlize --> gets replaced with htmlized file `filename' (only the <pre> tag). If a negative prefix is given, text between comments is removed. Only one pair of comments is processed (nearest one forward from current point position). " (interactive "p") (when (search-forward "<!-- htmlize " nil t) (let ((source-file (thing-at-point 'filename))) (beginning-of-line 2) (let ((start (point))) (search-forward "<!-- end htmlize ") (beginning-of-line) (delete-region start (point))) (when (>= prefix 0) ; '-' prefix prevents inserting the htmlized text (insert (with-current-buffer (find-file-noselect source-file) (with-current-buffer (htmlize-buffer) (jph/strip-htmlized-buffer) (prog1 (buffer-string) (kill-buffer))))))) t)) (defun jph/htmlize-all-fragments (prefix) "Replace all indicated fragments of current buffer with htmlized files. All pair of <!-- htmlize filename --> and <!-- end htmlize --> comments are processed with `jph/htmlize-fragment'. If negative prefix is given, inside of all such comment pairs is deleted." (interactive "p") (goto-char (point-min)) (while (jph/htmlize-fragment prefix)))
Powyższą wklejkę wpisałem w swój kod tak:
<!-- htmlize htmlize-fragments.el --> <!-- end htmlize -->
Następnie wywołałem magiczne zaklęcie M-x jph/htmlize-all-fragments—i gotowe. Z ujemnym prefiksem (M-- M-x jph/htmlize-all-fragments) kod spomiędzy magicznych komentarzy jest kasowany (jeśli np. edytujemy tekst, a wielkie <pre> przetykane <span>-ami nas rozpraszają). Kod jest do przeklejenia stąd, albo do ściągnięcia pod adresem http://gist.github.com/285335. Smacznego!
