diff --git a/collects/scribblings/main/private/make-search.ss b/collects/scribblings/main/private/make-search.ss
index 337bb562b1..0622a3e5f6 100644
--- a/collects/scribblings/main/private/make-search.ss
+++ b/collects/scribblings/main/private/make-search.ss
@@ -2,9 +2,10 @@
#lang scheme/base
(require scribble/decode
+ scribble/decode-struct
+ scribble/basic
scribble/struct
scribble/manual-struct
- scribble/basic
scheme/list
scheme/string
scheme/match
@@ -62,8 +63,9 @@
(if (= 1 (length body))
(car body)
(string-append* `("[" ,@(add-between body ",") "]")))))))
+ (define manual-refs (make-hash))
(define l
- (for/list ([i (get-index-entries sec ri)])
+ (for/list ([i (get-index-entries sec ri)] [idx (in-naturals)])
;; i is (list tag (text ...) (element ...) index-desc)
(define-values (tag texts elts desc) (apply values i))
(define text (string-downcase (string-join texts " ")))
@@ -73,6 +75,9 @@
[e (send renderer render-element e sec ri)])
(match e ; should always render to a single `a'
[`((a ([href ,href] [class "indexlink"]) . ,body))
+ (cond [(and (part-index-desc? desc)
+ (regexp-match #rx"(?:^|/)([^/]+)/index\\.html$" href))
+ => (lambda (man) (hash-set! manual-refs (cadr man) idx))])
(let (;; throw away tooltips, we don't need them
[body (match body
[`((span ((title ,label)) . ,body))
@@ -122,14 +127,24 @@
// or the string "module" for a module entry
plt_search_data = [
@(add-between l ",\n")];
+ // array of pointers to the previous array, for items that are manuals
+ plt_manual_ptrs = {
+ @(let* ([ms (hash-map manual-refs cons)]
+ [ms (sort ms < #:key cdr)]
+ [ms (map (lambda (x) (format "~s: ~a" (car x) (cdr x))) ms)])
+ (add-between ms ",\n "))};
// Globally visible bindings
var key_handler, toggle_help_pref, hide_prefs, new_query,
- set_results_num, set_type_delay, set_highlight_color;
+ set_show_manuals, set_show_manual_titles, set_results_num,
+ set_type_delay, set_highlight_color;
(function(){
- // Configuration options (use || in case the cookie exists but empty)
+ // Configuration options (use || in case a cookie exists but is empty)
+ var manual_settings = parseInt(GetCookie("PLT_ManualSettings",1));
+ var show_manuals = manual_settings % 10;
+ var show_manual_titles = ((manual_settings - show_manuals) / 10) > 0;
var results_num = (parseInt(GetCookie("PLT_ResultsNum", false)) || 20);
var type_delay = (parseInt(GetCookie("PLT_TypeDelay", false)) || 300);
var highlight_color = (GetCookie("PLT_HighlightColor", false) || "#ffd");
@@ -138,6 +153,13 @@
var query, status, results_container, result_links,
prev_page_link, next_page_link, panel;
+ // tabIndex fields are set:
+ // 1 query
+ // 2 index links
+ // 3 help/pref toggle
+ // 4 pref widgets
+ // -1 prev/next page (un-tab-able)
+
function InitializeSearch() {
var n;
n = document.getElementById("plt_search_container").parentNode;
@@ -149,14 +171,14 @@
+' '
+'
'
- +'[?] '
+' '
- +''
@@ -164,25 +186,45 @@
+'Hit PageUp /PageDown and Enter to'
+' scroll through the results. '
+'Use “M:str ” to match only'
- +' idenifiers from modles that match '
- +'“str ”; “M: ” by'
- +' itself will restrict results to bound names only '
+ +' idenifiers from modles that match'
+ +' “str ”; “M: ”'
+ +' by itself will restrict results to bound names only'
+'“L:str ” is similar to'
+' “L:str ”, but'
+' “str ” should match the module name'
+' exactly '
+ +'“T:str ” restricts results to ones'
+ +' in the “str ” manual (naming the'
+ +' directory where the manual is found) '
+ +'Entries that correspond to bindings have module links that'
+ +' create a query restricted to bindings in that module (using'
+ +' “L: ”), other entries have a similar'
+ +' manual links (using “T: ”); you can'
+ +' control whether manual links appear (and how) below '
+' '
+'Preferences:'
+ +'Show manuals:'
+ +' '
+ +'never '
+ +'except identifiers '
+ +'always '
+ +' '
+ +' '
+ +' use titles '
+'Results per page:'
- +' '
+'Type delay:'
- +' '
+'Exact matches color:'
- +' '
+' '
@@ -247,9 +289,14 @@
}
}
+ // constants for Compare(() results;
// `rexact' is for an actual exact match, so we know that we matched
- // *something* and can show exact matches as such
+ // *something* and can show exact matches as such, in other words:
+ // - < exact => this match is inexact
+ // - = exact => does not affect the exactness of this match
+ // - > exact => this is an exact match as far as this predicate goes
var C_fail = 0, C_match = 1, C_prefix = 2, C_exact = 3, C_rexact = 4;
+
function Compare(pat, str) {
var i = str.indexOf(pat);
if (i < 0) return C_fail;
@@ -264,26 +311,35 @@
return r;
}
+ function UrlToManual(url) {
+ return url.replace(/\/[^\/]*$/, "").replace(/^(.*\/|>)/, "");
+ }
+
function CompileTerm(term) {
- var flag = ((term.search(/^[LM]:/)==0) && term.substring(0,1));
+ var flag = ((term.search(/^[LMT]:/)==0) && term.substring(0,1));
if (flag) term = term.substring(2);
term = term.toLowerCase();
switch(flag) {
- case "L": return function(text,info) {
- if (!info) return C_fail;
- if (info == "module") return Compare(term,text); // rexact allowed!
- return (MaxCompares(term,info) >= C_exact) ? C_exact : C_fail;
+ case "L": return function(x) {
+ if (!x[3]) return C_fail;
+ if (x[3] == "module") return Compare(term,x[0]); // rexact allowed!
+ return (MaxCompares(term,x[3]) >= C_exact) ? C_exact : C_fail;
}
- case "M": return function(text,info) {
- if (!info) return C_fail;
- if (info == "module") return Compare(term,text); // rexact allowed!
- return (MaxCompares(term,info) >= C_match) ? C_exact : C_fail;
+ case "M": return function(x) {
+ if (!x[3]) return C_fail;
+ if (x[3] == "module") return Compare(term,x[0]); // rexact allowed!
+ return (MaxCompares(term,x[3]) >= C_match) ? C_exact : C_fail;
}
- default: return function(text,info) {
- switch (Compare(term,text)) {
+ case "T": return function(x) {
+ if (Compare(term,UrlToManual(x[1])) < C_exact) return C_fail;
+ else if (x[1].search(/\/index\.html$/) > 0) return C_rexact;
+ else return C_exact;
+ }
+ default: return function(x) {
+ switch (Compare(term,x[0])) {
case C_fail: return C_fail;
case C_match: case C_prefix: return C_match;
- case C_exact: case C_rexact: return (info ? C_rexact : C_match);
+ case C_exact: case C_rexact: return (x[3] ? C_rexact : C_match);
}
}
}
@@ -310,8 +366,7 @@
for (var i=0@";" i= C_rexact) exact_results.push(plt_search_data[i]);
else if (r > C_fail) search_results.push(plt_search_data[i]);
}
@@ -352,26 +407,39 @@
for (var i=0@";" i 0)) {
note = 'provided from ';
for (var j=0@";" j'
+ desc[j] + '';
} else if (desc == "module") {
note = 'module ';
}
+ if (show_manuals == 2 || (show_manuals == 1 && !desc)) {
+ var manual = UrlToManual(res[1]),
+ idx = (show_manual_titles && plt_manual_ptrs[manual]);
+ note = (note ? (note + " ") : "");
+ note += 'in '
+ + ''
+ + ((typeof idx == "number")
+ ? (''+UncompactHtml(plt_search_data[idx][2])+' ')
+ : manual)
+ + ' ';
+ }
if (note)
note = ' ' + note + ' ';
result_links[i].innerHTML =
- ''
- + UncompactHtml(search_results[n][2]) + ' ' + (note || "");
+ ''
+ + UncompactHtml(res[2]) + ' ' + (note || "");
result_links[i].style.backgroundColor =
(n < exact_results_num) ? highlight_color : background_color;
result_links[i].style.display = "block";
@@ -454,6 +522,7 @@
if (m < 0) return true;
else {
query.value = decodeURIComponent(node.href.substring(m+3));
+ query.focus();
DoSearch();
return false;
}
@@ -464,8 +533,12 @@
function TogglePanel() {
panel_shown = !panel_shown;
if (panel_shown) {
- document.getElementById("results_num_pref").value = results_num;
- document.getElementById("type_delay_pref").value = type_delay;
+ document.getElementById("show_manuals_pref").selectedIndex
+ = show_manuals;
+ document.getElementById("show_manual_titles_pref").checked
+ = show_manual_titles;
+ document.getElementById("results_num_pref").value = results_num;
+ document.getElementById("type_delay_pref").value = type_delay;
document.getElementById("highlight_color_pref").value = highlight_color;
}
panel.style.display = panel_shown ? "table-cell" : "none";
@@ -481,12 +554,30 @@
}
hide_prefs = HidePanel;
+ function SetShowManuals(inp) {
+ if (inp.selectedIndex != show_manuals) {
+ show_manuals = inp.selectedIndex;
+ SetCookie("PLT_ManualSettings", show_manuals+(show_manual_titles?10:0));
+ UpdateResults();
+ }
+ }
+ set_show_manuals = SetShowManuals;
+
+ function SetShowManualTitles(inp) {
+ if (inp.checked != show_manual_titles) {
+ show_manual_titles = inp.checked;
+ SetCookie("PLT_ManualSettings", show_manuals+(show_manual_titles?10:0));
+ UpdateResults();
+ }
+ }
+ set_show_manual_titles = SetShowManualTitles;
+
function SetResultsNum(inp) {
var n = (parseInt(inp.value.replace(/[^0-9]+/g,"")) || results_num);
inp.value = n;
if (n != results_num) {
results_num = n;
- SetCookie("PLT_ResultsNum", n);
+ SetCookie("PLT_ResultsNum", results_num);
AdjustResultsNum();
UpdateResults();
}
@@ -498,7 +589,7 @@
inp.value = n;
if (n != type_delay) {
type_delay = n;
- SetCookie("PLT_TypeDelay", n);
+ SetCookie("PLT_TypeDelay", type_delay);
}
}
set_type_delay = SetTypeDelay;
@@ -508,7 +599,7 @@
inp.value = c;
if (c != highlight_color) {
highlight_color = c;
- SetCookie("PLT_HighlightColor", c);
+ SetCookie("PLT_HighlightColor", highlight_color);
UpdateResults();
}
}