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