Changeset 12750 in project


Ignore:
Timestamp:
12/03/08 23:21:59 (12 years ago)
Author:
azul
Message:

Lots of fixes. Start including the code.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • wiki/svnwiki-chicken

    r12749 r12750  
     1[[toc:]]
     2
     3== Introduction
     4
     5The svnwiki-chicken egg extends [[http://wiki.freaks-unidos.net/svnwiki|Svnwiki]] to provide
     6functionality useful for repositories of Scheme code and documentation about Scheme code
     7such as [[.|The Chicken Wiki]].
     8
     9== Preamble
     10
     11<enscript highlight=scheme filename='svnwiki-chicken'>
    112; $id$
    213;
    3 ; License: GPL-3
    4 
     14; Copyright 2008 Alejandro Forero Cuervo <azul@freaks-unidos.net>
     15; All Rights Reserved
     16;
     17; This code is available under the GPLv3 license.
     18;
     19; The authoritative source for this program, where new versions may be
     20; available, is:
     21;
     22;   http://chicken.wiki.br/svnwiki-chicken
     23</enscript>
     24
     25This egg does not export any symbols:
     26
     27<enscript highlight=scheme filename='svnwiki-chicken'>
    528(declare (export))
     29</enscript>
     30
     31== Dependencies
     32
     33<enscript highlight=scheme filename='svnwiki-chicken'>
    634(use svnwiki-extensions-support svn-post-commit-hooks orders format-modular srfi-40 html-stream stream-ext embedded-test sqlite3 stream-wiki)
    7 
     35</enscript>
     36
     37== chickenegg
     38
     39We define a {{chickenegg}} tag, used by the eggs post-commit functionality when building the [[Eggs Unlimited]] wiki pages.
     40The {{chickenegg}} tag expects a set of parameters describing an egg and expands to an HTML row presenting it.
     41
     42<enscript highlight=scheme filename='svnwiki-chicken'>
    843(define *url-eggs*
    944  "http://www.call-with-current-continuation.org/eggs/")
    1045
    11 (define (chicken-egg-html env)
    12   (let-from-environment env (params parse path-in)
     46(define (chickenegg-html env)
     47  (let-from-environment env (params parse path-in output-format)
    1348    (or
    14       (and-let* ((name-stream (assoc 'name params))
     49      (and-let* ((eq? output-format 'html)
     50                 (name-stream (assoc 'name params))
    1551                 (name (stream->string (cdr name-stream)))
    1652                 (description (assoc 'description params))
    1753                 (license (assoc 'license params))
    1854                 (author (assoc 'author params))
    19                  (major (assoc 'major params))
    20                  )
     55                 (major (assoc 'major params)))
    2156        (parse
    22           (html-stream 
    23             (tr (td (if (file-exists? (svnwiki-make-pathname path-in name))
     57          (html-stream
     58            (tr (td (if (file-exists? (svnwiki-repository-path env name)))
    2459                      (format #f "[[~A]]" name)
    25                       (if major 
     60                      (if major
    2661                          (format #f "[[~A~A/~A.html|~A]]" *url-eggs* (stream->string (cdr major)) name name)
    2762                          (format #f "[[~A~A.html|~A]]" *url-eggs* name name))))
     
    3267      stream-null)))
    3368
     69(svnwiki-extension-define 'code-break 'chickenegg chickenegg-html)
     70</enscript>
     71
     72It should be noted that the Eggs Unlimited pages should not be commited to the
     73wiki (they are automatically generated), but that's what we have right now.
     74
     75== Definitions
     76
     77We define some markup for definitions documented in a wiki page.
     78The basic usage would be this:
     79
     80 <nowiki><procedure>(string-append a b ...)</procedure></nowiki>
     81
     82First we define a function that, given the text inside a definition
     83(eg. “{{(string-append a b ...)}}”),
     84evaluates whether it is a proper list:
     85
     86<enscript highlight=scheme filename='svnwiki-chicken'>
     87(define (definition-list? text)
     88  (and (not (stream-null? text))
     89       (char=? (stream-car text) #\()
     90       (char=? (stream-last text) #\))
     91       (not (char=? #\) (stream-car
     92                          (stream-drop-while
     93                            char-whitespace?
     94                            (stream-cdr text)))))))
     95</enscript>
     96
     97<examples filename='svnwiki-chicken' testgroup='definition-list?'>
     98
     99<example>
     100<expr>(definition-list? (string->stream "(foo)"))</expr>
     101<result>#t</result>
     102</example>
     103
     104<example>
     105<expr>(definition-list? (string->stream "(foo bar)"))</expr>
     106<result>#t</result>
     107</example>
     108
     109<example>
     110<expr>(definition-list? (string->stream "foo"))</expr>
     111<result>#f</result>
     112</example>
     113
     114<example>
     115<expr>(definition-list? (string->stream "(  )"))</expr>
     116<result>#f</result>
     117</example>
     118
     119<example>
     120<expr>(definition-list? (string->stream ""))</expr>
     121<result>#f</result>
     122</example>
     123
     124</examples>
     125
     126Based on that, we define a function that, given the text inside a definition,
     127returns the symbol being defined:
     128
     129<enscript highlight=scheme filename='svnwiki-chicken'>
     130(define (get-definition-name text)
     131  (stream-take-while
     132    (disjoin (complement char-whitespace?)
     133             (cut char=? <> #\))
     134    (if (definition-list? text)
     135      (stream-cdr (stream-butlast text))
     136      text)))
     137</enscript>
     138
     139<examples filename='svnwiki-chicken' testgroup='get-definition-name'>
     140
     141<example>
     142<expr>(stream->string (get-definition-name (string->stream "foo")))</expr>
     143<result>"foo"</result>
     144</example>
     145
     146<example>
     147<expr>(stream->string (get-definition-name (string->stream "(foo)")))</expr>
     148<result>"foo"</result>
     149</example>
     150
     151<example>
     152<expr>(stream->string (get-definition-name (string->stream "(foo bar)")))</expr>
     153<result>"foo"</result>
     154</example>
     155
     156<example>
     157<expr>(stream->string (get-definition-name (string->stream "(stream= proc str str ...)")))</expr>
     158<result>"stream="</result>
     159</example>
     160
     161</examples>
     162
     163With all that in place, we create a procedure to handle the definitions.  It will be
     164instantiated several types with {{type}} set to the type of definition (eg. “{{procedure}}”).
     165
     166If the output format is the {{scheme-definitions}}, it returns the name and type of the
     167definition.  Otherwise, it returns a nice view of the definition.
     168
     169<enscript highlight=scheme filename='svnwiki-chicken'>
     170(define (chicken-def type env)
     171  (let-from-environment env (path text parse output-format)
     172    ; Remove whitespace at beginning or end
     173    (let ((text (stream-reverse
     174                  (stream-drop-while
     175                    char-whitespace?
     176                    (stream-reverse
     177                      (stream-drop-while
     178                        char-whitespace?
     179                        text))))))
     180      (case output-format
     181        ((scheme-definitions)
     182          (let-from-environment env (return)
     183            (return (list type (get-definition-name text))))
     184          stream-null)
     185        (else
     186          (parse
     187            (html-stream
     188              ((a name (format #f "xsvnwiki-scheme-~A" (stream->string (get-definition-name text))))
     189               "["
     190               type
     191               "] {{"
     192               (if (definition-list? text)
     193                 (receive (name rest)
     194                          (stream-break char-whitespace?
     195                                        (stream-cdr (stream-butlast text)))
     196                   (html-stream
     197                     "('''" name "'''" rest ")"))
     198                 text)
     199               "}}\n\n"))))))))
     200</enscript>
     201
     202Now the actual instantiations, for all the types of definitions we support:
     203
     204<enscript highlight=scheme filename='svnwiki-chicken'>
     205(for-each
     206  (lambda (type)
     207    (svnwiki-extension-define
     208      'code-span
     209      type
     210      (cut chicken-def (symbol->string type) <>)))
     211  '(procedure macro read parameter record string class method integer constant))
     212</enscript>
     213
     214== Database
     215
     216=== Definition
     217
     218We will keep a database as a cache for interesting information found in the wiki.
     219
     220The {{definitions}} table will be used for a list of symbols documented in wiki pages.
     221It has the following attributes:
     222
     223; name : The name of a symbol.
     224
     225; type : The type of definition, such as “procedure”, “string”, etc..  The actual list of types will be defined elsewhere.
     226
     227; page : The path to the page on which it is defined.
     228
     229The {{tests}} table has a list of tests found in the wiki, with the following attributes:
     230
     231; expr : The Scheme expression that should be evaluated (eg. “{{(string-append "foo" "bar")}}”).
     232
     233; expect : Another Scheme expression which should evaluate to the expected value (eg. “{{"foobar"}}”).
     234
     235; cmp : If provided, a Scheme expresion that should evaluate to a procedure of 2 arguments that is used to compare the values that {{expr}} and {{expect}} evaluated to.  If empty, {{equal?}} should be used.
     236
     237; page : The page in the wiki in which the test was found.
     238
     239; blessed : This will be set to false (the empty string) by default.  Once the admin approves a test, he should set it to true (the string "true").
     240
     241The {{tests_results}} table contains results for the tests.
     242
     243<enscript highlight=scheme filename='svnwiki-chicken'>
     244(define (scheme-definitions-db-create env)
     245  (db-run env "CREATE TABLE definitions ( name varchar, type varchar, page varchar );")
     246  (db-run env "CREATE TABLE tests ( expr varchar, expect varchar, cmp varchar, page varchar, blessed boolean );")
     247  (db-run env "CREATE TABLE tests_results ( version varchar, received varchar, pass boolean, date integer );"))
     248</enscript>
     249
     250=== Usage
     251
     252Now some support functions for using the database:
     253
     254<enscript highlight=scheme filename='svnwiki-chicken'>
    34255(define *db* #f)
    35256(define *max-retries* 8)
     
    69290             (else
    70291              (signal e))))))))
    71 
    72 (define (scheme-definitions-db-create env)
    73   (db-run env "CREATE TABLE definitions ( name varchar, type varchar, page varchar );")
    74   (db-run env "CREATE TABLE tests ( expr varchar, expect varchar, cmp varchar, page varchar, blessed varchar );")
    75   (db-run env "CREATE TABLE tests_results ( version varchar, received varchar, pass boolean, date integer );"))
    76 
    77 (test-group definition-list?
    78   (test (definition-list? (string->stream "(foo bar)")))
    79   (test (not (definition-list? (string->stream "foo"))))
    80   (test (not (definition-list? (string->stream "")))))
    81 
    82 (define (definition-list? text)
    83   (and (not (stream-null? text))
    84        (char=? (stream-car text) #\()
    85        (char=? (stream-last text) #\))))
    86 
    87 (test-group get-definition-name
    88   (test (stream->string (get-definition-name (string->stream "(foo bar)")))
    89         "foo")
    90   (test (stream->string (get-definition-name (string->stream "bar")))
    91         "bar"))
    92 
    93 (define (get-definition-name text)
    94   (stream-take-while
    95     (complement char-whitespace?)
    96     (if (definition-list? text)
    97       (stream-cdr (stream-butlast text))
    98       text)))
    99 
    100 (define (chicken-def name env)
    101   (let-from-environment env (path text parse output-format)
    102     ; Remove whitespace at beginning or end
    103     (let ((text (stream-reverse
    104                   (stream-drop-while
    105                     char-whitespace?
    106                     (stream-reverse
    107                       (stream-drop-while
    108                         char-whitespace?
    109                         text))))))
    110       (case output-format
    111         ((scheme-definitions)
    112           (let-from-environment env (return)
    113             (return (list name (get-definition-name text))))
    114           stream-null)
    115         (else
    116           (parse
    117             (html-stream
    118               ((a name (format #f "xsvnwiki-scheme-~A" (stream->string (get-definition-name text))))
    119                "["
    120                name
    121                "] {{"
    122                (if (definition-list? text)
    123                  (receive (name rest)
    124                           (stream-break char-whitespace?
    125                                         (stream-cdr (stream-butlast text)))
    126                    (html-stream
    127                      "('''" name "'''" rest ")"))
    128                  text)
    129                "}}\n\n"))))))))
    130 
     292</enscript>
     293
     294== Examples and tests
     295
     296TODO: Document.
     297
     298<enscript highlight=scheme filename='svnwiki-chicken'>
    131299(define (chicken-examples env)
    132300  (let-from-environment env (params parse text output-format)
     
    188356      stream-null)))
    189357
     358(define (redirect-scheme env)
     359  (let-from-environment env (path return)
     360    (unless (file-exists? (svnwiki-repository-path env))
     361      (let ((targets (db-run env "SELECT page FROM definitions WHERE name = ?;" path)))
     362        (unless (stream-null? targets)
     363          (return
     364            (format #f "~A#xsvnwiki-scheme-~A"
     365                    (vector-ref (stream-car targets) 0)
     366                    path)))))))
     367
     368(svnwiki-extension-define 'redirect 'scheme-definitions redirect-scheme)
     369
     370(svnwiki-extension-define 'code-span 'examples chicken-examples)
     371(svnwiki-extension-define 'code-span 'example chicken-example)
     372; For the time being, we just ignore these:
     373(svnwiki-extension-define 'code-span 'init (lambda (env) stream-null))
     374(svnwiki-extension-define 'code-span 'expr chicken-expr)
     375(svnwiki-extension-define 'code-span 'result (cut chicken-result #t "=>" <>))
     376(svnwiki-extension-define 'code-span 'resultcmp chicken-result-cmp)
     377(svnwiki-extension-define 'code-span 'input (cut chicken-result #f "[input]" <>))
     378(svnwiki-extension-define 'code-span 'output (cut chicken-result #f "[output]" <>))
     379</enscript>
     380
     381== Update notify
     382
     383TODO: Get the list of tests and store it in the database.
     384
     385<enscript highlight=scheme filename='svnwiki-chicken'>
    190386(define (update-notify-scheme env)
    191387  (let-from-environment env (path-in path)
     
    207403            (environment-capture env (return))))))))
    208404
    209 (define (redirect-scheme env)
    210   (let-from-environment env (path return)
    211     (unless (file-exists? (svnwiki-repository-path env))
    212       (let ((targets (db-run env "SELECT page FROM definitions WHERE name = ?;" path)))
    213         (unless (stream-null? targets)
    214           (return
    215             (format #f "~A#xsvnwiki-scheme-~A"
    216                     (vector-ref (stream-car targets) 0)
    217                     path)))))))
    218 
    219 (svnwiki-extension-define 'redirect 'scheme-definitions redirect-scheme)
    220405(svnwiki-extension-define 'update-notify-recursive 'scheme-definitions update-notify-scheme)
    221 
    222 (svnwiki-extension-define 'code-break 'chickenegg chicken-egg-html)
    223 
    224 (svnwiki-extension-define 'code-span 'procedure (cut chicken-def "procedure" <>))
    225 (svnwiki-extension-define 'code-span 'macro (cut chicken-def "macro" <>))
    226 (svnwiki-extension-define 'code-span 'read (cut chicken-def "read" <>))
    227 (svnwiki-extension-define 'code-span 'parameter (cut chicken-def "parameter" <>))
    228 (svnwiki-extension-define 'code-span 'record (cut chicken-def "record" <>))
    229 (svnwiki-extension-define 'code-span 'string (cut chicken-def "string" <>))
    230 (svnwiki-extension-define 'code-span 'class (cut chicken-def "class" <>))
    231 (svnwiki-extension-define 'code-span 'method (cut chicken-def "method" <>))
    232 (svnwiki-extension-define 'code-span 'integer (cut chicken-def "integer" <>))
    233 (svnwiki-extension-define 'code-span 'constant (cut chicken-def "constant" <>))
    234 (svnwiki-extension-define 'code-span 'examples chicken-examples)
    235 (svnwiki-extension-define 'code-span 'example chicken-example)
    236 ; For the time being, we just ignore these:
    237 (svnwiki-extension-define 'code-span 'init (lambda (env) stream-null))
    238 (svnwiki-extension-define 'code-span 'expr chicken-expr)
    239 (svnwiki-extension-define 'code-span 'result (cut chicken-result #t "=>" <>))
    240 (svnwiki-extension-define 'code-span 'resultcmp chicken-result-cmp)
    241 (svnwiki-extension-define 'code-span 'input (cut chicken-result #f "[input]" <>))
    242 (svnwiki-extension-define 'code-span 'output (cut chicken-result #f "[output]" <>))
     406</enscript>
     407
     408== Version history
     409
     410; 1.0 : First public release.
Note: See TracChangeset for help on using the changeset viewer.