terça-feira, 6 de maio de 2008

Código formatado no Blogger

A minha primeira tentiva de escrita de código no Blogger foi frustrante: sem destaque de sintaxe (syntax highlight) e um editor com poucos recursos.

Vi que a marcação do texto era feita com HTML (surpresa!) e decidi fazer um script para gerar texto formatado para o Blogger. Faço a marcação do texto com web-scheme e o programa se encarrega de gerar o HTML. Depois só copio e colo o código HTML na caixa de edição do Blogger.

O programa para geração de HTML está a seguir (em Chicken Scheme). O "embelezamento" do código é feito com o programa Enscript.

(use posix utils web-scheme (srfi 1))

(define (run . cmd)
(let* ((p (open-input-pipe (sprintf "~A 2>&1" (apply conc cmd)))))
(read-all p)))

(define (run-enscript code lang #!optional pretty)
(let ((tmp (create-temporary-file)))
(with-output-to-file tmp (lambda ()
(if pretty
(pp code)
(print code))))
(let ((out (run "enscript -q --color --highlight="
lang " -o - -whtml " tmp)))
(delete-file tmp)
out)))

(define (htmlize code lang #!optional no-pre)
(let* ((out (run-enscript code lang (not (string? code))))
(lines (with-input-from-string out read-lines)))
(string-append
((if no-pre ;; pre nao quebra linhas
tt
pre)
(string-intersperse
;; retira cabecalho e rodape colocados pelo enscript
(drop-right (take-right lines (- (length lines) 11)) 5)
"\n"))
(if no-pre "\n" ""))))

(define ->
(let ((bookmarks
'((Chicken . "http://www.call-with-current-continuation.org")
(web-scheme . "http://chicken.wiki.br/web-scheme")
(eggs . "http://chicken.wiki.br/eggs"))))
(lambda (url #!optional text)
(let ((bookmarked (alist-ref url bookmarks)))
(if (and (symbol? url) bookmarked)
(a 'href bookmarked (symbol->string url))
(a 'href url (or text url)))))))

(define (p . text) ;; paragrafo do blogger
(string-append (apply conc text) "\n\n"))

(define (usage #!optional exit-code)
(print (program-name) " <input-file>")
(when exit-code (exit exit-code)))

(let ((args (command-line-arguments)))
(if (null? args)
(usage 1)
(print
(string-intersperse
(map eval (with-input-from-file (car args) read-file))))))

A função -> é especialmente interessante: admite como argumentos uma URL e um texto, somente uma URL, ou uma palavra-chave para acesso aos bookmarks.

O código fonte deste artigo inteiro é:

(p "A minha primeira tentiva de escrita de código no Blogger foi frustrante: sem destaque de sintaxe (" (i "syntax highlight") ") e um editor com poucos recursos.")

(p "Vi que a marcação do texto era feita com HTML (surpresa!) e decidi fazer um script para gerar texto formatado para o Blogger. Faço a marcação do texto com " (-> 'web-scheme) " e o programa se encarrega de gerar o HTML. Depois só copio e colo o código HTML na caixa de edição do Blogger.")

(p "O programa para geração de HTML está a seguir (em " (-> 'Chicken) " Scheme). O \"embelezamento\" do código é feito com o programa " (-> "http://www.gnu.org/software/enscript/" "Enscript") ".")

(htmlize (read-all "./bin/blog.scm") 'scheme)

(p "A função " (code "->") " é especialmente interessante: admite como argumentos uma URL e um texto, somente uma URL, ou uma palavra-chave para acesso aos " (i "bookmarks") ".")

(p "O código fonte " (b "deste artigo inteiro") " é:")

(htmlize (read-all "./call-hc/codigo-formatado-no-blogger.scm") 'scheme 'no-pre)

3 comentários:

Unknown disse...

Gostei da idéia do (-> 'palavra-chave), vou copiar ;-)

Para quem não ia postar frequentemente... :-)

Forte abraço!

ℭacilhας, ℒa ℬatalema disse...

Muuuuuito show!!!

Achei legal pacas.

[]'s
Cacilhas, La Batalema

ℭacilhας, ℒa ℬatalema disse...

Muito bom!

Gostei pacas.

[]'s
Cacilhas, La Batalema