sábado, 26 de fevereiro de 2011

REPL ilustrado

O REPL (Read, Eval, Print, Loop), vulgar e erroneamente conhecido como interpretador (existem compiladores com ambiente interativo), é uma das ferramentas mais indispensáveis para programadores. É o tipo de coisa que, depois que nos acostumamos a usar, é difícil viver sem.

Abaixo está uma implementação simplificada e graficamente comentada em Chicken Scheme que ilustra o conceito:






O código acima é executável:

$ csi -s repl.scm
(define (fatorial n) (if (< n 2) 1 (* n (fatorial (- n 1)))))
#<unspecified>
(fatorial 6)
720

segunda-feira, 7 de fevereiro de 2011

Recarregando aplicações em awful através do Emacs

Abaixo está um hackzinho para recarregar aplicações em awful através do Emacs, o qual pode ser bem útil quando usando awful no modo desenvolvimento (--development-mode). No modo de desenvolvimento, awful automaticamente define o caminho /reload, o qual, quando requisitado, recarrega as aplicações.
(defun awful-reload ()
(interactive)
(shell-command "lynx -dump http://localhost:8080/reload"))

(add-hook 'scheme-mode-hook
#'(lambda ()
(local-set-key "\C-cR" 'awful-reload)))

O código acima define uma função interativa (awful-reload) que pode ser invocada no Emacs através de C-cR estando-se no modo Scheme.

O cliente HTTP pode ser qualquer um de linha de comando. O lynx serve bem a este propósito por fornecer a opção -dump, que gera a saída sem formatação, a qual pode ser exibida com facilidade no buffer do Emacs.

Abaixo está um screenshot do Emacs logo após a execução de awful-reload através de C-cR.

domingo, 6 de fevereiro de 2011

Awful 0.28 e awful-ssl

Hoje foi lançada a versão 0.28 de awful. A nova versão apresenta correções de bugs, soluções para algumas limitações e algumas novas funcionalidades.

Também foi lançada a versão inicial da extensão awful-ssl, a qual permite o uso de awful com SSL de forma fácil.

quinta-feira, 18 de novembro de 2010

accents-substitute

Seguidamente tenho a necessidade de remover acentos de textos em português. Há umas semanas fiz uma extensão para Chicken chamada accents-substitute substituir caracteres acentuados pelos correspondentes sem acento (ou com entidades de HTML).

A extensão aceita textos em Latin1 (ISO-8859-1) ou UTF-8, havendo um módulo para cada codificação, ambos provendo o mesmo procedimento: accents-substitute (nome inspirado em string-substitute, da extensão regex).

Para facilitar o uso no dia-a-dia, fiz um pequeno script que usa o procedimento {{accents-substitute}}. Abaixo estão alguns exemplos de uso:
$ accents-substitute --help
Usage: accents-substitute [ --encoding= ] [ --mode= ] [ input file ]

Default values:
mode: ascii
encoding: utf8
$ cat lisp-br
Lisp-BR é um projeto que tem por objetivo divulgar linguagens de
programação da família Lisp no Brasil e formar uma comunidade de
usuários que tenham vontade de aprender não só uma nova forma de
programar, mas também uma nova maneira de pensar!
$ cat lisp-br | accents-substitute 
Lisp-BR e um projeto que tem por objetivo divulgar linguagens de
programacao da familia Lisp no Brasil e formar uma comunidade de
usuarios que tenham vontade de aprender nao so uma nova forma de
programar, mas tambem uma nova maneira de pensar!
$ accents-substitute --mode=html lisp-br
Lisp-BR &eacute; um projeto que tem por objetivo divulgar linguagens de
programa&ccedil;&atilde;o da fam&iacute;lia Lisp no Brasil e formar uma comunidade de
usu&aacute;rios que tenham vontade de aprender n&atilde;o s&oacute; uma nova forma de
programar, mas tamb&eacute;m uma nova maneira de pensar!


O código da ferramenta de linha de comando está a seguir:
#!/bin/sh
#| -*- scheme -*-
exec csi -s $0 "$@"
|#

(use
(rename
accents-substitute-latin1
(accents-substitute accents-substitute-latin1))
(rename
accents-substitute-utf8
(accents-substitute accents-substitute-utf8)))

(use posix regex (srfi 1 13))

(define (command-line-argument option args)
;; Return the argument associated to the command line option OPTION
;; in ARGS or #f if OPTION is not found in ARGS or doesn't have any
;; argument.
(let ((val (any (cut string-match (string-append option "=(.*)") <>) args)))
(and val (cadr val))))

(define (usage #!optional exit-code)
(print "Usage: " (pathname-strip-directory (program-name))
" [ --encoding=<utf8|latin1> ] [ --mode=<ascii|html> ] [ input file ]")
(print "\nDefault values:\n"
" mode: ascii\n"
" encoding: utf8")
(when exit-code (exit exit-code)))

(let* ((args (command-line-arguments))
(mode (command-line-argument "--mode" args))
(encoding (command-line-argument "--encoding" args))
(paramless-args (remove (cut string-prefix? "--" <>) args))
(accents-substitute accents-substitute-utf8))

(when (or (member "-h" args) (member "--help" args))
(usage 0))

(when (and encoding (not (member encoding '("utf8" "latin1"))))
(print "'" encoding "' is not a valid encoding.")
(exit 1))

(when (and mode (not (member mode '("ascii" "html"))))
(print "'" mode "' is not a valid mode.")
(exit 1))

(when (equal? encoding "latin1")
(set! accents-substitute accents-substitute-latin1))

(let ((port (if (null? paramless-args)
(current-input-port)
(open-input-file (car paramless-args)))))
(let loop ()
(let ((line (read-line port)))
(unless (eof-object? line)
(print (accents-substitute line mode: (and mode (string->symbol mode))))
(loop))))
(unless (null? paramless-args)
(close-input-port port))))


Adicionei este exemplo de aplicação à seção Examples da documentação de accents-substitute.

terça-feira, 5 de outubro de 2010

Awful no Windows ("That's too awful")

Com a correção da extensão sendfile (por David Krentzlin) para Windows, awful passa a funcionar também no sistema das telas azuis.



As correções ainda não foram oficialmente lançadas (i.e., ainda não estão disponíveis para serem instaladas via chicken-install), mas podem ser obtidas em http://code.call-cc.org/svn/chicken-eggs/release/4/sendfile/trunk/ (usuário: anonymous, sem senha).

segunda-feira, 13 de setembro de 2010

Chicken 4.6.0

Foi lançada hoje a versão 4.6.0 de Chicken. O download da nova versão pode ser feito de http://code.call-cc.org. As novidades estão listadas no arquivo NEWS.

sábado, 11 de setembro de 2010

Migração de site estático para awful: tratando requisições por index.html

Até pouco tempo atrás a minha página pessoal era totalmente estática. Depois que comecei a desenvolver awful achei que seria meio vergonhoso se a minha própria página não usasse o software que produzo. Então resolvi refazê-la usando awful (eu poderia simplesmente jogar os arquivos estáticos para o servidor web disponibilizá-los, mas não teria graça).

Um problema que ocorreu na migração do site estático para o com use de awful foi a ausência de arquivos index.html. Várias páginas eram disponibilizadas e referenciadas através um arquivo index.html, e esses arquivos não existem mais na nova estrutura com awful. A solução que adotei foi redirecionar os acessos aos arquivos index.html para o nome do "diretório" que os contém (na verdade não são diretórios, mas URIs associadas a procedimentos em Scheme).

Por exemplo, antes havia http://parenteses.org/mario/index.html. Hoje há um procedimento associado a http://parenteses.org/mario.

Com a possibilidade de associar procedimentos a URIs que casa com uma expressão regular, fazer com que http://parenteses.org/mario responda por http://parenteses.org/mario/index.html se torna bem fácil:
(use awful)

(define-page (regexp "/mario/.*index.html")
(lambda (path)
(redirect-to (string-chomp path "index.html"))))

Assim, todas as requisições por recursos /index.html disponíveis no caminho /mario/ serão redirecionadas para /.