Copied the web directory to work on it locally.
This commit is contained in:
parent
1736e367ef
commit
66c53fbd5c
47
new-racket-web/web/README
Normal file
47
new-racket-web/web/README
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
Sources:
|
||||||
|
========
|
||||||
|
|
||||||
|
* common: specific code for the racket web pages.
|
||||||
|
|
||||||
|
* www: actual content of main site.
|
||||||
|
|
||||||
|
* download: content of download site (only installer pages and such)
|
||||||
|
|
||||||
|
* */all.rkt: files that just require all the necessary modules to build
|
||||||
|
the whole site or sub-sites
|
||||||
|
|
||||||
|
* */resources.rkt: files that define the resources for a site (icon,
|
||||||
|
css, logo)
|
||||||
|
|
||||||
|
* minis: smaller one-source-file sites
|
||||||
|
|
||||||
|
* stubs: template "sites" that are intended to be hooked into other
|
||||||
|
systems to get the racket look.
|
||||||
|
|
||||||
|
To build:
|
||||||
|
=========
|
||||||
|
|
||||||
|
* Run `build.rkt' as the main entry point to building the web pages.
|
||||||
|
(Use `-h' as usual.)
|
||||||
|
|
||||||
|
* You need to choose `-w' or `-l' for a web or local mode respectively.
|
||||||
|
The difference is that in local mode inter-site links are set up as
|
||||||
|
relative links so you can see all sites from the resulting
|
||||||
|
directories, and this is what you usually need to test things out.
|
||||||
|
(You will still need to deal with an occasional addition of
|
||||||
|
"index.html" which is not done when looking at file:// URLs.)
|
||||||
|
|
||||||
|
* Use `-o <dir>' to specify a directory where the built contents is
|
||||||
|
placed, otherwise the content will be placed in the current directory.
|
||||||
|
(Use `-f' in scripts to avoid answering the question about deleting
|
||||||
|
existing files.)
|
||||||
|
|
||||||
|
* If you're not running from a git repository, you will also need to set
|
||||||
|
a $GIT_DIR environment variable otherwise the resulting build will not
|
||||||
|
have release information for the various builds. (This doesn't matter
|
||||||
|
if you're not working on download pages.)
|
||||||
|
|
||||||
|
* You can also include more files that hook additional contents with
|
||||||
|
with `-e <some-file>'. These files are required dynamically, and they
|
||||||
|
set things up to add more content building. The common example here
|
||||||
|
is "web/all.rkt" in iplt.
|
5
new-racket-web/web/all.rkt
Normal file
5
new-racket-web/web/all.rkt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "www/all.rkt" "download/all.rkt" "minis/all.rkt" "stubs/all.rkt")
|
||||||
|
(set-navbar! (list main download documentation planet community learning)
|
||||||
|
main help)
|
83
new-racket-web/web/build.rkt
Executable file
83
new-racket-web/web/build.rkt
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#| -*- scheme -*-
|
||||||
|
exe="racket";
|
||||||
|
if [ -x "$PLTHOME/bin/racket" ]; then exe="$PLTHOME/bin/racket"; fi
|
||||||
|
exec "$exe" "$0" "$@"
|
||||||
|
|#
|
||||||
|
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require racket/cmdline racket/runtime-path racket/file scribble/html
|
||||||
|
"common/distribute.rkt" "config.rkt" "all.rkt")
|
||||||
|
|
||||||
|
(define build-mode #f)
|
||||||
|
(define output-dir (current-directory))
|
||||||
|
(define distribute? #f)
|
||||||
|
(define warn? #t)
|
||||||
|
(define extra-files '())
|
||||||
|
|
||||||
|
(command-line
|
||||||
|
#:once-any
|
||||||
|
[("-l" "--local")
|
||||||
|
"local mode: create content that is viewable in the build directory"
|
||||||
|
" (all links are relative) "
|
||||||
|
(set! build-mode 'local)]
|
||||||
|
[("-w" "--web")
|
||||||
|
"web mode: create content that is viewable on the Racket web pages"
|
||||||
|
(set! build-mode 'web)]
|
||||||
|
#:once-each
|
||||||
|
[("-o" "--output") dir
|
||||||
|
"output directory"
|
||||||
|
" (defaults to the current directory)"
|
||||||
|
(unless (directory-exists? dir)
|
||||||
|
(printf "Creating \"~a\"\n" dir) (make-directory dir))
|
||||||
|
(set! output-dir dir)]
|
||||||
|
[("-f" "--force")
|
||||||
|
"avoid warning about directory cleanup"
|
||||||
|
(set! warn? #f)]
|
||||||
|
[("-d" "--dist")
|
||||||
|
"distribute resulting content"
|
||||||
|
" (will only work with the right access to the servers)"
|
||||||
|
(set! distribute? #t)]
|
||||||
|
#:multi
|
||||||
|
[("-e" "--extra") extra
|
||||||
|
"extra file to render more content"
|
||||||
|
(set! extra-files (cons extra extra-files))]
|
||||||
|
#:help-labels
|
||||||
|
" ** Note: set $KNOWN_MIRRORS_FILE to a file if you want to poll mirror"
|
||||||
|
" links (see top comment in \"download/mirror-link.rkt\").")
|
||||||
|
|
||||||
|
(unless build-mode (raise-user-error 'build "build mode not specified"))
|
||||||
|
|
||||||
|
(define-runtime-path here ".")
|
||||||
|
(let ([build (file-or-directory-identity output-dir)])
|
||||||
|
(let loop ([dir here])
|
||||||
|
(if (equal? build (file-or-directory-identity dir))
|
||||||
|
(raise-user-error 'build
|
||||||
|
"might clobber sources, refusing to build (use `-o')")
|
||||||
|
(let-values ([(base name dir?) (split-path dir)])
|
||||||
|
(when base (loop base))))))
|
||||||
|
|
||||||
|
(parameterize ([current-directory output-dir])
|
||||||
|
(define paths (sort (map path->string (directory-list)) string<?))
|
||||||
|
(when (pair? paths)
|
||||||
|
(if (or (not warn?)
|
||||||
|
(begin (printf "Directory not empty, these will be deleted: ~a.\n"
|
||||||
|
(string-join paths ", "))
|
||||||
|
(printf "Continue? ") (flush-output)
|
||||||
|
(regexp-match? #rx" *[yY]" (read-line))))
|
||||||
|
(for-each delete-directory/files paths)
|
||||||
|
(raise-user-error 'build "Aborting."))))
|
||||||
|
|
||||||
|
(printf "Building ~a content...\n" build-mode)
|
||||||
|
(parameterize ([url-roots (and (eq? 'web build-mode) sites)])
|
||||||
|
(for ([extra (in-list extra-files)])
|
||||||
|
(if (file-exists? extra)
|
||||||
|
(dynamic-require `(file ,extra) #f)
|
||||||
|
(printf " ignoring missing extra file: ~a\n" extra)))
|
||||||
|
(parameterize ([current-directory output-dir])
|
||||||
|
(render-all)
|
||||||
|
(when distribute?
|
||||||
|
(printf "Distributing...\n")
|
||||||
|
(distribute (distributions)))))
|
||||||
|
(printf "Done.\n")
|
29
new-racket-web/web/common/distribute.rkt
Normal file
29
new-racket-web/web/common/distribute.rkt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require racket/system racket/list racket/promise)
|
||||||
|
|
||||||
|
(define rsync-exe (lazy (or (find-executable-path "rsync")
|
||||||
|
(error 'distribute "couldn't find `rsync'"))))
|
||||||
|
|
||||||
|
(define (rsync . args)
|
||||||
|
(unless (apply system* (force rsync-exe) args)
|
||||||
|
(error 'distribute "errors when running: rsync with ~s" args)))
|
||||||
|
|
||||||
|
(define (flatten-path path)
|
||||||
|
(define m (regexp-match #rx"^(.*?)/\\*(/.*|$)$" path))
|
||||||
|
(if m
|
||||||
|
(append-map
|
||||||
|
flatten-path
|
||||||
|
(sort (map (λ(p) (string-append
|
||||||
|
(cadr m) "/" (path-element->string p) (caddr m)))
|
||||||
|
(directory-list (cadr m)))
|
||||||
|
string<?))
|
||||||
|
(list path)))
|
||||||
|
|
||||||
|
(provide distribute)
|
||||||
|
;; see "../config.rkt" for a description of the specs
|
||||||
|
(define (distribute specs)
|
||||||
|
(for ([s (in-list specs)])
|
||||||
|
(let ([srcs (append-map flatten-path (cdr s))] [tgt (car s)])
|
||||||
|
(printf " to ~a\n" tgt)
|
||||||
|
(apply rsync "-aqz" "-e" "ssh" "--delete" `(,@srcs ,tgt)))))
|
132
new-racket-web/web/common/extras.rkt
Normal file
132
new-racket-web/web/common/extras.rkt
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#lang at-exp racket/base
|
||||||
|
|
||||||
|
(require scribble/html)
|
||||||
|
|
||||||
|
;; list of a header paragraphs and sub paragraphs (don't use `p' since it looks
|
||||||
|
;; like they should not be nested)
|
||||||
|
(provide parlist)
|
||||||
|
(define (parlist first . rest)
|
||||||
|
(list (div class: 'parlisttitle first)
|
||||||
|
(map (λ (p) (div class: 'parlistitem p)) rest)))
|
||||||
|
|
||||||
|
;; a div that is centered, but the text is still left-justified
|
||||||
|
(provide center-div)
|
||||||
|
(define (center-div . text)
|
||||||
|
(let-values ([(attrs body) (split-attributes+body text)])
|
||||||
|
(apply div align: 'center
|
||||||
|
(append attrs
|
||||||
|
(list (div align: 'left style: "display: inline-block;"
|
||||||
|
body))))))
|
||||||
|
|
||||||
|
;; a grayish tt text
|
||||||
|
(provide TT)
|
||||||
|
(define (TT . xs)
|
||||||
|
@tt[style: "background-color: #d8d8e8;"]{@xs})
|
||||||
|
(provide PRE)
|
||||||
|
(define (PRE . xs)
|
||||||
|
@pre[style: "background-color: #d8d8e8;"]{@xs})
|
||||||
|
|
||||||
|
;; some tags with convenient separators
|
||||||
|
(provide make-separated-tag (rename-out [the-separator ~])
|
||||||
|
p* ul* ol* dl*)
|
||||||
|
(struct separator ())
|
||||||
|
(define the-separator (separator))
|
||||||
|
(define (split-list-by-separator list)
|
||||||
|
;; The idea is to drop all whitespace around the separator, and then drop the
|
||||||
|
;; common leading all-space prefixes in each chunk, so the separators are
|
||||||
|
;; effectively ignored for indentation in the output. This is too much for
|
||||||
|
;; html output (leaving the whitespaces in what this is used for is
|
||||||
|
;; harmless), but it might be useful for some future application.
|
||||||
|
(define (drop-ws list left?)
|
||||||
|
(if (and (pair? list) (string? (car list)))
|
||||||
|
(let ([str (regexp-replace (if left? #rx"^[ \t\r\n]+" #rx"[ \t\r\n]+$")
|
||||||
|
(car list) "")])
|
||||||
|
(if (equal? "" str) (drop-ws (cdr list) left?) (cons str (cdr list))))
|
||||||
|
list))
|
||||||
|
(define (drop-indentation/reverse orig-text)
|
||||||
|
(define N #f)
|
||||||
|
(if (null? orig-text)
|
||||||
|
orig-text
|
||||||
|
(let loop ([text orig-text] [r '()])
|
||||||
|
(cond [(null? (cdr text))
|
||||||
|
(if N (cons (car text) r) (reverse orig-text))]
|
||||||
|
[(not (equal? "\n" (cadr text)))
|
||||||
|
(loop (cdr text) (cons (car text) r))]
|
||||||
|
[(not (and (string? (car text))
|
||||||
|
(regexp-match? #rx"^ +$" (car text))))
|
||||||
|
(reverse orig-text)]
|
||||||
|
[else (let ([len (string-length (cadr text))])
|
||||||
|
(set! N (if N (min len N) len))
|
||||||
|
(loop (cddr text)
|
||||||
|
(list* (λ () (make-string (- len N) #\space))
|
||||||
|
"\n" r)))]))))
|
||||||
|
(let loop ([list (drop-ws list #t)] [cur '()] [r '()])
|
||||||
|
(define (get-r) (cons (drop-indentation/reverse (drop-ws cur #f)) r))
|
||||||
|
(cond [(null? list) (reverse (get-r))]
|
||||||
|
[(separator? (car list)) (loop (drop-ws (cdr list) #t) '() (get-r))]
|
||||||
|
[else (loop (cdr list) (cons (car list) cur) r)])))
|
||||||
|
(define ((make-separated-tag wrapper #:newlines? [nls? #t] . tags) . body)
|
||||||
|
(let* ([chunks (split-list-by-separator body)]
|
||||||
|
[chunks (if (null? (car chunks)) (cdr chunks) chunks)]
|
||||||
|
[body (for/list ([text (in-list chunks)]
|
||||||
|
[tag (in-cycle (in-list tags))])
|
||||||
|
(apply tag text))]
|
||||||
|
[body (if nls? (add-newlines body) body)])
|
||||||
|
(wrapper body)))
|
||||||
|
(define p* (make-separated-tag values p))
|
||||||
|
(define ul* (make-separated-tag ul li))
|
||||||
|
(define ol* (make-separated-tag ol li))
|
||||||
|
(define dl* (make-separated-tag dl dt dd))
|
||||||
|
|
||||||
|
;; conditional display on screen or print
|
||||||
|
(provide printonly screenonly)
|
||||||
|
(define (printonly . body) (apply div class: 'printonly body))
|
||||||
|
(define (screenonly . body) (apply div class: 'screenonly body))
|
||||||
|
|
||||||
|
;; (sections) defines a `section' function and spits out a (delayed) table of
|
||||||
|
;; contents for all its future uses in the page.
|
||||||
|
(provide sections)
|
||||||
|
(require (for-syntax racket/base))
|
||||||
|
(define (section->label title)
|
||||||
|
(regexp-replace* #rx"[^a-z0-9_]+" (string-downcase title) "_"))
|
||||||
|
(define (make-sectioner #:toc? [toc? #t]
|
||||||
|
#:newpages? [newpages? #f]
|
||||||
|
#:show-section-in-subtitle [sec-in-subsec? #t])
|
||||||
|
(define sections '())
|
||||||
|
(define cur-sec #f)
|
||||||
|
(define subsections '())
|
||||||
|
(define (->li/reverse items [more-style #f])
|
||||||
|
(ul style: more-style (add-newlines (map li (reverse items)))))
|
||||||
|
(define (collect-subs)
|
||||||
|
(when (pair? subsections)
|
||||||
|
(set! sections
|
||||||
|
(cons (list (car sections)
|
||||||
|
(->li/reverse subsections "font-size: small;"))
|
||||||
|
(cdr sections)))
|
||||||
|
(set! subsections '())))
|
||||||
|
(define ((add-section sub?) #:newpage? [newpage? newpages?] . title)
|
||||||
|
(let* ([title* (if sub? (list cur-sec ": " title) title)]
|
||||||
|
[label (section->label (xml->string title*))])
|
||||||
|
(unless sub? (collect-subs) (set! cur-sec title))
|
||||||
|
(let ([title (a href: (list "#" label) style: "text-decoration: none;"
|
||||||
|
title)])
|
||||||
|
(if sub?
|
||||||
|
(set! subsections (cons title subsections))
|
||||||
|
(set! sections (cons title sections))))
|
||||||
|
((if sub? h2 h1)
|
||||||
|
(a name: label
|
||||||
|
style: (and newpage? (pair? (cdr sections))
|
||||||
|
"page-break-before: always;")
|
||||||
|
(if sec-in-subsec? title* title)))))
|
||||||
|
(values (add-section #f) (add-section #t)
|
||||||
|
(and toc? (λ () (collect-subs) (->li/reverse sections)))))
|
||||||
|
(define-syntax (sections stx)
|
||||||
|
(define (make-it stx args)
|
||||||
|
(with-syntax ([sec (datum->syntax stx 'section)]
|
||||||
|
[sub (datum->syntax stx 'subsection)]
|
||||||
|
[(x ...) args])
|
||||||
|
#'(begin (define-values [sec sub toc] (make-sectioner x ...))
|
||||||
|
toc)))
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(s x ...) (make-it #'s #'(x ...))]
|
||||||
|
[_ (identifier? stx) (make-it stx #'())]))
|
253
new-racket-web/web/common/layout.rkt
Normal file
253
new-racket-web/web/common/layout.rkt
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
#lang at-exp racket/base
|
||||||
|
|
||||||
|
(require scribble/html (for-syntax racket/base syntax/name syntax/parse)
|
||||||
|
"utils.rkt" "resources.rkt")
|
||||||
|
|
||||||
|
(define-for-syntax (process-contents who layouter stx xs)
|
||||||
|
(let loop ([xs xs] [kws '()] [id? #f])
|
||||||
|
(syntax-case xs ()
|
||||||
|
[(k v . xs) (keyword? (syntax-e #'k))
|
||||||
|
(loop #'xs (list* #'v #'k kws) (or id? (eq? '#:id (syntax-e #'k))))]
|
||||||
|
[_ (with-syntax ([layouter layouter]
|
||||||
|
[(x ...) (reverse kws)]
|
||||||
|
[(id ...)
|
||||||
|
(if id?
|
||||||
|
'()
|
||||||
|
(let ([name (or (syntax-property stx 'inferred-name)
|
||||||
|
(syntax-local-name))])
|
||||||
|
(if name (list '#:id `',name) '())))]
|
||||||
|
;; delay body, allow definitions
|
||||||
|
[body #`(λ () (begin/text #,@xs))])
|
||||||
|
#'(layouter id ... x ... body))])))
|
||||||
|
|
||||||
|
(define (get-path who id file sfx dir)
|
||||||
|
(define file*
|
||||||
|
(or file
|
||||||
|
(let ([f (and id (symbol->string (force id)))])
|
||||||
|
(cond [(and f (regexp-match #rx"[.]" f)) f]
|
||||||
|
[(and f sfx)
|
||||||
|
(string-append f (regexp-replace #rx"^[.]?" sfx "."))]
|
||||||
|
[else (error who "missing `#:file', or `#:id'~a"
|
||||||
|
(if sfx "" " and `#:suffix'"))]))))
|
||||||
|
(if dir (web-path dir file*) file*))
|
||||||
|
|
||||||
|
;; The following are not intended for direct use, see
|
||||||
|
;; `define+provide-context' below (it could be used with #f for the
|
||||||
|
;; directory if this ever gets used for a flat single directory web
|
||||||
|
;; page.)
|
||||||
|
|
||||||
|
;; for plain text files
|
||||||
|
(define-syntax (plain stx)
|
||||||
|
(syntax-case stx () [(_ . xs) (process-contents 'plain #'plain* stx #'xs)]))
|
||||||
|
(define (plain* #:id [id #f] #:suffix [suffix #f]
|
||||||
|
#:dir [dir #f] #:file [file #f]
|
||||||
|
#:referrer [referrer values]
|
||||||
|
#:newline [newline? #t]
|
||||||
|
content)
|
||||||
|
(resource/referrer (get-path 'plain id file suffix dir)
|
||||||
|
(file-writer output (list content (and newline? "\n")))
|
||||||
|
referrer))
|
||||||
|
|
||||||
|
;; page layout function
|
||||||
|
(define-syntax (page stx)
|
||||||
|
(syntax-case stx () [(_ . xs) (process-contents 'page #'page* stx #'xs)]))
|
||||||
|
(define (page* #:id [id #f] #:dir [dir #f] #:file [file #f]
|
||||||
|
;; if this is true, return only the html -- don't create
|
||||||
|
;; a resource -- therefore no file is made, and no links
|
||||||
|
;; to it can be made (useful only for stub templates)
|
||||||
|
#:html-only [html-only? #f]
|
||||||
|
#:title [label (if id
|
||||||
|
(let* ([id (->string (force id))]
|
||||||
|
[id (regexp-replace #rx"^.*/" id "")]
|
||||||
|
[id (regexp-replace #rx"-" id " ")])
|
||||||
|
(string-titlecase id))
|
||||||
|
(error 'page "missing `#:id' or `#:title'"))]
|
||||||
|
#:link-title [linktitle label]
|
||||||
|
#:window-title [wintitle @list{Racket: @label}]
|
||||||
|
;; can be #f (default), 'full: full page (and no div),
|
||||||
|
;; otherwise, a css width
|
||||||
|
#:width [width #f]
|
||||||
|
#:description [description #f] ; for a meta tag
|
||||||
|
#:extra-headers [extra-headers #f]
|
||||||
|
#:extra-body-attrs [body-attrs #f]
|
||||||
|
#:resources resources0 ; see below
|
||||||
|
#:referrer [referrer
|
||||||
|
(λ (url . more)
|
||||||
|
(a href: url (if (null? more) linktitle more)))]
|
||||||
|
;; will be used instead of `this' to determine navbar highlights
|
||||||
|
#:part-of [part-of #f]
|
||||||
|
content0)
|
||||||
|
(define (page)
|
||||||
|
(define desc
|
||||||
|
(and description (meta name: 'description content: description)))
|
||||||
|
(define headers
|
||||||
|
(if (and extra-headers desc)
|
||||||
|
(list desc "\n" extra-headers)
|
||||||
|
(or desc extra-headers)))
|
||||||
|
(define resources (force resources0))
|
||||||
|
(define head (resources 'head wintitle headers))
|
||||||
|
(define navbar (resources 'navbar (or part-of this)))
|
||||||
|
(define content
|
||||||
|
(list navbar "\n"
|
||||||
|
(case width
|
||||||
|
[(full) content0]
|
||||||
|
[(#f) (div class: 'bodycontent content0)]
|
||||||
|
[else (div class: 'bodycontent style: @list{width: @|width|@";"}
|
||||||
|
content0)])))
|
||||||
|
@xhtml{@||
|
||||||
|
@head
|
||||||
|
@(if body-attrs
|
||||||
|
(apply body `(,@body-attrs ,content))
|
||||||
|
(body content))
|
||||||
|
@||})
|
||||||
|
(define this (and (not html-only?)
|
||||||
|
(resource/referrer (get-path 'page id file "html" dir)
|
||||||
|
(file-writer output-xml page)
|
||||||
|
referrer)))
|
||||||
|
(when this (pages->part-of this (or part-of this)))
|
||||||
|
(or this page))
|
||||||
|
|
||||||
|
;; maps pages to their parts, so symbolic values can be used to determine it
|
||||||
|
(define pages->part-of
|
||||||
|
(let ([t (make-hasheq)])
|
||||||
|
(case-lambda [(page) (hash-ref t page page)]
|
||||||
|
[(page part-of) (hash-set! t page part-of)])))
|
||||||
|
|
||||||
|
(provide set-navbar!)
|
||||||
|
(define-syntax-rule (set-navbar! pages top help)
|
||||||
|
(if (unbox navbar-info)
|
||||||
|
;; since generation is delayed, it won't make sense to change the navbar
|
||||||
|
(error 'set-navbar! "called twice")
|
||||||
|
(set-box! navbar-info (list (lazy pages) (lazy top) (lazy help)))))
|
||||||
|
|
||||||
|
(define navbar-info (box #f))
|
||||||
|
(define (navbar-maker logo)
|
||||||
|
(define pages-promise
|
||||||
|
(lazy (car (or (unbox navbar-info)
|
||||||
|
(error 'navbar "no navbar info set")))))
|
||||||
|
(define top-promise (lazy (cadr (unbox navbar-info))))
|
||||||
|
(define help-promise (lazy (caddr (unbox navbar-info))))
|
||||||
|
(define pages-parts-of-promise
|
||||||
|
(lazy (map pages->part-of (force pages-promise))))
|
||||||
|
(define (middle-text size x)
|
||||||
|
(span style: `("font-size: ",size"px; vertical-align: middle;")
|
||||||
|
class: 'navtitle
|
||||||
|
x))
|
||||||
|
(define OPEN
|
||||||
|
(list (middle-text 100 "(")
|
||||||
|
(middle-text 80 "(")
|
||||||
|
(middle-text 60 "(")
|
||||||
|
(middle-text 40 nbsp)))
|
||||||
|
(define CLOSE
|
||||||
|
(list (middle-text 80 "Racket")
|
||||||
|
(middle-text 40 nbsp)
|
||||||
|
(middle-text 60 ")")
|
||||||
|
(middle-text 80 ")")
|
||||||
|
(middle-text 100 ")")))
|
||||||
|
(define (header-cell logo)
|
||||||
|
(td (a href: (url-of (force top-promise))
|
||||||
|
OPEN
|
||||||
|
(img src: logo alt: "[logo]"
|
||||||
|
style: '("vertical-align: middle; "
|
||||||
|
"margin: 13px 0.25em 0 0; border: 0;"))
|
||||||
|
CLOSE)))
|
||||||
|
(define (links-table this)
|
||||||
|
(table width: "100%"
|
||||||
|
(tr (map (λ (nav navpart)
|
||||||
|
(td class: 'navlinkcell
|
||||||
|
(span class: 'navitem
|
||||||
|
(span class: (if (eq? (pages->part-of this) navpart)
|
||||||
|
'navcurlink 'navlink)
|
||||||
|
nav))))
|
||||||
|
(force pages-promise)
|
||||||
|
(force pages-parts-of-promise)))))
|
||||||
|
(λ (this)
|
||||||
|
(div class: 'racketnav
|
||||||
|
(div class: 'navcontent
|
||||||
|
(table border: 0 cellspacing: 0 cellpadding: 0 width: "100%"
|
||||||
|
(tr (header-cell logo)
|
||||||
|
(td class: 'helpiconcell
|
||||||
|
(let ([help (force help-promise)])
|
||||||
|
(span class: 'helpicon (if (eq? this help) nbsp help)))))
|
||||||
|
(tr (td colspan: 2 (links-table this))))))))
|
||||||
|
|
||||||
|
(define (html-favicon-maker icon)
|
||||||
|
(define headers
|
||||||
|
@list{@link[rel: "icon" href: icon type: "image/ico"]
|
||||||
|
@link[rel: "shortcut icon" href: icon]})
|
||||||
|
(λ () headers))
|
||||||
|
|
||||||
|
(define (html-head-maker style favicon)
|
||||||
|
(define headers
|
||||||
|
@list{
|
||||||
|
@meta[name: "generator" content: "Racket"]
|
||||||
|
@meta[http-equiv: "Content-Type" content: "text/html; charset=utf-8"]
|
||||||
|
@favicon
|
||||||
|
@link[rel: "stylesheet" type: "text/css" href: style title: "default"]})
|
||||||
|
(λ (title* more-headers)
|
||||||
|
(head "\n" (title title*)
|
||||||
|
"\n" headers
|
||||||
|
(and more-headers (list "\n" more-headers))
|
||||||
|
"\n")))
|
||||||
|
|
||||||
|
(define (make-resources files)
|
||||||
|
(define (getfile what) (cadr (assq what files)))
|
||||||
|
(define favicon (html-favicon-maker (getfile 'icon)))
|
||||||
|
(define make-head (html-head-maker (getfile 'style) favicon))
|
||||||
|
(define make-navbar (navbar-maker (getfile 'logo)))
|
||||||
|
(λ (what . more)
|
||||||
|
(apply (case what
|
||||||
|
[(head) make-head]
|
||||||
|
[(navbar) make-navbar]
|
||||||
|
[(favicon-headers) favicon]
|
||||||
|
[(icon-path logo-path style-path)
|
||||||
|
(λ () (let* ([x (symbol->string what)]
|
||||||
|
[x (regexp-replace #rx"-path$" x "")])
|
||||||
|
(url-of (getfile (string->symbol x)))))]
|
||||||
|
[else (error 'resources "internal error")])
|
||||||
|
more)))
|
||||||
|
|
||||||
|
;; `define+provide-context' should be used in each toplevel directory (= each
|
||||||
|
;; site) to have its own resources (and possibly other customizations).
|
||||||
|
(provide define+provide-context define-context)
|
||||||
|
(define-for-syntax (make-define+provide-context stx provide?)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ (~or (~optional dir:expr)
|
||||||
|
(~optional (~seq #:resources resources))
|
||||||
|
(~optional (~seq #:robots robots) #:defaults ([robots #'#t]))
|
||||||
|
(~optional (~seq #:htaccess htaccess) #:defaults ([htaccess #'#t])))
|
||||||
|
...)
|
||||||
|
(unless (attribute dir)
|
||||||
|
(raise-syntax-error 'define-context "missing <dir>"))
|
||||||
|
(with-syntax ([page-id (datum->syntax stx 'page)]
|
||||||
|
[plain-id (datum->syntax stx 'plain)]
|
||||||
|
[copyfile-id (datum->syntax stx 'copyfile)]
|
||||||
|
[symlink-id (datum->syntax stx 'symlink)]
|
||||||
|
[resources-id (datum->syntax stx 'the-resources)])
|
||||||
|
(with-syntax ([provides (if provide?
|
||||||
|
#'(provide page-id plain-id copyfile-id
|
||||||
|
symlink-id resources-id)
|
||||||
|
#'(begin))]
|
||||||
|
[resources
|
||||||
|
(or (attribute resources)
|
||||||
|
#'(make-resources
|
||||||
|
(make-resource-files
|
||||||
|
(λ (id . content)
|
||||||
|
(page* #:id id #:dir dir
|
||||||
|
#:resources (lazy resources-id)
|
||||||
|
content))
|
||||||
|
dir robots htaccess)))])
|
||||||
|
#'(begin (define resources-id resources)
|
||||||
|
(define-syntax-rule (page-id . xs)
|
||||||
|
(page #:resources resources-id #:dir dir . xs))
|
||||||
|
(define-syntax-rule (plain-id . xs)
|
||||||
|
(plain #:dir dir . xs))
|
||||||
|
(define (copyfile-id source [target #f])
|
||||||
|
(copyfile-resource source target #:dir dir))
|
||||||
|
(define (symlink-id source [target #f])
|
||||||
|
(symlink-resource source target #:dir dir))
|
||||||
|
provides)))]))
|
||||||
|
(define-syntax (define+provide-context stx)
|
||||||
|
(make-define+provide-context stx #t))
|
||||||
|
(define-syntax (define-context stx)
|
||||||
|
(make-define+provide-context stx #f))
|
64
new-racket-web/web/common/links.rkt
Normal file
64
new-racket-web/web/common/links.rkt
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#lang at-exp racket/base
|
||||||
|
|
||||||
|
(require scribble/html)
|
||||||
|
|
||||||
|
(define-syntax define*
|
||||||
|
(syntax-rules ()
|
||||||
|
[(_ (id . xs) E ...) (begin (define (id . xs) E ...) (provide id))]
|
||||||
|
[(_ id E) (begin (define id E) (provide id))]))
|
||||||
|
|
||||||
|
(define ((make-link url . text) . alternate)
|
||||||
|
(a href: url (if (null? alternate) text alternate)))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Pages that are made outside of this system
|
||||||
|
|
||||||
|
(define doc-url "http://docs.racket-lang.org/")
|
||||||
|
|
||||||
|
(define* -docs @make-link[doc-url]{Documentation})
|
||||||
|
|
||||||
|
(define-syntax-rule (define-doc-link id desc)
|
||||||
|
(define* id @make-link[`(,doc-url id "/")]{
|
||||||
|
@strong{@(string-titlecase (symbol->string 'id))}: @desc @;
|
||||||
|
@nbsp @small{@a[href: `(,doc-url "pdf/" id ".pdf")]{[pdf]}}}))
|
||||||
|
|
||||||
|
@define-doc-link[quick]{An Introduction to Racket with Pictures}
|
||||||
|
@define-doc-link[more ]{Systems Programming with Racket}
|
||||||
|
@define-doc-link[guide]{Racket}
|
||||||
|
@define-doc-link[continue]{Continue}
|
||||||
|
|
||||||
|
(define* intros (list quick more guide))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; External links
|
||||||
|
|
||||||
|
(define* -htdp
|
||||||
|
@make-link["http://htdp.org/"]{@i{How to Design Programs}})
|
||||||
|
|
||||||
|
(define* -redex
|
||||||
|
@make-link["http://redex.racket-lang.org/"]{Redex})
|
||||||
|
|
||||||
|
(define* -pbd
|
||||||
|
@make-link["http://programbydesign.org/"]{Program by Design})
|
||||||
|
|
||||||
|
(define* -schemers
|
||||||
|
@make-link["http://schemers.org/"]{@tt{schemers.org}})
|
||||||
|
|
||||||
|
(define* -plai
|
||||||
|
@make-link["http://www.plai.org/"]{
|
||||||
|
@i{Programming Languages: Application and Interpretation}})
|
||||||
|
|
||||||
|
(define* -bootstrap @make-link["http://www.bootstrapworld.org/"]{Bootstrap})
|
||||||
|
|
||||||
|
(define* (-rcon [year #f] . text)
|
||||||
|
(define years '(2013 2012 2011))
|
||||||
|
(a href: (list "http://con.racket-lang.org/"
|
||||||
|
(and year (not (eq? year (car years))) (list year "/")))
|
||||||
|
(cond [(pair? text) text]
|
||||||
|
[(not year) "RacketCon"]
|
||||||
|
[else year])))
|
||||||
|
|
||||||
|
(define* (-wiki [page #f] . text)
|
||||||
|
(a href: (list "https://github.com/plt/racket/wiki"
|
||||||
|
(and page (list "/" (regexp-replace #rx" " page "-"))))
|
||||||
|
(if (null? text) (or page "Racket wiki") text)))
|
BIN
new-racket-web/web/common/logo.png
Normal file
BIN
new-racket-web/web/common/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
7
new-racket-web/web/common/main.rkt
Normal file
7
new-racket-web/web/common/main.rkt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require scribble/html/lang
|
||||||
|
"layout.rkt" "resources.rkt" "extras.rkt" "links.rkt" "utils.rkt")
|
||||||
|
(provide (all-from-out scribble/html/lang
|
||||||
|
"layout.rkt" "resources.rkt" "extras.rkt" "links.rkt"
|
||||||
|
"utils.rkt"))
|
BIN
new-racket-web/web/common/plticon.ico
Normal file
BIN
new-racket-web/web/common/plticon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 318 B |
155
new-racket-web/web/common/resources.rkt
Normal file
155
new-racket-web/web/common/resources.rkt
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
#lang at-exp racket/base
|
||||||
|
|
||||||
|
(require scribble/html)
|
||||||
|
|
||||||
|
;; These are some resources that are shared across different toplevel
|
||||||
|
;; sites. They could be included from a single place, but then when one
|
||||||
|
;; machine crashes the rest won't work right. (Note: do not add
|
||||||
|
;; resources that are specific to only one site here, do so in the
|
||||||
|
;; site's "resources.rkt" file)
|
||||||
|
|
||||||
|
(require "utils.rkt")
|
||||||
|
|
||||||
|
(provide make-resource-files
|
||||||
|
navbar-style page-sizes font-family) ; needed for the blog template
|
||||||
|
|
||||||
|
;; robots is passed as #:robots in define-context, and htaccess as #:htaccess;
|
||||||
|
;; they can be #t (the default) for the standard ones, or some text that gets
|
||||||
|
;; added to the standard contents -- which is the user-agent line and the
|
||||||
|
;; ErrorDocument respectively.
|
||||||
|
(define (make-resource-files page dir robots htaccess)
|
||||||
|
(define (copyfile file [target file])
|
||||||
|
(copyfile-resource (in-here file) (web-path dir target)))
|
||||||
|
(define (writefile file . contents)
|
||||||
|
(resource (web-path dir file) (file-writer output (list contents "\n"))))
|
||||||
|
`([logo ,(copyfile "logo.png")]
|
||||||
|
[icon ,(copyfile "plticon.ico")]
|
||||||
|
[style ,(writefile "plt.css" racket-style)]
|
||||||
|
;; the following resources are not used directly, so their names are
|
||||||
|
;; irrelevant
|
||||||
|
[verification:google
|
||||||
|
@,writefile["google5b2dc47c0b1b15cb.html"]{
|
||||||
|
google-site-verification: google5b2dc47c0b1b15cb.html}]
|
||||||
|
[verification:bing
|
||||||
|
@,writefile["BingSiteAuth.xml"]{
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<users><user>140BE58EEC31CB97382E1016E21C405A</user></users>}]
|
||||||
|
[robots
|
||||||
|
;; #t (the default) => no-op file, good to avoid error-log lines
|
||||||
|
,(let* ([t (if (eq? #t robots) "Disallow:" robots)]
|
||||||
|
[t (and t (list "User-agent: *\n" t))])
|
||||||
|
(and t (writefile "robots.txt" t)))]
|
||||||
|
;; Seems like there are still some clients that look for a favicon.ico file
|
||||||
|
[favicon ,(copyfile "plticon.ico" "favicon.ico")]
|
||||||
|
[404
|
||||||
|
@,page['page-not-found]{
|
||||||
|
@h1[style: '("text-align: center; margin: 3em 0 1em 0;")]{
|
||||||
|
Page not found}
|
||||||
|
@(λ xs (table align: 'center (tr (td (pre xs))))){
|
||||||
|
> (@a[href: "/"]{(uncaught-exception-handler)}
|
||||||
|
(*(+(*)(*(+(*)(*)(*)(*)(*))(+(*)(*)(*)(*)(*))(+(*)(*)(*)(*))))@;
|
||||||
|
(+(*)(*)(*)(*))))
|
||||||
|
uncaught exception: 404}}]
|
||||||
|
;; set the 404 page in htaccess instead of in the conf file, so we get it
|
||||||
|
;; only in sites that we generate here
|
||||||
|
[.htaccess
|
||||||
|
,(let* ([t (and htaccess "ErrorDocument 404 /page-not-found.html")]
|
||||||
|
[t (if (boolean? htaccess) t (list htaccess "\n" t))])
|
||||||
|
(and t (writefile ".htaccess" t)))]))
|
||||||
|
|
||||||
|
(define page-sizes
|
||||||
|
@list{
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 45em;
|
||||||
|
})
|
||||||
|
(define font-family
|
||||||
|
@list{
|
||||||
|
font-family: Optima, Arial, Verdana, Helvetica, sans-serif;
|
||||||
|
})
|
||||||
|
|
||||||
|
(define navbar-style
|
||||||
|
;; All of these are made to apply only inside `racketnav', so the styles can
|
||||||
|
;; be used in places with their own CSS (eg, blog.racket-lang.org)
|
||||||
|
@list{
|
||||||
|
.racketnav {
|
||||||
|
background-color: #000000;
|
||||||
|
color: #ffffff;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
padding: 0.5em 0em;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.racketnav a {
|
||||||
|
color: #ffffff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.racketnav .navcontent {
|
||||||
|
@page-sizes
|
||||||
|
@font-family
|
||||||
|
}
|
||||||
|
.racketnav .navtitle {
|
||||||
|
font-size: xx-large;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.racketnav .navitem {
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 88%;
|
||||||
|
}
|
||||||
|
.racketnav .navlink a {
|
||||||
|
padding: 0em 1em;
|
||||||
|
}
|
||||||
|
.racketnav .navcurlink a {
|
||||||
|
padding: 0em 1em;
|
||||||
|
background-color: #555555;
|
||||||
|
}
|
||||||
|
.racketnav .navlink a:hover,
|
||||||
|
.racketnav .navcurlink a:hover {
|
||||||
|
background-color: #888888;
|
||||||
|
}
|
||||||
|
.racketnav .navlinkcell {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.racketnav .helpiconcell {
|
||||||
|
text-align: right;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.racketnav .helpicon {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 88%;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
(define racket-style
|
||||||
|
@list{
|
||||||
|
@; ---- generic styles ----
|
||||||
|
html {
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
@font-family
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
@; ---- content styles ----
|
||||||
|
.bodycontent {
|
||||||
|
@page-sizes
|
||||||
|
}
|
||||||
|
@; ---- styles for the navbar ----
|
||||||
|
@navbar-style
|
||||||
|
@; ---- styles for extras ----
|
||||||
|
.parlisttitle {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.parlistitem {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
})
|
52
new-racket-web/web/common/utils.rkt
Normal file
52
new-racket-web/web/common/utils.rkt
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#lang at-exp racket/base
|
||||||
|
|
||||||
|
(require scribble/html (for-syntax scheme/base))
|
||||||
|
|
||||||
|
(provide in-here)
|
||||||
|
(define-syntax (in-here stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ path paths ...)
|
||||||
|
(let ([src (let-values ([(dir name dir?)
|
||||||
|
(split-path (syntax-source stx))])
|
||||||
|
(or dir (raise-syntax-error
|
||||||
|
'in-here "missing source information" stx)))])
|
||||||
|
#`(build-path '#,src path paths ...))]))
|
||||||
|
|
||||||
|
(provide web-path)
|
||||||
|
(define (web-path . xs)
|
||||||
|
(string-join xs "/"))
|
||||||
|
|
||||||
|
(provide ->string)
|
||||||
|
(define (->string x)
|
||||||
|
(cond [(string? x) x]
|
||||||
|
[(path? x) (path->string x)]
|
||||||
|
[(bytes? x) (bytes->string/utf-8 x)]
|
||||||
|
[(symbol? x) (symbol->string x)]
|
||||||
|
[(number? x) (number->string x)]
|
||||||
|
[else (error '->string "don't know what to do with ~e" x)]))
|
||||||
|
|
||||||
|
;; resources with a specific referrer; if the referrer is `values',
|
||||||
|
;; return a plain resource (which behaves the same)
|
||||||
|
(provide resource/referrer url-of)
|
||||||
|
(struct referable (referrer resource) #:property prop:procedure 0)
|
||||||
|
(define (resource/referrer path renderer referrer)
|
||||||
|
(define url (resource path renderer))
|
||||||
|
(if (eq? referrer values)
|
||||||
|
url
|
||||||
|
(referable (λ args (apply referrer (url) args)) url)))
|
||||||
|
(define (url-of referable [absolute? #f])
|
||||||
|
(cond [(referable? referable) ((referable-resource referable) absolute?)]
|
||||||
|
[(resource? referable) (referable absolute?)]
|
||||||
|
[else (raise-type-error 'url-of "referable" referable)]))
|
||||||
|
|
||||||
|
;; simple file resources
|
||||||
|
(define ((make-path-resourcer file-op) source [target #f] #:dir [dir #f])
|
||||||
|
(let ([target (or target (let-values ([(base file dir?) (split-path source)])
|
||||||
|
(path->string file)))])
|
||||||
|
(resource (if (eq? void file-op)
|
||||||
|
(void) (if dir (web-path dir target) target))
|
||||||
|
(λ (file) (file-op source file)))))
|
||||||
|
|
||||||
|
(provide copyfile-resource symlink-resource)
|
||||||
|
(define copyfile-resource (make-path-resourcer copy-file))
|
||||||
|
(define symlink-resource (make-path-resourcer make-file-or-directory-link))
|
29
new-racket-web/web/config.rkt
Normal file
29
new-racket-web/web/config.rkt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(provide sites)
|
||||||
|
(define sites
|
||||||
|
'(("www" "http://racket-lang.org/")
|
||||||
|
("download" "http://download.racket-lang.org/")
|
||||||
|
("bugs" "http://bugs.racket-lang.org/")
|
||||||
|
("lists" "http://lists.racket-lang.org/")
|
||||||
|
("drracket" "http://drracket.org/")
|
||||||
|
;; stubs usually use absolute paths for resources, since they're
|
||||||
|
;; templates that often get used in sub-dir pages too
|
||||||
|
("stubs/planet" "http://planet.racket-lang.org/" abs)
|
||||||
|
("stubs/pre" "http://pre.racket-lang.org/" abs)
|
||||||
|
("stubs/git" "http://git.racket-lang.org/" abs)
|
||||||
|
("stubs/blog" "http://blog.racket-lang.org/" abs)
|
||||||
|
("stubs/mailman" "http://lists.racket-lang.org/" abs)
|
||||||
|
("stubs/dirlist" "http://download.racket-lang.org/" abs)
|
||||||
|
("stubs/docs" "http://docs.racket-lang.org/" abs)
|
||||||
|
("stubs/wiki" "http://wiki.racket-lang.org/" abs)))
|
||||||
|
|
||||||
|
(provide distributions)
|
||||||
|
(define distributions
|
||||||
|
(make-parameter
|
||||||
|
;; Each is a "hostname:dest-path", and then a list of directories to put in
|
||||||
|
;; that path. Warning: distributed directories are replicated from the
|
||||||
|
;; source, including removing material that is not distributed. A directory
|
||||||
|
;; can also have "*" parts which will be expanded recursively -- useful to
|
||||||
|
;; avoid deletions in case a target directory has additional materials.
|
||||||
|
'(["winooski:/www" "www" "download" "bugs" "lists" "drracket" "stubs"])))
|
3
new-racket-web/web/download/all.rkt
Normal file
3
new-racket-web/web/download/all.rkt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require "index.rkt" "version.rkt")
|
264
new-racket-web/web/download/data.rkt
Normal file
264
new-racket-web/web/download/data.rkt
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(define -platform-names-
|
||||||
|
`(;; source platforms
|
||||||
|
["win" "Windows"]
|
||||||
|
["mac" "Mac OS X"]
|
||||||
|
["unix" "Unix"]
|
||||||
|
;; binary platforms
|
||||||
|
["i386-win32" "Windows (x86, 32-bit)"]
|
||||||
|
["x86_64-win32" "Windows (x64, 64-bit)"]
|
||||||
|
["(ppc|i386|x86_64)-osx-mac"
|
||||||
|
,(λ (_ cpu)
|
||||||
|
(format "Mac OS X (~a)"
|
||||||
|
(cond
|
||||||
|
[(equal? cpu "ppc") "PPC"]
|
||||||
|
[(equal? cpu "i386") "Intel 32-bit"]
|
||||||
|
[(equal? cpu "x86_64") "Intel 64-bit"]
|
||||||
|
[else (error "unregonized cpu!")])))]
|
||||||
|
["(ppc|68k)-mac-classic" "Macintosh Classic (\\1)"]
|
||||||
|
["(ppc|i386)-darwin"
|
||||||
|
,(λ (_ cpu)
|
||||||
|
(format "Darwin (~a)"
|
||||||
|
(if (equal? cpu "ppc") "PPC" "Intel")))]
|
||||||
|
["i386-linux(-gcc2)?" "Linux i386"]
|
||||||
|
["i386-linux-fc([0-9]+)" "Linux i386 (Fedora Core \\1)"]
|
||||||
|
["(i386|x86_64)-linux-f([0-9]+)" "Linux \\1 (Fedora \\2)"]
|
||||||
|
["(i386|x86_64)-linux-debian" "Linux \\1 (Debian Stable)"]
|
||||||
|
["(i386|x86_64)-linux-debian-([a-zA-Z0-9]+)" "Linux \\1 (Debian \\2)"]
|
||||||
|
["(i386|x86_64)-linux-ubuntu([0-9]+)" "Linux \\1 (Ubuntu \\2)"]
|
||||||
|
["(i386|x86_64)-linux-ubuntu-([a-z]+)" "Linux \\1 (Ubuntu \\2)"]
|
||||||
|
["(i386|x86_64)-linux-ubuntu.*" "Linux \\1 (Ubuntu)"]
|
||||||
|
["(i386|x86_64)-freebsd" "FreeBSD \\1"]
|
||||||
|
["sparc-solaris" "Sparc Solaris (SunOS)"]
|
||||||
|
["i386-kernel" "x86 Standalone Kernel"]
|
||||||
|
))
|
||||||
|
|
||||||
|
(define -file-type-names-
|
||||||
|
'(["sh" "Self-extracting shell script"]
|
||||||
|
["exe" "Windows Installer"]
|
||||||
|
["tgz" "Gzipped TAR Archive"]
|
||||||
|
["zip" "Zipped Archive"]
|
||||||
|
["dmg" "Disk Image"]
|
||||||
|
["plt" "Racket Package"]
|
||||||
|
["sit" "StuffIt Archive"]))
|
||||||
|
|
||||||
|
(define -mirrors-
|
||||||
|
;; This is a sequence of
|
||||||
|
;; (location url reposnisble-name email [techincal-contact])
|
||||||
|
'(["Main download (USA, Massachusetts, Northeastern University)"
|
||||||
|
"http://download.racket-lang.org/installers/"
|
||||||
|
"Eli Barzilay"
|
||||||
|
"eli@barzilay.org"]
|
||||||
|
["USA, Illinois (Northwestern University)"
|
||||||
|
"http://www.eecs.northwestern.edu/racket/"
|
||||||
|
"Robby Findler"
|
||||||
|
"robby@eecs.northwestern.edu"]
|
||||||
|
["USA, Utah (University of Utah)"
|
||||||
|
"http://www.cs.utah.edu/plt/installers/"
|
||||||
|
"Matthew Flatt"
|
||||||
|
"mflatt@cs.utah.edu"]
|
||||||
|
["Canada, Ontario (University of Waterloo)"
|
||||||
|
"http://mirror.csclub.uwaterloo.ca/racket/racket-installers/"
|
||||||
|
"Systems Committee"
|
||||||
|
"syscom@csclub.uwaterloo.ca"]
|
||||||
|
["Germany (Universität Tübingen)"
|
||||||
|
"http://mirror.informatik.uni-tuebingen.de/mirror/racket/"
|
||||||
|
"Marcus Crestani"
|
||||||
|
"crestani@informatik.uni-tuebingen.de"]
|
||||||
|
["Belgium (Infogroep, Vrije Universiteit Brussel)"
|
||||||
|
"http://racket.infogroep.be/"
|
||||||
|
"Infogroep"
|
||||||
|
"research@infogroep.be"]
|
||||||
|
#;
|
||||||
|
["Turkey, Istanbul (Bilgi University)"
|
||||||
|
"http://russell.cs.bilgi.edu.tr/racket-installers/"
|
||||||
|
"Onur Gungor"
|
||||||
|
"onurgu@cs.bilgi.edu.tr"]
|
||||||
|
#;
|
||||||
|
["Austria (Vienna University of Technology)"
|
||||||
|
"http://gd.tuwien.ac.at/languages/scheme/plt/"
|
||||||
|
"Rudolf Ladner"
|
||||||
|
"ladner@zid.tuwien.ac.at"]
|
||||||
|
#; ; Scheme guy left
|
||||||
|
["France (Institut Pasteur)"
|
||||||
|
"ftp://ftp.pasteur.fr/pub/computing/Scheme/plt-scheme/"
|
||||||
|
"Marc Badouin"
|
||||||
|
"babafou@pasteur.fr"
|
||||||
|
"Pasteur Institute FTP ftpmain@pasteur.fr"]
|
||||||
|
#; ; ftp down (permanently?)
|
||||||
|
["Mexico (Wish Computing)"
|
||||||
|
"ftp://morpheus.wish.com.mx/pub/plt/"
|
||||||
|
"Francisco Solsona"
|
||||||
|
"solsona@acm.org"]
|
||||||
|
))
|
||||||
|
|
||||||
|
;; Used to sort packages when more then one is rendered on a page (delayed)
|
||||||
|
(define (-installer-orders-)
|
||||||
|
`((,installer-package ,eq? (racket racket-textual))
|
||||||
|
(,installer-binary? ,eq? (#t #f))
|
||||||
|
(,installer-platform ,regexp-match?
|
||||||
|
(#px"\\bwin(32)?\\b" #px"\\bmac\\b" #px"\\blinux\\b" #px""))
|
||||||
|
(,installer-platform ,regexp-match?
|
||||||
|
(#px"\\bi386\\b" #px"\\bx86_64\\b" #px"\\bppc\\b" #px""))))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(provide (struct-out mirror) mirrors
|
||||||
|
(struct-out release) (struct-out installer)
|
||||||
|
all-installers current-release all-releases all-packages
|
||||||
|
package->name platform->name suffix->name
|
||||||
|
set-announcements-file!)
|
||||||
|
|
||||||
|
(require racket/list racket/file version/utils racket/runtime-path
|
||||||
|
racket/promise "release-info.rkt")
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Mirror information
|
||||||
|
|
||||||
|
(struct mirror (location url person email))
|
||||||
|
|
||||||
|
(define mirrors
|
||||||
|
(map (λ (m) (mirror (car m) (regexp-replace #rx"/?$" (cadr m) "/")
|
||||||
|
(caddr m) (cadddr m)))
|
||||||
|
-mirrors-))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Release information
|
||||||
|
|
||||||
|
(struct release (version date date-string announcement))
|
||||||
|
|
||||||
|
(define announcements #f)
|
||||||
|
(define (set-announcements-file! file)
|
||||||
|
(set! announcements #t))
|
||||||
|
|
||||||
|
(define version->release
|
||||||
|
(let ([t (make-hash)]
|
||||||
|
[months '#("January" "February" "March" "April" "May" "June" "July"
|
||||||
|
"August" "September" "October" "November" "December")])
|
||||||
|
(λ (v)
|
||||||
|
(hash-ref! t v
|
||||||
|
(λ ()
|
||||||
|
(define info (get-version-tag-info v))
|
||||||
|
(if info
|
||||||
|
(let* ([tagger (car info)]
|
||||||
|
[date (cadr info)]
|
||||||
|
[announcement (caddr info)]
|
||||||
|
[year (date-year date)]
|
||||||
|
[month (vector-ref months (sub1 (date-month date)))])
|
||||||
|
(release v date (format "~a ~a" month year) announcement))
|
||||||
|
(release v #f "(unknown date)" "(no release text found)")))))))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Installer information
|
||||||
|
|
||||||
|
(define-runtime-path installers-data "installers.txt")
|
||||||
|
|
||||||
|
(struct installer
|
||||||
|
(path ; path to file from the installers directory
|
||||||
|
file ; just the file name
|
||||||
|
release ; the release that this installer comes from
|
||||||
|
size ; size in bytes
|
||||||
|
package ; package kind symbol 'racket or 'racket-textual
|
||||||
|
binary? ; #t = binary distribution, #f = source distribution
|
||||||
|
platform ; platform name string (generic for srcs, cpu-os for bins)
|
||||||
|
suffix)) ; string
|
||||||
|
|
||||||
|
(define installer-rx
|
||||||
|
(pregexp (string-append
|
||||||
|
"^"
|
||||||
|
"([0-9.]+)" ; size
|
||||||
|
"\t"
|
||||||
|
"(" ; path
|
||||||
|
"([0-9p.]+)" ; version
|
||||||
|
"/"
|
||||||
|
"(racket(?:-textual)?)" ; package
|
||||||
|
"/(" ; file
|
||||||
|
"\\4-\\3-" ; <package>-<version>-
|
||||||
|
"(bin|src)-" ; binary/source
|
||||||
|
"([^.]+)" ; platform
|
||||||
|
"\\."
|
||||||
|
"([a-z]+)" ; suffix
|
||||||
|
"))$")))
|
||||||
|
|
||||||
|
(define (make-installer size path version package file type platform suffix)
|
||||||
|
(installer path file (version->release version) (string->number size)
|
||||||
|
(string->symbol package) (equal? "bin" type) platform suffix))
|
||||||
|
|
||||||
|
(define (parse-installers in)
|
||||||
|
(port-count-lines! in)
|
||||||
|
(for/list ([line (in-lines in)] [num (in-naturals 1)])
|
||||||
|
(apply make-installer
|
||||||
|
(cdr (or (regexp-match installer-rx line)
|
||||||
|
(error 'installers "bad installer data line#~a: ~s"
|
||||||
|
num line))))))
|
||||||
|
|
||||||
|
(define (order->precedes order)
|
||||||
|
(define =? (car order))
|
||||||
|
(define l (cadr order))
|
||||||
|
(define (num-of x)
|
||||||
|
(let loop ([l l] [n 0])
|
||||||
|
(cond [(null? l)
|
||||||
|
(error 'precedes "could not find ~s in precedence list: ~s" x l)]
|
||||||
|
[(=? (car l) x) n]
|
||||||
|
[else (loop (cdr l) (add1 n))])))
|
||||||
|
(λ (x y) (< (num-of x) (num-of y))))
|
||||||
|
|
||||||
|
;; use this to avoid parsing the installers until generation starts
|
||||||
|
(define-syntax-rule (define-lazy name expr)
|
||||||
|
(begin (define p (lazy expr))
|
||||||
|
(define-syntax name
|
||||||
|
(syntax-id-rules (set!)
|
||||||
|
[(set! _ x) (error 'name "unmodifiable binding")]
|
||||||
|
[(_ x (... ...)) ((force p) x (... ...))]
|
||||||
|
[_ (force p)]))))
|
||||||
|
|
||||||
|
;; sorted by version (newest first), and then by -installer-orders-
|
||||||
|
(define-lazy all-installers
|
||||||
|
(sort
|
||||||
|
(call-with-input-file installers-data parse-installers)
|
||||||
|
(let ([fns `([,(λ (i)
|
||||||
|
(version->integer (release-version (installer-release i))))
|
||||||
|
. ,>]
|
||||||
|
,@(map (λ (o) (cons (car o) (order->precedes (cdr o))))
|
||||||
|
(-installer-orders-)))])
|
||||||
|
(λ (i1 i2)
|
||||||
|
(let loop ([fns fns])
|
||||||
|
(if (null? fns)
|
||||||
|
#f
|
||||||
|
(let* ([get (caar fns)] [<? (cdar fns)] [x1 (get i1)] [x2 (get i2)])
|
||||||
|
(or (<? x1 x2) (and (equal? x1 x2) (loop (cdr fns)))))))))))
|
||||||
|
|
||||||
|
(define-lazy all-releases ; still sorted from newest to oldest
|
||||||
|
(remove-duplicates (map installer-release all-installers)))
|
||||||
|
(define-lazy all-packages ; also sorted
|
||||||
|
(remove-duplicates (map installer-package all-installers)))
|
||||||
|
(define-lazy current-release (car all-releases))
|
||||||
|
|
||||||
|
(define package->name
|
||||||
|
(let ([t (make-hasheq)])
|
||||||
|
(λ (package)
|
||||||
|
(hash-ref! t package
|
||||||
|
(λ () (string-titlecase
|
||||||
|
(regexp-replace #rx"-" (symbol->string package) " ")))))))
|
||||||
|
|
||||||
|
(define platform-names
|
||||||
|
(for/list ([pn (in-list -platform-names-)])
|
||||||
|
(list (regexp (string-append "^" (car pn) "$")) (cadr pn))))
|
||||||
|
|
||||||
|
(define platform->name
|
||||||
|
(let ([t (make-hash)])
|
||||||
|
(λ (platform)
|
||||||
|
(hash-ref! t platform
|
||||||
|
(λ () (or (for/or ([pn (in-list platform-names)])
|
||||||
|
;; find out if a regexp applied by checking if the result
|
||||||
|
;; is different (relies on regexp-replace returning the
|
||||||
|
;; same string when fails)
|
||||||
|
(let ([new (regexp-replace (car pn) platform (cadr pn))])
|
||||||
|
(and (not (eq? new platform)) new)))
|
||||||
|
(error 'platform->name "unrecognized platform: ~e"
|
||||||
|
platform)))))))
|
||||||
|
|
||||||
|
(define (suffix->name suffix)
|
||||||
|
(cond [(assoc suffix -file-type-names-) => cadr]
|
||||||
|
[else (error 'suffix->name "unrecognized suffix: ~e" suffix)]))
|
249
new-racket-web/web/download/download-pages.rkt
Normal file
249
new-racket-web/web/download/download-pages.rkt
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "data.rkt" "installer-pages.rkt" "symlinks.rkt"
|
||||||
|
(prefix-in pre: "../stubs/pre.rkt"))
|
||||||
|
|
||||||
|
(provide render-download-page)
|
||||||
|
(define (render-download-page [release current-release] [package 'racket])
|
||||||
|
(define version (release-version release))
|
||||||
|
@center-div{
|
||||||
|
@h2{@(package->name package) v@version (@(release-date-string release))}
|
||||||
|
@div[id: "download_panel" align: "center" style: "display: none;"]{
|
||||||
|
@input[type: 'submit value: "Download" onclick: "do_jump();"
|
||||||
|
style: '("font-size: 200%; font-weight: bolder;"
|
||||||
|
" letter-spacing: 0.2em;"
|
||||||
|
" margin: 0.5ex 0 1ex 0; width: 100%;")]
|
||||||
|
@br
|
||||||
|
@div{
|
||||||
|
Platform:
|
||||||
|
@select[id: "platform_selector"
|
||||||
|
onchange: "selection_changed();"
|
||||||
|
onkeypress: "selection_changed();"]{
|
||||||
|
@(for/list ([i (in-list all-installers)]
|
||||||
|
#:when (and (equal? release (installer-release i))
|
||||||
|
(equal? package (installer-package i))))
|
||||||
|
(installer->page i 'render-option))}}
|
||||||
|
@|br br|
|
||||||
|
@(let* ([sep @list{@nbsp @bull @nbsp}]
|
||||||
|
[links (λ links @(tr (td (div style: "margin: 1ex 4ex;"
|
||||||
|
(add-between links sep)))))]
|
||||||
|
[docs @list{@|docs|/@|version|/html}])
|
||||||
|
@table[style: "text-align: center; font-size: small;"
|
||||||
|
frame: 'hsides rules: 'rows]{
|
||||||
|
@links[@list{Release: @nbsp @(release-page release){Announcement}}
|
||||||
|
@a[href: @list{@|docs|/release/}]{Notes}
|
||||||
|
@a[href: @docs]{Documentation}]
|
||||||
|
@links[@license{License}
|
||||||
|
all-version-pages
|
||||||
|
@pre:installers{Nightly Installers}]})
|
||||||
|
@br
|
||||||
|
@div[id: "linux_explain"
|
||||||
|
style: '("font-size: 75%; display: none; width: 28em;"
|
||||||
|
" margin-top: 1ex; text-align: center;")]{
|
||||||
|
@b{Note about the Linux installers:} if you don't see an option for
|
||||||
|
your particular platform, try other Linux installers, starting from
|
||||||
|
similar ones. Very often, a build on one Linux variant will work on
|
||||||
|
others too.}}
|
||||||
|
@downloader-script
|
||||||
|
@noscript{
|
||||||
|
Installers are available for the following platforms:
|
||||||
|
@ul{@(for/list ([i (in-list all-installers)]
|
||||||
|
#:when (and (equal? release (installer-release i))
|
||||||
|
(equal? package (installer-package i))))
|
||||||
|
@li{@(installer->page i 'only-platform)})}}})
|
||||||
|
|
||||||
|
(define (release-page* rel)
|
||||||
|
(define ver (release-version rel))
|
||||||
|
(define title @list{v@ver Release Notes})
|
||||||
|
@page[#:file (format "v~a.html" ver) #:title title #:part-of 'download]{
|
||||||
|
@table[align: 'center]{
|
||||||
|
@tr{@td{@h2{Release Announcements for Version @ver}}}
|
||||||
|
@tr{@td{@pre{@release-announcement[rel]}}}}
|
||||||
|
})
|
||||||
|
(define release-page
|
||||||
|
(let ([t (make-hash)])
|
||||||
|
(λ (rel) (hash-ref! t rel (λ () (release-page* rel))))))
|
||||||
|
|
||||||
|
(define all-version-pages
|
||||||
|
(let ()
|
||||||
|
(define (make-page rel pkg)
|
||||||
|
(define ver (release-version rel))
|
||||||
|
(define file (format "~a-v~a.html" pkg ver))
|
||||||
|
(define title @list{Download @(package->name pkg) v@ver})
|
||||||
|
@page[#:file file #:title title #:part-of 'download]{
|
||||||
|
@(render-download-page rel pkg)})
|
||||||
|
(define style
|
||||||
|
@style/inline[type: 'text/css]{
|
||||||
|
.version-row {
|
||||||
|
background-color: #ffffc0;
|
||||||
|
}
|
||||||
|
.version-row:hover {
|
||||||
|
background-color: #e0e0a0;
|
||||||
|
}
|
||||||
|
.version-row a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.version-row a:hover {
|
||||||
|
background-color: #eeee22;
|
||||||
|
}})
|
||||||
|
@page[#:id 'all-versions #:title "All Versions" #:part-of 'download
|
||||||
|
#:extra-headers style]{
|
||||||
|
@table[align: 'center cellspacing: 0 cellpadding: 4 frame: 'box
|
||||||
|
rules: 'groups]{
|
||||||
|
@thead{
|
||||||
|
@tr{@td{@nbsp @strong{Version & Release Notes}}
|
||||||
|
@(map (λ (p) @th[align: 'center]{@(package->name p)})
|
||||||
|
all-packages)
|
||||||
|
@td{@strong{Documentation}}}}
|
||||||
|
@(let ([sep (tr style: "height: 4px; margin: 0; padding: 0;"
|
||||||
|
(td) (map (λ (_) (td)) all-packages))])
|
||||||
|
(define (cell rel pkg)
|
||||||
|
@td[align: 'center]{
|
||||||
|
@nbsp @(make-page rel pkg){[download]} @nbsp})
|
||||||
|
@tbody{
|
||||||
|
@sep
|
||||||
|
@(for/list ([r (in-list all-releases)])
|
||||||
|
(define ver (release-version r))
|
||||||
|
@list{
|
||||||
|
@tr[class: 'version-row]{
|
||||||
|
@td{@|nbsp nbsp| @strong{Version @ver},
|
||||||
|
@(release-page r){@release-date-string[r]} @nbsp}
|
||||||
|
@(map (λ (p) (cell r p)) all-packages)
|
||||||
|
@td{@nbsp @a[href: @list{@|docs|/@|ver|/html}]{[HTML]} @;
|
||||||
|
@nbsp @a[href: @list{@|docs|/@|ver|/pdf}]{[PDF]} @;
|
||||||
|
@nbsp}}
|
||||||
|
@sep})})
|
||||||
|
@tfoot{
|
||||||
|
@tr[class: 'version-row]{
|
||||||
|
@td[align: 'center colspan: 3]{@pre:installers}
|
||||||
|
@td{@nbsp @pre:docs[#:sub 'html]{[HTML]} @;
|
||||||
|
@nbsp @pre:docs[#:sub 'pdf]{[PDF]} @nbsp}}}}}))
|
||||||
|
|
||||||
|
(define license
|
||||||
|
@page[#:title "Software License" #:part-of 'download]{
|
||||||
|
@p*{
|
||||||
|
@~ Racket is distributed under the
|
||||||
|
@a[href: "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html#SEC1"]{
|
||||||
|
GNU Lesser General Public License (LGPL)}.
|
||||||
|
@~ Our primary goal is to help as many people as possible use and
|
||||||
|
contribute to Racket. We encourage anyone to develop any kind of
|
||||||
|
software, with any kind of license, using Racket.
|
||||||
|
@~ We have chosen the LGPL as the license for Racket, which makes it
|
||||||
|
possible for for people to create software with Racket, and to allow us
|
||||||
|
to build on existing libraries that use the LGPL, such as the Lightning
|
||||||
|
assembler and the GMP math library. The basic requirement of the LGPL
|
||||||
|
is that you make your changes to Racket available, and that you let
|
||||||
|
other people use your software with new versions of Racket.
|
||||||
|
@~ Since the LGPL license that Racket uses was originally designed for C
|
||||||
|
programs, parts of it require some interpretation to apply to Racket in
|
||||||
|
detail. The following is how the Racket maintainers interpret the
|
||||||
|
license.
|
||||||
|
@~ @ul*{
|
||||||
|
@~ First, if you distribute your Racket application in source form or as
|
||||||
|
compiled bytecode files, the Racket license does not restrict you at
|
||||||
|
all.
|
||||||
|
@~ Second, if you distribute your Racket application as compiled binary
|
||||||
|
generated by @tt{raco exe}, there are no requirements placed on the
|
||||||
|
licensing of your software. However, the LGPL requires that you make
|
||||||
|
it possible to re-link your software with modified versions of
|
||||||
|
Racket. This means, basically, that you need to provide the compiled
|
||||||
|
bytecode files used to produce the compiled binary, if requested by
|
||||||
|
someone who got your software from you. Note that this does @em{not}
|
||||||
|
mean that your software has to be made open source, nor do you have
|
||||||
|
to give the source code to anyone, nor do you have to make the
|
||||||
|
compiled bytecode files available to the public or let other people
|
||||||
|
redistribute them. Furthermore, this is not revealing any more of
|
||||||
|
your source code than the @tt{raco exe} format, since the bytecode is
|
||||||
|
embedded in an extractable way in the resulting executable.}
|
||||||
|
@~ We are, of course, not lawyers, and this should not be taken as legal
|
||||||
|
advice. However, we wanted to make it clear that Racket is an
|
||||||
|
appropriate building block for all kinds of software, and to clarify how
|
||||||
|
we view the license of Racket.}})
|
||||||
|
|
||||||
|
(define downloader-script
|
||||||
|
@script/inline[type: 'text/javascript]{@||
|
||||||
|
var do_jump, selection_changed;
|
||||||
|
(function() {
|
||||||
|
// show the download panel, since JS is obviously working
|
||||||
|
document.getElementById("download_panel").style.display = "block";
|
||||||
|
//
|
||||||
|
var selector = document.getElementById("platform_selector");
|
||||||
|
// jump to the selected item
|
||||||
|
do_jump = function() {
|
||||||
|
location.href = selector[selector.selectedIndex].value;
|
||||||
|
}
|
||||||
|
// returns an ordering for the platform names, an array of regexps
|
||||||
|
// note that the entries are sorted in a good order, so return an order
|
||||||
|
// that only brings the locally desired entries to the top
|
||||||
|
function getPlatformOrder() {
|
||||||
|
var p = navigator.platform;
|
||||||
|
var l = function(str) { return p.indexOf(str) != -1@";" }
|
||||||
|
var Win = /Windows/,
|
||||||
|
Mac = /Mac/,
|
||||||
|
MacIntel = /Mac.*Intel/,
|
||||||
|
MacPPC = /Mac.*PPC/,
|
||||||
|
Linux = /Linux/,
|
||||||
|
Linux64 = /Linux.*x86_64/,
|
||||||
|
Linux32 = /Linux.*i386/,
|
||||||
|
Unix = /Unix/,
|
||||||
|
Solaris = /Solaris/;
|
||||||
|
if (p == null) return [];
|
||||||
|
else if (l("SunOS")) return [Solaris, Unix];
|
||||||
|
@; Note about Windows 64: seems like the best guess could be done by
|
||||||
|
@; checking that the platform has "Win64" or navigator.userAgent has
|
||||||
|
@; either "Win64" or "WOW64". But the 32 build might be better for many
|
||||||
|
@; people anyway, so keep things as is for now. (With the `Win' filter
|
||||||
|
@; which will get the 32 version first and the 64 second.)
|
||||||
|
else if (l("Win")) return [Win];
|
||||||
|
else if (l("Mac")) return [(l("Intel")?MacIntel:MacPPC), Mac, Unix];
|
||||||
|
else if (l("Linux")) {
|
||||||
|
// also show the linux explanation if it's a linux
|
||||||
|
document.getElementById("linux_explain").style.display = "block";
|
||||||
|
return [(l("_64")?Linux64:Linux32), Linux, Unix];
|
||||||
|
} else return [];
|
||||||
|
}
|
||||||
|
// show the linux explanation on change too (do it with a timeout so it
|
||||||
|
// changes even when the arrow keys are used to move the selection -- since
|
||||||
|
// then onchange is called only on blur)
|
||||||
|
linux_expl_s = document.getElementById("linux_explain").style;
|
||||||
|
selection_changed_timer = false;
|
||||||
|
selection_changed = function() {
|
||||||
|
if (selection_changed_timer) clearTimeout(selection_changed_timer);
|
||||||
|
selection_changed_timer = setTimeout(do_selection_changed, 250);
|
||||||
|
}
|
||||||
|
function do_selection_changed() {
|
||||||
|
linux_expl_s.display =
|
||||||
|
(selector[selector.selectedIndex].text.search(/Linux/) >= 0) ?
|
||||||
|
"block" : "none";
|
||||||
|
}
|
||||||
|
//
|
||||||
|
var opts = selector.options;
|
||||||
|
var len = opts.length;
|
||||||
|
// get the order and a make a sorting function
|
||||||
|
var order = getPlatformOrder();
|
||||||
|
function getOrder(str) {
|
||||||
|
for (var i=0@";" i<order.length@";" i++)
|
||||||
|
if (str.search(order[i]) >= 0) return i;
|
||||||
|
return 999;
|
||||||
|
}
|
||||||
|
function isBetter(opt1,opt2) {
|
||||||
|
// sort first by the order, then by how they were placed originally
|
||||||
|
var ord1 = getOrder(opt1[0]), ord2 = getOrder(opt2[0]);
|
||||||
|
if (ord1 < ord2) return -1;
|
||||||
|
else if (ord1 > ord2) return +1;
|
||||||
|
else if (opt1[2] < opt2[2]) return -1;
|
||||||
|
else if (opt1[2] > opt2[2]) return +1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
// sort the options, need to use a temporary array
|
||||||
|
var tmps = new Array(len);
|
||||||
|
for (var i=0@";" i<len@";" i++)
|
||||||
|
tmps[i]=[opts[i].text,opts[i].value,i];
|
||||||
|
tmps.sort(isBetter);
|
||||||
|
for (var i=0@";" i<len@";" i++) {
|
||||||
|
opts[i].text = tmps[i][0];
|
||||||
|
opts[i].value = tmps[i][1];
|
||||||
|
}
|
||||||
|
opts.selectedIndex = 0;
|
||||||
|
})();
|
||||||
|
@||})
|
21
new-racket-web/web/download/index.rkt
Normal file
21
new-racket-web/web/download/index.rkt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "symlinks.rkt" "../www/download.rkt")
|
||||||
|
|
||||||
|
(provide index)
|
||||||
|
(define index
|
||||||
|
@page[#:link-title "Downloads" #:part-of 'download
|
||||||
|
#:description
|
||||||
|
@'{Download Racket, a modern dialect of Lisp/Scheme. @;
|
||||||
|
Available for Windows, Mac, Linux, and other Unix platforms. @;
|
||||||
|
Includes the DrRacket IDE.}]{
|
||||||
|
@div[style: "float: right;"]{@download-button}
|
||||||
|
Use these links to browse the download directories directly:
|
||||||
|
@ul{@li{Current @a[href: `(,installers "/recent")]{installers}
|
||||||
|
(or @a[href: installers]{all versions}).}
|
||||||
|
@li{Current documentation in
|
||||||
|
@a[href: `(,docs "/recent/html")]{HTML} and in
|
||||||
|
@a[href: `(,docs "/recent/pdf")]{PDF}
|
||||||
|
(or @a[href: docs]{all versions}).}
|
||||||
|
@li{Binary @a[href: libs]{libraries} mainly for GRacket
|
||||||
|
(installed during the build process).}}})
|
79
new-racket-web/web/download/installer-pages.rkt
Normal file
79
new-racket-web/web/download/installer-pages.rkt
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "data.rkt" "mirror-link.rkt")
|
||||||
|
|
||||||
|
(define (render-installer-page installer)
|
||||||
|
(define path (installer-path installer))
|
||||||
|
(define file (installer-file installer))
|
||||||
|
(define html-file (string-append (regexp-replace* #rx"\\." file "-") ".html"))
|
||||||
|
(define release (installer-release installer))
|
||||||
|
(define version (release-version release))
|
||||||
|
(define date (release-date-string release))
|
||||||
|
(define package (package->name (installer-package installer)))
|
||||||
|
(define size (installer-size installer))
|
||||||
|
(define type (if (installer-binary? installer) "" " source"))
|
||||||
|
(define platform (platform->name (installer-platform installer)))
|
||||||
|
(define title @text{Download @package v@|version type| for @platform})
|
||||||
|
(define suffix-desc (suffix->name (installer-suffix installer)))
|
||||||
|
(define human-size
|
||||||
|
(let ([mb (/ size (* 1024 1024))])
|
||||||
|
(if (< mb 10)
|
||||||
|
(let-values ([(q r) (quotient/remainder (round (* mb 10)) 10)])
|
||||||
|
(format "~a.~aM" q r))
|
||||||
|
(format "~aM" (round mb)))))
|
||||||
|
(define (row label text)
|
||||||
|
@tr[valign: 'top]{
|
||||||
|
@td[align: 'right]{@b{@label}:}
|
||||||
|
@td{@nbsp}
|
||||||
|
@td[align: 'left]{@text}})
|
||||||
|
(define (this url [mode #f])
|
||||||
|
(case mode
|
||||||
|
[(only-platform) (a href: url platform type)]
|
||||||
|
[(render-option) (option value: url platform type)]
|
||||||
|
[(#f) @a[href: url]{@title}]
|
||||||
|
[else (error 'installer-page "unknown mode: ~e" mode)]))
|
||||||
|
@page[#:file html-file #:title title #:referrer this #:part-of 'download]{
|
||||||
|
@table[width: "90%" align: 'center]{
|
||||||
|
@tr[valign: 'top]{
|
||||||
|
@td[width: "50%"]{
|
||||||
|
@table{@(row "Package" package)
|
||||||
|
@(row "Version" @list{@version (@date)})
|
||||||
|
@(row "Platform" (list platform type))
|
||||||
|
@(row "Type" suffix-desc)
|
||||||
|
@(row "File" file)
|
||||||
|
@(row "Size" @span[title: @list{Exact size: @size bytes}]{
|
||||||
|
@human-size})}}
|
||||||
|
@td[width: "50%"]{
|
||||||
|
Download links:
|
||||||
|
@div[style: "font-size: 75%; text-align: right; float: right;"]{
|
||||||
|
(Choose the nearest site)}
|
||||||
|
@ul{@(let ([mirrors
|
||||||
|
(filter-map
|
||||||
|
(λ (m)
|
||||||
|
(define url
|
||||||
|
(mirror-link
|
||||||
|
(string-append (mirror-url m) path)
|
||||||
|
size
|
||||||
|
(λ () (format "~a <~a>"
|
||||||
|
(mirror-person m)
|
||||||
|
(mirror-email m)))))
|
||||||
|
(and url @li{@a[href: url]{@(mirror-location m)}}))
|
||||||
|
mirrors)])
|
||||||
|
(case (length mirrors)
|
||||||
|
[(0) (error 'installer-page "no available mirror for: ~e"
|
||||||
|
path)]
|
||||||
|
[(1) (list mirrors
|
||||||
|
@li{@small{(no additional mirrors, yet)}})]
|
||||||
|
[else mirrors]))}}}}
|
||||||
|
@;TODO: decide whether this is really needed
|
||||||
|
@; (looks redundant now that all of the installers are pretty standard)
|
||||||
|
@;section{Installation instructions}
|
||||||
|
@;(bundle-installation-instructions bundle)
|
||||||
|
})
|
||||||
|
|
||||||
|
(provide installer->page)
|
||||||
|
(define installer->page
|
||||||
|
(let ([t (make-hasheq)])
|
||||||
|
(λ (inst . more)
|
||||||
|
(let ([page (hash-ref! t inst (λ () (render-installer-page inst)))])
|
||||||
|
(if (null? more) page (apply page more))))))
|
382
new-racket-web/web/download/installers.txt
Normal file
382
new-racket-web/web/download/installers.txt
Normal file
|
@ -0,0 +1,382 @@
|
||||||
|
9300697 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-debian.sh
|
||||||
|
9304219 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-f12.sh
|
||||||
|
9313351 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
9598271 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-osx-mac.dmg
|
||||||
|
7195260 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-win32.exe
|
||||||
|
9275500 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-darwin.sh
|
||||||
|
9590434 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-osx-mac.dmg
|
||||||
|
9428494 5.0.1/racket-textual/racket-textual-5.0.1-bin-x86_64-linux-f7.sh
|
||||||
|
5832011 5.0.1/racket-textual/racket-textual-5.0.1-src-mac.dmg
|
||||||
|
5714125 5.0.1/racket-textual/racket-textual-5.0.1-src-unix.tgz
|
||||||
|
7115859 5.0.1/racket-textual/racket-textual-5.0.1-src-win.zip
|
||||||
|
48280952 5.0.1/racket/racket-5.0.1-bin-i386-linux-debian.sh
|
||||||
|
48274719 5.0.1/racket/racket-5.0.1-bin-i386-linux-f12.sh
|
||||||
|
48321280 5.0.1/racket/racket-5.0.1-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
49529404 5.0.1/racket/racket-5.0.1-bin-i386-osx-mac.dmg
|
||||||
|
29974852 5.0.1/racket/racket-5.0.1-bin-i386-win32.exe
|
||||||
|
48227579 5.0.1/racket/racket-5.0.1-bin-ppc-darwin.sh
|
||||||
|
49553958 5.0.1/racket/racket-5.0.1-bin-ppc-osx-mac.dmg
|
||||||
|
48582065 5.0.1/racket/racket-5.0.1-bin-x86_64-linux-f7.sh
|
||||||
|
17343846 5.0.1/racket/racket-5.0.1-src-mac.dmg
|
||||||
|
17272590 5.0.1/racket/racket-5.0.1-src-unix.tgz
|
||||||
|
20625477 5.0.1/racket/racket-5.0.1-src-win.zip
|
||||||
|
9753004 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-debian.sh
|
||||||
|
9759330 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-f12.sh
|
||||||
|
9769701 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
10061865 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-osx-mac.dmg
|
||||||
|
7483846 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-win32.exe
|
||||||
|
9723983 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-darwin.sh
|
||||||
|
10054183 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-osx-mac.dmg
|
||||||
|
9889541 5.0.2/racket-textual/racket-textual-5.0.2-bin-x86_64-linux-f7.sh
|
||||||
|
5939776 5.0.2/racket-textual/racket-textual-5.0.2-src-mac.dmg
|
||||||
|
5815219 5.0.2/racket-textual/racket-textual-5.0.2-src-unix.tgz
|
||||||
|
7283576 5.0.2/racket-textual/racket-textual-5.0.2-src-win.zip
|
||||||
|
50263773 5.0.2/racket/racket-5.0.2-bin-i386-linux-debian.sh
|
||||||
|
50264748 5.0.2/racket/racket-5.0.2-bin-i386-linux-f12.sh
|
||||||
|
50304157 5.0.2/racket/racket-5.0.2-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
51514800 5.0.2/racket/racket-5.0.2-bin-i386-osx-mac.dmg
|
||||||
|
31130193 5.0.2/racket/racket-5.0.2-bin-i386-win32.exe
|
||||||
|
50204906 5.0.2/racket/racket-5.0.2-bin-ppc-darwin.sh
|
||||||
|
51567239 5.0.2/racket/racket-5.0.2-bin-ppc-osx-mac.dmg
|
||||||
|
50579715 5.0.2/racket/racket-5.0.2-bin-x86_64-linux-f7.sh
|
||||||
|
17699549 5.0.2/racket/racket-5.0.2-src-mac.dmg
|
||||||
|
17622692 5.0.2/racket/racket-5.0.2-src-unix.tgz
|
||||||
|
21092427 5.0.2/racket/racket-5.0.2-src-win.zip
|
||||||
|
9015818 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-debian.sh
|
||||||
|
9025266 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-f12.sh
|
||||||
|
9039169 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
9324539 5.0/racket-textual/racket-textual-5.0-bin-i386-osx-mac.dmg
|
||||||
|
7023498 5.0/racket-textual/racket-textual-5.0-bin-i386-win32.exe
|
||||||
|
8999839 5.0/racket-textual/racket-textual-5.0-bin-ppc-darwin.sh
|
||||||
|
9330306 5.0/racket-textual/racket-textual-5.0-bin-ppc-osx-mac.dmg
|
||||||
|
9159233 5.0/racket-textual/racket-textual-5.0-bin-x86_64-linux-f7.sh
|
||||||
|
5539138 5.0/racket-textual/racket-textual-5.0-src-mac.dmg
|
||||||
|
5408767 5.0/racket-textual/racket-textual-5.0-src-unix.tgz
|
||||||
|
7041524 5.0/racket-textual/racket-textual-5.0-src-win.zip
|
||||||
|
46469932 5.0/racket/racket-5.0-bin-i386-linux-debian.sh
|
||||||
|
46483844 5.0/racket/racket-5.0-bin-i386-linux-f12.sh
|
||||||
|
46515740 5.0/racket/racket-5.0-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
47637362 5.0/racket/racket-5.0-bin-i386-osx-mac.dmg
|
||||||
|
28973247 5.0/racket/racket-5.0-bin-i386-win32.exe
|
||||||
|
46418573 5.0/racket/racket-5.0-bin-ppc-darwin.sh
|
||||||
|
47693225 5.0/racket/racket-5.0-bin-ppc-osx-mac.dmg
|
||||||
|
46784914 5.0/racket/racket-5.0-bin-x86_64-linux-f7.sh
|
||||||
|
16727955 5.0/racket/racket-5.0-src-mac.dmg
|
||||||
|
16661627 5.0/racket/racket-5.0-src-unix.tgz
|
||||||
|
20043612 5.0/racket/racket-5.0-src-win.zip
|
||||||
|
10608594 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-f12.sh
|
||||||
|
10617031 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
10944378 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-osx-mac.dmg
|
||||||
|
7871781 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-win32.exe
|
||||||
|
10563612 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-darwin.sh
|
||||||
|
10925675 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-osx-mac.dmg
|
||||||
|
10777466 5.1.1/racket-textual/racket-textual-5.1.1-bin-x86_64-linux-f14.sh
|
||||||
|
6088017 5.1.1/racket-textual/racket-textual-5.1.1-src-mac.dmg
|
||||||
|
5972450 5.1.1/racket-textual/racket-textual-5.1.1-src-unix.tgz
|
||||||
|
7072928 5.1.1/racket-textual/racket-textual-5.1.1-src-win.zip
|
||||||
|
51562160 5.1.1/racket/racket-5.1.1-bin-i386-linux-f12.sh
|
||||||
|
51583365 5.1.1/racket/racket-5.1.1-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
53227597 5.1.1/racket/racket-5.1.1-bin-i386-osx-mac.dmg
|
||||||
|
33299725 5.1.1/racket/racket-5.1.1-bin-i386-win32.exe
|
||||||
|
51319041 5.1.1/racket/racket-5.1.1-bin-ppc-darwin.sh
|
||||||
|
54275107 5.1.1/racket/racket-5.1.1-bin-ppc-osx-mac.dmg
|
||||||
|
51928808 5.1.1/racket/racket-5.1.1-bin-x86_64-linux-f14.sh
|
||||||
|
16221515 5.1.1/racket/racket-5.1.1-src-mac.dmg
|
||||||
|
15884853 5.1.1/racket/racket-5.1.1-src-unix.tgz
|
||||||
|
19117693 5.1.1/racket/racket-5.1.1-src-win.zip
|
||||||
|
10294418 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-f12.sh
|
||||||
|
10305056 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
10649433 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-osx-mac.dmg
|
||||||
|
7735142 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-win32.exe
|
||||||
|
10229144 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-darwin.sh
|
||||||
|
10600014 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-osx-mac.dmg
|
||||||
|
10465204 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-lenny.sh
|
||||||
|
10476031 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
10474930 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-f14.sh
|
||||||
|
10849704 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-osx-mac.dmg
|
||||||
|
8035589 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-win32.exe
|
||||||
|
5927007 5.1.2/racket-textual/racket-textual-5.1.2-src-mac.dmg
|
||||||
|
5814309 5.1.2/racket-textual/racket-textual-5.1.2-src-unix.tgz
|
||||||
|
6858089 5.1.2/racket-textual/racket-textual-5.1.2-src-win.zip
|
||||||
|
50068153 5.1.2/racket/racket-5.1.2-bin-i386-linux-f12.sh
|
||||||
|
50101512 5.1.2/racket/racket-5.1.2-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
51665644 5.1.2/racket/racket-5.1.2-bin-i386-osx-mac.dmg
|
||||||
|
32577645 5.1.2/racket/racket-5.1.2-bin-i386-win32.exe
|
||||||
|
49784628 5.1.2/racket/racket-5.1.2-bin-ppc-darwin.sh
|
||||||
|
52725371 5.1.2/racket/racket-5.1.2-bin-ppc-osx-mac.dmg
|
||||||
|
50416939 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-lenny.sh
|
||||||
|
50437726 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
50446330 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-f14.sh
|
||||||
|
51976069 5.1.2/racket/racket-5.1.2-bin-x86_64-osx-mac.dmg
|
||||||
|
33226602 5.1.2/racket/racket-5.1.2-bin-x86_64-win32.exe
|
||||||
|
16293184 5.1.2/racket/racket-5.1.2-src-mac.dmg
|
||||||
|
15960181 5.1.2/racket/racket-5.1.2-src-unix.tgz
|
||||||
|
19203148 5.1.2/racket/racket-5.1.2-src-win.zip
|
||||||
|
10277328 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-linux-f12.sh
|
||||||
|
10286517 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
10646200 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-osx-mac.dmg
|
||||||
|
7721338 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-win32.exe
|
||||||
|
10209882 5.1.3/racket-textual/racket-textual-5.1.3-bin-ppc-darwin.sh
|
||||||
|
10578888 5.1.3/racket-textual/racket-textual-5.1.3-bin-ppc-osx-mac.dmg
|
||||||
|
10445665 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-linux-debian-lenny.sh
|
||||||
|
10458130 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
10458009 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-linux-f14.sh
|
||||||
|
10844242 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-osx-mac.dmg
|
||||||
|
8024578 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-win32.exe
|
||||||
|
5909369 5.1.3/racket-textual/racket-textual-5.1.3-src-mac.dmg
|
||||||
|
5795883 5.1.3/racket-textual/racket-textual-5.1.3-src-unix.tgz
|
||||||
|
6840314 5.1.3/racket-textual/racket-textual-5.1.3-src-win.zip
|
||||||
|
50047413 5.1.3/racket/racket-5.1.3-bin-i386-linux-f12.sh
|
||||||
|
50082199 5.1.3/racket/racket-5.1.3-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
51638634 5.1.3/racket/racket-5.1.3-bin-i386-osx-mac.dmg
|
||||||
|
32548344 5.1.3/racket/racket-5.1.3-bin-i386-win32.exe
|
||||||
|
49765546 5.1.3/racket/racket-5.1.3-bin-ppc-darwin.sh
|
||||||
|
52694190 5.1.3/racket/racket-5.1.3-bin-ppc-osx-mac.dmg
|
||||||
|
50391225 5.1.3/racket/racket-5.1.3-bin-x86_64-linux-debian-lenny.sh
|
||||||
|
50405579 5.1.3/racket/racket-5.1.3-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
50431407 5.1.3/racket/racket-5.1.3-bin-x86_64-linux-f14.sh
|
||||||
|
51949468 5.1.3/racket/racket-5.1.3-bin-x86_64-osx-mac.dmg
|
||||||
|
33194397 5.1.3/racket/racket-5.1.3-bin-x86_64-win32.exe
|
||||||
|
16270003 5.1.3/racket/racket-5.1.3-src-mac.dmg
|
||||||
|
15939654 5.1.3/racket/racket-5.1.3-src-unix.tgz
|
||||||
|
19185643 5.1.3/racket/racket-5.1.3-src-win.zip
|
||||||
|
10661589 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-f12.sh
|
||||||
|
10674322 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
11019666 5.1/racket-textual/racket-textual-5.1-bin-i386-osx-mac.dmg
|
||||||
|
7899916 5.1/racket-textual/racket-textual-5.1-bin-i386-win32.exe
|
||||||
|
10627504 5.1/racket-textual/racket-textual-5.1-bin-ppc-darwin.sh
|
||||||
|
11009730 5.1/racket-textual/racket-textual-5.1-bin-ppc-osx-mac.dmg
|
||||||
|
10835079 5.1/racket-textual/racket-textual-5.1-bin-x86_64-linux-f14.sh
|
||||||
|
6064958 5.1/racket-textual/racket-textual-5.1-src-mac.dmg
|
||||||
|
5945844 5.1/racket-textual/racket-textual-5.1-src-unix.tgz
|
||||||
|
6071742 5.1/racket-textual/racket-textual-5.1-src-win.zip
|
||||||
|
51529968 5.1/racket/racket-5.1-bin-i386-linux-f12.sh
|
||||||
|
51560486 5.1/racket/racket-5.1-bin-i386-linux-ubuntu-jaunty.sh
|
||||||
|
53300468 5.1/racket/racket-5.1-bin-i386-osx-mac.dmg
|
||||||
|
33200268 5.1/racket/racket-5.1-bin-i386-win32.exe
|
||||||
|
51306060 5.1/racket/racket-5.1-bin-ppc-darwin.sh
|
||||||
|
54367850 5.1/racket/racket-5.1-bin-ppc-osx-mac.dmg
|
||||||
|
51892721 5.1/racket/racket-5.1-bin-x86_64-linux-f14.sh
|
||||||
|
16095941 5.1/racket/racket-5.1-src-mac.dmg
|
||||||
|
15759982 5.1/racket/racket-5.1-src-unix.tgz
|
||||||
|
17987080 5.1/racket/racket-5.1-src-win.zip
|
||||||
|
10268779 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-f12.sh
|
||||||
|
10279415 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
10829117 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-osx-mac.dmg
|
||||||
|
7719949 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-win32.exe
|
||||||
|
10766423 5.2.1/racket-textual/racket-textual-5.2.1-bin-ppc-osx-mac.dmg
|
||||||
|
10453826 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
10458751 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-f14.sh
|
||||||
|
10960644 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-osx-mac.dmg
|
||||||
|
8048658 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-win32.exe
|
||||||
|
5944766 5.2.1/racket-textual/racket-textual-5.2.1-src-mac.dmg
|
||||||
|
5822408 5.2.1/racket-textual/racket-textual-5.2.1-src-unix.tgz
|
||||||
|
6874674 5.2.1/racket-textual/racket-textual-5.2.1-src-win.zip
|
||||||
|
58246608 5.2.1/racket/racket-5.2.1-bin-i386-linux-f12.sh
|
||||||
|
58279927 5.2.1/racket/racket-5.2.1-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
60604498 5.2.1/racket/racket-5.2.1-bin-i386-osx-mac.dmg
|
||||||
|
39516478 5.2.1/racket/racket-5.2.1-bin-i386-win32.exe
|
||||||
|
61654421 5.2.1/racket/racket-5.2.1-bin-ppc-osx-mac.dmg
|
||||||
|
58616709 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
58626727 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-f14.sh
|
||||||
|
60847004 5.2.1/racket/racket-5.2.1-bin-x86_64-osx-mac.dmg
|
||||||
|
40203933 5.2.1/racket/racket-5.2.1-bin-x86_64-win32.exe
|
||||||
|
17941288 5.2.1/racket/racket-5.2.1-src-mac.dmg
|
||||||
|
17211427 5.2.1/racket/racket-5.2.1-src-unix.tgz
|
||||||
|
20641716 5.2.1/racket/racket-5.2.1-src-win.zip
|
||||||
|
10072568 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-f12.sh
|
||||||
|
10087724 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
10419223 5.2/racket-textual/racket-textual-5.2-bin-i386-osx-mac.dmg
|
||||||
|
7639819 5.2/racket-textual/racket-textual-5.2-bin-i386-win32.exe
|
||||||
|
10001213 5.2/racket-textual/racket-textual-5.2-bin-ppc-darwin.sh
|
||||||
|
10368884 5.2/racket-textual/racket-textual-5.2-bin-ppc-osx-mac.dmg
|
||||||
|
10243046 5.2/racket-textual/racket-textual-5.2-bin-x86_64-linux-debian-lenny.sh
|
||||||
|
10256265 5.2/racket-textual/racket-textual-5.2-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
10259861 5.2/racket-textual/racket-textual-5.2-bin-x86_64-linux-f14.sh
|
||||||
|
10631349 5.2/racket-textual/racket-textual-5.2-bin-x86_64-osx-mac.dmg
|
||||||
|
7965785 5.2/racket-textual/racket-textual-5.2-bin-x86_64-win32.exe
|
||||||
|
5926754 5.2/racket-textual/racket-textual-5.2-src-mac.dmg
|
||||||
|
5806691 5.2/racket-textual/racket-textual-5.2-src-unix.tgz
|
||||||
|
6846137 5.2/racket-textual/racket-textual-5.2-src-win.zip
|
||||||
|
54306960 5.2/racket/racket-5.2-bin-i386-linux-f12.sh
|
||||||
|
54333056 5.2/racket/racket-5.2-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
56070009 5.2/racket/racket-5.2-bin-i386-osx-mac.dmg
|
||||||
|
36205596 5.2/racket/racket-5.2-bin-i386-win32.exe
|
||||||
|
54161422 5.2/racket/racket-5.2-bin-ppc-darwin.sh
|
||||||
|
57109008 5.2/racket/racket-5.2-bin-ppc-osx-mac.dmg
|
||||||
|
54654394 5.2/racket/racket-5.2-bin-x86_64-linux-debian-lenny.sh
|
||||||
|
54678069 5.2/racket/racket-5.2-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
54685565 5.2/racket/racket-5.2-bin-x86_64-linux-f14.sh
|
||||||
|
56380421 5.2/racket/racket-5.2-bin-x86_64-osx-mac.dmg
|
||||||
|
36902485 5.2/racket/racket-5.2-bin-x86_64-win32.exe
|
||||||
|
16601808 5.2/racket/racket-5.2-src-mac.dmg
|
||||||
|
16260740 5.2/racket/racket-5.2-src-unix.tgz
|
||||||
|
19575041 5.2/racket/racket-5.2-src-win.zip
|
||||||
|
11552351 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-linux-f12.sh
|
||||||
|
11570689 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
12143855 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-osx-mac.dmg
|
||||||
|
8803203 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-win32.exe
|
||||||
|
12081255 5.3.1/racket-textual/racket-textual-5.3.1-bin-ppc-osx-mac.dmg
|
||||||
|
11748331 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
11757467 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-linux-f14.sh
|
||||||
|
12278659 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-osx-mac.dmg
|
||||||
|
9171125 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-win32.exe
|
||||||
|
6254337 5.3.1/racket-textual/racket-textual-5.3.1-src-mac.dmg
|
||||||
|
6134415 5.3.1/racket-textual/racket-textual-5.3.1-src-unix.tgz
|
||||||
|
7252130 5.3.1/racket-textual/racket-textual-5.3.1-src-win.zip
|
||||||
|
64527997 5.3.1/racket/racket-5.3.1-bin-i386-linux-f12.sh
|
||||||
|
64562401 5.3.1/racket/racket-5.3.1-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
67179194 5.3.1/racket/racket-5.3.1-bin-i386-osx-mac.dmg
|
||||||
|
43655604 5.3.1/racket/racket-5.3.1-bin-i386-win32.exe
|
||||||
|
67981764 5.3.1/racket/racket-5.3.1-bin-ppc-osx-mac.dmg
|
||||||
|
64911589 5.3.1/racket/racket-5.3.1-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
64927156 5.3.1/racket/racket-5.3.1-bin-x86_64-linux-f14.sh
|
||||||
|
67721160 5.3.1/racket/racket-5.3.1-bin-x86_64-osx-mac.dmg
|
||||||
|
44343519 5.3.1/racket/racket-5.3.1-bin-x86_64-win32.exe
|
||||||
|
19042596 5.3.1/racket/racket-5.3.1-src-mac.dmg
|
||||||
|
18296513 5.3.1/racket/racket-5.3.1-src-unix.tgz
|
||||||
|
21668825 5.3.1/racket/racket-5.3.1-src-win.zip
|
||||||
|
11948337 5.3.2/racket-textual/racket-textual-5.3.2-bin-i386-linux-f12.sh
|
||||||
|
11962344 5.3.2/racket-textual/racket-textual-5.3.2-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
15258690 5.3.2/racket-textual/racket-textual-5.3.2-bin-i386-osx-mac.dmg
|
||||||
|
9034873 5.3.2/racket-textual/racket-textual-5.3.2-bin-i386-win32.exe
|
||||||
|
15168349 5.3.2/racket-textual/racket-textual-5.3.2-bin-ppc-osx-mac.dmg
|
||||||
|
12150829 5.3.2/racket-textual/racket-textual-5.3.2-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
12155747 5.3.2/racket-textual/racket-textual-5.3.2-bin-x86_64-linux-f14.sh
|
||||||
|
15373372 5.3.2/racket-textual/racket-textual-5.3.2-bin-x86_64-osx-mac.dmg
|
||||||
|
9405386 5.3.2/racket-textual/racket-textual-5.3.2-bin-x86_64-win32.exe
|
||||||
|
5432417 5.3.2/racket-textual/racket-textual-5.3.2-src-mac.dmg
|
||||||
|
6220657 5.3.2/racket-textual/racket-textual-5.3.2-src-unix.tgz
|
||||||
|
7345556 5.3.2/racket-textual/racket-textual-5.3.2-src-win.zip
|
||||||
|
80046600 5.3.2/racket/racket-5.3.2-bin-i386-linux-f12.sh
|
||||||
|
80071196 5.3.2/racket/racket-5.3.2-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
77185236 5.3.2/racket/racket-5.3.2-bin-i386-osx-mac.dmg
|
||||||
|
53476867 5.3.2/racket/racket-5.3.2-bin-i386-win32.exe
|
||||||
|
73863798 5.3.2/racket/racket-5.3.2-bin-ppc-osx-mac.dmg
|
||||||
|
80444872 5.3.2/racket/racket-5.3.2-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
80455630 5.3.2/racket/racket-5.3.2-bin-x86_64-linux-f14.sh
|
||||||
|
77714727 5.3.2/racket/racket-5.3.2-bin-x86_64-osx-mac.dmg
|
||||||
|
54173869 5.3.2/racket/racket-5.3.2-bin-x86_64-win32.exe
|
||||||
|
17441261 5.3.2/racket/racket-5.3.2-src-mac.dmg
|
||||||
|
18903002 5.3.2/racket/racket-5.3.2-src-unix.tgz
|
||||||
|
22453626 5.3.2/racket/racket-5.3.2-src-win.zip
|
||||||
|
11948492 5.3.3/racket-textual/racket-textual-5.3.3-bin-i386-linux-f12.sh
|
||||||
|
11964412 5.3.3/racket-textual/racket-textual-5.3.3-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
15256661 5.3.3/racket-textual/racket-textual-5.3.3-bin-i386-osx-mac.dmg
|
||||||
|
9035043 5.3.3/racket-textual/racket-textual-5.3.3-bin-i386-win32.exe
|
||||||
|
15168071 5.3.3/racket-textual/racket-textual-5.3.3-bin-ppc-osx-mac.dmg
|
||||||
|
12151112 5.3.3/racket-textual/racket-textual-5.3.3-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
12158241 5.3.3/racket-textual/racket-textual-5.3.3-bin-x86_64-linux-f14.sh
|
||||||
|
15374489 5.3.3/racket-textual/racket-textual-5.3.3-bin-x86_64-osx-mac.dmg
|
||||||
|
9406684 5.3.3/racket-textual/racket-textual-5.3.3-bin-x86_64-win32.exe
|
||||||
|
5432743 5.3.3/racket-textual/racket-textual-5.3.3-src-mac.dmg
|
||||||
|
6220717 5.3.3/racket-textual/racket-textual-5.3.3-src-unix.tgz
|
||||||
|
7345556 5.3.3/racket-textual/racket-textual-5.3.3-src-win.zip
|
||||||
|
80042709 5.3.3/racket/racket-5.3.3-bin-i386-linux-f12.sh
|
||||||
|
80064095 5.3.3/racket/racket-5.3.3-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
77158882 5.3.3/racket/racket-5.3.3-bin-i386-osx-mac.dmg
|
||||||
|
53475451 5.3.3/racket/racket-5.3.3-bin-i386-win32.exe
|
||||||
|
77805576 5.3.3/racket/racket-5.3.3-bin-ppc-osx-mac.dmg
|
||||||
|
80441231 5.3.3/racket/racket-5.3.3-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
80445042 5.3.3/racket/racket-5.3.3-bin-x86_64-linux-f14.sh
|
||||||
|
77740581 5.3.3/racket/racket-5.3.3-bin-x86_64-osx-mac.dmg
|
||||||
|
54177148 5.3.3/racket/racket-5.3.3-bin-x86_64-win32.exe
|
||||||
|
17441645 5.3.3/racket/racket-5.3.3-src-mac.dmg
|
||||||
|
18903284 5.3.3/racket/racket-5.3.3-src-unix.tgz
|
||||||
|
22453769 5.3.3/racket/racket-5.3.3-src-win.zip
|
||||||
|
12320423 5.3.4/racket-textual/racket-textual-5.3.4-bin-i386-linux-f12.sh
|
||||||
|
12334215 5.3.4/racket-textual/racket-textual-5.3.4-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
15652299 5.3.4/racket-textual/racket-textual-5.3.4-bin-i386-osx-mac.dmg
|
||||||
|
9278646 5.3.4/racket-textual/racket-textual-5.3.4-bin-i386-win32.exe
|
||||||
|
15553227 5.3.4/racket-textual/racket-textual-5.3.4-bin-ppc-osx-mac.dmg
|
||||||
|
12545952 5.3.4/racket-textual/racket-textual-5.3.4-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
12547477 5.3.4/racket-textual/racket-textual-5.3.4-bin-x86_64-linux-f14.sh
|
||||||
|
15778683 5.3.4/racket-textual/racket-textual-5.3.4-bin-x86_64-osx-mac.dmg
|
||||||
|
9656737 5.3.4/racket-textual/racket-textual-5.3.4-bin-x86_64-win32.exe
|
||||||
|
5514976 5.3.4/racket-textual/racket-textual-5.3.4-src-mac.dmg
|
||||||
|
6314719 5.3.4/racket-textual/racket-textual-5.3.4-src-unix.tgz
|
||||||
|
7450712 5.3.4/racket-textual/racket-textual-5.3.4-src-win.zip
|
||||||
|
81404184 5.3.4/racket/racket-5.3.4-bin-i386-linux-f12.sh
|
||||||
|
81442144 5.3.4/racket/racket-5.3.4-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
78402102 5.3.4/racket/racket-5.3.4-bin-i386-osx-mac.dmg
|
||||||
|
54269511 5.3.4/racket/racket-5.3.4-bin-i386-win32.exe
|
||||||
|
79000954 5.3.4/racket/racket-5.3.4-bin-ppc-osx-mac.dmg
|
||||||
|
81847504 5.3.4/racket/racket-5.3.4-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
81863215 5.3.4/racket/racket-5.3.4-bin-x86_64-linux-f14.sh
|
||||||
|
78954459 5.3.4/racket/racket-5.3.4-bin-x86_64-osx-mac.dmg
|
||||||
|
54968330 5.3.4/racket/racket-5.3.4-bin-x86_64-win32.exe
|
||||||
|
17824228 5.3.4/racket/racket-5.3.4-src-mac.dmg
|
||||||
|
19314579 5.3.4/racket/racket-5.3.4-src-unix.tgz
|
||||||
|
22930176 5.3.4/racket/racket-5.3.4-src-win.zip
|
||||||
|
12292655 5.3.5/racket-textual/racket-textual-5.3.5-bin-i386-linux-f12.sh
|
||||||
|
15648971 5.3.5/racket-textual/racket-textual-5.3.5-bin-i386-osx-mac.dmg
|
||||||
|
9278714 5.3.5/racket-textual/racket-textual-5.3.5-bin-i386-win32.exe
|
||||||
|
15550280 5.3.5/racket-textual/racket-textual-5.3.5-bin-ppc-osx-mac.dmg
|
||||||
|
12518673 5.3.5/racket-textual/racket-textual-5.3.5-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
12500092 5.3.5/racket-textual/racket-textual-5.3.5-bin-x86_64-linux-f18.sh
|
||||||
|
12514647 5.3.5/racket-textual/racket-textual-5.3.5-bin-x86_64-linux-ubuntu-precise.sh
|
||||||
|
15777345 5.3.5/racket-textual/racket-textual-5.3.5-bin-x86_64-osx-mac.dmg
|
||||||
|
9653899 5.3.5/racket-textual/racket-textual-5.3.5-bin-x86_64-win32.exe
|
||||||
|
5514952 5.3.5/racket-textual/racket-textual-5.3.5-src-mac.dmg
|
||||||
|
6264428 5.3.5/racket-textual/racket-textual-5.3.5-src-unix.tgz
|
||||||
|
7450709 5.3.5/racket-textual/racket-textual-5.3.5-src-win.zip
|
||||||
|
80912617 5.3.5/racket/racket-5.3.5-bin-i386-linux-f12.sh
|
||||||
|
78333891 5.3.5/racket/racket-5.3.5-bin-i386-osx-mac.dmg
|
||||||
|
54222087 5.3.5/racket/racket-5.3.5-bin-i386-win32.exe
|
||||||
|
78969552 5.3.5/racket/racket-5.3.5-bin-ppc-osx-mac.dmg
|
||||||
|
81335329 5.3.5/racket/racket-5.3.5-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
81315398 5.3.5/racket/racket-5.3.5-bin-x86_64-linux-f18.sh
|
||||||
|
81340721 5.3.5/racket/racket-5.3.5-bin-x86_64-linux-ubuntu-precise.sh
|
||||||
|
78898223 5.3.5/racket/racket-5.3.5-bin-x86_64-osx-mac.dmg
|
||||||
|
54926791 5.3.5/racket/racket-5.3.5-bin-x86_64-win32.exe
|
||||||
|
17939101 5.3.5/racket/racket-5.3.5-src-mac.dmg
|
||||||
|
19260480 5.3.5/racket/racket-5.3.5-src-unix.tgz
|
||||||
|
23057646 5.3.5/racket/racket-5.3.5-src-win.zip
|
||||||
|
12295243 5.3.6/racket-textual/racket-textual-5.3.6-bin-i386-linux-f12.sh
|
||||||
|
15658693 5.3.6/racket-textual/racket-textual-5.3.6-bin-i386-osx-mac.dmg
|
||||||
|
9277473 5.3.6/racket-textual/racket-textual-5.3.6-bin-i386-win32.exe
|
||||||
|
15558719 5.3.6/racket-textual/racket-textual-5.3.6-bin-ppc-osx-mac.dmg
|
||||||
|
12518633 5.3.6/racket-textual/racket-textual-5.3.6-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
12502053 5.3.6/racket-textual/racket-textual-5.3.6-bin-x86_64-linux-f18.sh
|
||||||
|
12514865 5.3.6/racket-textual/racket-textual-5.3.6-bin-x86_64-linux-ubuntu-precise.sh
|
||||||
|
15785347 5.3.6/racket-textual/racket-textual-5.3.6-bin-x86_64-osx-mac.dmg
|
||||||
|
9655376 5.3.6/racket-textual/racket-textual-5.3.6-bin-x86_64-win32.exe
|
||||||
|
5518958 5.3.6/racket-textual/racket-textual-5.3.6-src-mac.dmg
|
||||||
|
6266358 5.3.6/racket-textual/racket-textual-5.3.6-src-unix.tgz
|
||||||
|
7452375 5.3.6/racket-textual/racket-textual-5.3.6-src-win.zip
|
||||||
|
80959315 5.3.6/racket/racket-5.3.6-bin-i386-linux-f12.sh
|
||||||
|
78522953 5.3.6/racket/racket-5.3.6-bin-i386-osx-mac.dmg
|
||||||
|
54275461 5.3.6/racket/racket-5.3.6-bin-i386-win32.exe
|
||||||
|
79152425 5.3.6/racket/racket-5.3.6-bin-ppc-osx-mac.dmg
|
||||||
|
81401477 5.3.6/racket/racket-5.3.6-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
81379740 5.3.6/racket/racket-5.3.6-bin-x86_64-linux-f18.sh
|
||||||
|
81399545 5.3.6/racket/racket-5.3.6-bin-x86_64-linux-ubuntu-precise.sh
|
||||||
|
79072519 5.3.6/racket/racket-5.3.6-bin-x86_64-osx-mac.dmg
|
||||||
|
54977925 5.3.6/racket/racket-5.3.6-bin-x86_64-win32.exe
|
||||||
|
17944355 5.3.6/racket/racket-5.3.6-src-mac.dmg
|
||||||
|
19278914 5.3.6/racket/racket-5.3.6-src-unix.tgz
|
||||||
|
23080500 5.3.6/racket/racket-5.3.6-src-win.zip
|
||||||
|
11235593 5.3/racket-textual/racket-textual-5.3-bin-i386-linux-f12.sh
|
||||||
|
11248024 5.3/racket-textual/racket-textual-5.3-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
11806657 5.3/racket-textual/racket-textual-5.3-bin-i386-osx-mac.dmg
|
||||||
|
8616632 5.3/racket-textual/racket-textual-5.3-bin-i386-win32.exe
|
||||||
|
11733097 5.3/racket-textual/racket-textual-5.3-bin-ppc-osx-mac.dmg
|
||||||
|
11429790 5.3/racket-textual/racket-textual-5.3-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
11433426 5.3/racket-textual/racket-textual-5.3-bin-x86_64-linux-f14.sh
|
||||||
|
11944406 5.3/racket-textual/racket-textual-5.3-bin-x86_64-osx-mac.dmg
|
||||||
|
8985418 5.3/racket-textual/racket-textual-5.3-bin-x86_64-win32.exe
|
||||||
|
6200415 5.3/racket-textual/racket-textual-5.3-src-mac.dmg
|
||||||
|
6076092 5.3/racket-textual/racket-textual-5.3-src-unix.tgz
|
||||||
|
7163517 5.3/racket-textual/racket-textual-5.3-src-win.zip
|
||||||
|
63546257 5.3/racket/racket-5.3-bin-i386-linux-f12.sh
|
||||||
|
63584563 5.3/racket/racket-5.3-bin-i386-linux-ubuntu-karmic.sh
|
||||||
|
66195664 5.3/racket/racket-5.3-bin-i386-osx-mac.dmg
|
||||||
|
43257532 5.3/racket/racket-5.3-bin-i386-win32.exe
|
||||||
|
66989480 5.3/racket/racket-5.3-bin-ppc-osx-mac.dmg
|
||||||
|
63926568 5.3/racket/racket-5.3-bin-x86_64-linux-debian-squeeze.sh
|
||||||
|
63943730 5.3/racket/racket-5.3-bin-x86_64-linux-f14.sh
|
||||||
|
66712297 5.3/racket/racket-5.3-bin-x86_64-osx-mac.dmg
|
||||||
|
43943553 5.3/racket/racket-5.3-bin-x86_64-win32.exe
|
||||||
|
18849342 5.3/racket/racket-5.3-src-mac.dmg
|
||||||
|
18111154 5.3/racket/racket-5.3-src-unix.tgz
|
||||||
|
21394184 5.3/racket/racket-5.3-src-win.zip
|
177
new-racket-web/web/download/mirror-link.rkt
Normal file
177
new-racket-web/web/download/mirror-link.rkt
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
#|
|
||||||
|
|
||||||
|
This file polls mirror links: (mirror-link <url> <size>) will return the
|
||||||
|
url only if it is live, and its size fits the expected size. Otherwise
|
||||||
|
it returns #f, or #t in some rare cases where the size is not known from
|
||||||
|
the poll.
|
||||||
|
|
||||||
|
This is done only if the "KNOWN_MIRRORS_FILE" environment variable is
|
||||||
|
set, otherwise all mirror links are included. If the variable is set,
|
||||||
|
it should point at a cache file that holds information about polls, used
|
||||||
|
to avoid re-polling all links all the time.
|
||||||
|
|
||||||
|
Polling a URL can result in one of four options:
|
||||||
|
1. The URL doesn't seem to exist. In this case, the link is not shown,
|
||||||
|
and the URL will be re-polled if a web-page build is done 15
|
||||||
|
minutes (or more) later.
|
||||||
|
2. The URL exists, but no size information is available (via a HEAD
|
||||||
|
query, or via an FTP directory listing). The link will be shown in
|
||||||
|
this case, but it will be re-polled two days later. (With a 1..2
|
||||||
|
random factor, and a nightly build that happens at the same time,
|
||||||
|
this will be around 3-5 days.) So far, all mirrors provide size
|
||||||
|
information, so this works fine.
|
||||||
|
3. The URL exists and we get its size, but the size does not match. The
|
||||||
|
URL is not shown, and will be re-polled in an hour. The assumption
|
||||||
|
here is either bad synchronization, or we caught it in progress.
|
||||||
|
4. The size is correct, so the URL is shown. This case still leads to
|
||||||
|
re-polling, but only after a month. The reason for this is in case a
|
||||||
|
mirror is not maintained -- we'll want the links to eventually
|
||||||
|
disappear.
|
||||||
|
|
||||||
|
|#
|
||||||
|
|
||||||
|
(require net/url net/ftp net/sendmail)
|
||||||
|
|
||||||
|
;; the mirrors file has (list url secs result) entries containing the url as a
|
||||||
|
;; string, the time it was checked (the result of `current-seconds'), and the
|
||||||
|
;; result of the `verify-*' function.
|
||||||
|
(define known-mirrors-file
|
||||||
|
(let ([f (getenv "KNOWN_MIRRORS_FILE")]) (and (not (equal? "" f)) f)))
|
||||||
|
(define known-mirrors
|
||||||
|
(if (and known-mirrors-file (file-exists? known-mirrors-file))
|
||||||
|
(call-with-input-file* known-mirrors-file
|
||||||
|
(λ (inp) (for/list ([x (in-producer read eof inp)]) x)))
|
||||||
|
'()))
|
||||||
|
|
||||||
|
;; main entry to getting a known entry result: given the url, return the
|
||||||
|
;; remembered result unless it doesn't exist or it expired; in those cases use
|
||||||
|
;; the thunk to get a current result and remember it; note that expiration
|
||||||
|
;; times are different for different results, and the decision whether to check
|
||||||
|
;; one is randomized (cheaply, since it'll be sensitive to how frequently a
|
||||||
|
;; build is done -- usually by the nightly build).
|
||||||
|
(define (known-mirror-get url size thunk get-responsible-email)
|
||||||
|
(define entry (assoc url known-mirrors))
|
||||||
|
(define last-time (and entry (cadr entry)))
|
||||||
|
(define result (and entry (caddr entry)))
|
||||||
|
(define R (+ 1 (random))) ; random 1..2 number, to avoid congestion
|
||||||
|
(define new
|
||||||
|
(and (cond
|
||||||
|
;; failed, check again after 15 minutes (to accomodate re-runs after
|
||||||
|
;; a release was done)
|
||||||
|
[(eq? #f result)
|
||||||
|
(or (not entry) ; actually missing => try now
|
||||||
|
(current-time . > . (+ last-time (* 15 60 R))))]
|
||||||
|
;; known but without a size to verify, check again after two days
|
||||||
|
[(eq? #t result)
|
||||||
|
(current-time . > . (+ last-time (* 2 24 60 60 R)))]
|
||||||
|
;; has a bad size, check again after an hour
|
||||||
|
[(not (= result size))
|
||||||
|
(current-time . > . (+ last-time (* 60 60 R)))]
|
||||||
|
;; otherwise check again after a month
|
||||||
|
[else (current-time . > . (+ last-time (* 30 24 60 60 R)))])
|
||||||
|
(list url current-time (thunk))))
|
||||||
|
(when new
|
||||||
|
;; keep them sorted by time
|
||||||
|
(set! known-mirrors
|
||||||
|
`(,@(if entry (remq entry known-mirrors) known-mirrors) ,new))
|
||||||
|
(call-with-output-file* known-mirrors-file #:exists 'truncate
|
||||||
|
(λ (outp) (for ([entry (in-list known-mirrors)])
|
||||||
|
(fprintf outp "~s\n" entry)))))
|
||||||
|
(when (and new ; we computed a new value
|
||||||
|
(equal? result size) ; we had a good result
|
||||||
|
(not (equal? (caddr new) size))) ; but now it's bad
|
||||||
|
;; this means that a good mirror just went bad => nag someone
|
||||||
|
(send-mail-message
|
||||||
|
"eli@barzilay.org" "*** Mirror Link Down ***"
|
||||||
|
;; FIXME: if these messages are useful, change it to nag the mirror owner
|
||||||
|
;; instead of a fixed email -- use (list (get-responsible-email))
|
||||||
|
'("eli@barzilay.org") '() '()
|
||||||
|
`("A mirror link that used to be fine is now broken:"
|
||||||
|
,(format " ~a" url)
|
||||||
|
,(format "The expected size is ~a, we now have ~a" size (caddr new))
|
||||||
|
""
|
||||||
|
"This mirror will not be listed for now, until a re-poll finds it"
|
||||||
|
"working.")))
|
||||||
|
(if new (caddr new) result))
|
||||||
|
|
||||||
|
;; use the time when the file is loaded (no point for a finer granularity)
|
||||||
|
(define current-time (current-seconds))
|
||||||
|
|
||||||
|
(provide mirror-link)
|
||||||
|
(define (mirror-link url size get-responsible-email)
|
||||||
|
(and (or (not known-mirrors-file) ; no file => don't check, just use all
|
||||||
|
(let ([r (known-mirror-get url size (λ () (validate url size))
|
||||||
|
get-responsible-email)])
|
||||||
|
(or (eq? r #t) (equal? r size))))
|
||||||
|
url))
|
||||||
|
|
||||||
|
(define (validate url size)
|
||||||
|
(eprintf " checking ~a\n" url)
|
||||||
|
((case (string->symbol (cadr (or (regexp-match #rx"^([^:]*):" url)
|
||||||
|
(error 'mirror-link "bad url: ~a" url))))
|
||||||
|
[(http https) verify-http]
|
||||||
|
[(ftp) verify-ftp]
|
||||||
|
[else (error 'mirror-link "unrecognizable url scheme: ~a\n" url)])
|
||||||
|
url))
|
||||||
|
|
||||||
|
;; Verifiers return #f for failures, #t for dumb success (= didn't get size),
|
||||||
|
;; and a number for success with the remote file's size.
|
||||||
|
;;
|
||||||
|
;; Note: if `net/url' gets to deal with `ftp://' URLs, then only a
|
||||||
|
;; single verification function will be needed. But for that it will
|
||||||
|
;; need to mimic HEAD requests too.
|
||||||
|
|
||||||
|
(define-syntax-rule (with-handlers+timeout name body ...)
|
||||||
|
(let ([cust (make-custodian)] [ch (make-channel)])
|
||||||
|
(parameterize ([current-custodian cust])
|
||||||
|
(thread (λ () (channel-put ch (with-handlers ([exn:fail? exn-message])
|
||||||
|
body ...)))))
|
||||||
|
(begin0 (or (sync/timeout 20 ch) (format "~a connection timeout" name))
|
||||||
|
(custodian-shutdown-all cust))))
|
||||||
|
|
||||||
|
(define (verify-http url)
|
||||||
|
(define (check-contents inp)
|
||||||
|
(define status (read-line inp))
|
||||||
|
(define status* (regexp-match #rx"^HTTP/[0-9.]+ ([0-9]+)" status))
|
||||||
|
(cond [(not status*)
|
||||||
|
(eprintf "WARNING: bad status line for ~a:\n ~s\n" url status)
|
||||||
|
#f]
|
||||||
|
[(not (regexp-match #rx"^2..$" (cadr status*)))
|
||||||
|
(eprintf "WARNING: bad status code for ~a: ~s\n" url (cadr status*))
|
||||||
|
#f]
|
||||||
|
[else
|
||||||
|
(or (for/or ([line (in-lines inp)])
|
||||||
|
(cond [(regexp-match #rx"^(?i:content-length: *([0-9]+) *)$"
|
||||||
|
line)
|
||||||
|
=> (compose string->number cadr)]
|
||||||
|
[else #f]))
|
||||||
|
(begin (eprintf "WARNING: no `content-length' for ~a\n" url)
|
||||||
|
#t))]))
|
||||||
|
(define r
|
||||||
|
(with-handlers+timeout 'http
|
||||||
|
(call/input-url (string->url url) head-impure-port check-contents)))
|
||||||
|
(if (string? r)
|
||||||
|
(begin (eprintf "WARNING: failure getting http info for ~a (~a)\n" url r)
|
||||||
|
#f)
|
||||||
|
r))
|
||||||
|
|
||||||
|
(define (verify-ftp url)
|
||||||
|
(define-values [host port? path]
|
||||||
|
(apply values
|
||||||
|
(cdr (or (regexp-match #rx"^ftp://([^/:]+)(?::([0-9]+))?(/.*)$" url)
|
||||||
|
(error 'verify-ftp "bad ftp url: ~a" url)))))
|
||||||
|
(define port (or port? 21))
|
||||||
|
(define r
|
||||||
|
(with-handlers+timeout 'ftp
|
||||||
|
(define c (ftp-establish-connection host port "anonymous" "anonymous@"))
|
||||||
|
(begin0 (ftp-directory-list c path) (ftp-close-connection c))))
|
||||||
|
(cond [(not (and (list? r) (= 1 (length r)) (list? (car r))))
|
||||||
|
(eprintf "WARNING: failure getting ftp info for ~a~a\n"
|
||||||
|
url (if (string? r) (format " (~a)" r) ""))
|
||||||
|
#f]
|
||||||
|
[(not (= 4 (length (car r))))
|
||||||
|
(eprintf "WARNING: no size for: ~a\n" url)
|
||||||
|
#t]
|
||||||
|
[else (string->number (list-ref (car r) 3))]))
|
60
new-racket-web/web/download/release-info.rkt
Normal file
60
new-racket-web/web/download/release-info.rkt
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require racket/system racket/port racket/match racket/runtime-path
|
||||||
|
racket/promise)
|
||||||
|
|
||||||
|
(define-runtime-path THIS-GIT "../../../../../.git")
|
||||||
|
|
||||||
|
(define (warn fmt . xs)
|
||||||
|
(eprintf "Warning: ~a\a\n" (apply format fmt xs))
|
||||||
|
(flush-output (current-error-port))
|
||||||
|
(sleep 1)
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(define git*
|
||||||
|
(lazy
|
||||||
|
(define exe (or (find-executable-path "git")
|
||||||
|
(warn "no `git' executable => no release info")))
|
||||||
|
(define (try dir) (and dir (directory-exists? dir) dir))
|
||||||
|
(define dir (and exe (or (ormap try (list (getenv "GIT_DIR") THIS-GIT))
|
||||||
|
(warn "no git dir found => no release info\n (~a)"
|
||||||
|
"set $GIT_DIR to a racket repo .git dir"))))
|
||||||
|
(define nowhere (open-output-nowhere))
|
||||||
|
(and dir (λ args (define o (open-output-string))
|
||||||
|
(parameterize ([current-directory dir]
|
||||||
|
[current-output-port o]
|
||||||
|
[current-error-port nowhere])
|
||||||
|
(and (apply system* exe "--no-pager" args)
|
||||||
|
(get-output-string o)))))))
|
||||||
|
|
||||||
|
(provide get-version-tag-info)
|
||||||
|
(define (get-version-tag-info version)
|
||||||
|
(define git (force git*))
|
||||||
|
(let/ec return
|
||||||
|
(unless git (return #f))
|
||||||
|
(define (bad . args) (apply warn args) (return #f))
|
||||||
|
(define (try fmt)
|
||||||
|
(let* ([tag (format fmt version)]
|
||||||
|
[text (and (git "cat-file" "-e" tag)
|
||||||
|
(git "cat-file" "tag" tag))])
|
||||||
|
(and text (cons tag text))))
|
||||||
|
(let* ([text (or (try "v~a") (try "old-v~a")
|
||||||
|
(bad "no git info for ~s (missing tag)" version))]
|
||||||
|
[tag (car text)]
|
||||||
|
[text (cdr text)]
|
||||||
|
[check (λ (x) (or x (bad "malformed git info for ~s" tag)))]
|
||||||
|
[sep (check (regexp-match-positions #rx"\n\n" text))]
|
||||||
|
[meta (map (λ (h)
|
||||||
|
(let ([m (check (regexp-match-positions #rx" " h))])
|
||||||
|
(list (string->symbol (substring h 0 (caar m)))
|
||||||
|
(substring h (cdar m)))))
|
||||||
|
(regexp-split #rx"\n" (substring text 0 (caar sep))))]
|
||||||
|
[text (substring text (cdar sep))])
|
||||||
|
(match meta
|
||||||
|
[`((object ,_) (type "commit") (tag ,_)
|
||||||
|
(tagger ,(regexp #rx"^(.* <.*>) ([0-9]+) ([-+]?[0-9][0-9])00$"
|
||||||
|
(list _ tagger date ofs))))
|
||||||
|
;; ignore the time offset (it probably depends on where the tag
|
||||||
|
;; was made)
|
||||||
|
(list tagger (seconds->date (string->number date)) text)]
|
||||||
|
[_ (check #f)]))))
|
3
new-racket-web/web/download/resources.rkt
Normal file
3
new-racket-web/web/download/resources.rkt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(define+provide-context "download")
|
13
new-racket-web/web/download/symlinks.rkt
Normal file
13
new-racket-web/web/download/symlinks.rkt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt")
|
||||||
|
|
||||||
|
(provide (all-defined-out))
|
||||||
|
|
||||||
|
(define (in-ftp . paths)
|
||||||
|
(string-join (cons "/var/ftp/pub/racket" paths) "/"))
|
||||||
|
|
||||||
|
(define docs (symlink "/www/docs"))
|
||||||
|
(define installers (symlink (in-ftp "installers")))
|
||||||
|
(define libs (symlink (in-ftp "libs/tags") "libs"))
|
||||||
|
(define stubs (symlink "/www/stubs"))
|
7
new-racket-web/web/download/version.rkt
Normal file
7
new-racket-web/web/download/version.rkt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "data.rkt")
|
||||||
|
|
||||||
|
(define version.txt
|
||||||
|
(plain (lazy (let ([v (release-version current-release)])
|
||||||
|
(format "~s" `((recent ,v) (stable ,v)))))))
|
18
new-racket-web/web/lang/reader.rkt
Normal file
18
new-racket-web/web/lang/reader.rkt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#lang s-exp syntax/module-reader
|
||||||
|
meta/web/common/main
|
||||||
|
|
||||||
|
;; Similar to `#lang scribble/html', but with a plain scribble reader
|
||||||
|
;; (not the inside one).
|
||||||
|
|
||||||
|
#:read scribble:read
|
||||||
|
#:read-syntax scribble:read-syntax
|
||||||
|
#:info (web-reader-info)
|
||||||
|
|
||||||
|
(require (prefix-in scribble: scribble/reader))
|
||||||
|
|
||||||
|
(define (web-reader-info)
|
||||||
|
(lambda (key defval default)
|
||||||
|
(case key
|
||||||
|
[(color-lexer)
|
||||||
|
(dynamic-require 'syntax-color/scribble-lexer 'scribble-lexer)]
|
||||||
|
[else (default key defval)])))
|
3
new-racket-web/web/minis/all.rkt
Normal file
3
new-racket-web/web/minis/all.rkt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require "lists.rkt" "bugs.rkt" "drracket.rkt")
|
265
new-racket-web/web/minis/bugs.rkt
Normal file
265
new-racket-web/web/minis/bugs.rkt
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(define-context "bugs")
|
||||||
|
|
||||||
|
(define planet-bugs "http://planet.racket-lang.org/trac/newticket")
|
||||||
|
|
||||||
|
;; a starred option is the default
|
||||||
|
(define platform-options
|
||||||
|
'([* "...or choose" ""]
|
||||||
|
["Windows 7/Vista, 32-bit" windows-7-32]
|
||||||
|
["Windows 7/Vista, 64-bit" windows-7-64]
|
||||||
|
["Windows Vista" windows-vista]
|
||||||
|
["Windows XP" windows-xp]
|
||||||
|
["Windows 2000" windows-2000]
|
||||||
|
["Windows NT" windows-nt]
|
||||||
|
["Windows 95/98/Me" windows-9x]
|
||||||
|
["Mac OS X PowerPC (MacOS X)" mac-ppc-osx]
|
||||||
|
["Mac OS X Intel (MacOS X)" mac-i386-osx]
|
||||||
|
["Linux, Fedora/RedHat based" linux-fedora]
|
||||||
|
["Linux, Ubuntu/Debian based" linux-ubuntu]
|
||||||
|
["Linux, other distro" linux-other]
|
||||||
|
["Sun Solaris" solaris]
|
||||||
|
;; ["Sun Solaris 8" solaris-8]
|
||||||
|
;; ["Sun Solaris, other version" solaris-other]
|
||||||
|
["Other Unix" unix-other]
|
||||||
|
;; ["Macintosh PowerPC (MacOS Classic)" mac-ppc-macos]
|
||||||
|
;; ["Macintosh 68K" mac-68k]
|
||||||
|
;; ["BeOS" beos]
|
||||||
|
;; ["MzScheme kernel" mzkernel]
|
||||||
|
))
|
||||||
|
(define severity-options
|
||||||
|
'([ "Critical" critical]
|
||||||
|
[* "Serious" serious]
|
||||||
|
[ "Non-critical" non-critical]))
|
||||||
|
(define bug-class-options
|
||||||
|
'([* "Software Bug" sw-bug]
|
||||||
|
[ "Documentation Bug" doc-bug]
|
||||||
|
[ "Change Request" change-request]
|
||||||
|
[ "Support" support]))
|
||||||
|
|
||||||
|
(require (only-in "../www/download.rkt" download))
|
||||||
|
|
||||||
|
(define (cgi-link from . to)
|
||||||
|
(apply symlink (format "/www/cgi-bin/~a" from) to))
|
||||||
|
(define bug-report-cgi (cgi-link "bug-report" "bug-report.cgi"))
|
||||||
|
(define bug-report-captcha (cgi-link "bug-report-captcha"))
|
||||||
|
|
||||||
|
(provide captcha-file+num captcha-text)
|
||||||
|
(define captcha-file+num (make-parameter #f))
|
||||||
|
(define captcha-text (make-parameter #f))
|
||||||
|
(define captcha-text-file
|
||||||
|
@plain[#:file "captcha-text" #:newline #f (or (captcha-text) "")])
|
||||||
|
|
||||||
|
(define query (cgi-link "gnatsweb" "query"))
|
||||||
|
|
||||||
|
(define (bugs-script)
|
||||||
|
@script/inline{
|
||||||
|
var bugform = null;
|
||||||
|
var browser_platform = "";
|
||||||
|
var params = new Array();
|
||||||
|
var cookies = new Array();
|
||||||
|
@||
|
||||||
|
function initBugData() {
|
||||||
|
bugform = document.getElementById("BugForm");
|
||||||
|
if (navigator.platform && navigator.platform != "")
|
||||||
|
browser_platform = navigator.platform;
|
||||||
|
if (navigator.cpuClass && navigator.cpuClass != "")
|
||||||
|
browser_platform += " / " + navigator.cpuClass;
|
||||||
|
if (navigator.userAgent && navigator.userAgent != "")
|
||||||
|
browser_platform += " / " + navigator.userAgent;
|
||||||
|
if (location.search.length > 0) {
|
||||||
|
var paramstrs = location.search.substring(1).split(@"/[;&]/");
|
||||||
|
for (var i in paramstrs) {
|
||||||
|
var param = paramstrs[i].split(/=/);
|
||||||
|
if (param.length == 2)
|
||||||
|
params[param[0]] = unescape(param[1]).replace(/\+/g," ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (document.cookie.length > 0) {
|
||||||
|
var cookiestrs = document.cookie.split(@"/; */");
|
||||||
|
for (var i in cookiestrs) {
|
||||||
|
var eql = cookiestrs[i].indexOf('=');
|
||||||
|
if (eql >= 0)
|
||||||
|
cookies[cookiestrs[i].substring(0,eql)] =
|
||||||
|
unescape(cookiestrs[i].substring(eql+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (params["v"]) bugform.version.value = params["v"];
|
||||||
|
DoUserFields(RestoreUserField);
|
||||||
|
if (bugform.platform.value == "") {
|
||||||
|
if (bugform.platform_options.selectedIndex == 0) UpdatePlatformUser();
|
||||||
|
else UpdatePlatformOptions();
|
||||||
|
}
|
||||||
|
if (bugform.email.value == "") bugform.email.focus();
|
||||||
|
else if (bugform.name.value == "") bugform.name.focus();
|
||||||
|
else bugform.subject.focus();
|
||||||
|
}
|
||||||
|
@||
|
||||||
|
function SaveUserField(field, name) {
|
||||||
|
if (field.value != "") {
|
||||||
|
var d = new Date();
|
||||||
|
d.setTime(d.getTime()+(365*24*60*60*1000));
|
||||||
|
document.cookie = name + "=" + escape(field.value)
|
||||||
|
+ "; expires="+ d.toGMTString()
|
||||||
|
+ "; path=/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function RestoreUserField(field, name) {
|
||||||
|
if (field.value == "" && cookies[name]) field.value = cookies[name];
|
||||||
|
}
|
||||||
|
function DoUserFields(op) {
|
||||||
|
op(bugform.email, "email");
|
||||||
|
op(bugform.name, "name");
|
||||||
|
op(bugform.version, "version");
|
||||||
|
op(bugform.platform, "platform");
|
||||||
|
op(bugform.platform_user, "platform_user");
|
||||||
|
op(bugform.platform_options, "platform_options");
|
||||||
|
}
|
||||||
|
@||
|
||||||
|
function CheckSubmit() {
|
||||||
|
DoUserFields(SaveUserField);
|
||||||
|
if (bugform.email.value == "") {
|
||||||
|
window.alert("Please enter an Email");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bugform.subject.value == "" && bugform.description.value == "") {
|
||||||
|
window.alert("Please enter a summary and/or a description"
|
||||||
|
+ " of your bug");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bugform.version.value == "") {
|
||||||
|
window.alert("Please enter your Racket version");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@||
|
||||||
|
var old_platform_user = null;
|
||||||
|
function UpdatePlatformUser() {
|
||||||
|
var newval = bugform.platform_user.value;
|
||||||
|
if (old_platform_user != newval) {
|
||||||
|
if (newval == "" && old_platform_user != browser_platform) {
|
||||||
|
newval = browser_platform;
|
||||||
|
bugform.platform_user.value = browser_platform;
|
||||||
|
bugform.platform_user.select();
|
||||||
|
}
|
||||||
|
bugform.platform.value = newval;
|
||||||
|
bugform.platform_options.selectedIndex = 0;
|
||||||
|
bugform.platform_user.focus();
|
||||||
|
old_platform_user = newval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@||
|
||||||
|
function UpdatePlatformOptions() {
|
||||||
|
var d = new Date();
|
||||||
|
var opts = bugform.platform_options;
|
||||||
|
var newval = opts.options[opts.selectedIndex].value;
|
||||||
|
if (newval == "") {
|
||||||
|
bugform.platform.value = browser_platform;
|
||||||
|
bugform.platform_user.value = old_platform_user = browser_platform;
|
||||||
|
} else {
|
||||||
|
bugform.platform.value = newval;
|
||||||
|
bugform.platform_user.value = old_platform_user = "...or type";
|
||||||
|
}
|
||||||
|
bugform.platform_user.select();
|
||||||
|
opts.focus();
|
||||||
|
}})
|
||||||
|
|
||||||
|
(provide (rename-out [index bug-reports]))
|
||||||
|
(define index
|
||||||
|
@page[#:title "Bug Reports" #:extra-headers bugs-script
|
||||||
|
#:extra-body-attrs `(onLoad: "initBugData();")]{
|
||||||
|
@p[style: '("padding: 5px; color: #aa0000; background-color: #ffffee;"
|
||||||
|
" border: 1px solid; font-weight: bold;")]{
|
||||||
|
If you can, please use the “Submit Bug Report” item in DrRacket's Help
|
||||||
|
menu. It works better than this page, because it helps you supply
|
||||||
|
precise information about your Racket installation and working
|
||||||
|
environment.}
|
||||||
|
@p{@strong{Note:} Bug reports for PLaneT packages are submitted on the
|
||||||
|
@a[href: planet-bugs]{PLaneT server}.}
|
||||||
|
@p{Before submitting a bug report, you may wish to:
|
||||||
|
@ul{@li{Consult the @-docs,}
|
||||||
|
@li{@download a newer Racket version if there is one (Racket
|
||||||
|
displays its version number on startup),}
|
||||||
|
@li{@a[href: (list query "/")]{Query existing bug reports}.}}}
|
||||||
|
@(define (mk-options opts)
|
||||||
|
(for/list ([s (in-list opts)])
|
||||||
|
(if (eq? '* (car s))
|
||||||
|
@option[selected: 'true value: (caddr s)]{@(cadr s)}
|
||||||
|
@option[value: (cadr s)]{@(car s)})))
|
||||||
|
@(define (field name mode html-mode html-title . args)
|
||||||
|
(define title (and html-title (b html-title ":")))
|
||||||
|
(define html-input
|
||||||
|
(case mode
|
||||||
|
[(text)
|
||||||
|
(let ([args (if (memq value: args) args (list* value: "" args))])
|
||||||
|
(apply input type: 'text name: name args))]
|
||||||
|
[(textarea)
|
||||||
|
(apply textarea name: name style: "font-family: monospace;" args)]
|
||||||
|
[(options)
|
||||||
|
(if (null? args)
|
||||||
|
(error 'field "internal error (missing options)")
|
||||||
|
(apply select name: name
|
||||||
|
`(,@(cdr args) ,(mk-options (car args)))))]
|
||||||
|
[else (error 'field "internal error")]))
|
||||||
|
(case html-mode
|
||||||
|
[(line) (list (and title (list title " ")) html-input br)]
|
||||||
|
[(br) (list (and title (list title br)) html-input br br)]
|
||||||
|
[(tr) (tr (td title) (td html-input))]
|
||||||
|
[(as-is) (list (and title (list title " ")) html-input)]
|
||||||
|
[else (error 'field "internal error")]))
|
||||||
|
@form[action: bug-report-cgi method: 'post id: 'BugForm
|
||||||
|
;; enctype: "multipart/form-data"
|
||||||
|
style: '("border: 2px solid #4444ff; padding: 6px;"
|
||||||
|
" background-color: #eeeeff;")
|
||||||
|
onsubmit: "return CheckSubmit();"]{
|
||||||
|
@input[type: 'hidden name: 'cont value: thanks]
|
||||||
|
@field['name 'text 'br "Your name" size: 40]
|
||||||
|
@field['email 'text 'br "Your e-mail address" size: 40]
|
||||||
|
@field['subject 'text 'br "Summary of the problem" size: 60]
|
||||||
|
@table{
|
||||||
|
@field['version 'text 'tr "Version" size: 14]
|
||||||
|
@; Note: if this is ever used to produce something that
|
||||||
|
@; help/bug-report.rkt can parse, then the following three
|
||||||
|
@; fields are actually a single editable drop-down called
|
||||||
|
@; "platform".
|
||||||
|
@tr{@td{@b{Platform:}}
|
||||||
|
@td{@field['platform_user 'text 'as-is #f value: #f size: 30
|
||||||
|
onchange: "UpdatePlatformUser();"
|
||||||
|
onkeyup: "UpdatePlatformUser();"]@;
|
||||||
|
@|nbsp|@;
|
||||||
|
@field['platform_options 'options 'as-is #f platform-options
|
||||||
|
onchange: "UpdatePlatformOptions();"]@;
|
||||||
|
@input[type: 'hidden name: 'platform]}}
|
||||||
|
@field['severity 'options 'tr "Severity" severity-options]
|
||||||
|
@field['class 'options 'tr "Class" bug-class-options]}
|
||||||
|
@br
|
||||||
|
@field['description 'textarea 'br "Description of the problem"
|
||||||
|
rows: 12 cols: 70]
|
||||||
|
@field['how-to-repeat 'textarea 'br
|
||||||
|
'("If possible, please give a short sequence of steps to"
|
||||||
|
" reproduce the problem")
|
||||||
|
rows: 8 cols: 70]
|
||||||
|
@; An attachement requires a cgi script that can deal with input
|
||||||
|
@; that is in "multipart/form-data" format.
|
||||||
|
@; @field['file 'attachment 'line "Attachment" size: 20]
|
||||||
|
@(let* ([c (captcha-file+num)]
|
||||||
|
[n (and c (cdr c))]
|
||||||
|
[c (and c (img src: (cgi-link (car c)) align: "middle"))])
|
||||||
|
(and c @field['captcha 'text 'line
|
||||||
|
@list{Please type @c and then a “@tt{*@n}”}
|
||||||
|
size: 10]))
|
||||||
|
@input[type: 'submit value: "Submit"]}})
|
||||||
|
|
||||||
|
(define thanks
|
||||||
|
@page[#:title "Thanks!" #:extra-headers bugs-script #:referrer values]{
|
||||||
|
@p{@strong{Thanks!}}
|
||||||
|
@p{Your Racket bug report has been submitted.}
|
||||||
|
@p{You should receive an email confirming your report in a few minutes.
|
||||||
|
The confirmation will be sent to the email address you specified in
|
||||||
|
your report.}
|
||||||
|
@p{If you do not receive such confirmation, please report the problem to
|
||||||
|
@tt{@small{racket@"@"racket-lang.org}}
|
||||||
|
or to the Racket
|
||||||
|
@a[href: "http://lists.racket-lang.org/users/"]{mailing list}.}})
|
154
new-racket-web/web/minis/drracket.rkt
Normal file
154
new-racket-web/web/minis/drracket.rkt
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(define-context "drracket")
|
||||||
|
|
||||||
|
;; This just shows an ascii logo and redirects to the main page. Thanks
|
||||||
|
;; to Can Burak Cilingir for both the logo and the drracket.org domain
|
||||||
|
;; name.
|
||||||
|
|
||||||
|
(define index
|
||||||
|
(page #:title "DrRacket" #:extra-headers (lazy headers) (center-div logo)))
|
||||||
|
|
||||||
|
(require (only-in "../www/all.rkt" main))
|
||||||
|
|
||||||
|
(define (logo)
|
||||||
|
(define (text->lines text)
|
||||||
|
(cond [(null? text) '()]
|
||||||
|
[(null? (cdr text))
|
||||||
|
(if (equal? "\n" (car text)) '() text)]
|
||||||
|
[(equal? "\n" (cadr text))
|
||||||
|
(cons (car text) (text->lines (cddr text)))]
|
||||||
|
[else
|
||||||
|
(text->lines (cons (string-append (car text) (cadr text))
|
||||||
|
(cddr text)))]))
|
||||||
|
(define (do-line chars colors)
|
||||||
|
(let loop ([chars (map (λ (c) (if (eq? #\space c) nbsp c))
|
||||||
|
(string->list chars))]
|
||||||
|
[colors (string->list colors)])
|
||||||
|
(let* ([class (car colors)]
|
||||||
|
[n (for/or ([color (in-list (cdr colors))] [i (in-naturals 1)])
|
||||||
|
(and (not (equal? class color)) i))]
|
||||||
|
[block (if n (take chars n) chars)]
|
||||||
|
[block (if (eq? #\space class)
|
||||||
|
block (span class: (list "c" class) block))])
|
||||||
|
(if n
|
||||||
|
(cons block (loop (drop chars n) (drop colors n)))
|
||||||
|
(list block)))))
|
||||||
|
(pre style: "font-family: monospace, fixed; font-weight: bold;"
|
||||||
|
(add-newlines (map do-line (text->lines char-matrix)
|
||||||
|
(text->lines color-matrix)))))
|
||||||
|
|
||||||
|
(define (headers)
|
||||||
|
(list
|
||||||
|
(style/inline type: 'text/css
|
||||||
|
(add-newlines (map (λ (c) @list{.c@(car c) {
|
||||||
|
color: #@(cadr c);
|
||||||
|
background-color: #@(caddr c);
|
||||||
|
}})
|
||||||
|
colors)))
|
||||||
|
(meta http-equiv: "refresh"
|
||||||
|
content: (list "2;URL=" (url-of main)))))
|
||||||
|
|
||||||
|
(define char-matrix
|
||||||
|
@list|{
|
||||||
|
88XSS%
|
||||||
|
.888;@88@:88@XXS%tt
|
||||||
|
8@Xt tX88X X88@XS%%t:.
|
||||||
|
8%:.. ::t@88;88@XX%%t;:..
|
||||||
|
@t. 8: :X@ %888XX%%t;:. :
|
||||||
|
8 . . . 8 .S8%888@XS%%t;:. .S
|
||||||
|
@ .:8S888@XStt;;:. .;
|
||||||
|
X. . 8. :% ;888XS%tt;::. .t
|
||||||
|
@: . . . . 8% t@8X88@X%%;;::. :t
|
||||||
|
8: . % .SX%88@XStt;::.. .;S
|
||||||
|
8S . . S .%S8888XS%t;::.. .:tX
|
||||||
|
8; . . . . S 8; t@8@X@XS%t;::.. .:;S
|
||||||
|
@@: . . . 8.8 8..%@8X8@XStt;:... .:;%@
|
||||||
|
@X: . . . ;8 8XS88@X88%%;::.. ..;%@
|
||||||
|
@@: . . . X;.% 888Xtt88St;::.. .:;tX
|
||||||
|
@8; . .X..X ;@St; .8;;:.. ..:;%@
|
||||||
|
X8S. . . . 8 8 ;S8;;. 8X::. ...;t%@
|
||||||
|
%@@%. . X ; %%% :. ;tX%;:. ..:;tS8
|
||||||
|
tX8X;. . 8. .X .S@888@.:t%%@;: ..::t%S8
|
||||||
|
:%X8Xt:. . .8 . 8 ;X8888X8:;%S@X t...::;tS@@
|
||||||
|
;%@88%t;:.. . ; S :S@8888XXXX%SX888::.::;t%X8
|
||||||
|
.;tX@8@XS%ttt:t%X .tX@8888@XS%%SS@@88888.:;t%S8X
|
||||||
|
:t%X8888@@:8888 S@888888XXS%t;tSX88888@@t;t%S@8
|
||||||
|
:;t%S@88t%%% ;8888@@@SS%%t;;:::;8@88@XX @%X@8
|
||||||
|
. :;t%S:....8@@@XSSS%%tt;:::....S8@8XS X S@8
|
||||||
|
:. .:@t%;:.8%%%%ttt;;:::.... ;SXS X 8S
|
||||||
|
t:. 88X@8@;;;;;;;:::... ..:.:8 X S8
|
||||||
|
8X@88X%::.::::... ...:::;tt;. .S8
|
||||||
|
88X:.:.........::::;;;tt%%SS@;8@
|
||||||
|
8SS%tt;;;;;;t;tttt%%SSX@88X
|
||||||
|
@@XXSSSSSSSSXX@@888@
|
||||||
|
@@8888XS}|)
|
||||||
|
|
||||||
|
(define colors
|
||||||
|
'([a "000" "00a"]
|
||||||
|
[b "000" "555"]
|
||||||
|
[c "000" "a00"]
|
||||||
|
[d "00a" "000"]
|
||||||
|
[e "00a" "555"]
|
||||||
|
[f "00a" "55f"]
|
||||||
|
[g "0aa" "555"]
|
||||||
|
[h "555" "000"]
|
||||||
|
[i "555" "00a"]
|
||||||
|
[j "555" "a00"]
|
||||||
|
[k "555" "aaa"]
|
||||||
|
[l "55f" "00a"]
|
||||||
|
[m "55f" "aaa"]
|
||||||
|
[n "a00" "000"]
|
||||||
|
[o "a00" "555"]
|
||||||
|
[p "a00" "f55"]
|
||||||
|
[q "a0a" "555"]
|
||||||
|
[r "a0a" "55f"]
|
||||||
|
[s "a0a" "a00"]
|
||||||
|
[t "a0a" "aaa"]
|
||||||
|
[u "a0a" "f55"]
|
||||||
|
[v "a50" "555"]
|
||||||
|
[w "a50" "a00"]
|
||||||
|
[x "a50" "aaa"]
|
||||||
|
[y "a50" "f55"]
|
||||||
|
[z "aaa" "555"]
|
||||||
|
[0 "aaa" "f55"]
|
||||||
|
[1 "aaa" "fff"]
|
||||||
|
[2 "f55" "a00"]
|
||||||
|
[3 "f55" "aaa"]
|
||||||
|
[4 "f5f" "f55"]
|
||||||
|
[5 "fff" "aaa"]))
|
||||||
|
|
||||||
|
(define color-matrix
|
||||||
|
@list|{
|
||||||
|
ifllll
|
||||||
|
qktx555155kflllllllg
|
||||||
|
2pppppppp5111155fllllllllll
|
||||||
|
pppppppppppp511111kffllllllllllv
|
||||||
|
ppppppppppppppp1111115ffllllllllllla
|
||||||
|
jpppppppppppppppp0111111rfflllllllllliaa
|
||||||
|
ppppppppppppppppppp1111111ffllllllllllllaa
|
||||||
|
pppppppppppppppppppp11111115ffllllllllllliaa
|
||||||
|
ppppppppppppppppppppp11111111mfflllllllllllaaa
|
||||||
|
pppppppppppppppppppppp111111115fflllllllllllaaaa
|
||||||
|
2ppppppppppppppppppppp31111111115flllllllllllaaaaa
|
||||||
|
pppppppppppppppppppppp115p1111111kfllllllllllaaaaa
|
||||||
|
2ppppppppppppppppppppp111ppp1111155fllllllllllaaaaaa
|
||||||
|
2pppppppppppppppppppp511ppppp1111555ifllllllllaaaaaa
|
||||||
|
2ppppppppppppppppppp3114pppppp111555kllllllllaaaaaaa
|
||||||
|
2pppppppppppppppppp3113pppppppp155555qfllllllaaaaaaa
|
||||||
|
2ppppppppppppppppp0111pppppppppk155555illllliaaaaaaa
|
||||||
|
22ppppppppppppppp3111ppppppppppp555kkkklillaaaaaaaaa
|
||||||
|
222ppppppppppppp01113pppppppppppp5kkkkkklilaaaaaaaaa
|
||||||
|
2222ppppppppppp01111pppppppppp222kkkkkkkqliaaaaaaaad
|
||||||
|
2222pppppppppp1111ppppppppp222222kkkkkkkqlaaaaaaaa
|
||||||
|
22222pppppppu1111yppppppp22222222okkkkkzkiiaaaaaad
|
||||||
|
222222ppppy1511kppppp222222222222zkkzzzzziaaaaad
|
||||||
|
22222222255555p22222222222222222skzzzzzzgiaaad
|
||||||
|
c2222225555k222222222222222222w2okzzzzgzgaad
|
||||||
|
cc222zkkkkqp222222222222222jjjwjzzzqzqqved
|
||||||
|
ccjqkkkkk222222222222222wjcccccjqzqqqqbh
|
||||||
|
ozzzzzj2j2j2j2j2w22jccccccccccqvqqbh
|
||||||
|
ojjjccccjcccccccccccccccccccjgbh
|
||||||
|
cccccccccccccccccccccccccnn
|
||||||
|
cccccccccccccccccnnn
|
||||||
|
nncnnnnn}|)
|
168
new-racket-web/web/minis/lists.rkt
Normal file
168
new-racket-web/web/minis/lists.rkt
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(provide mailing-lists-quick)
|
||||||
|
|
||||||
|
(define-context "lists")
|
||||||
|
|
||||||
|
(struct ML (name gmane-name google-name description))
|
||||||
|
|
||||||
|
(define MLs
|
||||||
|
(list (ML "users" "user" "racket-users"
|
||||||
|
@text{A discussion list for all things related to Racket.
|
||||||
|
Ask your questions here!})
|
||||||
|
(ML "announce" "announce" #f
|
||||||
|
@text{A low-volume, moderated list for announcements, only.
|
||||||
|
@small{(These are posted on the @TT{users} list too, no need
|
||||||
|
to subscribe to both.)}})
|
||||||
|
(ML "dev" "devel" #f
|
||||||
|
@text{A mailing list for Racket development.
|
||||||
|
@small{(For people who want to see how the sausages are made
|
||||||
|
— and help make them.)}})))
|
||||||
|
|
||||||
|
(define lists
|
||||||
|
@page[#:title "Mailing Lists" #:file "" #:part-of 'community
|
||||||
|
#:description
|
||||||
|
@'{Racket mailing lists for users, developers, announcements, and more.}
|
||||||
|
(define (list-cells what) (map (λ (r) (r what)) list-renderers))
|
||||||
|
]{
|
||||||
|
@p{This is the Racket mailing list server. We have several public mailing
|
||||||
|
lists, some are listed below with several mirrors for each one. The
|
||||||
|
complete list of public mailing lists is available on
|
||||||
|
@a[href: "listinfo"]{this page}.}
|
||||||
|
@(define gap1 (tr (map (λ (_) @td{@div[style: "height: 1ex;"]{}}) MLs)))
|
||||||
|
@(define gap2 (tr (map (λ (_) @td{}) MLs)))
|
||||||
|
@(define (sec . text)
|
||||||
|
@list{@gap1
|
||||||
|
@tr{@td[style: '("background-color: #dddddd; font-weight: bold;"
|
||||||
|
" padding: 0;")
|
||||||
|
colspan: (length MLs)]{@text}}
|
||||||
|
@gap2})
|
||||||
|
@table[style: "width: 100%; margin: auto; text-align: center;"
|
||||||
|
frame: 'box rules: 'cols cellpadding: 5]{
|
||||||
|
@tr[style: "border-bottom: 1px solid; background-color: #ccccff;"]{
|
||||||
|
@(list-cells 'header-cell)}
|
||||||
|
@tr[valign: 'top style: "text-align: left;"]{@(list-cells 'description)}
|
||||||
|
@tr{@(list-cells 'main-page-cell)}
|
||||||
|
@tr{@(list-cells 'graph-cell)}
|
||||||
|
@sec{Subscription: enter your email here to subscribe to a mailing list}
|
||||||
|
@tr{@(list-cells 'subscribe-cell)}
|
||||||
|
@sec{Gmane Mirror}
|
||||||
|
@tr{@(list-cells 'gmane-cell)}
|
||||||
|
@sec{Archive at mail-archive.com}
|
||||||
|
@tr{@(list-cells 'mail-archive-cell)}
|
||||||
|
@sec{Google group mirror}
|
||||||
|
@tr{@(list-cells 'google-cell)}}})
|
||||||
|
|
||||||
|
(define (list-renderer ml)
|
||||||
|
(define name (ML-name ml))
|
||||||
|
(define at-domain "@racket-lang.org")
|
||||||
|
(define email (list name at-domain))
|
||||||
|
(define description (ML-description ml))
|
||||||
|
(define gmane
|
||||||
|
(let ([gm (ML-gmane-name ml)])
|
||||||
|
(and gm @list{gmane.comp.lang.racket.@(ML-gmane-name ml)})))
|
||||||
|
(define (gmane-link base . body)
|
||||||
|
(unless gmane
|
||||||
|
(error 'list-renderer "internal error: no gmane info for ~a" name))
|
||||||
|
(let* ([path (if (pair? base) (list "/" (cdr base) "/") "/")]
|
||||||
|
[base (if (pair? base) (car base) base)]
|
||||||
|
[pfx (if (regexp-match? #rx"://" base) base (list "http://" base))])
|
||||||
|
@a[href: (list pfx ".gmane.org" path gmane)]{@body}))
|
||||||
|
(define (mail-archive-link suffix . body)
|
||||||
|
@a[href: (list "http://www.mail-archive.com/" email "/" suffix)]{@body})
|
||||||
|
(define google-groups-url
|
||||||
|
(let ([g (ML-google-name ml)])
|
||||||
|
(and g (list "http://groups.google.com/group/" g "/"))))
|
||||||
|
(define ((mk-form make) url #:method [method 'get] . body)
|
||||||
|
(make @form[action: url method: method
|
||||||
|
style: "display: inline; clear: none;"]{
|
||||||
|
@div{@body}}))
|
||||||
|
(define (mk-subscribe mk)
|
||||||
|
@(mk-form mk)[(list (url-of lists #t) name "/subscribe") #:method 'post]{
|
||||||
|
@input[type: 'text name: 'email size: 20 value: ""
|
||||||
|
placeholder: "Email to Subscribe"
|
||||||
|
title: @list{Enter your email to subscribe
|
||||||
|
to the "@name" mailing list.}]})
|
||||||
|
(define form-cell (mk-form td))
|
||||||
|
(λ (what)
|
||||||
|
(case what
|
||||||
|
[(header-cell)
|
||||||
|
@th[style: "width: 33%;"]{
|
||||||
|
@; the mixed styles will help against some spam harvesting too
|
||||||
|
@span[style: '("font-size: x-large;"
|
||||||
|
" font-family: monospace; font-weight: bold;")]{
|
||||||
|
@TT{@name}@;
|
||||||
|
@span[style: "font-size: small;"]{@at-domain}}}]
|
||||||
|
[(description) @td{@description}]
|
||||||
|
[(main-page-cell)
|
||||||
|
@td{@a[href: (list name "/")]{@big{@b{@TT{@name}}} page}
|
||||||
|
@bull
|
||||||
|
@a[href: (list name "/archive/")]{archive}}]
|
||||||
|
[(graph-cell)
|
||||||
|
@td{@img[src: (list "http://gmane.org/plot-rate.php?group=" gmane)
|
||||||
|
style: "width: 80%;"]}]
|
||||||
|
[(subscribe-cell) (mk-subscribe td)]
|
||||||
|
[(google-cell)
|
||||||
|
(if google-groups-url
|
||||||
|
@form-cell[(list google-groups-url "search")]{
|
||||||
|
@a[href: google-groups-url]{
|
||||||
|
@(string-titlecase
|
||||||
|
(regexp-replace* #rx"-" (ML-google-name ml) " "))}
|
||||||
|
@br
|
||||||
|
@span[style: "white-space: nowrap;"]{
|
||||||
|
Search: @input[type: 'text name: 'q value: "" size: 20].}}
|
||||||
|
@td{@small{—none—}})]
|
||||||
|
[(mail-archive-cell)
|
||||||
|
@form-cell["http://www.mail-archive.com/search"]{
|
||||||
|
@input[type: 'hidden name: 'l value: email]
|
||||||
|
@mail-archive-link["info.html"]{Archive}
|
||||||
|
@bull
|
||||||
|
@mail-archive-link[""]{Browse}
|
||||||
|
@bull
|
||||||
|
@mail-archive-link["maillist.xml"]{RSS}
|
||||||
|
@br
|
||||||
|
@span[style: "white-space: nowrap;"]{
|
||||||
|
Search: @input[type: 'text name: 'q value: "" size: 20].}}]
|
||||||
|
[(gmane-cell)
|
||||||
|
@form-cell["http://search.gmane.org/"]{
|
||||||
|
@input[type: 'hidden name: 'group value: gmane]
|
||||||
|
@gmane-link["dir"]{@TT{@gmane}}
|
||||||
|
@br
|
||||||
|
@gmane-link["news"]{threaded}
|
||||||
|
@bull
|
||||||
|
@gmane-link["blog"]{blog}
|
||||||
|
@bull
|
||||||
|
@gmane-link["nntp://news"]{newsgroup}
|
||||||
|
@br
|
||||||
|
Feed:
|
||||||
|
@gmane-link['("rss" "messages/complete")]{messages}
|
||||||
|
@bull
|
||||||
|
@gmane-link['("rss" "topics/complete")]{topics}
|
||||||
|
@br
|
||||||
|
@;Excerpt feed:
|
||||||
|
@;@gmane-link['("rss" "messages/excerpts")]{messages}
|
||||||
|
@;@bull
|
||||||
|
@;@gmane-link['("rss" "topics/excerpts")]{topics}
|
||||||
|
@;@br
|
||||||
|
@span[style: "white-space: nowrap;"]{
|
||||||
|
Search: @input[type: 'text name: 'query value: "" size: 20].}}]
|
||||||
|
[(quick)
|
||||||
|
@text{
|
||||||
|
@big{@TT{@b{@name}}@small{@tt{@at-domain}}}
|
||||||
|
@div[style: "margin-left: 2em;"]{
|
||||||
|
@description
|
||||||
|
@br
|
||||||
|
@div[style: "float: right;"]{@(mk-subscribe values)}
|
||||||
|
[@a[href: (list (url-of lists) name "/")]{list page},
|
||||||
|
@gmane-link["dir"]{gmane mirror},
|
||||||
|
@mail-archive-link[""]{mail-archive}@;
|
||||||
|
@(and google-groups-url
|
||||||
|
@text{, @a[href: google-groups-url]{google group mirror}})]}}]
|
||||||
|
[else (error 'list-cell "internal error")])))
|
||||||
|
|
||||||
|
(define list-renderers (map list-renderer MLs))
|
||||||
|
|
||||||
|
(define (mailing-lists-quick)
|
||||||
|
@text{@(apply parlist @strong{Mailing Lists}
|
||||||
|
(map (λ (r) (r 'quick)) list-renderers))
|
||||||
|
@p{See the @lists{mailing list server} for more details.}})
|
9
new-racket-web/web/stubs/all.rkt
Normal file
9
new-racket-web/web/stubs/all.rkt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(provide documentation planet)
|
||||||
|
|
||||||
|
(require "docs.rkt" ; for the doc tweaking script
|
||||||
|
"planet.rkt" "blog.rkt" ; these need to be copied to the service
|
||||||
|
"pre.rkt" "git.rkt" ; / these are used on the
|
||||||
|
"mailman.rkt" "dirlist.rkt" ; \ server directly
|
||||||
|
"wiki.rkt")
|
1084
new-racket-web/web/stubs/blog.rkt
Normal file
1084
new-racket-web/web/stubs/blog.rkt
Normal file
File diff suppressed because it is too large
Load Diff
19
new-racket-web/web/stubs/dirlist.rkt
Normal file
19
new-racket-web/web/stubs/dirlist.rkt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
;; This stub is to generate fancy directory listings with the Racket style
|
||||||
|
|
||||||
|
(require (prefix-in dnld: (only-in "../download/resources.rkt" the-resources)))
|
||||||
|
|
||||||
|
(define-context "stubs/dirlist" #:resources dnld:the-resources)
|
||||||
|
|
||||||
|
(define header+footer
|
||||||
|
(lazy (regexp-split #rx"{{{BODY}}}"
|
||||||
|
(xml->string @page[#:id 'browse-downloads
|
||||||
|
#:html-only #t
|
||||||
|
#:part-of 'download
|
||||||
|
"{{{BODY}}}"]))))
|
||||||
|
|
||||||
|
(define header
|
||||||
|
@plain[#:file "header.html" #:newline #f (car (force header+footer))])
|
||||||
|
(define footer
|
||||||
|
@plain[#:file "footer.html" #:newline #f (cadr (force header+footer))])
|
11
new-racket-web/web/stubs/docs.rkt
Normal file
11
new-racket-web/web/stubs/docs.rkt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require (prefix-in www: (only-in "../www/resources.rkt" the-resources)))
|
||||||
|
|
||||||
|
(define-context "stubs/docs" #:resources www:the-resources)
|
||||||
|
|
||||||
|
(provide documentation)
|
||||||
|
(define documentation
|
||||||
|
;; This is a stub page to get the header for tweaked doc pages
|
||||||
|
(page #:file "" #:link-title "Documentation" #:window-title "{{{TITLE}}}"
|
||||||
|
"\n{{{BODY}}}\n"))
|
2939
new-racket-web/web/stubs/git.rkt
Normal file
2939
new-racket-web/web/stubs/git.rkt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
new-racket-web/web/stubs/gitweb-logo.png
Normal file
BIN
new-racket-web/web/stubs/gitweb-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
633
new-racket-web/web/stubs/mailman.rkt
Normal file
633
new-racket-web/web/stubs/mailman.rkt
Normal file
|
@ -0,0 +1,633 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(define-context "stubs/mailman")
|
||||||
|
|
||||||
|
(define (MM . tag) @literal{<MM-@|tag|>})
|
||||||
|
(define (MM/ . tag) @literal{</MM-@|tag|>})
|
||||||
|
(define (MMform name . body)
|
||||||
|
(list @MM{@(and name (list name "-"))Form-Start} body @MM{Form-End}))
|
||||||
|
|
||||||
|
(define style-header
|
||||||
|
@style/inline{
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
background-color: #99ccff;
|
||||||
|
padding: 0.5em;
|
||||||
|
font-size: 150%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.1em 0.5em;
|
||||||
|
background-color: #ffddaa;
|
||||||
|
font-size: 120%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.subp {
|
||||||
|
margin: 0.5ex 0 0.5ex 1em;
|
||||||
|
}})
|
||||||
|
|
||||||
|
(define (subp . body) (apply div class: 'subp body))
|
||||||
|
(define (graytd . body) (apply td bgcolor: "#dddddd" body))
|
||||||
|
|
||||||
|
;; this should move to common
|
||||||
|
(define HOLE (literal "<<<HOLE>>>"))
|
||||||
|
(define (split-template template #:encoder [encoder values] . files)
|
||||||
|
(define p
|
||||||
|
;; use `xml->string' only if the input is not a string, since `page%%'
|
||||||
|
;; below hacks up a string, so this avoids doing double-html encoding (this
|
||||||
|
;; won't be necessary if `page%%' is done properly)
|
||||||
|
(lazy (let* ([t (force template)]
|
||||||
|
[t (if (string? t) t (xml->string t))]
|
||||||
|
[t (regexp-split #rx"<<<HOLE>>>" t)])
|
||||||
|
(unless (= (length t) (length files))
|
||||||
|
(error 'split-template "got ~e parts, but expected ~e"
|
||||||
|
(length t) (length files)))
|
||||||
|
(map encoder t))))
|
||||||
|
(for/list ([f (in-list files)] [i (in-naturals)])
|
||||||
|
(plain #:file f #:newline #f (list-ref (force p) i))))
|
||||||
|
|
||||||
|
(define generic-templates
|
||||||
|
(split-template @page[#:html-only #t #:title HOLE
|
||||||
|
#:extra-headers style-header #:part-of 'community
|
||||||
|
HOLE]
|
||||||
|
"header1.html" "header2.html" "footer.html"))
|
||||||
|
|
||||||
|
(define (make-listinfo archive?)
|
||||||
|
@page[#:title @list{Mailing lists: @MM{List-Name}} #:part-of 'community
|
||||||
|
#:extra-headers style-header
|
||||||
|
#:file (if archive? "listinfo+archive.html" "listinfo.html")]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "listinfo.html", revision: 5865
|
||||||
|
Modified to fit the racket pages, add a mail-archive searchbox for
|
||||||
|
public lists.
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
@h1{@MM{List-Name}: @MM{List-Description}}
|
||||||
|
@; --------------------
|
||||||
|
@h2{About the @MM{List-Name} list
|
||||||
|
@span[style: '("float: right; font-weight: normal; font-size: 80%;"
|
||||||
|
" margin-top: 4px;")]{
|
||||||
|
@MMform['Lang]{@MM{displang-box} @MM{list-langs}}}}
|
||||||
|
@subp{@MM{List-Info}}
|
||||||
|
@subp{To post a message to the list, send email to
|
||||||
|
@a[href: @list{mailto:@MM{Posting-Addr}}]{@MM{Posting-Addr}}.
|
||||||
|
You can subscribe to the list or change your existing subscription
|
||||||
|
options in the sections below.}
|
||||||
|
@subp{To see the collection of prior postings to the list, visit the
|
||||||
|
@MM{Archive}@MM{List-Name} archives@MM/{Archive}.
|
||||||
|
@MM{Restricted-List-Message}}
|
||||||
|
@when[archive?]{
|
||||||
|
@; This is the mail-archive search box
|
||||||
|
@form[action: "http://www.mail-archive.com/search" method: 'get]{@subp{
|
||||||
|
@input[type: 'hidden name: 'l value: @MM{Posting-Addr}]
|
||||||
|
Archives are also available at
|
||||||
|
@a[href: @list{http://www.mail-archive.com/@MM{Posting-Addr}/}]{
|
||||||
|
mail-archive.com},
|
||||||
|
search it here:
|
||||||
|
@input[type: 'text name: 'q value: "" size: 16]}
|
||||||
|
@subp{(@a[href: "/"]{More information} on other ways to use this list
|
||||||
|
and other public Racket lists.)}}}
|
||||||
|
@; --------------------
|
||||||
|
@h2{@a[name: 'subscribers]{@MM{List-Name} subscribers}}
|
||||||
|
@subp{@MMform['Options]{@MM{Editing-Options}}}
|
||||||
|
@; not needed: @subp{@MMform['Roster]{@MM{Roster-Option}}}
|
||||||
|
@; --------------------
|
||||||
|
@h2{Subscribing to @MM{List-Name}}
|
||||||
|
@subp{Subscribe to @MM{List-Name} by filling out the following form.
|
||||||
|
@MM{List-Subscription-Msg}}
|
||||||
|
@subp{
|
||||||
|
@MMform['Subscribe]{
|
||||||
|
@table[cellspacing: 2 cellpadding: 2 width: "90%" align: 'center]{
|
||||||
|
@tr{@graytd{Your email address:}
|
||||||
|
@td{@MM{Subscribe-Box}}
|
||||||
|
@td{@nbsp}}
|
||||||
|
@tr{@graytd{Your name (optional):}
|
||||||
|
@td{@MM{fullname-box}}
|
||||||
|
@td{@nbsp}}
|
||||||
|
@tr{@td[colspan: 3 style: "font-size: 82.5%;"]{
|
||||||
|
@p{You may enter a privacy password below. This provides
|
||||||
|
only mild security, but should prevent others from messing
|
||||||
|
with your subscription. @b{Do not use a valuable password}
|
||||||
|
as it will occasionally be emailed back to you in
|
||||||
|
cleartext.}
|
||||||
|
@p{If you choose not to enter a password, one will be
|
||||||
|
automatically generated for you, and it will be sent to you
|
||||||
|
once you've confirmed your subscription. You can always
|
||||||
|
request a mail-back of your password when you edit your
|
||||||
|
personal options.}
|
||||||
|
@MM{Reminder}}}
|
||||||
|
@tr{@graytd{Pick a password:}
|
||||||
|
@td{@MM{New-Password-Box}}
|
||||||
|
@td{@nbsp}}
|
||||||
|
@tr{@graytd{Reenter password to confirm:}
|
||||||
|
@td{@MM{Confirm-Password}}
|
||||||
|
@td{@nbsp}}
|
||||||
|
@tr{@graytd{Which language do you prefer to display your messages?}
|
||||||
|
@td{@MM{list-langs}}
|
||||||
|
@td{@nbsp}}
|
||||||
|
@MM{digest-question-start}
|
||||||
|
@tr{@td{Would you like to receive list mail batched in a daily
|
||||||
|
digest?}
|
||||||
|
@td{@MM{Undigest-Radio-Button} No
|
||||||
|
@MM{Digest-Radio-Button} Yes}
|
||||||
|
@td{@nbsp}}
|
||||||
|
@MM{digest-question-end}
|
||||||
|
@tr{@td[colspan: 3]{
|
||||||
|
@p[style: "text-align: center;"]{
|
||||||
|
@MM{Subscribe-Button}}}}}}}
|
||||||
|
@; --------------------
|
||||||
|
@h2{@nbsp}
|
||||||
|
@MM{Mailman-Footer}})
|
||||||
|
|
||||||
|
(define listinfos (map make-listinfo '(#t #f)))
|
||||||
|
|
||||||
|
(define subscribe
|
||||||
|
@page[#:title @list{@MM{List-Name} Subscription results} #:part-of 'community
|
||||||
|
#:extra-headers style-header]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "subscribe.html", revision: 3550
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
@h1{@MM{List-Name} Subscription results}
|
||||||
|
@subp{@MM{Results}}
|
||||||
|
@MM{Mailman-Footer}})
|
||||||
|
|
||||||
|
(define options
|
||||||
|
@page[#:title @list{@MM{Presentable-User} membership configuration
|
||||||
|
for @MM{List-Name}}
|
||||||
|
#:part-of 'community
|
||||||
|
#:extra-headers style-header]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "options.html" (no revision specified)
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
@h1{@MM{List-Name} mailing list membership configuration for
|
||||||
|
@MM{Presentable-User}}
|
||||||
|
@subp{@div[style: "float: right;"]{@MMform[#f]{@MM{logout-button}}}
|
||||||
|
@b{@MM{Presentable-User}}'s subscription status, password, and options
|
||||||
|
for the @MM{List-Name} mailing list.}
|
||||||
|
@subp{@MM{Case-Preserved-User}
|
||||||
|
@MM{Disabled-Notice}
|
||||||
|
@div[style: "background-color: #ffaaaa;"]{@MM{Results}}}
|
||||||
|
@(define (tablesec . body)
|
||||||
|
(apply table cellspacing: 5 cellpadding: 3 width: "100%" align: 'center
|
||||||
|
body))
|
||||||
|
@(define (h2sub . body)
|
||||||
|
@h2[style: "margin-bottom: 0; font-size: 100%;"]{@body})
|
||||||
|
@(define (center . body)
|
||||||
|
@div[style: "text-align: center; margin-top: 1ex;"]{@body})
|
||||||
|
@(define (global-checkbox button-name)
|
||||||
|
@div[align: 'right]{@MM{global-@|button-name|-button}@i{Set globally}})
|
||||||
|
@MMform[#f]{
|
||||||
|
@tablesec{
|
||||||
|
@tr{@td[colspan: 2]{
|
||||||
|
@h2sub{Changing your @MM{List-Name} membership information}
|
||||||
|
@subp{You can change the address that you are subscribed to the
|
||||||
|
mailing list with by entering the new address in the fields
|
||||||
|
below. Note that a confirmation email will be sent to the new
|
||||||
|
address, and the change must be confirmed before it is
|
||||||
|
processed.
|
||||||
|
@small{(Confirmations time out after about
|
||||||
|
@MM{pending-days}.)}}
|
||||||
|
@subp{You can also optionally set or change your real name
|
||||||
|
(i.e. @em{John Smith}).}
|
||||||
|
@subp{If you want to make the membership changes for all the
|
||||||
|
lists that you are subscribed to at @MM{host}, turn on the
|
||||||
|
@em{Change globally} check box.}}}
|
||||||
|
@tr{@td[align: 'center]{
|
||||||
|
@table[cellspacing: 2 cellpadding: 2 width: "80%"]{
|
||||||
|
@tr{@graytd[align: 'right]{New address:}
|
||||||
|
@td{@MM{new-address-box}}}
|
||||||
|
@tr{@graytd[align: 'right]{Again to confirm:}
|
||||||
|
@td{@MM{confirm-address-box}}}}}
|
||||||
|
@td[align: 'center]{
|
||||||
|
@table[cellspacing: 2 cellpadding: 2 width: "80%"]{
|
||||||
|
@tr{@graytd[align: 'right]{Your name (optional):}
|
||||||
|
@td{@MM{fullname-box}}}}}}
|
||||||
|
@tr{@td[colspan: 2 align: 'center]{@MM{change-address-button}}}
|
||||||
|
@tr{@td[colspan: 2 align: 'center]{
|
||||||
|
@MM{global-change-of-address}Change globally}}}
|
||||||
|
@tablesec{
|
||||||
|
@tr{@td[width: "50%"]{@h2sub{Unsubscribing from @MM{List-Name}}}
|
||||||
|
@td[width: "50%"]{@h2sub{Your other @MM{Host} subscriptions}}}
|
||||||
|
@tr{@td{Turn on the confirmation checkbox and hit this button to
|
||||||
|
unsubscribe from this mailing list.
|
||||||
|
@br
|
||||||
|
@strong{Warning:} This action will be taken immediately!
|
||||||
|
@center{@MM{Unsubscribe-Button}}}
|
||||||
|
@td{You can view a list of all the other mailing lists at
|
||||||
|
@MM{host} for which you are a member. Use this if you want to
|
||||||
|
make the same membership option changes to this other
|
||||||
|
subscriptions.
|
||||||
|
@center{@MM{Other-Subscriptions-Submit}}}}}
|
||||||
|
@tablesec{
|
||||||
|
@tr{@td[colspan: 2]{@h2sub{Your @MM{List-Name} Password}}}
|
||||||
|
@tr[valign: 'top]{
|
||||||
|
@td[width: "50%"]{
|
||||||
|
@h3{@a[name: "reminder"]{Forgotten Your Password?}}
|
||||||
|
Click this button to have your password emailed to your membership
|
||||||
|
address.
|
||||||
|
@br
|
||||||
|
@MM{Umbrella-Notice}
|
||||||
|
@center{@MM{Email-My-Pw}}}
|
||||||
|
@td[width: "50%"]{
|
||||||
|
@h3{@a[name: "changepw"]{Change Your Password}}
|
||||||
|
@table[cellspacing: 2 cellpadding: 2 width: "70%" align: 'center]{
|
||||||
|
@tr{@graytd[align: 'right]{New password:}
|
||||||
|
@td{@MM{New-Pass-Box}}}
|
||||||
|
@tr{@graytd[align: 'right]{Again to confirm:}
|
||||||
|
@td{@MM{Confirm-Pass-Box}}}}
|
||||||
|
@center{@MM{Change-Pass-Button}}
|
||||||
|
@center{@MM{global-pw-changes-button}Change globally}}}}
|
||||||
|
@tablesec{
|
||||||
|
@tr{@td[colspan: 2]{@h2sub{Your @MM{List-Name} Subscription Options}}}
|
||||||
|
@tr{@td[colspan: 2]{
|
||||||
|
@subp{@em{Current values are checked.}}
|
||||||
|
@subp{Note that some of the options have a @em{Set globally}
|
||||||
|
checkbox. Checking this field will cause the changes to be
|
||||||
|
made to every mailing list that you are a member of on
|
||||||
|
@MM{host}. Click on @em{List my other subscriptions} above to
|
||||||
|
see which other mailing lists you are subscribed to.}}}
|
||||||
|
@tr{@graytd[width: "80%"]{
|
||||||
|
@a[name: "disable"]{@strong{Mail delivery}} @br
|
||||||
|
Set this option to @em{Enabled} to receive messages posted to
|
||||||
|
this mailing list. Set it to @em{Disabled} if you want to stay
|
||||||
|
subscribed, but don't want mail delivered to you for a while
|
||||||
|
(e.g. you're reading the list elsewhere).}
|
||||||
|
@graytd[width: "20%"]{
|
||||||
|
@MM{delivery-enable-button}Enabled @br
|
||||||
|
@MM{delivery-disable-button}Disabled @br
|
||||||
|
@global-checkbox{deliver}}}
|
||||||
|
@tr{@graytd{@strong{Set Digest Mode} @br
|
||||||
|
If you turn digest mode on, you'll get posts bundled together
|
||||||
|
(usually one per day but possibly more on busy lists), instead of
|
||||||
|
singly when they're sent. If digest mode is changed from on to
|
||||||
|
off, you may receive one last digest.}
|
||||||
|
@graytd{
|
||||||
|
@MM{Undigest-Radio-Button}Off @br
|
||||||
|
@MM{Digest-Radio-Button}On}}
|
||||||
|
@tr{@graytd{@strong{Get MIME or Plain Text Digests?} @br
|
||||||
|
Your mail reader may or may not support MIME digests. In general
|
||||||
|
MIME digests are preferred, but if you have a problem reading
|
||||||
|
them, select plain text digests.}
|
||||||
|
@graytd{
|
||||||
|
@MM{Mime-Digests-Button}MIME @br
|
||||||
|
@MM{Plain-Digests-Button}Plain Text @br
|
||||||
|
@global-checkbox{mime}}}
|
||||||
|
@tr{@graytd{@strong{Receive your own posts to the list?} @br
|
||||||
|
Ordinarily, you will get a copy of every message you post to the
|
||||||
|
list. If you don't want to receive this copy, set this option to
|
||||||
|
@em{No}.}
|
||||||
|
@graytd{@MM{dont-receive-own-mail-button}No @br
|
||||||
|
@MM{receive-own-mail-button}Yes}}
|
||||||
|
@tr{@graytd{@strong{Receive acknowledgement mail when you send mail to
|
||||||
|
the list?}}
|
||||||
|
@graytd{
|
||||||
|
@MM{dont-ack-posts-button}No @br
|
||||||
|
@MM{ack-posts-button}Yes}}
|
||||||
|
@tr{@graytd{@strong{Get password reminder email for this list?} @br
|
||||||
|
Once a month, you will get an email containing a password
|
||||||
|
reminder for every list at this host to which you are subscribed.
|
||||||
|
You can turn this off on a per-list basis by selecting @em{No}
|
||||||
|
for this option. If you turn off password reminders for all the
|
||||||
|
lists you are subscribed to, no reminder email will be sent to
|
||||||
|
you.}
|
||||||
|
@graytd{
|
||||||
|
@MM{dont-get-password-reminder-button}No @br
|
||||||
|
@MM{get-password-reminder-button}Yes @p
|
||||||
|
@global-checkbox{remind}}}
|
||||||
|
@tr{@graytd{@strong{Conceal yourself from subscriber list?} @br
|
||||||
|
When someone views the list membership, your email address is
|
||||||
|
normally shown (in an obscured fashion to thwart spam
|
||||||
|
harvesters). If you do not want your email address to show up on
|
||||||
|
this membership roster at all, select @em{Yes} for this option.}
|
||||||
|
@graytd{
|
||||||
|
@MM{Public-Subscription-Button}No @br
|
||||||
|
@MM{Hide-Subscription-Button}Yes}}
|
||||||
|
@tr{@graytd{@strong{What language do you prefer?}}
|
||||||
|
@graytd{@MM{list-langs}}}
|
||||||
|
@tr{@graytd{@strong{Which topic categories would you like to subscribe
|
||||||
|
to?} @br
|
||||||
|
By selecting one or more topics, you can filter the traffic on
|
||||||
|
the mailing list, so as to receive only a subset of the messages.
|
||||||
|
If a message matches one of your selected topics, then you will
|
||||||
|
get the message,otherwise you will not.
|
||||||
|
@br
|
||||||
|
If a message does not match any topic, the delivery rule depends
|
||||||
|
on the setting of the option below. If you do not select any
|
||||||
|
topics of interest, you will get all the messages sent to the
|
||||||
|
mailing list.}
|
||||||
|
@graytd{@MM{topics}}}
|
||||||
|
@tr{@graytd{@strong{Do you want to receive messages that do not match
|
||||||
|
any topic filter?} @br
|
||||||
|
This option only takes effect if you've subscribed to at least
|
||||||
|
one topic above. It describes what the default delivery rule is
|
||||||
|
for messages that don't match any topic filter. Selecting
|
||||||
|
@em{No} says that if the message does not match any topic
|
||||||
|
filters, then you won't get the message, while selecting @em{Yes}
|
||||||
|
says to deliver such non-matching messages to you.
|
||||||
|
@br
|
||||||
|
If no topics of interest are selected above, then you will
|
||||||
|
receive every message sent to the mailing list.}
|
||||||
|
@graytd{
|
||||||
|
@MM{suppress-nonmatching-topics}No @br
|
||||||
|
@MM{receive-nonmatching-topics}Yes}}
|
||||||
|
@tr{@graytd{@strong{Avoid duplicate copies of messages?} @br
|
||||||
|
When you are listed explicitly in the @tt{To:} or @tt{Cc:}
|
||||||
|
headers of a list message, you can opt to not receive another
|
||||||
|
copy from the mailing list. Select @em{Yes} to avoid receiving
|
||||||
|
copies from the mailing list; select @em{No} to receive copies.
|
||||||
|
@br
|
||||||
|
If the list has member personalized messages enabled, and you
|
||||||
|
elect to receive copies, every copy will have a
|
||||||
|
@tt{X-Mailman-Copy: yes} header added to it.}
|
||||||
|
@graytd{
|
||||||
|
@MM{receive-duplicates-button}No @br
|
||||||
|
@MM{dont-receive-duplicates-button}Yes @br
|
||||||
|
@global-checkbox{nodupes}}}
|
||||||
|
@tr{@td[colspan: 2 align: 'center]{@MM{options-Submit-button}}}}}
|
||||||
|
@MM{Mailman-Footer}})
|
||||||
|
|
||||||
|
(define roster
|
||||||
|
@page[#:title @list{@MM{List-Name} subscribers}
|
||||||
|
#:part-of 'community
|
||||||
|
#:extra-headers style-header]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "roster.html", revision 3394
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
@h1{@MM{List-Name} subscribers}
|
||||||
|
@; @p[align: 'right]{
|
||||||
|
@; @MM{lang-form-start}@MM{displang-box} @MM{list-langs}@MM{form-end}}
|
||||||
|
@p{Click on your address to visit your subscription options page.
|
||||||
|
@br
|
||||||
|
@i{(Parenthesized entries have list delivery disabled.)}}
|
||||||
|
@table[cellspacing: 4 cellpadding: 5 width: "80%" align: 'center]{
|
||||||
|
@thead{
|
||||||
|
@tr[valign: 'top]{
|
||||||
|
@graytd[width: "50%" align: 'center]{
|
||||||
|
@MM{Num-Reg-Users} Non-digested Members:}
|
||||||
|
@graytd[width: "50%" align: 'center]{
|
||||||
|
@MM{Num-Digesters} Digested Members:}}}
|
||||||
|
@tr[valign: 'top]{
|
||||||
|
@td{@MM{Regular-Users}}
|
||||||
|
@td{@MM{Digest-Users}}}}
|
||||||
|
@MM{Mailman-Footer}})
|
||||||
|
|
||||||
|
;; Files below go through "%(...)s" substitutions, so "%"s should be doubled to
|
||||||
|
;; avoid python errors -- hack this with regexps below. A proper solution
|
||||||
|
;; would be to use the improved feature that `with-writer' is not, then have
|
||||||
|
;; this code use it to add another substitution.
|
||||||
|
(define (encode-%s content)
|
||||||
|
(regexp-replace*
|
||||||
|
#rx"%[^(]"
|
||||||
|
(let ([c (force content)]) (if (string? c) c (xml->string c)))
|
||||||
|
"%\\0"))
|
||||||
|
(require (for-syntax racket/base))
|
||||||
|
(define-syntax (page%% stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(page%% #:html-only #t x ...)
|
||||||
|
#`(lazy (encode-%s (page #:html-only #t x ...)))]
|
||||||
|
[(page%% x ...)
|
||||||
|
(let ([id (or (syntax-property stx 'inferred-name)
|
||||||
|
(syntax-local-name))])
|
||||||
|
#`(plain #,@(if id #`(#:id '#,id) #`()) #:suffix "html" #:newline #f
|
||||||
|
(page%% #:html-only #t x ...)))]))
|
||||||
|
|
||||||
|
(define private
|
||||||
|
@page%%[#:title @list{%(realname)s private archives authentication}
|
||||||
|
#:part-of 'community
|
||||||
|
#:extra-headers
|
||||||
|
@list{@style-header
|
||||||
|
@script/inline{function sf(){document.f.adminpw.focus()@";"}}}
|
||||||
|
#:extra-body-attrs `(onLoad: "sf();")]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "private.html" (no revision specified)
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
%(message)s
|
||||||
|
@form[method: 'post action: "%(action)s" name: "f"]{
|
||||||
|
@h1{%(realname)s private archives authentication}
|
||||||
|
@table[cellspacing: 4 cellpadding: 5 width: "80%" align: 'center]{
|
||||||
|
@tr{@td[align: 'right]{Email address:}
|
||||||
|
@td{@input[type: 'text name: 'username size: 30]}}
|
||||||
|
@tr{@td[align: 'right]{Password:}
|
||||||
|
@td{@input[type: 'password name: 'password size: 30]}}
|
||||||
|
@tr{@td[colspan: 2 align: 'middle]{
|
||||||
|
@input[type: 'submit name: 'submit value: "Let me in..."]}}}}
|
||||||
|
@p{@strong{Important:} From this point on, you must have cookies enabled in
|
||||||
|
your browser, otherwise you will have to re-authenticate with every
|
||||||
|
operation.}
|
||||||
|
@p{Session cookies are used in Mailman's private archive interface so that
|
||||||
|
you don't need to re-authenticate with every operation. This cookie will
|
||||||
|
expire automatically when you exit your browser, or you can explicitly
|
||||||
|
expire the cookie by visiting your member options page and clicking the
|
||||||
|
@em{Log out} button.}
|
||||||
|
@h2{Password reminder}
|
||||||
|
@p{If you don't remember your password, enter your email address above and
|
||||||
|
click the @em{Remind} button and your password will be emailed to you.}})
|
||||||
|
|
||||||
|
(define admlogin
|
||||||
|
@page%%[#:title @list{%(listname)s %(who)s Authentication}
|
||||||
|
#:part-of 'community
|
||||||
|
#:extra-headers
|
||||||
|
@list{@style-header
|
||||||
|
@script/inline{function sf(){document.f.adminpw.focus()@";"}}}
|
||||||
|
#:extra-body-attrs `(onLoad: "sf();")]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "admlogin.html" (no revision specified)
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
%(message)s
|
||||||
|
@form[method: 'post action: "%(path)s" name: "f"]{
|
||||||
|
@h1{%(listname)s %(who)s authentication}
|
||||||
|
@table[cellspacing: 4 cellpadding: 5 width: "80%" align: 'center]{
|
||||||
|
@tr{@td[align: 'right]{List %(who)s Password:}
|
||||||
|
@td{@input[type: 'password name: 'adminpw size: 30]}}
|
||||||
|
@tr{@td[colspan: 2 align: 'middle]{
|
||||||
|
@input[type: 'submit name: 'admlogin value: "Let me in..."]}}}}
|
||||||
|
@p{@strong{Important:} From this point on, you must have cookies enabled in
|
||||||
|
your browser, otherwise no administrative changes will take effect.}
|
||||||
|
@p{Session cookies are used in Mailman's administrative interface so that
|
||||||
|
you don't need to re-authenticate with every administrative operation.
|
||||||
|
This cookie will expire automatically when you exit your browser, or you
|
||||||
|
can explicitly expire the cookie by hitting the @em{Logout} link under
|
||||||
|
@em{Other Administrative Activities} (which you'll see once you
|
||||||
|
successfully log in).}})
|
||||||
|
|
||||||
|
;; Archive templates
|
||||||
|
|
||||||
|
(define emptyarchive
|
||||||
|
@page%%[#:title @list{%(listname)s archives} #:part-of 'community
|
||||||
|
#:extra-headers style-header]{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "emptyarchive.html" (no revision specified)
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
@h1{%(listname)s archives}
|
||||||
|
@p{No messages have been posted to this list yet, so the archives are
|
||||||
|
currently empty. You can get @a[href: "%(listinfo)s"]{more information
|
||||||
|
about this list}.}})
|
||||||
|
|
||||||
|
(define archtocs
|
||||||
|
(let ([title @list{%(listname)s archives}]
|
||||||
|
[headers @list{@style-header
|
||||||
|
@;meta[name: 'robots content: "noindex,follow"]
|
||||||
|
%(meta)s}])
|
||||||
|
(define (content mbox?)
|
||||||
|
@list{
|
||||||
|
@; --------------------
|
||||||
|
@comment{@||
|
||||||
|
Based on the Mailman file "archtoc.html" and "archtocnombox.html"
|
||||||
|
(no revision specified)
|
||||||
|
Modified to fit the racket pages
|
||||||
|
@||}
|
||||||
|
@; --------------------
|
||||||
|
@h1{%(listname)s archives}
|
||||||
|
@p{You can get @;
|
||||||
|
@a[href: "%(listinfo)s"]{more information about this list}@;
|
||||||
|
@(when mbox?
|
||||||
|
@list{ or you can @;
|
||||||
|
@a[href: "%(fullarch)s"]{download the full raw archive} @;
|
||||||
|
(%(size)s)}).}
|
||||||
|
%(noarchive_msg)s
|
||||||
|
%(archive_listing_start)s
|
||||||
|
%(archive_listing)s
|
||||||
|
%(archive_listing_end)s})
|
||||||
|
(define archtoc.html
|
||||||
|
(@page%% #:title title #:part-of 'community #:extra-headers headers
|
||||||
|
(content #t)))
|
||||||
|
(define archtocnombox.html
|
||||||
|
(@page%% #:title title #:part-of 'community #:extra-headers headers
|
||||||
|
(content #f)))
|
||||||
|
(list archtoc.html archtocnombox.html)))
|
||||||
|
|
||||||
|
(define archlist-templates
|
||||||
|
(split-template
|
||||||
|
#:encoder encode-%s
|
||||||
|
@table[border: 2 bordercolor: "#888" cellspacing: 0 cellpadding: 5
|
||||||
|
align: 'center]{
|
||||||
|
@tr{@td{Archive}
|
||||||
|
@td{View by:}
|
||||||
|
@td{Downloadable version}}
|
||||||
|
@HOLE
|
||||||
|
@tr{@td[align: 'right]{%(archivelabel)s:}
|
||||||
|
@td{@a[href: "%(archive)s/thread.html"]{[Thread]} @;
|
||||||
|
@a[href: "%(archive)s/subject.html"]{[Subject]} @;
|
||||||
|
@a[href: "%(archive)s/author.html"]{[Author]} @;
|
||||||
|
@a[href: "%(archive)s/date.html"]{[Date]}}
|
||||||
|
%(textlink)s}
|
||||||
|
@HOLE}
|
||||||
|
"archliststart.html" "archtocentry.html" "archlistend.html"))
|
||||||
|
|
||||||
|
(define archiveidx-templates
|
||||||
|
(split-template
|
||||||
|
@page%%[#:html-only #t
|
||||||
|
#:title "%(listname)s %(archive)s archives by %(archtype)s"
|
||||||
|
#:part-of 'community
|
||||||
|
#:extra-headers @list{@style-header
|
||||||
|
@;meta[name: 'robots content: "noindex,follow"]
|
||||||
|
%(encoding)s}]{
|
||||||
|
@(define sorted-info
|
||||||
|
@ul{@li{@b{Messages sorted by:}
|
||||||
|
%(thread_ref)s %(subject_ref)s %(author_ref)s %(date_ref)s}
|
||||||
|
@li{@a[href: "%(listinfo)s"]{More info on this list...}}})
|
||||||
|
@a[name: "start"]
|
||||||
|
@h1{%(archive)s archives by %(archtype)s}
|
||||||
|
@sorted-info
|
||||||
|
@p{@b{Starting:} @i{%(firstdate)s}@br
|
||||||
|
@b{Ending:} @i{%(lastdate)s}@br
|
||||||
|
@b{Messages:} %(size)s}
|
||||||
|
@ul{
|
||||||
|
@|HOLE|@;
|
||||||
|
@li{@a[href: "%(filename)s" name: "%(sequence)i"]{%(subject)s},
|
||||||
|
@i{%(author)s}}
|
||||||
|
@HOLE}
|
||||||
|
@p{@a[name: "end"]{@b{Last message date:}} @i{%(lastdate)s}@br
|
||||||
|
@b{Archived on:} @i{%(archivedate)s}}
|
||||||
|
@sorted-info
|
||||||
|
@hr
|
||||||
|
@p[style: "text-align: right; font-size: x-small; font-style: italic;"]{
|
||||||
|
(This archive was generated by Pipermail %(version)s.)}}
|
||||||
|
"archidxhead.html" "archidxentry.html" "archidxfoot.html"))
|
||||||
|
|
||||||
|
(define article
|
||||||
|
@page%%[#:title @list{%(title)s}
|
||||||
|
#:part-of 'community
|
||||||
|
#:extra-headers
|
||||||
|
@list{@style-header
|
||||||
|
@link[rel: 'index href: "index.html"]
|
||||||
|
@link[rel: 'made
|
||||||
|
href: '@{mailto:%(email_url)s?Subject=%(subject_url)s&@;
|
||||||
|
In-Reply-To=%(in_reply_to_url)s}]
|
||||||
|
@;meta[name: 'robots content: "index,nofollow"]
|
||||||
|
@style/inline{pre { white-space: pre-wrap@";" }}
|
||||||
|
%(encoding)s
|
||||||
|
%(prev)s
|
||||||
|
%(next)s}]{
|
||||||
|
@(define sorted-by
|
||||||
|
@list{Messages sorted by: @;
|
||||||
|
@a[href: "date.html#%(sequence)s"]{[date]}
|
||||||
|
@a[href: "thread.html#%(sequence)s"]{[thread]}
|
||||||
|
@a[href: "subject.html#%(sequence)s"]{[subject]}
|
||||||
|
@a[href: "author.html#%(sequence)s"]{[author]}})
|
||||||
|
@(define navcell
|
||||||
|
(let ([n 0])
|
||||||
|
(λ () (set! n (add1 n))
|
||||||
|
@td{@ul[style: "font-size: x-small;"]{
|
||||||
|
@; need only one of these things, at the end
|
||||||
|
@(when (= n 2) (list "\n" @comment{threads} "\n"))@;
|
||||||
|
%(prev_wsubj)s
|
||||||
|
%(next_wsubj)s
|
||||||
|
@li{@sorted-by}}})))
|
||||||
|
@; --------------------
|
||||||
|
@; Based on the Mailman file "article.html" (no revision specified)
|
||||||
|
@; Modified to fit the racket pages
|
||||||
|
@; (This comment is not included on actual archive message pages)
|
||||||
|
@; --------------------
|
||||||
|
@h1{%(subject_html)s}
|
||||||
|
@table{@tr{@td{
|
||||||
|
From: @b{%(author_html)s} @;
|
||||||
|
(@a[href: '@{mailto:%(email_url)s?Subject=%(subject_url)s&@;
|
||||||
|
In-Reply-To=%(in_reply_to_url)s}
|
||||||
|
title: "%(subject_html)s"]{
|
||||||
|
%(email_html)s})@;
|
||||||
|
@br
|
||||||
|
Date: @i{%(datestr_html)s}}
|
||||||
|
@navcell}}
|
||||||
|
@hr
|
||||||
|
@comment{beginarticle}
|
||||||
|
%(body)s
|
||||||
|
@comment{endarticle}
|
||||||
|
@hr
|
||||||
|
@table{@tr{@td{Posted on the @;
|
||||||
|
@a[href: "%(listurl)s"]{%(listname)s mailing list}.}
|
||||||
|
@navcell}}})
|
||||||
|
|
||||||
|
;; Previously mailman had a "site" directory which would override the default
|
||||||
|
;; "en" files. I don't see this setup now, so a cheap hack is to create
|
||||||
|
;; symlinks to a directory with the original versions for all files that are
|
||||||
|
;; not generated above.
|
||||||
|
(define symlinks
|
||||||
|
(map (λ(f) (symlink (format "/etc/mailman/templates/en-orig/~a" f)))
|
||||||
|
'("admindbdetails.html" "admindbpreamble.html" "admindbsummary.html"
|
||||||
|
"adminsubscribeack.txt" "adminunsubscribeack.txt" "approve.txt"
|
||||||
|
"bounce.txt" "checkdbs.txt" "convert.txt" "cronpass.txt" "disabled.txt"
|
||||||
|
"headfoot.html" "help.txt" "invite.txt" "masthead.txt" "newlist.txt"
|
||||||
|
"nomoretoday.txt" "postack.txt" "postauth.txt" "postheld.txt"
|
||||||
|
"probe.txt" "refuse.txt" "subauth.txt" "subscribeack.txt" "unsub.txt"
|
||||||
|
"unsubauth.txt" "userpass.txt" "verify.txt")))
|
17
new-racket-web/web/stubs/planet.rkt
Normal file
17
new-racket-web/web/stubs/planet.rkt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(define-context "stubs/planet")
|
||||||
|
|
||||||
|
(provide planet)
|
||||||
|
(define planet
|
||||||
|
@page[#:file "" #:link-title "PLaneT" #:window-title "{{{TITLE}}}"
|
||||||
|
#:extra-headers "{{{HEAD}}}"]{
|
||||||
|
@; This is a stub page to get the header for planet
|
||||||
|
{{{BODY}}}})
|
||||||
|
|
||||||
|
(define readme
|
||||||
|
@plain[#:file "README"]{
|
||||||
|
This directory contains files that are placed here automatically by
|
||||||
|
the web build process. The HTML file contains holes to be filled in
|
||||||
|
for the title, header, and body, and the other files are resources
|
||||||
|
that are used by the template.})
|
299
new-racket-web/web/stubs/pre.rkt
Normal file
299
new-racket-web/web/stubs/pre.rkt
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "git.rkt")
|
||||||
|
|
||||||
|
(define-context "stubs/pre")
|
||||||
|
|
||||||
|
(define temporary-outdated-warning
|
||||||
|
@div[style: "border: 1px dotted red; padding: 0ex 1ex"]{
|
||||||
|
@p*{
|
||||||
|
This page is not currently updating with new nightly builds, but it will
|
||||||
|
resume soon.
|
||||||
|
@~
|
||||||
|
Meanwhile, recent builds for various platforms are available from the
|
||||||
|
following sites:
|
||||||
|
@ul*{@~ @a[href: "http://www.cs.utah.edu/plt/snapshots/"]{
|
||||||
|
University of Utah}
|
||||||
|
@~ @a[href: "http://plt.eecs.northwestern.edu/snapshots/"]{
|
||||||
|
Northwestern University}}}})
|
||||||
|
|
||||||
|
(define (hole tag)
|
||||||
|
@list{@||
|
||||||
|
{{{@tag}}}
|
||||||
|
@||})
|
||||||
|
|
||||||
|
(define title-hole (list "Prebuilt:" (hole "TITLE")))
|
||||||
|
(define content-hole (hole "CONTENT"))
|
||||||
|
(define version-hole
|
||||||
|
(div style: "text-align: right; font-size: small; font-style: italic;"
|
||||||
|
(hole "VERSION")))
|
||||||
|
|
||||||
|
(define template
|
||||||
|
;; generic skeleton for all files that don't have a specific template below.
|
||||||
|
@page[#:window-title title-hole]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@content-hole
|
||||||
|
@hr
|
||||||
|
@version-hole})
|
||||||
|
|
||||||
|
(provide index)
|
||||||
|
(define index
|
||||||
|
@page[#:file "" #:window-title "Prebuilt materials"]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@p{This directory contains Racket materials that are built daily from the
|
||||||
|
development repository. See below for instructions.}
|
||||||
|
@hr
|
||||||
|
@content-hole
|
||||||
|
@hr
|
||||||
|
@p*{
|
||||||
|
The nightly-builds page is being built every night from the current @git,
|
||||||
|
which lets you use the latest material with close to zero hassle that is
|
||||||
|
normally associated with checking out the development tree. You can
|
||||||
|
choose whether you want to use the full source tree, which means that you
|
||||||
|
will get a lot more than you get with a standard distribution, or the
|
||||||
|
installers that contain the same material as a standard distribution.
|
||||||
|
@~
|
||||||
|
For the easiest way of getting a build, choose an installer for your
|
||||||
|
platform from the @a[href: "installers/"]{@tt{installers}} directory.
|
||||||
|
@~
|
||||||
|
For an approach that is more suitable for scripting, you should:
|
||||||
|
@ol*{@~ start at the @a[href: "binaries/"]{@tt{binaries}} subdirectory
|
||||||
|
for your platform,
|
||||||
|
@~ download the @tt{racket-...-full.tgz} file,
|
||||||
|
@~ unpack it with GNU Tar (or something compatible to it), for
|
||||||
|
example: "@tt{tar xzf racket-...-full.tgz}".}
|
||||||
|
Note that there are many other @tt{tgz} files that contain various
|
||||||
|
subsets of the tree, for example, you can get just the documentation
|
||||||
|
part, the clean @tt{plt/src} part, the full tree before any compilation,
|
||||||
|
documentation @tt{.plt} files, or for each platform a @tt{tgz} file that
|
||||||
|
contains just native-code binary files.
|
||||||
|
@~
|
||||||
|
It is also easy to setup a script that will automate the process of
|
||||||
|
retrieving the @tt{tgz} file, unpacking and installing it. This is
|
||||||
|
explained in more details in @script{scripts}. In addition to being
|
||||||
|
convenient for updating your tree, it can be used by an automatic job
|
||||||
|
scheduler (for example, a cron job on Unix) to make tree that is always
|
||||||
|
updated.}
|
||||||
|
@hr
|
||||||
|
@version-hole})
|
||||||
|
|
||||||
|
(define pre-installers
|
||||||
|
@page[#:file "pre-installers/" #:title "Nightly build pre-installers"]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@p{This directory contains distribution packages in tgz format. They are
|
||||||
|
later converted to the actual platform-specific
|
||||||
|
@a[href: "../installers/"]{installers}.}
|
||||||
|
@hr
|
||||||
|
@content-hole
|
||||||
|
@hr
|
||||||
|
@version-hole})
|
||||||
|
|
||||||
|
(provide installers)
|
||||||
|
(define installers
|
||||||
|
@page[#:file "installers/" #:title "Nightly build installers"]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@p{Pre-release software is built using actively developed sources.
|
||||||
|
Binaries are built nightly, and minute-by-minute changes are available
|
||||||
|
through @|git|.}
|
||||||
|
@; ----------------------------------------
|
||||||
|
@h2{Option 1: Installer}
|
||||||
|
@content-hole
|
||||||
|
@version-hole
|
||||||
|
@table[width: "80%" align: 'center]{
|
||||||
|
@tr{@td[valign: 'top]{Installers:}
|
||||||
|
@td{@nbsp}
|
||||||
|
@td{@dl*{@~ @b{Racket}
|
||||||
|
@~ Same as the normal distribution, containing the basic
|
||||||
|
systems and DrRacket.
|
||||||
|
@~ @b{Racket Textual}
|
||||||
|
@~ A small distribution that contains only Racket and
|
||||||
|
console applications based on it, including the Racket
|
||||||
|
web server. No docs and no GUI applications.
|
||||||
|
@~ @b{Racket Full}
|
||||||
|
@~ Contains the @i{complete} Racket tree from the
|
||||||
|
@git{repository}, including full documentation, full
|
||||||
|
source tree, libraries that are not completely stable,
|
||||||
|
and esoteric material.}}}
|
||||||
|
@tr{@td[colspan: 3]{
|
||||||
|
Note: the default installation directory contains the version
|
||||||
|
number to avoid clobbering a normal installation.
|
||||||
|
@small{(Under Windows, registry names are different, too.)}}}}
|
||||||
|
@; ----------------------------------------
|
||||||
|
@h2{Option 2: git Repository}
|
||||||
|
@p{Full source is available from the @git{repository}.}
|
||||||
|
@; ----------------------------------------
|
||||||
|
@h2{Option 3: Other}
|
||||||
|
@p{Want Racket sources from @git but don't want to build binaries?
|
||||||
|
Want to browse a @git checkout? The
|
||||||
|
@a[href: "../"]{nightly build page} has everything you
|
||||||
|
could want.}})
|
||||||
|
|
||||||
|
(provide (rename-out [docs* docs]))
|
||||||
|
(define (docs* #:sub [sub #f] . text)
|
||||||
|
(if sub
|
||||||
|
(apply a href: (list (url-of docs) sub "/") (if (null? text) sub text))
|
||||||
|
(apply docs text)))
|
||||||
|
(define docs
|
||||||
|
@page[#:file "docs/" #:title "Prebuilt documentation"]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@p{This directory contains documentation files in all forms, compiled from
|
||||||
|
the current sources.}
|
||||||
|
@hr
|
||||||
|
@content-hole
|
||||||
|
@hr
|
||||||
|
@version-hole})
|
||||||
|
|
||||||
|
(define binaries
|
||||||
|
@page[#:file "binaries/" #:title "Prebuilt binaries"]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@p{This directory contains a subdirectory for each supported platform.}
|
||||||
|
@hr
|
||||||
|
@content-hole
|
||||||
|
@hr
|
||||||
|
@version-hole})
|
||||||
|
|
||||||
|
(define script
|
||||||
|
@page[#:file "script.html" #:title "Using the nightly Racket builds"]{
|
||||||
|
@temporary-outdated-warning
|
||||||
|
@(define (url . s) @list{http://pre.racket-lang.org/@s})
|
||||||
|
@(define (pre* . text) (apply pre style: "margin-left: 2em;" text))
|
||||||
|
@p*{
|
||||||
|
Using the nightly builds to get the latest version is very simple, and
|
||||||
|
does not require git. If you use the @a[href: "installers"]{installers}
|
||||||
|
directory, then things are as simple as they are with a normal Racket
|
||||||
|
distribution – the only slight difference is that by default the
|
||||||
|
directory name contains the version number, so it does not clobber an
|
||||||
|
official installation (this also works on Windows, where the registry
|
||||||
|
keys are separate for each nightly version).
|
||||||
|
@~
|
||||||
|
But there is a lot of material in here that might fit better a script
|
||||||
|
that updates a Racket tree automatically. For this, the only tools you
|
||||||
|
will need are GNU tar, a utility to fetch files from the web, and some
|
||||||
|
scripting facility. For example, assuming that your @tt{racket}
|
||||||
|
directory is in "@tt{$BASE}", retrieving the latest source tree is as
|
||||||
|
simple as:
|
||||||
|
@pre*{
|
||||||
|
cd $BASE
|
||||||
|
wget @url{racket-src.tgz} -O - | tar xzf -}
|
||||||
|
or with @tt{curl}:
|
||||||
|
@pre*{
|
||||||
|
cd $BASE
|
||||||
|
curl @url{racket-src.tgz} | tar xzf -}
|
||||||
|
@~
|
||||||
|
This will fetch and unpack the full @tt{racket} source tree at the
|
||||||
|
current directory, on top of any @tt{racket} directory that might happen
|
||||||
|
to be there. Since it probably doesn't make sense to have older binaries
|
||||||
|
and newer source files, it is a good idea to remove any previous tree (if
|
||||||
|
any):
|
||||||
|
@pre*{
|
||||||
|
cd $BASE
|
||||||
|
rm -rf racket
|
||||||
|
curl @url{racket-clean-tree.tgz} | tar xzf -}
|
||||||
|
@~
|
||||||
|
This is possible with any of the subsets that are packed as tgz files.
|
||||||
|
For example, to update just the binaries for OS X (over an existing
|
||||||
|
@tt{racket} tree):
|
||||||
|
@pre*{
|
||||||
|
cd $BASE
|
||||||
|
wget @url{binaries/i386-osx-mac/racket-i386-osx-mac-binaries.tgz} -O - \
|
||||||
|
|| tar xzf -}
|
||||||
|
To get a fully built tree for Windows:
|
||||||
|
@pre*{
|
||||||
|
cd $BASE
|
||||||
|
rm -rf racket
|
||||||
|
wget @url{binaries/i386-win32/racket-i386-win32-full.tgz} -O - \
|
||||||
|
|| tar xzf -
|
||||||
|
cd racket}
|
||||||
|
Note that there is no “install” step: the archive contains a ready-to-run
|
||||||
|
tree.
|
||||||
|
@~
|
||||||
|
Finally, there is a @tt{stamp} file in the nightly build directory that
|
||||||
|
can be used for scripts that periodically poll for new builds. This file
|
||||||
|
is updated last in the build process, so if a build fails it will stay
|
||||||
|
the same and not fool you into getting the same build. To demonstrate
|
||||||
|
using this, here is an @tt{sh} script that compares a local copy of the
|
||||||
|
@tt{stamp} file to the one on the web, and if there is any difference,
|
||||||
|
retrieves and installs the new full Windows build (assuming it is in my
|
||||||
|
home directory):
|
||||||
|
@pre*{
|
||||||
|
#!/bin/sh
|
||||||
|
cd
|
||||||
|
URL="@url{}"
|
||||||
|
touch stamp # make sure that it is there
|
||||||
|
if ! curl -s $URL/stamp | diff -q stamp - >/dev/null 2>&1; then
|
||||||
|
curl -s $URL/stamp > stamp # remember the new stamp
|
||||||
|
#----------
|
||||||
|
rm -rf racket
|
||||||
|
wget $URL/binaries/i386-win32/racket-i386-win32-full.tgz -O - @;
|
||||||
|
| tar xzf -
|
||||||
|
#----------
|
||||||
|
fi}
|
||||||
|
The marked part of this script can be replaced by any of the options
|
||||||
|
mentioned above, for other platforms or something other than retrieving a
|
||||||
|
full build.
|
||||||
|
@~
|
||||||
|
This script will retrieve and install a new build only when one is ready.
|
||||||
|
It is suitable for running periodically via a crontab entry. For
|
||||||
|
example, save it in @tt{~/bin/update-full-racket}, run @tt{crontab -e} to
|
||||||
|
edit your @tt{crontab} entries, and add a line that looks like this:
|
||||||
|
@pre*{13 */6 * * * ~/bin/update-full-racket}
|
||||||
|
This will run the script on the 13th minute of every sixth hour. It is
|
||||||
|
harmless to run it every hour, but there's no real need for it.
|
||||||
|
Currently, the nightly build process starts at 3:50am (EDT) and lasts for
|
||||||
|
about two hours, but every once in a while there would be additional
|
||||||
|
builds (eg, after a minor version change).}
|
||||||
|
@h3{A note about defensive scripting:}
|
||||||
|
@p{Writing scripts that work for you is easy. Making them robust enough to
|
||||||
|
be usable by others or by site-wide setups can be a delicate job — you
|
||||||
|
have to plan for bad @tt{PATH} setting (for example, a cron job is
|
||||||
|
started in a pretty much bare environment), errors that happen in one
|
||||||
|
command etc. The following is just like the above script, modified to
|
||||||
|
be more robust in the following way:
|
||||||
|
@ol*{@~ The @tt{PATH} environment variable is explicitly set.
|
||||||
|
@~ Use variable definitions to make customization easy.
|
||||||
|
@~ Usages of @tt{$URL} and others are quoted in case they will ever
|
||||||
|
contain spaces.
|
||||||
|
@~ If we fail to retrieve a file, we quit the script.
|
||||||
|
@~ Use a temporary directory to retrieve the tree, and then move it
|
||||||
|
to its real place (so if it fails we don't end up with no
|
||||||
|
@tt{racket}) through renaming (if we delete @tt{racket} and then
|
||||||
|
rename the new one, we might fail halfway into the deletion).
|
||||||
|
@~ Also, there might be some binary process running from an old
|
||||||
|
file which might prevent removing the directory, so failure to
|
||||||
|
remove the old tree does not abort the script.
|
||||||
|
@~ The new stamp is remembered only if everything succeeded.}}
|
||||||
|
@hr
|
||||||
|
@pre*{
|
||||||
|
#!/bin/sh
|
||||||
|
PATH="/bin:/usr/bin"
|
||||||
|
# where is our racket tree placed?
|
||||||
|
MAINDIR="$HOME"
|
||||||
|
# where should the local stamp file copy be stored?
|
||||||
|
STAMP="$MAINDIR/stamp"
|
||||||
|
# where is the online stuff?
|
||||||
|
URL="@url{}"
|
||||||
|
cd "$MAINDIR"
|
||||||
|
touch "$STAMP" # make sure that it is there
|
||||||
|
curl -s "$URL/stamp" > "$STAMP-new"
|
||||||
|
if diff -q "$STAMP" "$STAMP-new" >/dev/null 2>&1; then
|
||||||
|
# nothing changed
|
||||||
|
rm "$STAMP-new"
|
||||||
|
else
|
||||||
|
#----------
|
||||||
|
mkdir "$MAINDIR/racket-temp-$$"
|
||||||
|
cd "$MAINDIR/racket-temp-$$"
|
||||||
|
wget "$URL/binaries/i386-win32/racket-i386-win32-full.tgz" -O - \
|
||||||
|
| tar xzf - \
|
||||||
|
|| exit 1
|
||||||
|
cd "$MAINDIR"
|
||||||
|
if [ -e "racket" ]; then mv "racket" "racket-temp-$$/racket-old"; fi \
|
||||||
|
&& mv "racket-temp-$$/racket" . \
|
||||||
|
|| exit 1
|
||||||
|
rm -rf "racket-temp-$$"
|
||||||
|
#----------
|
||||||
|
cd "$MAINDIR"
|
||||||
|
rm "$STAMP" # remember the new stamp only if no failure so far
|
||||||
|
mv "$STAMP-new" "$STAMP"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
@hr})
|
11
new-racket-web/web/stubs/wiki.rkt
Normal file
11
new-racket-web/web/stubs/wiki.rkt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require (prefix-in www: (only-in "../www/resources.rkt" the-resources)))
|
||||||
|
|
||||||
|
(define-context "stubs/wiki" #:resources www:the-resources)
|
||||||
|
|
||||||
|
(define template
|
||||||
|
(page #:title "{{{TITLE}}}"
|
||||||
|
#:extra-headers "{{{HEADERS}}}"
|
||||||
|
#:extra-body-attrs '(|{{{ATTRS}}}|: #t)
|
||||||
|
"{{{BODY}}}"))
|
525
new-racket-web/web/www/NEW.html
Normal file
525
new-racket-web/web/www/NEW.html
Normal file
|
@ -0,0 +1,525 @@
|
||||||
|
<!doctype html>
|
||||||
|
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
|
||||||
|
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
|
||||||
|
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
||||||
|
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
|
||||||
|
<!--[if IE 9]> <html class="no-js ie9" lang="en"> <![endif]-->
|
||||||
|
<!-- Consider adding an manifest.appcache: h5bp.com/d/Offline -->
|
||||||
|
<!--[if gt IE 9]><!--> <html class="no-js" lang="en" itemscope itemtype="http://schema.org/Product"> <!--<![endif]-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<!-- Use the .htaccess and remove these lines to avoid edge case issues.
|
||||||
|
More info: h5bp.com/b/378 -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
|
||||||
|
<title>The Racket Language</title>
|
||||||
|
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
|
||||||
|
|
||||||
|
<!-- Mobile viewport optimized: j.mp/bplateviewport -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
|
||||||
|
|
||||||
|
<!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->
|
||||||
|
|
||||||
|
<!-- CSS: implied media=all -->
|
||||||
|
<!-- CSS concatenated and minified via ant build script-->
|
||||||
|
<!-- <link rel="stylesheet" href="css/minified.css"> -->
|
||||||
|
|
||||||
|
<!-- CSS imports non-minified for staging, minify before moving to production-->
|
||||||
|
<link rel="stylesheet" href="css/gumby.css">
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
<link rel="stylesheet" href="css/scribble.css">
|
||||||
|
<!-- end CSS-->
|
||||||
|
|
||||||
|
<!-- More ideas for your <head> here: h5bp.com/d/head-Tips -->
|
||||||
|
|
||||||
|
<!-- All JavaScript at the bottom, except for Modernizr / Respond.
|
||||||
|
Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries
|
||||||
|
For optimal performance, use a custom Modernizr build: www.modernizr.com/download/ -->
|
||||||
|
<script src="js/libs/modernizr-2.6.2.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="navbar" gumby-fixed="top" id="nav1">
|
||||||
|
<div class="row">
|
||||||
|
<a class="toggle" gumby-trigger="#nav1 > .row > ul" href="#"><i class="icon-menu"></i></a>
|
||||||
|
<a class="five columns logo" href="">
|
||||||
|
<img class="logo" src="img/logo.png" />
|
||||||
|
</a>
|
||||||
|
<ul class="five columns" >
|
||||||
|
<li><a href="https://pkg.racket-lang.org">Packages</a></li>
|
||||||
|
<li><a href="http://docs.racket-lang.org">Documentation</a></li>
|
||||||
|
<li><a href="http://blog.racket-lang.org">Blog</a></li>
|
||||||
|
<li>
|
||||||
|
<button class="medium metro info btn icon-left entypo icon-install">
|
||||||
|
<a href="#">Download</a>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" id="modal1">
|
||||||
|
<div class="content unique_lines codesnip active">
|
||||||
|
<a class="close switch" gumby-trigger="|#modal1"><i class="icon-cancel" ></i></a>
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered center-text">
|
||||||
|
<h4>Unique Lines</h4>
|
||||||
|
|
||||||
|
<pre style="font-size: 140%; font-family: 'Inconsolata';">
|
||||||
|
#lang <a href="http://docs.racket-lang.org/reference/index.html" class="codemodpath" rel="nofollow">racket</a>
|
||||||
|
<span class="codecomment">;; Report each unique line from stdin</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket/private/letstx-scheme..rkt)._let))" class="codelinkimportform" rel="nofollow">let</a> <span class="codeparenthesis">(</span><span class="codeparenthesis">[</span><span class="codeid">saw</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._make-hash))" class="codelinkimportid" rel="nofollow">make-hash</a><span class="codeparenthesis">)</span><span class="codeparenthesis">]</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/for.html#(form._((lib._racket/private/base..rkt)._for))" class="codelinkimportform" rel="nofollow">for</a> <span class="codeparenthesis">(</span><span class="codeparenthesis">[</span><span class="codeid">line</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/sequences.html#(def._((lib._racket/private/base..rkt)._in-lines))" class="codelinkimportid" rel="nofollow">in-lines</a><span class="codeparenthesis">)</span><span class="codeparenthesis">]</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/when_unless.html#(form._((lib._racket/private/letstx-scheme..rkt)._unless))" class="codelinkimportform" rel="nofollow">unless</a> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-ref))" class="codelinkimportid" rel="nofollow">hash-ref</a> <span class="codeid">saw</span> <span class="codeid">line</span> <span class="codeconstant">#f</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((lib._racket/private/misc..rkt)._displayln))" class="codelinkimportid" rel="nofollow">displayln</a> <span class="codeid">line</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-set!))"
|
||||||
|
class="codelinkimportid"
|
||||||
|
rel="nofollow">hash-set!</a> <span class="codeid">saw</span> <span class="codeid">line</span> <span class="codeconstant">#t</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span>
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered center-text">
|
||||||
|
<p>
|
||||||
|
Uses a hash table to record previously seen lines. You can run this program in DrRacket, but it makes more sense from the command line.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To run the example, install Racket, start DrRacket, paste the example
|
||||||
|
program into the top area in DrRacket, and click the Run
|
||||||
|
button. Alternatively, save the program to a file and run <code>racket</code> on
|
||||||
|
the file.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="font-size: 80%">
|
||||||
|
Form and function names in the code are hyperlinked to
|
||||||
|
documentation, so click on them for more information.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="content web_scraper codesnip">
|
||||||
|
<a class="close switch" gumby-trigger="|#modal1"><i class="icon-cancel" /></i></a>
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered center-text">
|
||||||
|
<h4>Web scraper</h4>
|
||||||
|
<pre style="font-size: 140%; font-family: 'Inconsolata';">
|
||||||
|
#lang <a href="http://docs.racket-lang.org/reference/index.html" class="codemodpath" rel="nofollow">racket</a> <span class="codecomment">; Simple web scraper</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._require))" class="codelinkimportform" rel="nofollow">require</a> <a href="http://docs.racket-lang.org/net/url.html" class="codemodpath" rel="nofollow">net/url</a> <a href="http://docs.racket-lang.org/net/uri-codec.html" class="codemodpath" rel="nofollow">net/uri-codec</a><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" class="codelinkimportform" rel="nofollow">define</a> <span class="codeparenthesis">(</span><span class="codeid">let-me-google-that-for-you</span> <span class="codeid">str</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket/private/letstx-scheme..rkt)._let*))" class="codelinkimportform" rel="nofollow">let*</a> <span class="codeparenthesis">(</span><span class="codeparenthesis">[</span><span class="codeid">g</span> <span class="codestring">"http://www.google.com/search?q="</span><span class="codeparenthesis">]</span>
|
||||||
|
<span class="codeparenthesis">[</span><span class="codeid">u</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-append))" class="codelinkimportid" rel="nofollow">string-append</a> <span class="codeid">g</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/net/uri-codec.html#(def._((lib._net/uri-codec..rkt)._uri-encode))" class="codelinkimportid" rel="nofollow">uri-encode</a> <span class="codeid">str</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">]</span>
|
||||||
|
<span class="codeparenthesis">[</span><span class="codeid">rx</span> <span class="codestring">#rx"(?<=<h3 class=\"r\">).*?(?=</h3>)"</span><span class="codeparenthesis">]</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/regexp.html#(def._((lib._racket/private/base..rkt)._regexp-match*))" class="codelinkimportid" rel="nofollow">regexp-match*</a> <span class="codeid">rx</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/net/url.html#(def._((lib._net/url..rkt)._get-pure-port))" class="codelinkimportid" rel="nofollow">get-pure-port</a> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/net/url.html#(def._((lib._net/url..rkt)._string-~3eurl))" class="codelinkimportid" rel="nofollow">string->url</a> <span class="codeid">u</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered center-text">
|
||||||
|
<p>
|
||||||
|
Add a call to <code>let-me-google-that-for-you</code> to get a list of search
|
||||||
|
results.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To run the example, install Racket, start DrRacket, paste the example
|
||||||
|
program into the top area in DrRacket, and click the Run
|
||||||
|
button. Alternatively, save the program to a file and run <code>racket</code> on
|
||||||
|
the file.
|
||||||
|
</p>
|
||||||
|
<p class="footnote" style="font-size: 80%">
|
||||||
|
Form and function names in the code are hyperlinked to
|
||||||
|
documentation, so click on them for more information.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row" >
|
||||||
|
<div class="ten columns centered">
|
||||||
|
<h2 style="font-size: 180%; margin-bottom: 10pt">
|
||||||
|
<strong>Racket</strong> —
|
||||||
|
<span style="font-style: italic">a programmable programming
|
||||||
|
language</span>
|
||||||
|
</h2>
|
||||||
|
</div></div>
|
||||||
|
<div class="row" >
|
||||||
|
<div class="eight columns centered" style="margin-bottom: 10pt; font-size: 120%; text-align:justify;">
|
||||||
|
|
||||||
|
Racket is a wide-spectrum programming language that inherits from Lisp
|
||||||
|
and Scheme but also provides dialects that support objects, types,
|
||||||
|
laziness, and many other paradigms. Racket's module system allows
|
||||||
|
programmers to write and link together components written in different
|
||||||
|
dialects. Racket's libraries range from web servers to distributed
|
||||||
|
computing and from databases to charts.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <div class="row" > -->
|
||||||
|
<!-- <div class="one columns"></div> -->
|
||||||
|
<!-- <div class="eight columns"><h2 style="font-size: 180%; -->
|
||||||
|
<!-- margin-bottom: -->
|
||||||
|
<!-- 10pt"></>Start -->
|
||||||
|
<!-- Quickly</h2></div> -->
|
||||||
|
|
||||||
|
<!-- <div class="three columns"><h2 style="font-size: 180%; -->
|
||||||
|
<!-- margin-bottom: -->
|
||||||
|
<!-- 10pt"></>News -->
|
||||||
|
<!-- </h2></div> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- The other version of the buttons: -->
|
||||||
|
<!-- <div class="eight columns centered" -->
|
||||||
|
<!-- style="font-size: 140%; position: relative; -->
|
||||||
|
<!-- font-family: 'Inconsolata';"> -->
|
||||||
|
<!-- <a href="#" class="toggle" gumby-trigger=".unique_lines|.web_scraper"> -->
|
||||||
|
<!-- <img class="halign" src="img/prev.png" style="position: -->
|
||||||
|
<!-- absolute; top: 50%; left: -20%; margin-top: -25px"> -->
|
||||||
|
<!-- </a> -->
|
||||||
|
<!-- <a href="#" class="toggle" gumby-trigger=".unique_lines|.web_scraper"> -->
|
||||||
|
<!-- <img class="halign" src="img/next.png" -->
|
||||||
|
<!-- style="position: absolute; top: 50%; right: -20%; -->
|
||||||
|
<!-- margin-top: -->
|
||||||
|
<!-- -25px"> -->
|
||||||
|
<!-- </a> -->
|
||||||
|
|
||||||
|
|
||||||
|
<div id="topcontent">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="one columns">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="seven columns" >
|
||||||
|
<h2 style="font-size: 180%;
|
||||||
|
margin-bottom:
|
||||||
|
10pt"></>Start
|
||||||
|
Quickly</h2>
|
||||||
|
<div style="position: relative; ">
|
||||||
|
<p class="metro primary btn"
|
||||||
|
style="position: absolute; top: -10%; right: 0%;" >
|
||||||
|
<a href="#" class="switch" gumby-trigger="#modal1"> <i class="icon-help"></i></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a href="#" class="toggle narrow_only"
|
||||||
|
gumby-trigger=".unique_lines|.web_scraper" style="position: absolute; top: -40%; left: 35%">
|
||||||
|
<img src="img/prev.png" style="width: 50px">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" class="toggle narrow_only"
|
||||||
|
gumby-trigger=".unique_lines|.web_scraper" style="position: absolute; top: -40%; right: 35%">
|
||||||
|
<img src="img/next.png" style="width: 50px">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" class="toggle wide_only"
|
||||||
|
gumby-trigger=".unique_lines|.web_scraper" style="position: absolute; top: 40%; left: -15%">
|
||||||
|
<img src="img/prev.png" style="width: 50px">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="#" class="toggle wide_only"
|
||||||
|
gumby-trigger=".unique_lines|.web_scraper" style="position: absolute; top: 40%; right: -15%">
|
||||||
|
<img src="img/next.png" style="width: 50px">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<pre class="codesnip active unique_lines" style="font-size: 140%;">
|
||||||
|
#lang <a href="http://docs.racket-lang.org/reference/index.html" class="codemodpath" rel="nofollow">racket</a>
|
||||||
|
<span class="codecomment">;; Report each unique line from stdin</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket/private/letstx-scheme..rkt)._let))" class="codelinkimportform" rel="nofollow">let</a> <span class="codeparenthesis">(</span><span class="codeparenthesis">[</span><span class="codeid">saw</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._make-hash))" class="codelinkimportid" rel="nofollow">make-hash</a><span class="codeparenthesis">)</span><span class="codeparenthesis">]</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/for.html#(form._((lib._racket/private/base..rkt)._for))" class="codelinkimportform" rel="nofollow">for</a> <span class="codeparenthesis">(</span><span class="codeparenthesis">[</span><span class="codeid">line</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/sequences.html#(def._((lib._racket/private/base..rkt)._in-lines))" class="codelinkimportid" rel="nofollow">in-lines</a><span class="codeparenthesis">)</span><span class="codeparenthesis">]</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/when_unless.html#(form._((lib._racket/private/letstx-scheme..rkt)._unless))" class="codelinkimportform" rel="nofollow">unless</a> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-ref))" class="codelinkimportid" rel="nofollow">hash-ref</a> <span class="codeid">saw</span> <span class="codeid">line</span> <span class="codeconstant">#f</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((lib._racket/private/misc..rkt)._displayln))" class="codelinkimportid" rel="nofollow">displayln</a> <span class="codeid">line</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-set!))"
|
||||||
|
class="codelinkimportid"
|
||||||
|
rel="nofollow">hash-set!</a> <span class="codeid">saw</span> <span class="codeid">line</span> <span class="codeconstant">#t</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<pre class="codesnip web_scraper">
|
||||||
|
#lang <a href="http://docs.racket-lang.org/reference/index.html" class="codemodpath" rel="nofollow">racket</a> <span class="codecomment">; Simple web scraper</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket/private/base..rkt)._require))" class="codelinkimportform" rel="nofollow">require</a> <a href="http://docs.racket-lang.org/net/url.html" class="codemodpath" rel="nofollow">net/url</a> <a href="http://docs.racket-lang.org/net/uri-codec.html" class="codemodpath" rel="nofollow">net/uri-codec</a><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))" class="codelinkimportform" rel="nofollow">define</a> <span class="codeparenthesis">(</span><span class="codeid">let-me-google-that-for-you</span> <span class="codeid">str</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket/private/letstx-scheme..rkt)._let*))" class="codelinkimportform" rel="nofollow">let*</a> <span class="codeparenthesis">(</span><span class="codeparenthesis">[</span><span class="codeid">g</span> <span class="codestring">"http://www.google.com/search?q="</span><span class="codeparenthesis">]</span>
|
||||||
|
<span class="codeparenthesis">[</span><span class="codeid">u</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-append))" class="codelinkimportid" rel="nofollow">string-append</a> <span class="codeid">g</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/net/uri-codec.html#(def._((lib._net/uri-codec..rkt)._uri-encode))" class="codelinkimportid" rel="nofollow">uri-encode</a> <span class="codeid">str</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">]</span>
|
||||||
|
<span class="codeparenthesis">[</span><span class="codeid">rx</span> <span class="codestring">#rx"(?<=<h3 class=\"r\">).*?(?=</h3>)"</span><span class="codeparenthesis">]</span><span class="codeparenthesis">)</span>
|
||||||
|
<span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/reference/regexp.html#(def._((lib._racket/private/base..rkt)._regexp-match*))" class="codelinkimportid" rel="nofollow">regexp-match*</a> <span class="codeid">rx</span> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/net/url.html#(def._((lib._net/url..rkt)._get-pure-port))" class="codelinkimportid" rel="nofollow">get-pure-port</a> <span class="codeparenthesis">(</span><a href="http://docs.racket-lang.org/net/url.html#(def._((lib._net/url..rkt)._string-~3eurl))" class="codelinkimportid" rel="nofollow">string->url</a> <span class="codeid">u</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span><span class="codeparenthesis">)</span>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="one columns"> </div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="three columns" style="text-color: black">
|
||||||
|
<h2 style="font-size: 180%; margin-bottom: 10pt">News </h2>
|
||||||
|
<p>Racket version 5.3.5 has been released.</p>
|
||||||
|
<p>Racket videos are now available.</p>
|
||||||
|
<p><a href="racketcon.html">RacketCon 2013</a> will be in September in Boston.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<p class="twelve columns centered" style="text-align:justify;font-size: 120%; margin-top: 20pt; ">
|
||||||
|
<a href="http://docs.racket-lang.org/quick/">Draw more pictures</a> or
|
||||||
|
<a href="http://docs.racket-lang.org/more/">build a web server from scratch</a>. Racket includes both
|
||||||
|
<a href="http://docs.racket-lang.org/">batteries</a> and a <a href="http://docs.racket-lang.org/drracket/">programming environment</a>,
|
||||||
|
so <a href="http://docs.racket-lang.org/getting-started/">get started</a>!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- below code snippets -->
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered">
|
||||||
|
<h3 >Go Further</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row" id="growboxes">
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">Grow your Program</div><p>Racket's
|
||||||
|
<a href="http://docs.racket-lang.org/guide/intro.html#(part._.Interacting_with_.Racket)">interactive mode</a>
|
||||||
|
encourages experimentation, and quick scripts easily compose into
|
||||||
|
larger systems. Small scripts and large systems both benefit from
|
||||||
|
<a href="http://docs.racket-lang.org/guide/performance.html">native-code JIT compilation</a>.
|
||||||
|
When a system gets too big to keep in your head, you can add
|
||||||
|
<a href="http://docs.racket-lang.org/ts-guide/index.html">static types</a>.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">Grow your Language</div><p><a href="http://docs.racket-lang.org/guide/languages.html">Extend Racket</a> whenever you need to.
|
||||||
|
Mold it to better suit your tasks without sacrificing
|
||||||
|
<a href="http://docs.racket-lang.org/guide/dialects.html">interoperability</a> with existing
|
||||||
|
libraries and without having to modify the
|
||||||
|
<a href="http://docs.racket-lang.org/guide/intro.html">tool chain</a>. When less is more, you can
|
||||||
|
remove parts of a language or start over and build a new one.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
|
||||||
|
<div class="panetitle">Grow your Skills</div><p>Whether you're just <a href="http://htdp.org/">starting out</a>, want to know more about
|
||||||
|
programming language <a href="http://www.plai.org/">applications</a> or <a href="http://redex.racket-lang.org/">models</a>,
|
||||||
|
looking to <a href="http://docs.racket-lang.org/continue/">expand your horizons</a>, or ready to dive into
|
||||||
|
<a href="learning.html">research</a>, Racket can help you become a better programmer
|
||||||
|
and system builder.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered">
|
||||||
|
<h3 >Documentation</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="five columns">
|
||||||
|
<div class="panetitle">For getting started</div>
|
||||||
|
<p><a href="http://docs.racket-lang.org/quick/"><strong>Quick</strong>:
|
||||||
|
An Introduction to Racket with
|
||||||
|
Pictures</a>
|
||||||
|
gives you a taste of Racket.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><a href="http://docs.racket-lang.org/more/"><strong>More</strong>:
|
||||||
|
Systems Programming with Racket</a>
|
||||||
|
dives
|
||||||
|
much deeper and much faster, showing how to build a complete
|
||||||
|
continuation-based web server.</p>
|
||||||
|
|
||||||
|
<p><a href="http://docs.racket-lang.org/guide/"><strong>Guide</strong>:
|
||||||
|
Racket</a> starts with a tutorial on Racket basics, and then it
|
||||||
|
describes the rest of the Racket language.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="five columns push_two">
|
||||||
|
<div class="panetitle">For experienced Racketeers</div>
|
||||||
|
<p>
|
||||||
|
<a href="http://docs.racket-lang.org/reference/"><strong>Reference</strong>:
|
||||||
|
Racket</a> provides comprehensive coverage of all of Racket.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><a href="http://docs.racket-lang.org/continue/"><strong>Continue</strong>:
|
||||||
|
Web Applications in Racket</a>
|
||||||
|
describes how to use the
|
||||||
|
Racket <a href="http://docs.racket-lang.org/web-server/">web
|
||||||
|
server</a> to build dynamic web applications.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><a href="http://docs.racket-lang.org/pkg/"><strong>Package
|
||||||
|
Management</strong></a> explains how to install
|
||||||
|
<a href="https://pkg.racket-lang.org">packages</a>, and how to
|
||||||
|
build and distribute your own.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered">
|
||||||
|
<h3>Community</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=row>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">News & Events</div>
|
||||||
|
|
||||||
|
<p><a href="racketcon.html">RacketCon</a> ? the annual
|
||||||
|
Racket meeting, coming up in September. Previously
|
||||||
|
in <a href="http://con.racket-lang.org/2012">2012</a>
|
||||||
|
and <a href="http://con.racket-lang.org/2012">2011</a>.</p>
|
||||||
|
|
||||||
|
<p><a href="http://blog.racket-lang.org/">Blog</a>
|
||||||
|
? announcements, helpful hints, and thoughtful rants.</p>
|
||||||
|
<p><a href="http://twitter.com/#!/racketlang">Twitter</a>
|
||||||
|
? short bits of Racket news.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">Discussion</div>
|
||||||
|
<p><a href="http://lists.racket-lang.org/">Mailing lists</a>
|
||||||
|
? discussion for using and developing Racket.</p>
|
||||||
|
<p><a href="http://racket-lang.org/irc-chat.html">IRC</a> ?
|
||||||
|
Chat in the <tt style="background-color: #d8d8e8;"><big><strong>#racket</strong></big></tt> channel on
|
||||||
|
<a href="http://freenode.net"><tt>freenode.net</tt></a> ? an informal
|
||||||
|
discussion channel for all things related to Racket.
|
||||||
|
(<a href="https://botbot.me/freenode/racket/">Browse the logs</a>.)</p>
|
||||||
|
|
||||||
|
<p><a href="http://racket-lang.org/people.html">People</a> ?
|
||||||
|
The people behind Racket.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">Contributing</div>
|
||||||
|
<p><a href="https://github.com/plt/racket/">Code</a>
|
||||||
|
? the Racket source code on GitHub.</p>
|
||||||
|
<p><a href="https://github.com/plt/racket/wiki">Wiki</a> ?
|
||||||
|
Useful pages
|
||||||
|
include <a href="https://github.com/plt/racket/wiki/Intro-Projects">Intro
|
||||||
|
Projects</a>
|
||||||
|
and <a href="https://github.com/plt/racket/wiki/Videos">Videos</a>,
|
||||||
|
including tutorials, interviews, and more.</p>
|
||||||
|
<p><a href="http://www.cs.utah.edu/plt/snapshots">Snapshot builds</a> ?
|
||||||
|
The freshest versions of Racket.</p>
|
||||||
|
|
||||||
|
<p><a href="http://bugs.racket-lang.org">Bug reports</a> ?
|
||||||
|
File, query and maybe fix existing reports.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="ten columns centered">
|
||||||
|
<h3>Learning</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="two columns image rounded" style="margin-top: 2pt">
|
||||||
|
<a href="http://www.htdp.org"><img src="img/htdp-cover.gif" /></a>
|
||||||
|
</div>
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">How to Design Programs</div>
|
||||||
|
<p>A principled approach to program design</p>
|
||||||
|
<ul>
|
||||||
|
<li>Teaching language support built-in to DrRacket</li>
|
||||||
|
<li>Aimed at the programming novice</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">Realm of Racket</div>
|
||||||
|
<p>Learn Racket and programming, one game at a time</p>
|
||||||
|
<ul>
|
||||||
|
<li>Sample game code comes with the Racket distribution</li>
|
||||||
|
<li>For those just starting out with Racket</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="two columns image rounded" style="margin-top: 2pt">
|
||||||
|
<a href="http://www.realmofracket.com"><img src="img/racket_cover_web.png" /></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="two columns image rounded" style="margin-top: 2pt">
|
||||||
|
<a href="http://cs.brown.edu/~sk/Publications/Books/ProgLangs/2007-04-26/">
|
||||||
|
<img src="img/plai-cover.jpg" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">PLAI</div>
|
||||||
|
<p>Foundations of programming languages</p>
|
||||||
|
<ul>
|
||||||
|
<li>Understand the features that make languages tick</li>
|
||||||
|
<li>For undergraduates, graduate students, and experts</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="four columns">
|
||||||
|
<div class="panetitle">Semantics Engineering with PLT Redex</div>
|
||||||
|
<p>Lightweight automation for semantics</p>
|
||||||
|
<ul>
|
||||||
|
<li>Model your own programming language semantics</li>
|
||||||
|
<li>For the working language engineer</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="two columns image rounded" style="margin-top: 2pt">
|
||||||
|
<a href="http://redex.racket-lang.org/">
|
||||||
|
<img src="img/redex-cover.jpg" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
|
<script>window.jQuery || document.write('<script src="/js/libs/jquery-1.9.1.min.js"><\/script>')</script>
|
||||||
|
|
||||||
|
<script src="js/libs/gumby.min.js"></script>
|
||||||
|
<script src="js/plugins.js"></script>
|
||||||
|
<script src="js/main.js"></script>
|
||||||
|
<!-- end scripts-->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
5
new-racket-web/web/www/all.rkt
Normal file
5
new-racket-web/web/www/all.rkt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require "index.rkt" "download.rkt" "community.rkt" "learning.rkt" "help.rkt"
|
||||||
|
"new-name.rkt" "web-copyright.rkt")
|
||||||
|
(provide (rename-out [index main]) download community learning help)
|
118
new-racket-web/web/www/code.rkt
Normal file
118
new-racket-web/web/www/code.rkt
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require syntax-color/module-lexer setup/xref
|
||||||
|
scribble/xref scribble/tag)
|
||||||
|
|
||||||
|
(provide code)
|
||||||
|
|
||||||
|
(define doc-root "http://docs.racket-lang.org/")
|
||||||
|
|
||||||
|
(define expand-namespace (make-base-namespace))
|
||||||
|
(define xref (load-collections-xref))
|
||||||
|
|
||||||
|
(define (code . strs)
|
||||||
|
(define str
|
||||||
|
(let* ([str (string-append* strs)]
|
||||||
|
[N (- 6 (length (regexp-match-positions* "\n" str)))])
|
||||||
|
(cond [(N . > . 0) (string-append str (make-string N #\newline))]
|
||||||
|
[(N . < . 0) (error 'code "too many lines in example: ~e" str)]
|
||||||
|
[else str])))
|
||||||
|
(define bstr (string->bytes/utf-8 (regexp-replace* #rx"(?m:^$)" str "\xA0")))
|
||||||
|
(define in (open-input-bytes bstr))
|
||||||
|
(define (substring* bstr start [end (bytes-length bstr)])
|
||||||
|
(bytes->string/utf-8 (subbytes bstr start end)))
|
||||||
|
(define e
|
||||||
|
(parameterize ([read-accept-reader #t] [current-namespace expand-namespace])
|
||||||
|
(expand (read-syntax 'prog (open-input-bytes bstr)))))
|
||||||
|
(define ids
|
||||||
|
(let loop ([e e])
|
||||||
|
(cond
|
||||||
|
[(and (identifier? e) (syntax-original? e))
|
||||||
|
(define pos (sub1 (syntax-position e)))
|
||||||
|
(define b (identifier-binding e))
|
||||||
|
(define imp?
|
||||||
|
(and (list? b)
|
||||||
|
(let-values ([(name base) (module-path-index-split (car b))])
|
||||||
|
(or name base))))
|
||||||
|
(define tag (and imp? (xref-binding->definition-tag xref e 0)))
|
||||||
|
(list (list (cond [(not imp?) 'id]
|
||||||
|
[(not tag) 'importid]
|
||||||
|
[else (define-values [p a]
|
||||||
|
(xref-tag->path+anchor
|
||||||
|
xref tag #:external-root-url doc-root))
|
||||||
|
(cons (if (eq? (car tag) 'form)
|
||||||
|
'linkimportform 'linkimportid)
|
||||||
|
(if a (format "~a#~a" p a) p))])
|
||||||
|
pos (+ pos (syntax-span e)) 1))]
|
||||||
|
[(syntax? e)
|
||||||
|
(append (loop (syntax-e e))
|
||||||
|
(loop (or (syntax-property e 'origin) null))
|
||||||
|
(loop (or (syntax-property e 'disappeared-use) null)))]
|
||||||
|
[(pair? e) (append (loop (car e)) (loop (cdr e)))]
|
||||||
|
[else null])))
|
||||||
|
(define (link-mod mp-stx priority #:orig? [always-orig? #f])
|
||||||
|
(if (or always-orig? (syntax-original? mp-stx))
|
||||||
|
(let ([mp (syntax->datum mp-stx)])
|
||||||
|
(define-values [p a]
|
||||||
|
(xref-tag->path+anchor xref
|
||||||
|
(make-module-language-tag mp)
|
||||||
|
#:external-root-url doc-root))
|
||||||
|
(if p
|
||||||
|
(list (let ([pos (sub1 (syntax-position mp-stx))])
|
||||||
|
(list (cons 'modpath (if a (format "~a#~a" p a) p))
|
||||||
|
pos (+ pos (syntax-span mp-stx)) priority)))
|
||||||
|
null))
|
||||||
|
null))
|
||||||
|
(define mods
|
||||||
|
(let loop ([e e])
|
||||||
|
(syntax-case e (module #%require begin)
|
||||||
|
[(module name lang (mod-beg form ...))
|
||||||
|
(append* (link-mod #'lang 2) (map loop (syntax->list #'(form ...))))]
|
||||||
|
[(#%require spec ...)
|
||||||
|
(append-map (λ (spec)
|
||||||
|
;; Need to add support for renaming forms, etc.:
|
||||||
|
(if (module-path? (syntax->datum spec))
|
||||||
|
(link-mod spec 2)
|
||||||
|
null))
|
||||||
|
(syntax->list #'(spec ...)))]
|
||||||
|
[(begin form ...) (append-map loop (syntax->list #'(form ...)))]
|
||||||
|
[else null])))
|
||||||
|
(define language
|
||||||
|
(let ([m (regexp-match #rx"^#lang ([-a-zA-Z/._+]+)" bstr)])
|
||||||
|
(if m
|
||||||
|
(link-mod #:orig? #t
|
||||||
|
(datum->syntax #f
|
||||||
|
(string->symbol (bytes->string/utf-8 (cadr m)))
|
||||||
|
(vector 'in 1 6 7 (bytes-length (cadr m))))
|
||||||
|
3)
|
||||||
|
null)))
|
||||||
|
(define raw-tokens
|
||||||
|
(let loop ([mode #f])
|
||||||
|
(define-values [lexeme type data start end backup-delta mode*]
|
||||||
|
(module-lexer in 0 mode))
|
||||||
|
(if (eof-object? lexeme)
|
||||||
|
null
|
||||||
|
(cons (list type (sub1 start) (sub1 end) 0) (loop mode*)))))
|
||||||
|
(define tokens
|
||||||
|
(sort (append ids mods language
|
||||||
|
(filter (λ (x) (not (eq? (car x) 'symbol)))
|
||||||
|
;; Drop #lang entry:
|
||||||
|
(cdr raw-tokens)))
|
||||||
|
(λ (a b) (or (< (cadr a) (cadr b))
|
||||||
|
(and (= (cadr a) (cadr b))
|
||||||
|
(> (cadddr a) (cadddr b)))))))
|
||||||
|
(let loop ([pos 0] [tokens tokens])
|
||||||
|
(cond
|
||||||
|
[(null? tokens) (list (substring* bstr pos))]
|
||||||
|
[(eq? (caar tokens) 'white-space) (loop pos (cdr tokens))]
|
||||||
|
[(= pos (cadar tokens))
|
||||||
|
(define style (caar tokens))
|
||||||
|
(define s (substring* bstr (cadar tokens) (caddar tokens)))
|
||||||
|
(cons (if (pair? style)
|
||||||
|
(a href: (cdr style) class: @list{code@(car style)}
|
||||||
|
rel: 'nofollow s)
|
||||||
|
(span class: @list{code@style} s))
|
||||||
|
(loop (caddar tokens) (cdr tokens)))]
|
||||||
|
[(> pos (cadar tokens)) (loop pos (cdr tokens))]
|
||||||
|
[else (cons (substring* bstr pos (cadar tokens))
|
||||||
|
(loop (cadar tokens) tokens))])))
|
47
new-racket-web/web/www/community.rkt
Normal file
47
new-racket-web/web/www/community.rkt
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "people.rkt" "irc.rkt"
|
||||||
|
"../minis/lists.rkt" "../minis/bugs.rkt"
|
||||||
|
"../stubs/blog.rkt" "../stubs/git.rkt"
|
||||||
|
(prefix-in pre: "../stubs/pre.rkt"))
|
||||||
|
|
||||||
|
(provide community)
|
||||||
|
(define community
|
||||||
|
@page[#:window-title "Racket Community Resources" #:part-of 'community
|
||||||
|
#:description
|
||||||
|
@'{Racket-related community resources: mailing lists, IRC channel, @;
|
||||||
|
resources for developers, RacketCon, blog, and more.}]{
|
||||||
|
@mailing-lists-quick
|
||||||
|
@irc-quick
|
||||||
|
@parlist[@strong{RacketCon}
|
||||||
|
@text{@-rcon[] is our annual conference:
|
||||||
|
@-rcon[2012] and @-rcon[2011].}]
|
||||||
|
@parlist[@strong{PLT Design Inc.}
|
||||||
|
@text{@blog — announcements, helpful hints, and thoughtful rants.}
|
||||||
|
@text{@a[href: "http://twitter.com/#!/racketlang"]{Twitter}
|
||||||
|
— random Racket bits.}
|
||||||
|
@text{@people — the people behind Racket.}]
|
||||||
|
@parlist[@strong{Wiki}
|
||||||
|
@text{@-wiki[#f]{Wiki pages}, including:}
|
||||||
|
@text{@-wiki{Intro Projects} — Find a project to contribute,}
|
||||||
|
@text{@-wiki{Videos} — Watch tutorials, interviews, and more.}]
|
||||||
|
@parlist[@strong{Development}
|
||||||
|
@text{@git (also available on
|
||||||
|
@a[href: "http://github.com/plt/racket/"]{GitHub}).}
|
||||||
|
@text{@pre:installers and @pre:index{more}.}
|
||||||
|
@text{@bug-reports — create and query existing reports.}]
|
||||||
|
@parlist[@strong{Support}
|
||||||
|
@text{
|
||||||
|
Thanks to @a[href: "http://www.nsf.gov/"]{the NSF},
|
||||||
|
@a[href: "http://www.darpa.mil/"]{DARPA},
|
||||||
|
the
|
||||||
|
@a[href: "http://www.ed.gov/FIPSE/"]{
|
||||||
|
Fund for the Improvement of Postsecondary Education (FIPSE)}
|
||||||
|
at the @a[href: "http://www.ed.gov/"]{US Department of Education},
|
||||||
|
the @a[href: '("http://www.exxonmobil.com/Corporate/"
|
||||||
|
"community_foundation.aspx")]{Exxon Foundation},
|
||||||
|
CORD,partners of the Academy of Information Technology,
|
||||||
|
@a[href: "http://microsoft.com"]{Microsoft},
|
||||||
|
@a[href: "http://mozilla.org"]{Mozilla},
|
||||||
|
and @a[href: "http://google.com"]{Google}
|
||||||
|
for their generous support over the years.}]})
|
BIN
new-racket-web/web/www/download-dark.png
Normal file
BIN
new-racket-web/web/www/download-dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
BIN
new-racket-web/web/www/download.png
Normal file
BIN
new-racket-web/web/www/download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
42
new-racket-web/web/www/download.rkt
Normal file
42
new-racket-web/web/www/download.rkt
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "../download/download-pages.rkt")
|
||||||
|
|
||||||
|
(provide download)
|
||||||
|
(define download
|
||||||
|
@page[#:link-title "Download" #:window-title "Download Racket"
|
||||||
|
#:file "download/" #:part-of 'download]{
|
||||||
|
@(render-download-page)})
|
||||||
|
|
||||||
|
(define images (list (copyfile (in-here "download.png"))
|
||||||
|
(copyfile (in-here "download-dark.png"))))
|
||||||
|
|
||||||
|
(provide download-button)
|
||||||
|
(define (download-button)
|
||||||
|
@text{
|
||||||
|
@script/inline[type: "text/javascript"]{
|
||||||
|
@; Don't load all images here -- it causes a delay when loading the
|
||||||
|
@; page instead, do it only when needed, and also set a timer to do it
|
||||||
|
@; after loading the page. This makes it so that there's almost never
|
||||||
|
@; a delay when loading the page, and also no delay when switching the
|
||||||
|
@; image.
|
||||||
|
var rollovers = false, the_download_button = false;
|
||||||
|
function init_rollovers() {
|
||||||
|
if (!rollovers) {
|
||||||
|
rollovers = [ new Image(), new Image() ];
|
||||||
|
rollovers[0].src = "@(car images)";
|
||||||
|
rollovers[1].src = "@(cadr images)";
|
||||||
|
the_download_button = document.getElementById("download_button");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function set_download_image(n) {
|
||||||
|
if (!rollovers) init_rollovers();
|
||||||
|
the_download_button.src = rollovers[n].src;
|
||||||
|
}
|
||||||
|
setTimeout(init_rollovers, 400);
|
||||||
|
}
|
||||||
|
@a[href: (url-of download)
|
||||||
|
onmouseover: "set_download_image(1);"
|
||||||
|
onmouseout: "set_download_image(0);"]{
|
||||||
|
@img[id: "download_button" src: (car images) style: "border-width: 0;"
|
||||||
|
alt: "Download Racket" title: "Download Racket"]}})
|
38
new-racket-web/web/www/help.rkt
Normal file
38
new-racket-web/web/www/help.rkt
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "community.rkt")
|
||||||
|
|
||||||
|
(provide help)
|
||||||
|
(define help
|
||||||
|
@page[#:link-title "Need Help?"]{
|
||||||
|
@parlist[@strong{Don't Panic!}
|
||||||
|
@text{Racket has a variety of resources designed to help you
|
||||||
|
with any problems you may have.}]
|
||||||
|
@parlist[@strong{Help Desk}
|
||||||
|
@text{Your first stop should always be with the help system that's
|
||||||
|
built into Racket and available from DrRacket's help menu
|
||||||
|
@strong{or by pressing F1 with the cursor on a search term}.
|
||||||
|
This documentation is customized for your installation, and
|
||||||
|
may include documentation for optional packages you've
|
||||||
|
installed. As a second line of defense, the documentation
|
||||||
|
for the core of the most recent version of Racket is
|
||||||
|
available @-docs{from this web site}.}
|
||||||
|
@text{Not sure what to search for? The documentation includes a
|
||||||
|
@guide{guide} (also located in your local copy of the
|
||||||
|
documentation) that provides a narrative introduction to many
|
||||||
|
of Racket's features.}]
|
||||||
|
@parlist[@strong{Learning how to Program}
|
||||||
|
@text{Try going through @|-htdp|.}]
|
||||||
|
@parlist[@strong{Searching the Web}
|
||||||
|
@text{Your favorite search engine may well provide answers for many
|
||||||
|
of your questions, in particular, try to search through
|
||||||
|
Racket questions on
|
||||||
|
@a[href: "http://stackoverflow.com/questions/tagged/racket"]{
|
||||||
|
stackoverflow}.}]
|
||||||
|
@parlist[@strong{The Mailing List}
|
||||||
|
@text{The @tt|{users@racket-lang.org}| mailing list is a great
|
||||||
|
source for answers to questions when the above resources
|
||||||
|
don't pan out@";" sign up for it in the @community area of
|
||||||
|
the website.}]
|
||||||
|
@br
|
||||||
|
@text{Thanks for using Racket!}})
|
542
new-racket-web/web/www/index.rkt
Normal file
542
new-racket-web/web/www/index.rkt
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "code.rkt" "download.rkt" "learning.rkt")
|
||||||
|
|
||||||
|
(define (doc path . text)
|
||||||
|
(apply a href: (list "http://docs.racket-lang.org/" path) text))
|
||||||
|
|
||||||
|
(struct example (code desc))
|
||||||
|
|
||||||
|
(define ((example-with-help . help) code desc)
|
||||||
|
(example code (list desc help)))
|
||||||
|
(define generic-example
|
||||||
|
@example-with-help{
|
||||||
|
@p{To run the example, install Racket, start DrRacket, paste the example
|
||||||
|
program into the top area in DrRacket, and click the Run button.
|
||||||
|
Alternatively, save the program to a file and run @tt{racket} on the
|
||||||
|
file.}})
|
||||||
|
(define cmdline-example
|
||||||
|
@example-with-help{
|
||||||
|
@p{This example is a command-line script. To run the example, install
|
||||||
|
Racket, paste the example program into a file, and run @tt{racket} on
|
||||||
|
the file with command-line arguments after the filename. Alternatively,
|
||||||
|
for a Unix installation, you can add @tt{#!/usr/bin/env racket} at the
|
||||||
|
top and make the file executable, and then you can run the file
|
||||||
|
directly.}})
|
||||||
|
(define scribble-example
|
||||||
|
@example-with-help{
|
||||||
|
@p{To run the example, install Racket, start DrRacket, and paste the
|
||||||
|
example program into the top area in DrRacket. When a program in a
|
||||||
|
Scribble language is opened in DrRacket, a @b{Scribble HTML} button
|
||||||
|
appears for rendering the document to HTML. Click it.}})
|
||||||
|
(define graphical-example
|
||||||
|
@example-with-help{
|
||||||
|
@p{To run the example, install Racket, start DrRacket, paste the example
|
||||||
|
program into the top area in DrRacket, and click the Run button.}})
|
||||||
|
|
||||||
|
(define desc div)
|
||||||
|
(define (elemcode . strs) (apply tt strs))
|
||||||
|
|
||||||
|
(define examples
|
||||||
|
@; --- Each example here should be at most 7 lines long ------------
|
||||||
|
(list
|
||||||
|
@; Candidates for initial example: --------------------------------
|
||||||
|
(list
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket
|
||||||
|
;; Finds Racket sources in all subdirs
|
||||||
|
(for ([path (in-directory)])
|
||||||
|
(when (regexp-match? #rx"[.]rkt$" path)
|
||||||
|
(printf "source file: ~a\n" path)))}
|
||||||
|
@desc{The @elemcode{in-directory} function constructs a sequence that
|
||||||
|
walks a directory tree (starting with the current directory, by default)
|
||||||
|
and generates paths in the tree. The @elemcode{for} form binds
|
||||||
|
@elemcode{p} to each path in the sequence, and @elemcode{regexp-match?}
|
||||||
|
applies a pattern to the path.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang web-server/insta
|
||||||
|
;; A "hello world" web server
|
||||||
|
(define (start request)
|
||||||
|
(response/xexpr
|
||||||
|
'(html
|
||||||
|
(body "Hello World"))))}
|
||||||
|
@desc{This example implements a web server using the
|
||||||
|
@elemcode{web-server/insta} language. Each time a connection is made to
|
||||||
|
the server, the @elemcode{start} function is called to get the HTML to
|
||||||
|
send back to the client.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket ; An echo server
|
||||||
|
(define listener (tcp-listen 12345))
|
||||||
|
(let echo-server ()
|
||||||
|
(define-values (in out) (tcp-accept listener))
|
||||||
|
(thread (lambda () (copy-port in out)
|
||||||
|
(close-output-port out)))
|
||||||
|
(echo-server))}
|
||||||
|
@desc{Racket makes it easy to use TCP sockets and spawn threads to handle
|
||||||
|
them. This program starts a server at TCP port 12345 that echos
|
||||||
|
anything a client sends back to the client.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket
|
||||||
|
;; Report each unique line from stdin
|
||||||
|
(let ([saw (make-hash)])
|
||||||
|
(for ([line (in-lines)])
|
||||||
|
(unless (hash-ref saw line #f)
|
||||||
|
(displayln line))
|
||||||
|
(hash-set! saw line #t)))}
|
||||||
|
@desc{Uses a hash table to record previously seen lines. You can run this
|
||||||
|
program in DrRacket, but it makes more sense from the command line.}))
|
||||||
|
@; Additional examples: -------------------------------------------
|
||||||
|
(list
|
||||||
|
(graphical-example ; ---------------------------------------------
|
||||||
|
@code{#lang racket ; A picture
|
||||||
|
(require 2htdp/image)
|
||||||
|
(let sierpinski ([n 8])
|
||||||
|
(if (zero? n)
|
||||||
|
(triangle 2 'solid 'red)
|
||||||
|
(let ([t (sierpinski (- n 1))])
|
||||||
|
(freeze (above t (beside t t))))))}
|
||||||
|
@desc{The @elemcode{2htdp/image} library provides easy-to-use functions
|
||||||
|
for constructing images, and DrRacket can display an image result as
|
||||||
|
easily as it can display a number result. In this case, a
|
||||||
|
@elemcode{sierpinski} function is defined and called (at the same time)
|
||||||
|
to generate a Sierpinski triangle of depth 8.})
|
||||||
|
(graphical-example ; ---------------------------------------------
|
||||||
|
@code{#lang racket/gui ; A GUI guessing game
|
||||||
|
(define f (new frame% [label "Guess"]))
|
||||||
|
(define n (random 5)) (send f show #t)
|
||||||
|
(define ((check i) btn evt)
|
||||||
|
(message-box "." (if (= i n) "Yes" "No")))
|
||||||
|
(for ([i (in-range 5)])
|
||||||
|
(make-object button% (format "~a" i) f (check i)))}
|
||||||
|
@desc{This simple guesing game demonstates Racket's class-based GUI
|
||||||
|
toolkit. The @elemcode{frame%} class implements a top-level window, and
|
||||||
|
@elemcode{button%} obviously implements a button. The @elemcode{check}
|
||||||
|
function defined here produces an function that is used for the button's
|
||||||
|
callback action.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket ; Simple web scraper
|
||||||
|
(require net/url net/uri-codec)
|
||||||
|
(define (let-me-google-that-for-you str)
|
||||||
|
(let* ([g "http://www.google.com/search?q="]
|
||||||
|
[u (string-append g (uri-encode str))]
|
||||||
|
[rx #rx"(?<=<h3 class=\"r\">).*?(?=</h3>)"])
|
||||||
|
(regexp-match* rx (get-pure-port (string->url u)))))}
|
||||||
|
@desc{Add a call to @elemcode{let-me-google-that-for-you} to get a list of
|
||||||
|
search results.})
|
||||||
|
(cmdline-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket
|
||||||
|
;; A dice-rolling command-line utility
|
||||||
|
(command-line
|
||||||
|
#:args (dice sides)
|
||||||
|
(for ([i (in-range (string->number dice))])
|
||||||
|
(displayln
|
||||||
|
(+ 1 (random (string->number sides))))))}
|
||||||
|
@desc{Playing a game but no dice on hand? Let Racket roll for you. The
|
||||||
|
@elemcode{command-line} form makes sure that the right number of
|
||||||
|
arguments are provided and automatically implements the @tt{--help}
|
||||||
|
switch.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket
|
||||||
|
;; Print the Greek alphabet
|
||||||
|
(for ([i (in-range 25)])
|
||||||
|
(displayln
|
||||||
|
(integer->char
|
||||||
|
(+ i (char->integer #\u3B1)))))}
|
||||||
|
@desc{The only reason we use the encoded form of a character
|
||||||
|
@elemcode{#\u3B1} instead of the more direct form @elemcode{#\α} is that
|
||||||
|
we don't trust your browser to render it correctly. DrRacket is
|
||||||
|
perfectly happy with @elemcode{#\α}.})
|
||||||
|
(graphical-example ; ---------------------------------------------
|
||||||
|
@code{#lang htdp/bsl ; Any key inflates the balloon
|
||||||
|
(require 2htdp/image) (require 2htdp/universe)
|
||||||
|
(define (balloon b) (circle b "solid" "red"))
|
||||||
|
(define (blow-up b k) (+ b 5))
|
||||||
|
(define (deflate b) (max (- b 1) 1))
|
||||||
|
(big-bang 50 (on-key blow-up) (on-tick deflate)
|
||||||
|
(to-draw balloon 200 200))}
|
||||||
|
@desc{Racket's mission includes education at all levels. This program
|
||||||
|
uses the @elemcode{htdp/bsl} teaching language, the
|
||||||
|
@elemcode{2htdp/image} library for creating pictures in the teaching
|
||||||
|
languages, and the @elemcode{2htdp/universe} library for interactive
|
||||||
|
animations.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang lazy
|
||||||
|
;; An infinite list:
|
||||||
|
(define fibs
|
||||||
|
(list* 1 1 (map + fibs (cdr fibs))))
|
||||||
|
@||
|
||||||
|
;; Print the 1000th Fibonacci number:
|
||||||
|
(print (list-ref fibs 1000))}
|
||||||
|
@desc{And now for something completely different. The @elemcode{lazy}
|
||||||
|
language is more like Haskell than Lisp, so feel free to build an
|
||||||
|
infinite list and look at only part of it.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang typed/racket
|
||||||
|
;; Using higher-order occurrence typing
|
||||||
|
(define-type SrN (U String Number))
|
||||||
|
(: tog ((Listof SrN) -> String))
|
||||||
|
(define (tog l)
|
||||||
|
(apply string-append (filter string? l)))
|
||||||
|
(tog (list 5 "hello " 1/2 "world" (sqrt -1)))}
|
||||||
|
@desc{Racket's type system is designed to let you add types after you've
|
||||||
|
worked for a while in untyped mode — even if your untyped program
|
||||||
|
wouldn't fit nicely in a conventional type system.})
|
||||||
|
(scribble-example ; ----------------------------------------------
|
||||||
|
@code|{#lang scribble/base
|
||||||
|
@; Generate a PDF or HTML document
|
||||||
|
@title{Bottles --- @italic{Abridged}}
|
||||||
|
@(apply itemlist
|
||||||
|
(for/list ([n (in-range 100 0 -1)])
|
||||||
|
@item{@(format "~a" n) bottles.}))}|
|
||||||
|
@desc{This program uses the @elemcode{scribble/base} language for
|
||||||
|
generating documents using a prose-friendly syntax.})
|
||||||
|
(graphical-example ; ---------------------------------------------
|
||||||
|
@code{#lang racket ; draw a graph of cos
|
||||||
|
(require plot) ; and deriv^3(cos)
|
||||||
|
(define ((deriv f) x)
|
||||||
|
(/ (- (f x) (f (- x 0.001))) 0.001))
|
||||||
|
(define (thrice f) (lambda (x) (f (f (f x)))))
|
||||||
|
(plot (list (function ((thrice deriv) sin) -5 5)
|
||||||
|
(function cos -5 5 #:color 'blue)))}
|
||||||
|
@desc{This program uses the @elemcode{plot} library to draw plots of
|
||||||
|
functions. Note that the plots are actual value, which DrRacket shows
|
||||||
|
in graphical form.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket ; Sending email from racket
|
||||||
|
(require net/sendmail)
|
||||||
|
(sleep (* (- (* 60 4) 15) 60)) ; 4h - 15m
|
||||||
|
(send-mail-message
|
||||||
|
(getenv "EMAIL") "Parking meter alert!"
|
||||||
|
(list (getenv "EMAIL")) null null
|
||||||
|
'("Time to go out and move your car."))}
|
||||||
|
@desc{Racket comes with plenty of libraries.})
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang scheme/base ; Simple use of the FFI
|
||||||
|
(require ffi/unsafe)
|
||||||
|
(define mci-send-string
|
||||||
|
(get-ffi-obj "mciSendStringA" "Winmm"
|
||||||
|
(_fun _string [_pointer = #f] [_int = 0]
|
||||||
|
[_pointer = #f] -> [ret : _int])))
|
||||||
|
(mci-send-string "play sound.wav wait")}
|
||||||
|
@desc{Using the FFI means that you're not limited to using Racket
|
||||||
|
libraries: pulling out a foreign function is easy, and can even be done
|
||||||
|
dynamically on the REPL.})
|
||||||
|
;; Is this effective without any highlights?
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang datalog
|
||||||
|
ancestor(A, B) :- parent(A, B).
|
||||||
|
ancestor(A, B) :-
|
||||||
|
parent(A, C), D = C, ancestor(D, B).
|
||||||
|
parent(john, douglas).
|
||||||
|
parent(bob, john).
|
||||||
|
ancestor(A, B)?}
|
||||||
|
@desc{Racket is useful for building other languages. This example uses
|
||||||
|
the pre-packaged Racket implementation of Datalog, a logic programming
|
||||||
|
language. If you use this from DrRacket, you'll see that it provides
|
||||||
|
proper highlighting, Check Syntax, and a Datalog-specific REPL.})
|
||||||
|
#; ; Not easy to present something like this.
|
||||||
|
(generic-example ; -----------------------------------------------
|
||||||
|
@code{#lang racket
|
||||||
|
(provide (except-out (all-from-out racket)
|
||||||
|
#%top #%app)
|
||||||
|
(rename-out [top #%top] [app #%app]))
|
||||||
|
(define-syntax-rule (top . x) 'x)
|
||||||
|
(define-syntax-rule (app f . xs)
|
||||||
|
(if (hash? f) (hash-ref f . xs) (f . xs)))
|
||||||
|
}
|
||||||
|
@desc{TODO, and use this example:
|
||||||
|
@pre{#lang s-exp "foo"
|
||||||
|
(define x (make-hasheq))
|
||||||
|
(hash-set! x A B)
|
||||||
|
(x A)}})
|
||||||
|
)))
|
||||||
|
|
||||||
|
(define blurb "Racket is a programming language")
|
||||||
|
|
||||||
|
(provide set-news-flashes!)
|
||||||
|
(define news-flashes #f)
|
||||||
|
(define (set-news-flashes! . text)
|
||||||
|
(when news-flashes (error 'set-news-flashes! "text already set"))
|
||||||
|
(set! news-flashes text))
|
||||||
|
|
||||||
|
(provide index)
|
||||||
|
(define index
|
||||||
|
(page #:link-title "About" #:window-title "The Racket Language"
|
||||||
|
#:description
|
||||||
|
@'{Racket is a modern programming language in the Lisp/Scheme family, @;
|
||||||
|
suitable for a wide range of applications. @;
|
||||||
|
Racket provides a rich language extension API, the DrRacket @;
|
||||||
|
integrated development environment, and many batteries-included @;
|
||||||
|
libraries.}
|
||||||
|
#:extra-headers @list{@meta[name: "robots" content: "NOODP"]
|
||||||
|
@(lazy more.css)}
|
||||||
|
@div[class: 'leftpane]{
|
||||||
|
@span[style: "font-size: large; font-weight: bold;"]{Racket}
|
||||||
|
is a programming language.
|
||||||
|
@(and news-flashes (list br (div style: "width: 100%;" news-flashes)))}
|
||||||
|
@div[class: 'downloadbutton]{@download-button}
|
||||||
|
@div[class: 'aboutpane]{
|
||||||
|
@div[class: 'panetitle]{Start Quickly}
|
||||||
|
@div{@(apply slideshow-panel examples)}
|
||||||
|
@p{@doc["quick/"]{Draw more pictures} or
|
||||||
|
@doc["more/"]{build a web server from scratch}. Racket includes both
|
||||||
|
@doc[""]{batteries} and a @doc["drracket/"]{programming environment},
|
||||||
|
so @doc["getting-started/"]{get started}!}}
|
||||||
|
@((λ xs (table class: 'threepanes
|
||||||
|
(tr (map (λ (x) (td (div class: 'panetitle (car x)) (cdr x)))
|
||||||
|
xs))))
|
||||||
|
(list "Grow your Program"
|
||||||
|
@p{Racket's
|
||||||
|
@doc["guide/intro.html#(part._.Interacting_with_.Racket)"]{
|
||||||
|
interactive mode}
|
||||||
|
encourages experimentation, and quick scripts easily compose into
|
||||||
|
larger systems. Small scripts and large systems both benefit from
|
||||||
|
@doc["guide/performance.html"]{native-code JIT compilation}.
|
||||||
|
When a system gets too big to keep in your head, you can add
|
||||||
|
@doc["ts-guide/index.html"]{static types}.})
|
||||||
|
(list "Grow your Language"
|
||||||
|
@p{@doc["guide/languages.html"]{Extend Racket} whenever you need to.
|
||||||
|
Mold it to better suit your tasks without sacrificing
|
||||||
|
@doc["guide/dialects.html"]{interoperability} with existing
|
||||||
|
libraries and without having to modify the
|
||||||
|
@doc["guide/intro.html"]{tool chain}. When less is more, you can
|
||||||
|
remove parts of a language or start over and build a new one.})
|
||||||
|
(list "Grow your Skills"
|
||||||
|
@p{Whether you're just @-htdp{starting out}, want to know more about
|
||||||
|
programming language @-plai{applications} or @-redex{models},
|
||||||
|
looking to @continue{expand your horizons}, or ready to dive into
|
||||||
|
@learning{research}, Racket can help you become a better programmer
|
||||||
|
and system builder.}))))
|
||||||
|
(define index2
|
||||||
|
@page{
|
||||||
|
new stuff here
|
||||||
|
})
|
||||||
|
|
||||||
|
(define (slideshow-panel l1 l2)
|
||||||
|
(define l (append l1 l2))
|
||||||
|
(define button-ids+labels '())
|
||||||
|
;; this separator is shown in non-CSS browsers (e.g., textual ones)
|
||||||
|
(define invisible-separator @div[style: "display: none;"]{@br{}@hr{}})
|
||||||
|
(define (button txt tip id onclick)
|
||||||
|
(set! button-ids+labels (cons (cons id txt) button-ids+labels))
|
||||||
|
(a href: "#" id: id onclick: (list onclick "; return false;") title: tip
|
||||||
|
nbsp)) ; empty, filled by JS code, so JS-less browsers won't see it
|
||||||
|
(div class: 'slideshow
|
||||||
|
(div class: 'buttonpanel
|
||||||
|
@button["<" "Previous example" 'rewindbutton "rewind_show()"]
|
||||||
|
@button[">" "Next example" 'advancebutton "advance_show()"]
|
||||||
|
@button["?" "Explain this code" 'helpbutton "set_help(!help_showing)"]
|
||||||
|
(div class: 'hiddenhelp id: "helppanel" style: "display: none;"
|
||||||
|
(div class: 'helpcontent
|
||||||
|
@button["close" "Close help" 'closebutton "set_help(false)"]
|
||||||
|
(div id: 'helpdesc "") ; placeholder for the descriptions (see below)
|
||||||
|
@div[class: 'helptext]{
|
||||||
|
Form and function names in the code are hyperlinked to
|
||||||
|
documentation, so click on them for more information.})))
|
||||||
|
(for/list ([elem (in-list l)] [pos (in-naturals)])
|
||||||
|
@list{
|
||||||
|
@invisible-separator
|
||||||
|
@pre[class: 'slideshowframe id: @list{frame@pos}
|
||||||
|
style: @list{display: @(if (zero? pos) "block" "none")@";"}]{
|
||||||
|
@(example-code elem)}@;
|
||||||
|
@; have the descriptions appear in a logical place and then ...
|
||||||
|
@div[id: @list{helpframe@pos} style: "display: none;"]{
|
||||||
|
@(example-desc elem)}})
|
||||||
|
@invisible-separator
|
||||||
|
@script/inline[type: "text/javascript"]{
|
||||||
|
@; ... move them to a convenient-for-display place
|
||||||
|
var helpdesc = document.getElementById("helpdesc");
|
||||||
|
for (var i=0@";" i<@(length l)@";" i++) {
|
||||||
|
var help_item = document.getElementById("helpframe"+i);
|
||||||
|
help_item.parentNode.removeChild(help_item);
|
||||||
|
helpdesc.appendChild(help_item);
|
||||||
|
}
|
||||||
|
var showing = 0, help_showing = false;
|
||||||
|
var frame_s=new Array(), helpframe_s=new Array();
|
||||||
|
for (var i=0@";" i<@(length l)@";" i++) {
|
||||||
|
frame_s[i] = document.getElementById("frame" + i).style;
|
||||||
|
helpframe_s[i] = document.getElementById("helpframe" + i).style;
|
||||||
|
}
|
||||||
|
var advbutton_s = document.getElementById("advancebutton").style;
|
||||||
|
var rewbutton_s = document.getElementById("rewindbutton").style;
|
||||||
|
function set_display(disp) {
|
||||||
|
frame_s[showing].display = disp;
|
||||||
|
helpframe_s[showing].display = disp;
|
||||||
|
}
|
||||||
|
function change_show_to(new_showing) {
|
||||||
|
set_display("none");
|
||||||
|
showing = new_showing;
|
||||||
|
set_display("block");
|
||||||
|
rewbutton_s.color = (showing==0) ? "#aaaaaa" : "#444444";
|
||||||
|
advbutton_s.color =
|
||||||
|
(showing==@(sub1 (length l))) ? "#aaaaaa" : "#444444";
|
||||||
|
}
|
||||||
|
function advance_show() {
|
||||||
|
if (showing < @(sub1 (length l))) change_show_to(showing+1);
|
||||||
|
}
|
||||||
|
function rewind_show() {
|
||||||
|
if (showing > 0) change_show_to(showing-1);
|
||||||
|
}
|
||||||
|
var help_panel_s = document.getElementById("helppanel").style;
|
||||||
|
function set_help(show) {
|
||||||
|
help_panel_s.display = show ? "block" : "none";
|
||||||
|
help_showing = show;
|
||||||
|
}
|
||||||
|
change_show_to(Math.floor(Math.random() * @(length l1)));
|
||||||
|
@; display button texts now, instead of making it part of the html,
|
||||||
|
@; so it's not shown on JS-less browsers
|
||||||
|
@(add-newlines
|
||||||
|
(for/list ([id+label (in-list button-ids+labels)])
|
||||||
|
(let ([id (car id+label)] [label (cdr id+label)])
|
||||||
|
@list{document.getElementById("@id").textContent = "@label"@";"})))
|
||||||
|
}))
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
;; (define screenshots
|
||||||
|
;; (let ([image (copyfile (in-here "screenshot.jpg"))])
|
||||||
|
;; @a[href: screenshots]{
|
||||||
|
;; @img[src: image alt: "[screenshots]" border: 0
|
||||||
|
;; style: "margin-bottom: 2px;"]@;
|
||||||
|
;; @|br|@small{Screenshots}}))
|
||||||
|
|
||||||
|
;; (define tour-video
|
||||||
|
;; (page #:title "DrRacket Tour" #:file "tour.html"
|
||||||
|
;; (define (center . body)
|
||||||
|
;; (table align: 'center style: "margin: 3em 0em;"
|
||||||
|
;; (tr (td align: 'center body))))
|
||||||
|
;; ;; someone posted a comment saying that adding "&fmt=18" to the url
|
||||||
|
;; ;; shows a higher resolution video, but it looks exactly the same.
|
||||||
|
;; (define url "http://www.youtube.com/v/vgQO_kHl39g&hl=en")
|
||||||
|
;; @center{
|
||||||
|
;; @object[type: "application/x-shockwave-flash" data: url
|
||||||
|
;; width: (round (* 3/2 425)) height: (round (* 3/2 344))]{
|
||||||
|
;; @param[name: "movie" value: url]}}))
|
||||||
|
|
||||||
|
|
||||||
|
;; resources that are specific to the front page
|
||||||
|
|
||||||
|
(define loud (copyfile (in-here "loud.png")))
|
||||||
|
|
||||||
|
(define more.css
|
||||||
|
@plain[#:referrer (λ (url) (link rel: "stylesheet" type: "text/css"
|
||||||
|
href: url title: "default"))]{
|
||||||
|
.bodycontent {
|
||||||
|
background-image: url('@loud');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center top;
|
||||||
|
}
|
||||||
|
.leftpane {
|
||||||
|
font-size: medium;
|
||||||
|
float: left;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
.aboutpane {
|
||||||
|
width: 56%;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.panetitle {
|
||||||
|
width: 100%;
|
||||||
|
font-size: large;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #dd0000;
|
||||||
|
}
|
||||||
|
.threepanes {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.threepanes td {
|
||||||
|
vertical-align: top;
|
||||||
|
margin: auto;
|
||||||
|
width: 30%;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
.slideshow {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.slideshowframe {
|
||||||
|
height: 17ex;
|
||||||
|
}
|
||||||
|
.buttonpanel {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 100%;
|
||||||
|
top: -3ex;
|
||||||
|
width: 3em;
|
||||||
|
margin: 0em 0em 0em -5em;
|
||||||
|
}
|
||||||
|
#advancebutton, #rewindbutton, #helpbutton, #closebutton {
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid #ddddd;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #44444;
|
||||||
|
background-color: #eeeee;
|
||||||
|
padding: 0px 1px 0px 1px;
|
||||||
|
}
|
||||||
|
#advancebutton, #rewindbutton {
|
||||||
|
margin: 0px 1px 0px 1px;
|
||||||
|
}
|
||||||
|
#helpbutton {
|
||||||
|
margin: 0px 1px 0px 10px;
|
||||||
|
}
|
||||||
|
.hiddenhelp {
|
||||||
|
width: 0em;
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
.helpcontent {
|
||||||
|
width: 20em;
|
||||||
|
background-color: #ffffee;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 3px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
#closebutton {
|
||||||
|
font-size: small;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.helptext, #helpdesc {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.helptext {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
.downloadbutton {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
@;
|
||||||
|
.codecomment {
|
||||||
|
color: #c2741f;
|
||||||
|
}
|
||||||
|
.codeparenthesis {
|
||||||
|
color: #843c24;
|
||||||
|
}
|
||||||
|
.codeconstant, .codestring {
|
||||||
|
color: #228b22;
|
||||||
|
}
|
||||||
|
.codeid, .codemodpath {
|
||||||
|
color: #262680;
|
||||||
|
}
|
||||||
|
.codeimportid {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
.codeimportform {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.codelinkimportid {
|
||||||
|
color: blue;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.codelinkimportform {
|
||||||
|
font-weight: bold;
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.codelinkimportid:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.codelinkimportform:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.codemodpath:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}})
|
42
new-racket-web/web/www/irc.rkt
Normal file
42
new-racket-web/web/www/irc.rkt
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt")
|
||||||
|
|
||||||
|
(define webchat-link
|
||||||
|
"http://webchat.freenode.net?channels=racket&uio=OT10cnVlJjExPTIzNg6b")
|
||||||
|
|
||||||
|
(define irc-chat
|
||||||
|
@page[#:title "IRC" #:part-of 'community]{
|
||||||
|
@iframe[src: webchat-link width: "100%" height: "400"]})
|
||||||
|
|
||||||
|
(define log-header+footer
|
||||||
|
(lazy (regexp-split #rx"{{{BODY}}}"
|
||||||
|
(xml->string @page[#:id 'browse-downloads
|
||||||
|
#:html-only #t
|
||||||
|
#:part-of 'community
|
||||||
|
"{{{BODY}}}"]))))
|
||||||
|
(define header @plain[#:file "irc-logs/dummy/HEADER.html" #:newline #f
|
||||||
|
(car (force log-header+footer))])
|
||||||
|
(define footer @plain[#:file "irc-logs/dummy/README.html" #:newline #f
|
||||||
|
(cadr (force log-header+footer))])
|
||||||
|
|
||||||
|
(provide irc-logs)
|
||||||
|
(define irc-logs
|
||||||
|
(let ([base "/home/scheme/irc-logs"])
|
||||||
|
(define t (make-hash))
|
||||||
|
(λ (type . text)
|
||||||
|
(hash-ref! t type (λ() (a href: (symlink (format "~a/~a" base type)
|
||||||
|
(format "irc-logs/~a" type))
|
||||||
|
text))))))
|
||||||
|
(void (irc-logs ".htaccess"))
|
||||||
|
|
||||||
|
(provide irc-quick)
|
||||||
|
(define (irc-quick)
|
||||||
|
(define (chan name) @TT{@big{@strong{#@name}}})
|
||||||
|
@parlist[@strong{Discussion Channel}
|
||||||
|
@text{@irc-chat{Chat on IRC} in the @chan{racket} channel on
|
||||||
|
@a[href: "http://freenode.net"]{@tt{freenode.net}} — an informal
|
||||||
|
discussion channel for all things related to Racket.
|
||||||
|
(@irc-logs['racket]{Browse the logs}.)
|
||||||
|
There is also @chan{racket-dev} (@irc-logs['racket-dev]{logs}), a channel
|
||||||
|
for notification bots.}])
|
102
new-racket-web/web/www/learning.rkt
Normal file
102
new-racket-web/web/www/learning.rkt
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt" "people.rkt" "techreports.rkt" "old-techreports.rkt")
|
||||||
|
|
||||||
|
(provide learning)
|
||||||
|
(define learning
|
||||||
|
@page[#:window-title "Racket Learning" #:part-of 'learning
|
||||||
|
#:description
|
||||||
|
'@{Racket-related learning resources. Introductions to Racket, @;
|
||||||
|
the Racket Guide, Computer Science textbooks that use Racket, @;
|
||||||
|
outreach programs, and graduate studies.}]{
|
||||||
|
@parlist[@strong{Resources for Learning}
|
||||||
|
(apply parlist @text{Documentation for getting started:} intros)
|
||||||
|
@text{@-htdp — a textbook for introductory programming, but also
|
||||||
|
worthwhile for experience programmers who are new to “functional
|
||||||
|
programming.”}
|
||||||
|
@text{@-plai — a textbook on programming languages.}]
|
||||||
|
@parlist[@strong{Videos}
|
||||||
|
@text{See the @-wiki["Videos"] page at the @|-wiki|.}]
|
||||||
|
@parlist[
|
||||||
|
@strong{Outreach}
|
||||||
|
@text{@-pbd — a workshop to train teachers using @-htdp in the
|
||||||
|
classroom.}
|
||||||
|
@text{@-bootstrap — a curriculum for middle-school students.}]
|
||||||
|
@(apply parlist @strong{PLT Publications}
|
||||||
|
(cons techreports
|
||||||
|
(for*/list ([place (in-list all-places)]
|
||||||
|
[pubs (in-value (place-pubs place))]
|
||||||
|
#:when pubs)
|
||||||
|
@a[href: pubs]{@(place-name place)})))
|
||||||
|
@parlist[@strong{Graduate Study}
|
||||||
|
@text{We welcome applications from students interested in
|
||||||
|
@|graduate-study|.}]})
|
||||||
|
|
||||||
|
(define graduate-study
|
||||||
|
@page[#:file "common-plt-app.html" #:part-of 'learning]{
|
||||||
|
@(define (box-style border-width color)
|
||||||
|
@list{border: @|border-width|px solid black; padding: 5px; @;
|
||||||
|
background: @|color|@";"})
|
||||||
|
@(define place-names
|
||||||
|
(add-between
|
||||||
|
(sort (map (λ (p)
|
||||||
|
(regexp-replace #rx", [A-Z][A-Z]$" (place-location p) ""))
|
||||||
|
all-places)
|
||||||
|
string<?)
|
||||||
|
" / "))
|
||||||
|
@(define responsible-people
|
||||||
|
(add-between
|
||||||
|
(for/list ([person (sort (map (compose car place-people) all-places)
|
||||||
|
string<? #:key person-name)])
|
||||||
|
@a[href: (person-url person)]{
|
||||||
|
@(regexp-replace #rx" .*$" (person-name person) "")})
|
||||||
|
", "))
|
||||||
|
@h1{Graduate Study with PLT}
|
||||||
|
@p{An open letter to graduate applicants:}
|
||||||
|
@div[style: (box-style 3 "#dddddd")]{
|
||||||
|
@p*{
|
||||||
|
Dear Prospective Graduate Student,
|
||||||
|
@|br br|
|
||||||
|
Thank you for your interest in working with PLT. We get several
|
||||||
|
inquiries every year from students interested in working with one or more
|
||||||
|
of us. We're flattered and, of course, interested in your applications.
|
||||||
|
Because you are more interested in PLT than in our specific institutions,
|
||||||
|
we have created the following common application form. By filling it in
|
||||||
|
once, you can automatically apply to all current PLT institutions.
|
||||||
|
@~ @|style: (box-style 1 "#bbbbbb")|@;
|
||||||
|
Yes, we know you don't like @place-names (circle those applicable). But
|
||||||
|
we like them, or we wouldn't be living there. Think about the message
|
||||||
|
you're sending by rejecting our choices. Moreover, we think very highly
|
||||||
|
of our colleagues—more highly than we think of your judgment in this
|
||||||
|
matter—so for your own good, we're going to forward your application to
|
||||||
|
them anyway.
|
||||||
|
@~ How many years have you programmed in Scheme?
|
||||||
|
@~ How many years have you programmed in Racket?
|
||||||
|
@~ If the two numbers above are not identical, justify.
|
||||||
|
@~ How many Racket Web applications have you written?
|
||||||
|
@~ What problems did you find with the Racket Web server in the process?
|
||||||
|
Please list bug report numbers.
|
||||||
|
@~ Which wheels did you inadvertently reinvent?
|
||||||
|
@~ Do you prefer your calculi Classic or Featherweight?
|
||||||
|
@~ Should types be intervals or ideals?
|
||||||
|
@~ In your opinion, which Barendregt proof has the highest hours spent
|
||||||
|
understanding-to-symbols ratio?
|
||||||
|
@~ Which is your favorite combinator?
|
||||||
|
@~ Thank you for your interest. Don't be a cat squandering the popcorn.
|
||||||
|
@~ @|align: 'right|
|
||||||
|
—Shriram, Outreach Coordinator, PLT}}
|
||||||
|
@p{Seriously, we @em{do} enjoy working with graduate students. If you are
|
||||||
|
inspired by the PLT project and want to drive the next generation of
|
||||||
|
innovation, you should strongly consider graduate study with us. We
|
||||||
|
look forward to hearing from you. All of us, no matter where we may
|
||||||
|
live.}
|
||||||
|
@p[align: 'right]{—@responsible-people}})
|
||||||
|
|
||||||
|
;; redirection page for the previous name of this page
|
||||||
|
(define outreach+research
|
||||||
|
@page[#:part-of 'learning
|
||||||
|
#:title "Outreach & Research"
|
||||||
|
#:link-title @list{Outreach@|nbsp|&@|nbsp|Research}
|
||||||
|
#:extra-headers
|
||||||
|
@meta[http-equiv: "refresh" content: "0;url=learning.html"]]{
|
||||||
|
Moved.})
|
BIN
new-racket-web/web/www/loud.png
Normal file
BIN
new-racket-web/web/www/loud.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
171
new-racket-web/web/www/new-name.rkt
Normal file
171
new-racket-web/web/www/new-name.rkt
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt")
|
||||||
|
|
||||||
|
(define name i)
|
||||||
|
|
||||||
|
(define (url str) (tt (a href: str str)))
|
||||||
|
|
||||||
|
(define styles
|
||||||
|
@style/inline{
|
||||||
|
.nestedheading {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
.nested {
|
||||||
|
width: 80%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.faqsection {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-top: 2em;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.faqques {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.faqans {
|
||||||
|
margin-left: 1em;
|
||||||
|
}})
|
||||||
|
|
||||||
|
(define ((FAQ tag . ques) . answer)
|
||||||
|
@div[class: 'faqentry]{
|
||||||
|
@div[class: 'faqques]{@a[name: tag]{@ques}}
|
||||||
|
@div[class: 'faqans]{@answer}})
|
||||||
|
|
||||||
|
(define (heading . text)
|
||||||
|
(apply div class: 'nestedheading text))
|
||||||
|
(define (nested . text)
|
||||||
|
(apply div class: 'nested text))
|
||||||
|
|
||||||
|
(define new-name
|
||||||
|
@page[#:title "From PLT Scheme to Racket"]{
|
||||||
|
@styles
|
||||||
|
|
||||||
|
@heading{PLT Scheme is a Racket}
|
||||||
|
|
||||||
|
@nested{Sure, it has parentheses, uses the keyword @tt{lambda}, provides
|
||||||
|
lexical scope, and emphasizes macros — but don't be fooled. PLT Scheme
|
||||||
|
is no minimalist embodiment of 1930s math or 1970s technology. PLT
|
||||||
|
Scheme is a cover for a gang of academic hackers who want to fuse
|
||||||
|
cutting-edge programming-language research with everyday programming.
|
||||||
|
They draw you in with the promise of a simple and polite little Scheme,
|
||||||
|
but soon you'll find yourself using modules, contracts, keyword
|
||||||
|
arguments, classes, static types, and even curly braces.}
|
||||||
|
|
||||||
|
|
||||||
|
@heading{Racket is a Scheme}
|
||||||
|
|
||||||
|
@nested{Racket is still a dialect of Lisp and a descendant of Scheme. The
|
||||||
|
tools developed by PLT will continue to support R5RS, R6RS, the old
|
||||||
|
@tt{mzscheme} environment, Typed Scheme, and more. At the same time,
|
||||||
|
instead of having to say “PLT's main variant of Scheme,” programmers can
|
||||||
|
now simply say “Racket” to refer to the specific descendant of Scheme
|
||||||
|
that powers PLT's languages and libraries.}
|
||||||
|
|
||||||
|
|
||||||
|
@div[class: 'faqsection]{
|
||||||
|
@heading{Anticipated Questions}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['why]{Why change the name?}{
|
||||||
|
@p*{
|
||||||
|
The @name{Scheme} part of the name @name{PLT Scheme} is misleading, and
|
||||||
|
it is often an obstacle to explaining and promoting PLT research and
|
||||||
|
tools.
|
||||||
|
@~
|
||||||
|
For example, when you type “scheme” into Google, the first hit is a
|
||||||
|
Wikipedia entry written from an R5RS perspective. That's appropriate
|
||||||
|
for a Wikipedia page on Scheme, but it's not a good introduction to PLT
|
||||||
|
Scheme. As long as we call our language @name{Scheme}, we struggle to
|
||||||
|
explain our language, and we are usually forced to start the
|
||||||
|
explanation with a disclaimer. At the same time, to the degree that
|
||||||
|
the PLT community has defined @name{Scheme} through market share,
|
||||||
|
publications, and educational outreach, we interfere with everyone
|
||||||
|
else's ability to define @name{Scheme} — and many have a valid claim to
|
||||||
|
that ability.
|
||||||
|
@~
|
||||||
|
By switching to @name{Racket}, we expect to resolve this communication
|
||||||
|
problem.}}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['what]{What will the change look like?}{
|
||||||
|
@p*{
|
||||||
|
@name{DrScheme} becomes @name{DrRacket}. The @tt{mzscheme} executable
|
||||||
|
becomes @tt{racket}, and @tt{mred} becomes @tt{gracket} (following a
|
||||||
|
common convention for “GUI @tt{racket}”). We change each @tt{#lang
|
||||||
|
scheme} to @tt{#lang racket} in the Racket distribution, although
|
||||||
|
@tt{#lang scheme} will be supported for backward compatibility. The
|
||||||
|
@url{http://plt-scheme.org} site will be replaced by
|
||||||
|
@url{http://racket-lang.org}. The @tt{plt-scheme} mailing list becomes
|
||||||
|
the @tt{racket} mailing list (@tt|{users@racket-lang.org}|).
|
||||||
|
@~
|
||||||
|
The Racket site and documentation will note that Racket is a descendant
|
||||||
|
of Scheme, but most current uses of the word “Scheme” (which implicitly
|
||||||
|
mean PLT Scheme) will be replaced by “Racket.”
|
||||||
|
@~
|
||||||
|
Racket programmers are @name{Racketeers}, of course.}}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['scheme]{Does this mean that PLT will no longer implement Scheme?}{
|
||||||
|
@p*{
|
||||||
|
There will be little difference between the current @tt{#lang scheme}
|
||||||
|
and the new @tt{#lang racket}, but the latter will become the preferred
|
||||||
|
form.
|
||||||
|
@~
|
||||||
|
In addition, PLT will continue to support standards such as R5RS and
|
||||||
|
R6RS. The transition from/to various Scheme languages to/from Racket
|
||||||
|
will be as easy/difficult as before.}}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['transition]{What happens to all of the old programs, scripts,
|
||||||
|
address books, bookmarks, papers, etc. that refer to @name{PLT Scheme}
|
||||||
|
instead of @name{Racket}?}{
|
||||||
|
@p*{
|
||||||
|
Old executables, web sites, mailing addresses, and module names will
|
||||||
|
forward to the new ones. We will work to make the transition as
|
||||||
|
painless as possible and to preserve old references for as long as
|
||||||
|
possible.}}
|
||||||
|
|
||||||
|
@@FAQ['edu]{How can I tell my department that we should teach with Racket
|
||||||
|
instead of Scheme? They've never heard of @name{Racket}.}{
|
||||||
|
@p*{
|
||||||
|
If you felt comfortable claiming that PLT Scheme was Scheme before,
|
||||||
|
then you can still say that you want to teach with Scheme, even if the
|
||||||
|
environment is called @name{DrRacket}. Racket is a descendant of
|
||||||
|
Scheme, just like PLT Scheme was.}}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['brand]{Aren't you worried that you will lose brand recognition by
|
||||||
|
switching from the name @name{Scheme} to @name{Racket}?}{
|
||||||
|
@p*{
|
||||||
|
Yes. Nevertheless, we think the long-term benefit of a new name will
|
||||||
|
outweigh the short-term difficulties of changing.}}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['plt]{Instead of picking a new name, why not just call the language
|
||||||
|
@name{PLT}?}{
|
||||||
|
@p*{
|
||||||
|
Some of us tried that, informally. It felt awkward, because we use
|
||||||
|
@name{PLT} to refer to a group of people, and because we have used
|
||||||
|
@name{PLT} as a modifier for @name{Scheme} and other nouns. Switching
|
||||||
|
the language name from one noun to another sounds better, it's clearer,
|
||||||
|
and it's easier to explain.}}
|
||||||
|
|
||||||
|
|
||||||
|
@@FAQ['suggestions]{Couldn't you find a better name?
|
||||||
|
@name{[Insert name here]} would be better.}{
|
||||||
|
@p*{
|
||||||
|
Thank you for the suggestion. The name @name{Racket} meets some basic
|
||||||
|
criteria: it isn't used already, it's easy to pronounce and spell, and
|
||||||
|
it has a vague connection to the word “scheme.” Mostly, though, we
|
||||||
|
just like it.}}
|
||||||
|
|
||||||
|
}})
|
482
new-racket-web/web/www/old-techreports.rkt
Normal file
482
new-racket-web/web/www/old-techreports.rkt
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
;; Old style TR entries
|
||||||
|
|
||||||
|
;; This code is intended only to keep the old techreports/ page up for
|
||||||
|
;; old links.
|
||||||
|
|
||||||
|
(require "resources.rkt" "techreports.rkt" "people.rkt"
|
||||||
|
(prefix-in - version/utils))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Data
|
||||||
|
|
||||||
|
(define last-old-tr "4.9")
|
||||||
|
|
||||||
|
;; This list is fixed to these versions (since this is an old page, no
|
||||||
|
;; need to update with new versions)
|
||||||
|
(define versions+dates
|
||||||
|
'(["4.2.5" "April" "2010"]
|
||||||
|
["4.2.4" "January" "2010"]
|
||||||
|
["4.2.3" "December" "2009"]
|
||||||
|
["4.2.2" "October" "2009"]
|
||||||
|
["4.2.1" "July" "2009"]
|
||||||
|
["4.2" "June" "2009"]
|
||||||
|
["4.1.5" "March" "2009"]
|
||||||
|
["4.1.4" "January" "2009"]
|
||||||
|
["4.1.3" "November" "2008"]
|
||||||
|
["4.1.2" "October" "2008"]
|
||||||
|
["4.1.1" "October" "2008"]
|
||||||
|
["4.1" "August" "2008"]
|
||||||
|
["4.0.2" "July" "2008"]
|
||||||
|
["4.0.1" "June" "2008"]
|
||||||
|
["4.0" "June" "2008"]
|
||||||
|
["372" "December" "2007"]
|
||||||
|
["371" "August" "2007"]
|
||||||
|
["370" "May" "2007"]
|
||||||
|
["360" "November" "2006"]
|
||||||
|
["352" "July" "2006"]
|
||||||
|
["351" "July" "2006"]
|
||||||
|
["350" "June" "2006"]
|
||||||
|
["301" "January" "2006"]
|
||||||
|
["300" "December" "2005"]
|
||||||
|
["209" "December" "2004"]
|
||||||
|
["208" "August" "2004"]
|
||||||
|
["207" "May" "2004"]
|
||||||
|
["206p1" "January" "2004"]
|
||||||
|
["206" "January" "2004"]
|
||||||
|
["205" "August" "2003"]
|
||||||
|
["204" "May" "2003"]
|
||||||
|
["203" "December" "2002"]
|
||||||
|
["202" "August" "2002"]
|
||||||
|
["201" "July" "2002"]
|
||||||
|
["200" "June" "2002"]
|
||||||
|
["103p1" "August" "2001"]
|
||||||
|
["103" "September" "2000"]
|
||||||
|
["053" "July" "1998"]
|
||||||
|
))
|
||||||
|
|
||||||
|
(define authors
|
||||||
|
'([plt "PLT"]
|
||||||
|
[ff mflatt robby]
|
||||||
|
[fplt mflatt plt]
|
||||||
|
[rplt robby plt]
|
||||||
|
[ffplt ff plt]
|
||||||
|
[ffc ff clements]
|
||||||
|
[fb mflatt eli]
|
||||||
|
[dorai "Dorai Sitaram"]
|
||||||
|
[wright "Andrew K. Wright"]
|
||||||
|
[flanagan "Cormac Flanagan"]
|
||||||
|
[web burns gregp jay]
|
||||||
|
[burns "Mike Burns"]
|
||||||
|
[gregp "Greg Pettyjohn"]
|
||||||
|
[dyoo "Danny Yoo"]
|
||||||
|
[ym dyoo jay]
|
||||||
|
[kathyg "Kathryn E. Gray"]
|
||||||
|
[jacobm "Jacob Matthews"]
|
||||||
|
[sowens "Scott Owens"]
|
||||||
|
[plot alex raymond]
|
||||||
|
[alex "Alexander Friedman"]
|
||||||
|
[raymond "Jamie Raymond"]
|
||||||
|
[dskippy "Mike T. McHenry"]
|
||||||
|
[ptg "Paul Graunke"]
|
||||||
|
[ryanc "Ryan Culpepper"]
|
||||||
|
[steck "Paul Steckler"]
|
||||||
|
[samth "Sam Tobin-Hochstadt"]
|
||||||
|
[gcooper "Greg Cooper"]))
|
||||||
|
|
||||||
|
(define doc-defs
|
||||||
|
;; each item is:
|
||||||
|
;; (docname [docnum] versions author title . attrs)
|
||||||
|
;; docname: a symbol for the name of the document
|
||||||
|
;; docnum: an optional integer used in the TR number (docname used otherwise)
|
||||||
|
;; versions: version range specification (see `versions->pred' below)
|
||||||
|
;; author: is a symbol from the `authors' table
|
||||||
|
;; title: is a string (no braces)
|
||||||
|
`(;; old versions
|
||||||
|
(mzscheme 1 "...*" mflatt "PLT MzScheme: Language Manual")
|
||||||
|
(mred 2 "...*" ff "PLT MrEd: Graphical Toolbox Manual")
|
||||||
|
(drscheme 3 "...*" robby "PLT DrScheme: Programming Environment Manual"
|
||||||
|
[#:note ("See also:"
|
||||||
|
"R. B. Findler, J. Clements, C. Flanagan, M. Flatt,"
|
||||||
|
"S. Krishnamurthi, P. Steckler and M. Felleisen."
|
||||||
|
"DrScheme: A programming environment for Scheme,"
|
||||||
|
"Journal of Functional Programming,"
|
||||||
|
"12(2):159--182, March 2002."
|
||||||
|
"http://www.ccs.neu.edu/scheme/pubs/")])
|
||||||
|
(mzlib 4 "200...*" plt "PLT MzLib: Libraries Manual")
|
||||||
|
(framework "...*" plt "PLT Framework: GUI Application Framework")
|
||||||
|
(tools "...*" robby "PLT Tools: DrScheme Extension Manual")
|
||||||
|
(web-server "300...*" web "Web Server Manual")
|
||||||
|
(mrlib "207...*" plt "PLT MrLib: Graphical Libraries Manual")
|
||||||
|
(plot "207...*" plot "PLoT Manual")
|
||||||
|
(mzc "...*" plt "PLT mzc: MzScheme Compiler Manual")
|
||||||
|
(insidemz "...*" mflatt "Inside PLT MzScheme")
|
||||||
|
(foreign "...*" eli "PLT Foreign Interface Manual")
|
||||||
|
(misclib "...*" plt "PLT Miscellaneous Libraries: Reference Manual")
|
||||||
|
(tex2page "200...*" dorai "TeX2page")
|
||||||
|
(t-y-scheme "200...*" dorai "Teach Yourself Scheme in Fixnum Days"
|
||||||
|
[type "Introduction"])
|
||||||
|
(match "103p1" wright "Pattern Matching for Scheme")
|
||||||
|
(mrspidey "103p1" flanagan "PLT MrSpidey: Static Debugger Manual")
|
||||||
|
;; new Scheme versions
|
||||||
|
(quick "*...!" mflatt
|
||||||
|
"Quick: An Introduction to PLT Scheme with Pictures"
|
||||||
|
[type "Introduction"])
|
||||||
|
(more "*...!" plt "More: Systems Programming with PLT Scheme"
|
||||||
|
[type "Introduction"])
|
||||||
|
(continue "4.1.1..." ym "Continue: Web Applications in PLT Scheme"
|
||||||
|
[type "Introduction"])
|
||||||
|
(guide "*...!" ffplt "Guide: PLT Scheme" [type "Introduction"])
|
||||||
|
(reference "*...!" fplt "Reference: PLT Scheme")
|
||||||
|
(htdp-langs "*...!" plt "How to Design Programs Languages")
|
||||||
|
(htdc "*...!" kathyg "How to Design Classes Languages")
|
||||||
|
(teachpack "*...!" plt "Teachpacks")
|
||||||
|
(eopl "*...!" plt "Essentials of Programming Languages Language")
|
||||||
|
(drscheme "*...!" rplt "DrScheme: PLT Programming Environment")
|
||||||
|
(mzc "*...!" plt "mzc: PLT Compilation and Packaging")
|
||||||
|
(setup-plt "*...!" plt "setup-plt: PLT Configuration and Installation")
|
||||||
|
(planet "*...!" jacobm "PLaneT: Automatic Package Distribution")
|
||||||
|
(redex "4.1...!" robby "Redex: Debugging Operational Semantics")
|
||||||
|
(scribble "*...!" fb "Scribble: PLT Documentation Tool")
|
||||||
|
(slideshow "*...!" ff "Slideshow: PLT Figure and Presentation Tools")
|
||||||
|
(web-server "*...!" jay "Web Server: PLT HTTP Server")
|
||||||
|
(tools "*...!" robby "Plugins: Extending DrScheme")
|
||||||
|
(gui "*...!" ffc "GUI: PLT Graphics Toolkit")
|
||||||
|
(framework "*...!" ff "Framework: PLT GUI Application Framework")
|
||||||
|
(sgl "*...!" sowens "GL: 3-D Graphics")
|
||||||
|
(plot "*...!" plot "PLoT: Graph Plotting")
|
||||||
|
(browser "*...!" plt "Browser: Simple HTML Rendering")
|
||||||
|
(cards "*...!" plt "Cards: Virtual Playing Cards Library")
|
||||||
|
(embedded-gui "*...!" dskippy "Embedded GUI: Widgets within editor<%>")
|
||||||
|
(games "*...!" plt "Games: Fun Examples")
|
||||||
|
(gl-board-game "*...!" plt "GL Board Game: 3-D Game Support")
|
||||||
|
(mrlib "*...!" plt "MrLib: Extra GUI Libraries")
|
||||||
|
(string-constants "*...!" plt "String Constants: GUI Internationalization")
|
||||||
|
(syntax-color "*...!" sowens "Syntax Color: Utilities")
|
||||||
|
(turtles "*...!" plt "Turtle Graphics")
|
||||||
|
(net "*...!" plt "Net: PLT Networking Libraries")
|
||||||
|
(openssl "*...!" plt "OpenSSL")
|
||||||
|
(file "*...!" plt "File: PLT File Format Libraries")
|
||||||
|
(html "*...!" plt "HTML: Parsing Library")
|
||||||
|
(parser-tools "*...!" sowens "Parser Tools: lex and yacc-style Parsing")
|
||||||
|
(xml "*...!" ptg "XML: Parsing and Writing")
|
||||||
|
(config "*...!" plt "Config: Installation and Search Paths")
|
||||||
|
(dynext "*...!" plt "Dynext: Running a C Compiler/Linker")
|
||||||
|
(errortrace "*...!" plt "Errortrace: Debugging and Profiling")
|
||||||
|
(macro-debugger "*...!" ryanc "Macro Debugger")
|
||||||
|
(make "*...!" plt "Make: Dependency Manager")
|
||||||
|
(readline "*...!" plt "Readline: Terminal Interaction")
|
||||||
|
(slatex-wrap "*...!" plt "SLaTeX Wrapper")
|
||||||
|
(trace "*...!" plt "Trace: Instrumentation to Show Function Calls")
|
||||||
|
(version "*...!" plt "Version: PLT Version Checking")
|
||||||
|
(foreign "*...!" eli "FFI: PLT Scheme Foreign Interface")
|
||||||
|
(inside "*...!" mflatt "Inside: PLT Scheme C API")
|
||||||
|
(cffi "*...!" mflatt "c-lambda: C FFI via mzc")
|
||||||
|
(mysterx "*...!" steck "MysterX: Using Windows COM Objects in Scheme")
|
||||||
|
(mzcom "*...!" steck "MzCOM: Scheme as a Windows COM Object")
|
||||||
|
(srfi "*...!" plt "SRFIs: Libraries")
|
||||||
|
(swindle "*...!" plt "Swindle")
|
||||||
|
(syntax "*...!" plt "Syntax: Meta-Programming Helpers")
|
||||||
|
(typed-scheme "*...!" samth "Typed Scheme: Scheme with Static Types")
|
||||||
|
(frtime "*...!" gcooper "FrTime: A Language for Reactive Programs")
|
||||||
|
(lazy "*...!" eli "Lazy Scheme")
|
||||||
|
(r5rs "*...!" plt "R5RS: Legacy Standard Language"
|
||||||
|
[#:note ("See also:"
|
||||||
|
"Rickard Kelsey and William Clinger"
|
||||||
|
"and Jonathan Rees (Editors)"
|
||||||
|
"Revised$^5$ Report of the Algorithmic Language Scheme"
|
||||||
|
"ACM SIGPLAN Notices"
|
||||||
|
"33(9):26--76, 1998")])
|
||||||
|
(graphics "*...!" plt "Graphics: Legacy Library")
|
||||||
|
(mzlib "*...!" plt "MzLib: Legacy PLT Libraries")
|
||||||
|
(preprocessor "*...!" eli "mzpp and mztext: Preprocessors")
|
||||||
|
(mzscheme "*...!" plt "MzScheme: Legacy Module Language")
|
||||||
|
(algol60 "*...!" plt "Algol 60")
|
||||||
|
(honu "*...!" plt "Honu")
|
||||||
|
(test-box-recovery "*...!" plt "Test Box Recovery Tool")
|
||||||
|
|
||||||
|
;; Racket versions
|
||||||
|
(quick "!..." mflatt
|
||||||
|
"Quick: An Introduction to Racket with Pictures"
|
||||||
|
[type "Introduction"])
|
||||||
|
(more "!..." plt "More: Systems Programming with Racket"
|
||||||
|
[type "Introduction"])
|
||||||
|
(guide "!..." ffplt "Guide: Racket" [type "Introduction"])
|
||||||
|
(reference "!..." fplt "Reference: Racket")
|
||||||
|
(drracket "!..." rplt "DrRacket: Programming Environment")
|
||||||
|
(scribble "!..." fb "Scribble: Racket Documentation Tool")
|
||||||
|
(slideshow "!..." ff "Slideshow: Racket Figure and Presentation Tools")
|
||||||
|
(web-server "!..." jay "Web Server: Racket HTTP Server")
|
||||||
|
(foreign "!..." eli "FFI: Racket Foreign Interface")
|
||||||
|
(inside "!..." mflatt "Inside: Racket C API")
|
||||||
|
|
||||||
|
;; Both Scheme and Racket
|
||||||
|
(r6rs "*..." plt "R6RS: Standard Language"
|
||||||
|
[#:note ("See also:"
|
||||||
|
"Michael Sperber and R. Kent Dybvig and Matthew Flatt"
|
||||||
|
"and Anton Van Straaten (Editors)"
|
||||||
|
"Revised$^6$ Report of the Algorithmic Language Scheme"
|
||||||
|
"September 2007")])
|
||||||
|
|
||||||
|
;; (article fcffksf:drscheme
|
||||||
|
;; [author "Robert Bruce Findler and John Clements and Cormac Flanagan"
|
||||||
|
;; "and Matthew Flatt and Shriram Krishnamurthi"
|
||||||
|
;; "and Paul Steckler and Matthias Felleisen"]
|
||||||
|
;; [title "{DrScheme}: A Programming Environment for {Scheme}"]
|
||||||
|
;; [volume 12]
|
||||||
|
;; [number 2]
|
||||||
|
;; [pages "159--182"]
|
||||||
|
;; [month "March"]
|
||||||
|
;; [journal "Journal of Functional Programming"]
|
||||||
|
;; [year "2002"])
|
||||||
|
))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Bib stuff
|
||||||
|
|
||||||
|
;; bib values are hash tables mapping field names (symbols) to strings.
|
||||||
|
;; Keywords can also be used for the field names, which makes them meta-fields
|
||||||
|
;; that are not included in the usual bib printout. Two of them are required:
|
||||||
|
;; - #:type the type of the entry (a symbol: 'article, 'techreport, etc)
|
||||||
|
;; - #:key the label for the entry
|
||||||
|
|
||||||
|
(define bib-fields
|
||||||
|
'(author editor title booktitle journal
|
||||||
|
edition volume number series
|
||||||
|
chapter pages
|
||||||
|
type
|
||||||
|
school institution organization
|
||||||
|
publisher howpublished
|
||||||
|
address
|
||||||
|
month year
|
||||||
|
key
|
||||||
|
crossref
|
||||||
|
url
|
||||||
|
note
|
||||||
|
eprint))
|
||||||
|
|
||||||
|
(define meta-field? keyword?)
|
||||||
|
|
||||||
|
(define key->number
|
||||||
|
(let ([t (for/hash ([k bib-fields] [i (in-naturals)]) (values k i))])
|
||||||
|
(λ (key) (hash-ref t key
|
||||||
|
(λ () (error 'key->number "unknown field name: ~e" key))))))
|
||||||
|
|
||||||
|
;; converts the hash to an alist with the order specified by bib-fields
|
||||||
|
(define (bib->alist bib)
|
||||||
|
(sort (filter-not (compose meta-field? car) (hash-map bib cons))
|
||||||
|
< #:key (compose key->number car) #:cache-keys? #t))
|
||||||
|
|
||||||
|
(define (display* . xs)
|
||||||
|
(for-each display xs))
|
||||||
|
|
||||||
|
(define (display-attr attr)
|
||||||
|
(let* ([prefix (format " ~a = {" (car attr))]
|
||||||
|
[sep (lazy (string-append "\n" (make-string (string-length prefix)
|
||||||
|
#\space)))])
|
||||||
|
(display* prefix
|
||||||
|
(if (regexp-match? #rx"\n" (cdr attr))
|
||||||
|
(regexp-replace* #rx"\n" (cdr attr) (force sep))
|
||||||
|
(cdr attr))
|
||||||
|
"}")))
|
||||||
|
|
||||||
|
(define (display-bib bib)
|
||||||
|
(display* "@" (hash-ref bib '#:type) "{" (hash-ref bib '#:key))
|
||||||
|
(for ([attr (bib->alist bib)]) (display* ",\n") (display-attr attr))
|
||||||
|
(display* "\n}\n"))
|
||||||
|
|
||||||
|
(define (with-braces str) (regexp-replace* #px"\\b\\w+[A-Z]\\w*" str "{\\0}"))
|
||||||
|
(define (without-braces str) (regexp-replace* #rx"[{}]+" str ""))
|
||||||
|
|
||||||
|
(define (bib-author bib)
|
||||||
|
(let ([authors (regexp-split #rx"[ \t\n]+and[ \t\n]+"
|
||||||
|
(hash-ref bib 'author))])
|
||||||
|
(case (length authors)
|
||||||
|
[(0) "???"]
|
||||||
|
[(1) (car authors)]
|
||||||
|
[(2) (apply format "~a and ~a" authors)]
|
||||||
|
[(3) (apply format "~a, ~a, and ~a" authors)]
|
||||||
|
[else (format "~a et al" (car authors))])))
|
||||||
|
|
||||||
|
;; processes the (key val ...) alist to a hash of (key . val) by combining the
|
||||||
|
;; possibly multiple values for each key (each value becomes a line)
|
||||||
|
(define (bib type key attrs)
|
||||||
|
(define t (make-hasheq))
|
||||||
|
(hash-set! t '#:type type)
|
||||||
|
(hash-set! t '#:key key)
|
||||||
|
(for ([a attrs])
|
||||||
|
(define (err) (error 'make-bib "bad attribute: ~e" a))
|
||||||
|
(unless (and (pair? a) (pair? (cdr a)) (list? (cdr a))) (err))
|
||||||
|
(let ([key (car a)])
|
||||||
|
(unless (hash-ref t key #f) ; previous keys take precedence
|
||||||
|
(cond [(symbol? key)
|
||||||
|
;; turn non-strings to strings, join multiple strings, normalize
|
||||||
|
;; spaces
|
||||||
|
(let* ([val (cdr a)]
|
||||||
|
[val (map (λ (x) (if (string? x) x (format "~a" x))) val)]
|
||||||
|
[val (string-append* (add-between val "\n"))]
|
||||||
|
[val (regexp-replace* #rx"\t" val " ")]
|
||||||
|
[val (regexp-replace* #rx" +" val " ")]
|
||||||
|
[val (regexp-replace #rx"^ +" val "")]
|
||||||
|
[val (regexp-replace #rx" +$" val "")]
|
||||||
|
[val (regexp-replace* #rx"(?: *\r?\n *)+" val "\n")])
|
||||||
|
(hash-set! t key val))]
|
||||||
|
[(and (meta-field? key) (null? (cddr a)))
|
||||||
|
(hash-set! t key (cadr a))]
|
||||||
|
[else (err)]))))
|
||||||
|
t)
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Version etc
|
||||||
|
|
||||||
|
;; Use this instead of the built-in one, to make sure that we only deal
|
||||||
|
;; with known versions.
|
||||||
|
(define version->integer
|
||||||
|
(let ([t (for*/hash ([v (in-list (map car versions+dates))])
|
||||||
|
(values v (-version->integer (regexp-replace #rx"^0+" v ""))))])
|
||||||
|
(λ (ver)
|
||||||
|
(hash-ref t ver
|
||||||
|
(λ () (error 'version->integer "unknown pltreport version: ~e" ver))))))
|
||||||
|
|
||||||
|
;; "V...V" version range
|
||||||
|
;; "...V", "V..." open-ended version range
|
||||||
|
;; "..." all versions
|
||||||
|
;; "V" specific version
|
||||||
|
;; "" no versions
|
||||||
|
;; V can be `*': a number between the v3 docs and the v4 docs
|
||||||
|
;; V can be `!': a number between the last PLT Scheme and the first Racket
|
||||||
|
(define v:3->4 (-version->integer "379"))
|
||||||
|
(define v:4->5 (-version->integer "4.3"))
|
||||||
|
(define (versions->pred str)
|
||||||
|
(let* ([str (regexp-replace* #rx" +" str " ")]
|
||||||
|
[str (regexp-replace #rx"^ +" str "")]
|
||||||
|
[str (regexp-replace #rx" +$" str "")]
|
||||||
|
[l (regexp-split #rx" *[.][.][.] *" str)]
|
||||||
|
[l (map (λ (x)
|
||||||
|
(cond [(equal? "" x) #f]
|
||||||
|
[(equal? "*" x) v:3->4]
|
||||||
|
[(equal? "!" x) v:4->5]
|
||||||
|
[(version->integer x)]
|
||||||
|
[else (error 'versions->pred "bad version: ~e" x)]))
|
||||||
|
l)])
|
||||||
|
(apply
|
||||||
|
(case-lambda [(ver)
|
||||||
|
(if ver
|
||||||
|
(λ (v) (equal? ver (version->integer v)))
|
||||||
|
(λ (v) #f))]
|
||||||
|
[(from to)
|
||||||
|
(let ([from (or from -inf.0)]
|
||||||
|
[to (or to +inf.0)])
|
||||||
|
(λ (v) (<= from (version->integer v) to)))]
|
||||||
|
[_ (error 'versions->pred "bad versions spec: ~e" str)])
|
||||||
|
l)))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Authors
|
||||||
|
|
||||||
|
(define authors*
|
||||||
|
(let ([t (make-hasheq)])
|
||||||
|
(for ([a authors])
|
||||||
|
(hash-set! t (car a)
|
||||||
|
((if (and (= 2 (length a)) (string? (cadr a))) cadr cdr) a)))
|
||||||
|
t))
|
||||||
|
|
||||||
|
(define (author->string author)
|
||||||
|
(let ([r (hash-ref authors* author
|
||||||
|
(λ () (person-bibname (find-person author))))])
|
||||||
|
(if (string? r)
|
||||||
|
r
|
||||||
|
(let ([r (string-join (map author->string r) " and ")])
|
||||||
|
(hash-set! authors* author r)
|
||||||
|
r))))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
;; Main
|
||||||
|
|
||||||
|
(define doc-defs*
|
||||||
|
(for/list ([d doc-defs])
|
||||||
|
(apply
|
||||||
|
(λ (docname docnum versions author title . attrs)
|
||||||
|
`(,(versions->pred versions)
|
||||||
|
[#:docname ,docname]
|
||||||
|
[#:number-template ,(format "PLT-TR~~a-~a-v~~a" (or docnum docname))]
|
||||||
|
[title ,(with-braces title)]
|
||||||
|
[author ,(author->string author)]
|
||||||
|
,@attrs))
|
||||||
|
(if (number? (cadr d)) d (list* (car d) #f (cdr d))))))
|
||||||
|
|
||||||
|
(define last-old-tr-version (-version->integer last-old-tr))
|
||||||
|
|
||||||
|
(define bibs
|
||||||
|
(for/list ([ver (in-list (map car versions+dates))]
|
||||||
|
[month (in-list (map cadr versions+dates))]
|
||||||
|
[year (in-list (map caddr versions+dates))]
|
||||||
|
#:when (<= (version->integer ver) last-old-tr-version)
|
||||||
|
[doc (in-list doc-defs*)]
|
||||||
|
#:when ((car doc) ver))
|
||||||
|
(define attrs (cdr doc))
|
||||||
|
(define (get key [dflt #f]) (cond [(assq key attrs) => cadr] [else dflt]))
|
||||||
|
(define docname (get '#:docname))
|
||||||
|
(define number (format (get '#:number-template) year ver))
|
||||||
|
(define key (regexp-replace* #rx":" (string-downcase number) "_"))
|
||||||
|
(define old? (< (version->integer ver) v:4->5))
|
||||||
|
(define site (if old? "plt-scheme" "racket-lang"))
|
||||||
|
(define note
|
||||||
|
(let ([n1 (format "\\url{http://~a.org/techreports/}" site)]
|
||||||
|
[n2 (get '#:note #f)])
|
||||||
|
(if n2 (cons (string-append n1 ";") n2) (list n1))))
|
||||||
|
(define maybe-s (if old? "" "s"))
|
||||||
|
(define (mk-url dir sfx)
|
||||||
|
(format "http://download.~a.org/doc~a/~a/~a/~a~a"
|
||||||
|
site maybe-s ver dir docname sfx))
|
||||||
|
(define pdf-url (mk-url "pdf" ".pdf"))
|
||||||
|
(define pdf-html (mk-url "html" "/"))
|
||||||
|
(bib 'techreport key
|
||||||
|
`(,@attrs
|
||||||
|
[year ,year]
|
||||||
|
[month ,month]
|
||||||
|
[institution "PLT Design Inc."]
|
||||||
|
[type "Reference Manual"]
|
||||||
|
[number ,number]
|
||||||
|
[#:version ,ver]
|
||||||
|
[url ,pdf-url]
|
||||||
|
[#:pdf-url ,pdf-url]
|
||||||
|
[#:html-url ,pdf-html]
|
||||||
|
[note ,@note]))))
|
||||||
|
|
||||||
|
(define old-techreports
|
||||||
|
@page[#:file "techreports/" #:title "Old PLT Technical Reports"
|
||||||
|
#:part-of 'learning
|
||||||
|
#:extra-headers
|
||||||
|
@script/inline[type: "text/javascript"]{
|
||||||
|
function show_bib(n) {
|
||||||
|
var s = document.getElementById("bibrow"+n).style;
|
||||||
|
s.display = (s.display == "table-row") ? "none" : "table-row";
|
||||||
|
}}]{
|
||||||
|
@p{@strong{Note:} the entries on this page are outdated, please see the new
|
||||||
|
@techreports page.}
|
||||||
|
@p{PLT publishes technical reports about some of its tools and libraries so
|
||||||
|
that scholars who wish to give proper credit to some of our innovations
|
||||||
|
have a definite citation. Each entry below provides the full pdf and a
|
||||||
|
bibtex entry; some of the bibtex entries provide additional citations to
|
||||||
|
published papers.}
|
||||||
|
@table[width: "98%" cellspacing: 0 cellpadding: 6 border: 0
|
||||||
|
align: 'center style: "font-size: 75%;"]{
|
||||||
|
@(for/list ([bib (in-list bibs)] [n (in-naturals)])
|
||||||
|
(define bgcolor (if (even? n) "#e0e0e0" "white"))
|
||||||
|
(define bibtext
|
||||||
|
(parameterize ([current-output-port (open-output-string)])
|
||||||
|
(display-bib bib)
|
||||||
|
(get-output-string (current-output-port))))
|
||||||
|
@list{
|
||||||
|
@tr[valign: 'top bgcolor: bgcolor]{
|
||||||
|
@td[style: "white-space: nowrap;"]{@(hash-ref bib 'number)}
|
||||||
|
@td[align: 'left]{@i{@(without-braces (hash-ref bib 'title))}}
|
||||||
|
@td{@(bib-author bib)}
|
||||||
|
@td{@a[href: @list{javascript: show_bib(@n)@";"}]{[bib]}@|nbsp|@;
|
||||||
|
@a[href: (hash-ref bib '#:pdf-url)]{[pdf]}@|nbsp|@;
|
||||||
|
@a[href: (hash-ref bib '#:html-url)]{[html]}}}
|
||||||
|
@tr[valign: 'top bgcolor: bgcolor
|
||||||
|
id: @list{bibrow@n} style: "display: none;"]{
|
||||||
|
@td{}@td[colspan: 3]{@pre{@bibtext}}}})}})
|
108
new-racket-web/web/www/people.rkt
Normal file
108
new-racket-web/web/www/people.rkt
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt")
|
||||||
|
|
||||||
|
(define (make-all place person)
|
||||||
|
;; The first person in a place is the one responsible for it
|
||||||
|
(list
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'neu "Northeastern University"
|
||||||
|
#:location "Boston, MA"
|
||||||
|
#:url "http://www.ccs.neu.edu/racket/"
|
||||||
|
#:pubs "http://www.ccs.neu.edu/racket/pubs/"
|
||||||
|
(person 'matthias "Matthias Felleisen"
|
||||||
|
#:url "http://www.ccs.neu.edu/home/matthias/")
|
||||||
|
(person 'eli "Eli Barzilay"
|
||||||
|
#:url "http://barzilay.org/"))
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'utah "University of Utah"
|
||||||
|
#:location "Salt Lake City, UT"
|
||||||
|
#:url "http://www.cs.utah.edu/plt/"
|
||||||
|
#:pubs "http://www.cs.utah.edu/plt/publications/"
|
||||||
|
(person 'mflatt "Matthew Flatt"
|
||||||
|
#:url "http://www.cs.utah.edu/~mflatt/"))
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'nwu "Northwestern University"
|
||||||
|
#:location "Evanston, IL"
|
||||||
|
#:url "http://plt.eecs.northwestern.edu/"
|
||||||
|
#:pubs "http://www.eecs.northwestern.edu/~robby/pubs/"
|
||||||
|
(person 'robby "Robby Findler"
|
||||||
|
#:bibname "Robert Bruce Findler"
|
||||||
|
#:url "http://www.eecs.northwestern.edu/~robby/"))
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'brown "Brown University"
|
||||||
|
#:location "Providence, RI"
|
||||||
|
#:url "http://www.cs.brown.edu/research/plt/"
|
||||||
|
#:pubs "http://www.cs.brown.edu/~sk/Publications/Papers/"
|
||||||
|
(person 'shriram "Shriram Krishnamurthi"
|
||||||
|
#:url "http://www.cs.brown.edu/~sk/"))
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'byu "Brigham Young University"
|
||||||
|
#:location "Provo, UT"
|
||||||
|
#:url "http://faculty.cs.byu.edu/~jay/"
|
||||||
|
#:pubs "http://faculty.cs.byu.edu/~jay/home/#(part._pubs)"
|
||||||
|
(person 'jay "Jay McCarthy"
|
||||||
|
#:url "http://faculty.cs.byu.edu/~jay/"))
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'calpoly "California Polytechnic State University"
|
||||||
|
#:location "San Luis Obispo, CA"
|
||||||
|
#:url "http://users.csc.calpoly.edu/~clements/"
|
||||||
|
#:pubs "http://www.brinckerhoff.org/clements/papers/"
|
||||||
|
(person 'clements "John Clements"
|
||||||
|
#:url "http://users.csc.calpoly.edu/~clements/"))
|
||||||
|
(place ; -------------------------------------------------------------------
|
||||||
|
'wpi "Worcester Polytechnic Institute"
|
||||||
|
#:location "Worcester, MA"
|
||||||
|
#:url "http://web.cs.wpi.edu/~kfisler/"
|
||||||
|
(person 'kathi "Kathi Fisler"
|
||||||
|
#:url "http://web.cs.wpi.edu/~kfisler/"))))
|
||||||
|
|
||||||
|
;; ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(struct person (nick name url bibname place) #:prefab)
|
||||||
|
(struct place (nick name location url pubs people) #:prefab)
|
||||||
|
|
||||||
|
(provide (struct-out place) all-places find-place
|
||||||
|
(struct-out person) all-people find-person)
|
||||||
|
|
||||||
|
(define-values (all-places find-place all-people find-person)
|
||||||
|
(let ()
|
||||||
|
(define places0
|
||||||
|
(make-all
|
||||||
|
;; make a place
|
||||||
|
(λ (nick name #:location loc #:url url #:pubs [pubs #f] . people)
|
||||||
|
(place nick name loc url pubs people))
|
||||||
|
;; make a person
|
||||||
|
(λ (nick name #:url url #:bibname [bibname name])
|
||||||
|
(person nick name url bibname (make-placeholder #f)))))
|
||||||
|
(for* ([place (in-list places0)]
|
||||||
|
[person (in-list (place-people place))])
|
||||||
|
(placeholder-set! (person-place person) place))
|
||||||
|
(define places (make-reader-graph places0))
|
||||||
|
(define people (append-map place-people places))
|
||||||
|
(when (ormap (λ (p) (null? (place-people p))) places)
|
||||||
|
(error 'places "all places should have people in them"))
|
||||||
|
(define (make-finder what xs get-nick)
|
||||||
|
(define t (make-hasheq))
|
||||||
|
(for ([x (in-list xs)])
|
||||||
|
(hash-update! t (get-nick x)
|
||||||
|
(λ (old) (if old (error what "got duplicate nicks") x))
|
||||||
|
#f))
|
||||||
|
(λ (nick) (or (hash-ref t nick #f)
|
||||||
|
(error what "nick not found: ~s" nick))))
|
||||||
|
(values places (make-finder 'places places place-nick)
|
||||||
|
people (make-finder 'people people person-nick))))
|
||||||
|
|
||||||
|
(provide people)
|
||||||
|
(define people
|
||||||
|
@page[#:window-title "Racket People: The PLT Group" #:part-of 'community
|
||||||
|
#:description "PLT: the group that is the Racket development team."]{
|
||||||
|
@p{“PLT” refers to the group that is the core of the Racket development
|
||||||
|
team. PLT consists of numerous people distributed across several
|
||||||
|
different universities in the USA:
|
||||||
|
@(ul (map (λ (p) @li{@a[href: (place-url p)]{
|
||||||
|
@(place-name p), @(place-location p)}})
|
||||||
|
all-places))}
|
||||||
|
@p{Also, Racket is supported by a band of volunteers who contribute not
|
||||||
|
only code and documentation but also infectious enthusiasm—too many to
|
||||||
|
name but whose help and encouragement make this fun and worthwhile.}})
|
3
new-racket-web/web/www/resources.rkt
Normal file
3
new-racket-web/web/www/resources.rkt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(define+provide-context "www")
|
105
new-racket-web/web/www/techreports.rkt
Normal file
105
new-racket-web/web/www/techreports.rkt
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
;; New style TR entries
|
||||||
|
|
||||||
|
(require "resources.rkt" "people.rkt" "../download/data.rkt")
|
||||||
|
|
||||||
|
(define (-all-techreports-)
|
||||||
|
(list (TR 1 'reference "Reference: Racket" '(mflatt plt)
|
||||||
|
#:description "Racket Programming Language")
|
||||||
|
(TR 2 'drracket "DrRacket: Programming Environment" '(robby plt)
|
||||||
|
#:description "DrRacket API"
|
||||||
|
#:note
|
||||||
|
@list{
|
||||||
|
Preferred generic citation:
|
||||||
|
@blockquote[style: "margin-top: 0.5ex; margin-bottom: 0.5ex;"]{
|
||||||
|
R. B. Findler, J. Clements, C. Flanagan, M. Flatt,
|
||||||
|
S. Krishnamurthi, P. Steckler and M. Felleisen. @br
|
||||||
|
@i{DrScheme: A programming environment for Scheme.} @br
|
||||||
|
Journal of Functional Programming, 12(2): 159–182, March 2002.}
|
||||||
|
Please cite the DrRacket technical report only if internal
|
||||||
|
details of DrRacket are concerned, otherwise use the DrScheme
|
||||||
|
reference.})
|
||||||
|
(TR 3 'gui "GUI: Racket Graphics Toolkit" '(mflatt robby clements)
|
||||||
|
#:description "Racket Graphics Toolkit")))
|
||||||
|
|
||||||
|
(define (doc-url doc [fmt 'html] [ver 'recent])
|
||||||
|
(format "http://download.racket-lang.org/docs/~a/~a/~a~a" ver fmt doc
|
||||||
|
(if (eq? 'html fmt) "" (format ".~a" fmt))))
|
||||||
|
|
||||||
|
(define (TR num docname title authors* #:description [desc title]
|
||||||
|
#:note [note #f])
|
||||||
|
(define tr-name @list{PLT-TR-2010-@num})
|
||||||
|
(define author-strings
|
||||||
|
(map (λ (a) (if (eq? 'plt a) "PLT" (person-bibname (find-person a))))
|
||||||
|
authors*))
|
||||||
|
(define (link fmt [ver 'recent]) @a[href: (doc-url docname fmt ver)]{[@fmt]})
|
||||||
|
(define (title-line link?)
|
||||||
|
@list{@big{@b{@(if link? cite-page values){@tr-name}}}
|
||||||
|
@|nbsp nbsp| @small{@link['html] @link['pdf]}})
|
||||||
|
(define (content)
|
||||||
|
@list{@(add-between author-strings " and ") @br
|
||||||
|
@i{@title} @br
|
||||||
|
PLT Technical Report #@num @br
|
||||||
|
@(and note @div[style: "margin-top: 1ex; font-size: small;"]{
|
||||||
|
@note})})
|
||||||
|
(define ((refblock . title) . body)
|
||||||
|
@list{@h2{@title}
|
||||||
|
@blockquote{@PRE{@body}}})
|
||||||
|
(define cite-page
|
||||||
|
@page[#:file (format "tr~a/" num) #:title tr-name #:part-of 'learning]{
|
||||||
|
@h1{@title-line[#f]}
|
||||||
|
@p*{@blockquote{@big{@content}}
|
||||||
|
@~ For citations of the @desc, please use @TT{\cite{plt-tr@num}} in
|
||||||
|
LaTeX, or @TT|{@cite[plt-tr1]}| in Scribble, using the definitions
|
||||||
|
below.
|
||||||
|
@~ For references to specific releases and/or chapters, use
|
||||||
|
@TT{\cite[Version M.N]{plt-tr@num}} or
|
||||||
|
@TT|{@cite[(in-bib plt-tr|@num "Version M.N")]}| instead. The
|
||||||
|
year in the bibliographic entry should be 2010 regardless of the
|
||||||
|
version's date.}
|
||||||
|
@@refblock{BibTeX}|{
|
||||||
|
@techreport{plt-tr|@num,
|
||||||
|
title = {|@title},
|
||||||
|
author = {|@(add-between author-strings " and ")},
|
||||||
|
number = {|@tr-name},
|
||||||
|
institution = {PLT Inc.},
|
||||||
|
year = {2010},
|
||||||
|
note = {\url{|@(url-of cite-page #t)}}
|
||||||
|
}}|
|
||||||
|
@@refblock{Scribble}|{
|
||||||
|
(define plt-tr|@num
|
||||||
|
(make-bib #:title "|@title"
|
||||||
|
#:author |@(format "~s" (cons 'authors author-strings))
|
||||||
|
#:date "2010"
|
||||||
|
#:location (techrpt-location #:institution "PLT Inc."
|
||||||
|
#:number "|@tr-name")
|
||||||
|
#:url "|@(url-of cite-page #t)"))}|
|
||||||
|
@h2{Specific Versions}
|
||||||
|
@blockquote{
|
||||||
|
@table[frame: 'box rules: 'rows cellpadding: 10]{
|
||||||
|
@(for/list ([r (in-list all-releases)])
|
||||||
|
(define v (release-version r))
|
||||||
|
@tr{@td{@b{@v} @br @small{(@(release-date-string r))}}
|
||||||
|
@td{@TT{\cite[Version @v]{plt-tr@num}} @br
|
||||||
|
@TT|{@cite[(in-bib plt-tr|@num "Version |@v")]}|}
|
||||||
|
@td{@link['html v], @link['pdf v]}})}
|
||||||
|
@p{@small{Reminder: the release dates should not be included in the
|
||||||
|
entry or the citation.}}}})
|
||||||
|
@list{@dt{@title-line[#t]}
|
||||||
|
@dd[style: "margin-bottom: 1.5ex;"]{
|
||||||
|
@content}})
|
||||||
|
|
||||||
|
(provide techreports)
|
||||||
|
(define techreports
|
||||||
|
@page[#:file "tr/" #:title "PLT Technical Reports" #:part-of 'learning]{
|
||||||
|
@p*{
|
||||||
|
@~ For citations of generic pieces of the Racket infrastructure, please use
|
||||||
|
@TT{\cite{plt-tr1}}, @TT{\cite{plt-tr2}}, etc. in LaTeX, or
|
||||||
|
@TT|{@cite[plt-tr1]}|, @TT|{@cite[plt-tr2]}|, etc. in Scribble, with the
|
||||||
|
BibTeX and Scribble entries provided in the web pages below.
|
||||||
|
@~ For references to specific releases and/or chapters of the language, use
|
||||||
|
@TT{\cite[Version M.N]{plt-tr1}} or
|
||||||
|
@TT|{@cite[(in-bib plt-tr1 "Version M.N")]}|
|
||||||
|
instead.}
|
||||||
|
@dl{@(add-newlines (-all-techreports-))}})
|
12
new-racket-web/web/www/web-copyright.rkt
Normal file
12
new-racket-web/web/www/web-copyright.rkt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#lang meta/web
|
||||||
|
|
||||||
|
(require "resources.rkt")
|
||||||
|
|
||||||
|
(provide web-copyright)
|
||||||
|
(define web-copyright
|
||||||
|
@page{
|
||||||
|
The text of this website is available for modification and reuse
|
||||||
|
under the terms of the Creative Commons Attribution-Sharealike 3.0
|
||||||
|
Unported License and the GNU Free Documentation
|
||||||
|
License (unversioned, with no invariant sections, front-cover texts,
|
||||||
|
or back-cover texts).})
|
Loading…
Reference in New Issue
Block a user