This chapter presents fontification functions, that is
functions that can be used in prgm environment to
colorize computer program texts. For the sake of the example, all
along this chapter we will a function for fontifiying Shell scripts.
We will call this function shell. This fontification scheme
will be very simple. Prompts, that is string of characters start at
the beginning of a line and ending with a ">" character
will be rendered in a bold font. Shell comments, that is strings
of characters starting with a "#" ending with the end of line
are displayed using an italic face. Shell results, that is lines not
starting by a prompt, are displayed in red. For instance:
redrock:.../project/scribe> ls
apache/ examples/ Makefile.tpl scribeapi/ scribeman/
autoconf/ INSTALL manuals/ scribecgi/ scribetex/
bin/ lib/ old/ scribehtml/ scribetext/
configure* Makefile README scribehtmlgui/ work/
emacs/ Makefile.scrconfig scribe/ scribeinfo/
redrock:.../project/scribe> ls -ld a* # Only files starting with an a
drwxr-x--- 2 serrano serrano 280 Dec 4 10:03 apache/
drwxr-x--- 2 serrano serrano 184 Nov 22 2000 autoconf/ |
A fontification function is a function accepting one parameter.
This formal parameter is bound to a string representing the text to
be fontified. It is to the responsibility of the fontification function
to process any computation on this string. The result of the
fontification will be included in the target file. That is, the fontification
function takes a string and returns a Scribe expression representing
the fontified program.
The definition of the shell fontification is:
(define (shell obj)
(parse-shell (open-input-string obj))) |
In order to implement the fontification we are using Bigloo
regular parser. This mechanism enables a lexical analysis of string of
characters. (See Bigloo for a documentation
on lexical analysis in Scheme.)
(define (parse-shell port::input-port)
(let ((g (regular-grammar ()
((bol (: (+ (out #\space #\Newline #\>)) #\>))
;; shell prompt
(let ((prompt (the-string)))
(cons (bold prompt) (ignore))))
((bol (+ (out #\>)))
;; answer line
(let ((anw (the-string)))
(cons (color :fg "#ff0000" anw) (ignore))))
((: #\# (+ all))
;; shell comment
(let ((cmt (the-string)))
(cons (it cmt) (ignore))))
((+ (out #\> #\# #\Newline))
;; plain strings
(let ((str (the-string)))
(cons str (ignore))))
((+ #\Newline)
;; new lines
(let ((nl (the-string)))
(cons nl (ignore))))
(else
;; default
(let ((c (the-failure)))
(if (eof-object? c)
'()
(error "prgm(shell)" "Unexpected character" c)))))))
(read/rp g port))) |