It is common that some parts of a Skribe text represent other
texts. For instance, for a document describing a computer programming
language, it is frequent to include excerpt of programs. These
embedded texts are frequently displayed in a specific font and with no
justification but with a precise indentation. This indentation is
important because it helps in understanding the text;
it is thus desirable to preserve it in the Skribe text. The
pre text layout already enables such a
text formating. This chapter presents two new Skribe functions:
prog and source that is specially 
designed to represent computer programs in Skribe text.
A prog function call preserves the indentation of the
program. It may automatically introduce line numbers.
| prototype | 
|---|
| (prog [:ident] [:class "prog"] [:line1] [:linedigit] [:mark";!"]) | 
| ident | html latex xml | The node identifier. | 
| class | html latex xml | The node class. | 
| line | html latex xml | Enables/disables automatic line numbering. An integer
               value enables the line number and specifies the number of
               the first line of the program. A value of #fdisables
               the line numbering. | 
| linedigit | html latex xml | The number of digit for representing line
               numbers. | 
| mark | html latex xml | A string or the boolean #f. If this option 
               is a string, that string is the prefix 
               of line marks. These marks can be used in therefreference. A mark
               identifier is defined by the regular expression:[_a-zA-Z][_a-zA-Z0-9]*. The prefix and the mark are removed from the output program. | 
| sourcepreref | 
Example:
| 
| (frame :width 100. 
       (prog :line 10 :mark "##" [
SKRIBE=skribe
all: demo.html demo.man  ##main-goal
demo.html: demo.skb
        $(SKRIBE) demo.skb -o demo.html
demo.man: demo.skb
        $(SKRIBE) demo.skb -o demo.man
]))
(p [The main goal is specified line ,(ref :line "main-goal").])
                
 |  | 
Ex. 31: A program
Produces:
| 
| 
| 10: SKRIBE=skribe
11: 
12: all: demo.html demo.man  
13: 
14: demo.html: demo.skb
15: 	$(SKRIBE) demo.skb -o demo.html
16: 
17: demo.man: demo.skb
18: 	$(SKRIBE) demo.skb -o demo.man
 |  The main goal is specified line 12. |  | 
 
The source function extracts part of the source code and
enables fontification. That is, some words of the program
can be rendered using different colors or faces.
Example:
| 
| (frame :width 100. 
       (prog (source :language bigloo :file "prgm.skb" :definition 'fib)))
(p [The Fibonacci function is defined line ,(ref :line "fib").])
;!start
(frame :width 100.
       (prog :line 11 :mark #f
             (source :language skribe :file "prgm.skb" :start 11 :stop 24)))
;!stop
(p [Here is the source of the frame above:])
(frame :width 100.
       (prog :line 30 :mark #f
             (source :language skribe :file "src/prgm2.skb"
                :start ";!start"
                :stop ";!stop")))
 |  | 
Ex. 32: The source markup
Produces:
| 
| 
| 1: (define (fib x) 
2:    (if (< x 2)
3:        1
4:        (+ (fib (- x 1)) (fib (- x 2)))))
 |  The Fibonacci function is defined line 1. 
| 11: ;*---------------------------------------------------------------------*/
12: ;*    fib ...                                                          */
13: ;*---------------------------------------------------------------------*/
14: (define (fib x) ;!fib
15:    (if (< x 2)
16:        1
17:        (+ (fib (- x 1)) (fib (- x 2)))))
18: 
19: ;*---------------------------------------------------------------------*/
20: ;*    Computer programs                                                */
21: ;*---------------------------------------------------------------------*/
22: (chapter :title "Computer programs" 
23: 
 |  Here is the source of the frame above: 
| 30: (frame :width 100.
31:        (prog :line 11 :mark #f
32:              (source :language skribe :file "prgm.skb" :start 11 :stop 24)))
 |  |  | 
 
The language function builds a language that can be used
in source function call.
| prototype | 
|---|
| (language :name [:fontifier] [:extractor]) | 
| name | html latex xml | A string which denotes the name of the language. | 
| fontifier | html latex xml | A function of one argument (a string), that
               colorizes a line source code. | 
| extractor | html latex xml | A function of three arguments: an input port,
               an identifier, a tabulation size. This function scans
               in the input port the definition is looks for. | 
| progsourceref | 
Example:
| 
| (define (makefile-fontifier string)
   (with-input-from-string string
      (lambda ()
         (read/rp (regular-grammar ()
                     ((: #\# (+ all))
                      ;; makefile comment
                      (let ((cmt (the-string)))
                         (cons (it cmt) (ignore))))
                     ((bol (: (+ (out " \t\n:")) #\:))
                      ;; target
                      (let ((prompt (the-string)))
                         (cons (bold prompt) (ignore))))
                     ((bol (: (+ alpha) #\=))
                      ;; variable definitions
                      (let* ((len (- (the-length) 1))
                             (var (the-substring 0 len)))
                         (cons (list (color :fg "#bb0000" (bold var)) "=")
                               (ignore))))
                     ((+ (out " \t\n:=$"))
                      ;; plain strings
                      (let ((str (the-string)))
                         (cons str (ignore))))
                     ((: #\$ #\( (+ (out " )\n")) #\))
                      ;; variable references
                      (let ((str (the-string))
                            (var (the-substring 2 (- (the-length) 1))))
                         (cons (underline str) (ignore))))
                     ((+ (in " \t\n:"))
                      ;; separators
                      (let ((nl (the-string)))
                         (cons nl (ignore))))
                     (else
                      ;; default
                      (let ((c (the-failure)))
                         (if (eof-object? c)
                             '()
                             (skribe-error 'makefile "Unexpected char" c)))))
                  (current-input-port)))))
(define makefile
   (language :name "Makefile"
             :fontifier makefile-fontifier))
             
(frame :width 100. 
       (prog (source :language makefile [
SKRIBE=skribe
all: demo.html demo.man
demo.html: demo.skb
        $(SKRIBE) demo.skb -o demo.html
demo.man: demo.skb
        $(SKRIBE) demo.skb -o demo.man
])))
 |  | 
Ex. 33: An ad-hoc fontification
Produces:
| 
| 
|  1: SKRIBE=skribe
 2: 
 3: all: demo.html demo.man
 4: 
 5: demo.html: demo.skb
 6:         $(SKRIBE) demo.skb -o demo.html
 7: 
 8: demo.man: demo.skb
 9:         $(SKRIBE) demo.skb -o demo.man
 |  |  |