commit 72829e1d1d2d7fa1cf8ebc91336231c2b86ed81c
parent d7488ba11bd7294fb57668f29a9c428c9f27e072
Author: Eli Barzilay <eli@racket-lang.org>
Date: Wed, 30 Jan 2008 18:20:04 +0000
searchable index pages
svn: r8477
original commit: b012e7dbe7cc0291ba2af8d22dd05e88f626c274
Diffstat:
2 files changed, 139 insertions(+), 58 deletions(-)
diff --git a/collects/scribble/basic.ss b/collects/scribble/basic.ss
@@ -208,64 +208,60 @@
(string<? (car a) (car b)))]
[else (string-ci<? (car a) (car b))])))
(define alpha (string->list "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
+ (define (rows . rows)
+ (make-table 'index (map (lambda (row)
+ (list (make-flow (list (make-paragraph row)))))
+ rows)))
+ (define line-break (make-element 'newline '("/n")))
(define contents
- (make-delayed-flow-element
- (lambda (renderer sec ri)
- (define l null)
- (define alpha-starts (make-hash-table))
- (define (rows . rows)
- (make-table 'index
- (map (lambda (row)
- (list (make-flow (list (make-paragraph row)))))
- rows)))
- (hash-table-for-each
- (let ([parent (collected-info-parent (part-collected-info sec ri))])
- (if parent
- (collected-info-info (part-collected-info parent ri))
- (collect-info-ext-ht (resolve-info-ci ri))))
- (lambda (k v)
- (when (and (pair? k) (eq? 'index-entry (car k)))
- (set! l (cons (cons (cadr k) v) l)))))
- (set! l (sort l cadr-string-lists<?))
- (rows
- (let loop ([i l] [alpha alpha])
- (define (add-letter let l)
- (list* (make-element "nonavigation" (list (string let))) " " l))
- (cond [(null? alpha) null]
- [(null? i) (add-letter (car alpha) (loop i (cdr alpha)))]
- [else
- (let* ([strs (cadr (car i))]
- [letter (if (or (null? strs) (string=? "" (car strs)))
- #f
- (char-upcase (string-ref (car strs) 0)))])
- (cond [(not letter) (loop (cdr i) alpha)]
- [(char-ci>? letter (car alpha))
- (add-letter (car alpha) (loop i (cdr alpha)))]
- [(char-ci=? letter (car alpha))
- (hash-table-put! alpha-starts (car i) letter)
- (list* (make-element
- (make-target-url (format "#alpha:~a" letter)
- #f)
- (list (string (car alpha))))
- " "
- (loop (cdr i) (cdr alpha)))]
- [else (loop (cdr i) alpha)]))]))
- (list 'nbsp)
- ((if (null? l) values cdr) ; drop one 'newline
- (apply append
- (map (lambda (i)
- (define e (make-link-element
- "indexlink" (commas (caddr i)) (car i)))
- (list (make-element 'newline '("/n"))
- (cond [(hash-table-get alpha-starts i #f)
- => (lambda (let)
- (make-element
- (make-url-anchor
- (format "alpha:~a" (char-upcase let)))
- (list e)))]
- [else e])))
- l)))))))
- (list contents))
+ (lambda (renderer sec ri)
+ (define l null)
+ (define alpha-starts (make-hash-table))
+ (hash-table-for-each
+ (let ([parent (collected-info-parent (part-collected-info sec ri))])
+ (if parent
+ (collected-info-info (part-collected-info parent ri))
+ (collect-info-ext-ht (resolve-info-ci ri))))
+ (lambda (k v)
+ (when (and (pair? k) (eq? 'index-entry (car k)))
+ (set! l (cons (cons (cadr k) v) l)))))
+ (set! l (sort l cadr-string-lists<?))
+ (rows
+ (let loop ([i l] [alpha alpha])
+ (define (add-letter let l)
+ (list* (make-element "nonavigation" (list (string let))) " " l))
+ (cond [(null? alpha) null]
+ [(null? i) (add-letter (car alpha) (loop i (cdr alpha)))]
+ [else
+ (let* ([strs (cadr (car i))]
+ [letter (if (or (null? strs) (string=? "" (car strs)))
+ #f
+ (char-upcase (string-ref (car strs) 0)))])
+ (cond [(not letter) (loop (cdr i) alpha)]
+ [(char-ci>? letter (car alpha))
+ (add-letter (car alpha) (loop i (cdr alpha)))]
+ [(char-ci=? letter (car alpha))
+ (hash-table-put! alpha-starts (car i) letter)
+ (list* (make-element
+ (make-target-url (format "#alpha:~a" letter) #f)
+ (list (string (car alpha))))
+ " "
+ (loop (cdr i) (cdr alpha)))]
+ [else (loop (cdr i) alpha)]))]))
+ (list 'nbsp)
+ (map (lambda (i)
+ (define e
+ (make-link-element "indexlink"
+ `(,@(commas (caddr i)) ,line-break)
+ (car i)))
+ (cond [(hash-table-get alpha-starts i #f)
+ => (lambda (let)
+ (make-element (make-url-anchor
+ (format "alpha:~a" (char-upcase let)))
+ (list e)))]
+ [else e]))
+ l))))
+ (list (make-delayed-flow-element contents)))
;; ----------------------------------------
diff --git a/collects/scribble/html-render.ss b/collects/scribble/html-render.ss
@@ -66,6 +66,89 @@
(loop (substring s (cdar m)))))]
[else s])))
+ (define literal
+ (let ([loc (xml:make-location 0 0 0)])
+ (lambda strings (xml:make-cdata loc loc (apply string-append strings)))))
+ (define (script . body)
+ `(script ((type "text/javascript"))
+ ,(apply literal
+ `("\n"
+ ,@(map (lambda (x) (if (string? x) x (format "~a" x))) body)
+ "\n"))))
+
+ #reader scribble/reader
+ (define search-script
+ @script{
+ var search_nodes = null;
+ var last_search_terms = null;
+ function node_to_text(node) {
+ if (node.nodeType == 3) return node.nodeValue;
+ var r = "";
+ var children = node.childNodes;
+ for (var i=0@";" i<children.length@";" i++) {
+ r = r + node_to_text(children[i]);
+ }
+ return r;
+ }
+ function initialize_search() {
+ var all_links = document.getElementsByTagName("a");
+ search_nodes = new Array();
+ for (var i=0@";" i<all_links.length@";" i++)
+ if (all_links[i].className == "indexlink") {
+ all_links[i].flat_text = node_to_text(all_links[i]).toLowerCase();
+ search_nodes.push(all_links[i]);
+ }
+ var search_box = document.getElementById("search_box");
+ if (location.search.indexOf('?q=') == 0) {
+ var search = location.search.substring(3)
+ search_box.value = search;
+ }
+ if (search_box.value != "") do_search(search_box.value);
+ search_box.focus();
+ search_box.select();
+ }
+ window.onload = initialize_search;
+ function do_search(terms) {
+ terms = terms.toLowerCase();
+ if (terms == last_search_terms) return;
+ last_search_terms = terms;
+ terms = terms.split(/ +/);
+ var none = true;
+ for (var i=0@";" i<search_nodes.length@";" i++) {
+ var show = true, curtext = search_nodes[i].flat_text;
+ for (var j=0@";" j<terms.length@";" j++) {
+ if (terms[j] != "" && curtext.indexOf(terms[j]) < 0) {
+ show = false;
+ break;
+ }
+ }
+ if (show) none = false;
+ var style = search_nodes[i].style;
+ var newdisp = show ? "block" : "none";
+ if (newdisp != style.display) style.display = newdisp;
+ }
+ search_box.style.backgroundColor = none ? "#ffe0e0" : "white";
+ }
+ var search_timer = null;
+ function delayed_search(str, event) {
+ if (event && event.keyCode == 13) {
+ do_search(str);
+ } else {
+ if (search_timer != null) {
+ var t = search_timer;
+ search_timer = null;
+ clearTimeout(t);
+ }
+ search_timer = setTimeout(function(){do_search(str)@";"}, 1000);
+ }
+ }})
+
+ #reader scribble/reader
+ (define search-field
+ @`p{Search: @(input ((type "text") (id "search_box")
+ (onChange "delayed_search(this.value,event);")
+ (onKeyUp "delayed_search(this.value,event);")))})
+
;; ----------------------------------------
;; main mixin
@@ -632,7 +715,9 @@
[else (super render-element e part ri)])))
(define/override (render-table t part ri)
- `((table ((cellspacing "0")
+ (define index? (eq? 'index (table-style t)))
+ `(,@(if index? `(,search-script ,search-field) '())
+ (table ((cellspacing "0")
,@(case (table-style t)
[(boxed) '((class "boxed"))]
[(centered) '((align "center"))]