added title filtering & options
svn: r10081
This commit is contained in:
parent
cd8621726a
commit
299e736ff8
|
@ -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 @@
|
|||
+'<input type="text" id="search_box" style="width: 100%;"'
|
||||
+' tabIndex="1" onkeydown="return key_handler(event);" />'
|
||||
+'</td><td>'
|
||||
+'<a href="#" title="help/preference" tabIndex="3"'
|
||||
+'<a href="#" title="help/preference" tabIndex="3" id="toggle_panel"'
|
||||
+' style="text-decoration: none; font-weight: bold; color: black;"'
|
||||
+' onclick="toggle_help_pref(); return false;"'
|
||||
+'><tt><b>[?]</b></tt></a>'
|
||||
+'</td></tr>'
|
||||
+'<tr><td colspan="3" id="help_pref"'
|
||||
+'<tr><td colspan="3" id="help_pref" class="smaller"'
|
||||
+' style="display: none; border: 1px solid #222;'
|
||||
+' font-size: 82%; font-family: arial, sans-serif;'
|
||||
+' font-family: arial, sans-serif;'
|
||||
+' border-top: 0px; padding: 0.5em;'
|
||||
+' background-color: #f0f0f0;"'
|
||||
+'>'
|
||||
|
@ -164,25 +186,45 @@
|
|||
+'<li>Hit <tt>PageUp</tt>/<tt>PageDown</tt> and <tt>Enter</tt> to'
|
||||
+' scroll through the results.</li>'
|
||||
+'<li>Use “<tt>M:<i>str</i></tt>” to match only'
|
||||
+' idenifiers from modles that match '
|
||||
+'“<tt><i>str</i></tt>”; “<tt>M:</tt>” by'
|
||||
+' itself will restrict results to bound names only</li>'
|
||||
+' idenifiers from modles that match'
|
||||
+' “<tt><i>str</i></tt>”; “<tt>M:</tt>”'
|
||||
+' by itself will restrict results to bound names only</li>'
|
||||
+'<li>“<tt>L:<i>str</i></tt>” is similar to'
|
||||
+' “<tt>L:<i>str</i></tt>”, but'
|
||||
+' “<tt><i>str</i></tt>” should match the module name'
|
||||
+' exactly</li>'
|
||||
+'<li>“<tt>T:<i>str</i></tt>” restricts results to ones'
|
||||
+' in the “<tt><i>str</i></tt>” manual (naming the'
|
||||
+' directory where the manual is found)</li>'
|
||||
+'<li>Entries that correspond to bindings have module links that'
|
||||
+' create a query restricted to bindings in that module (using'
|
||||
+' “<tt>L:</tt>”), other entries have a similar'
|
||||
+' manual links (using “<tt>T:</tt>”); you can'
|
||||
+' control whether manual links appear (and how) below</li>'
|
||||
+'</ul><hr size=1>'
|
||||
+'Preferences:<blockquote style="margin: 0.25em 1em;">'
|
||||
+'Show manuals:'
|
||||
+' <select tabIndex="4" id="show_manuals_pref"'
|
||||
+' onkeypress="hide_prefs(event);"'
|
||||
+' onchange="set_show_manuals(this); return true;">'
|
||||
+'<option>never</option>'
|
||||
+'<option>except identifiers</option>'
|
||||
+'<option>always</option>'
|
||||
+'</select>'
|
||||
+' <input type="checkbox" tabIndex="4" id="show_manual_titles_pref"'
|
||||
+' onkeypress="hide_prefs(event);"'
|
||||
+' onchange="set_show_manual_titles(this); return true;">'
|
||||
+' use titles<br>'
|
||||
+'Results per page:'
|
||||
+' <input type="text" tabIndex="1" id="results_num_pref"'
|
||||
+' <input type="text" tabIndex="4" id="results_num_pref"'
|
||||
+' onkeypress="hide_prefs(event);"'
|
||||
+' onchange="set_results_num(this); return true;"><br>'
|
||||
+'Type delay:'
|
||||
+' <input type="text" tabIndex="1" id="type_delay_pref"'
|
||||
+' <input type="text" tabIndex="4" id="type_delay_pref"'
|
||||
+' onkeypress="hide_prefs(event);"'
|
||||
+' onchange="set_type_delay(this); return true;"><br>'
|
||||
+'Exact matches color:'
|
||||
+' <input type="text" tabIndex="1" id="highlight_color_pref"'
|
||||
+' <input type="text" tabIndex="4" id="highlight_color_pref"'
|
||||
+' onkeypress="hide_prefs(event);"'
|
||||
+' onchange="set_highlight_color(this); return true;"><br>'
|
||||
+'</blockquote></td></tr>'
|
||||
|
@ -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<plt_search_data.length@";" i++) {
|
||||
var r = C_rexact;
|
||||
for (var j=0@";" j<terms.length@";" j++)
|
||||
r = Math.min(r, terms[j](plt_search_data[i][0],
|
||||
plt_search_data[i][3]));
|
||||
r = Math.min(r, terms[j](plt_search_data[i]));
|
||||
if (r >= 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<result_links.length@";" i++) {
|
||||
var n = i + first_search_result;
|
||||
if (n < search_results.length) {
|
||||
var note = false, desc = search_results[n][3];
|
||||
var note = false, res = search_results[n], desc = res[3];
|
||||
if ((desc instanceof Array) && (desc.length > 0)) {
|
||||
note = '<span class="smaller">provided from</span> ';
|
||||
for (var j=0@";" j<desc.length@";" j++)
|
||||
note +=
|
||||
(j==0 ? "" : ", ")
|
||||
+ '<a href="?q=L:' + encodeURIComponent(desc[j]) + '"'
|
||||
+ ' class="schememod" tabIndex="2"'
|
||||
+' class="schememod" tabIndex="2"'
|
||||
+' style="text-decoration: none; color: #006;"'
|
||||
+' onclick="return new_query(this);">'
|
||||
+ desc[j] + '</a>';
|
||||
} else if (desc == "module") {
|
||||
note = '<span class="smaller">module</span>';
|
||||
}
|
||||
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 += '<span class="smaller">in</span> '
|
||||
+ '<a href="?q=T:' + manual + '" tabIndex="2"'
|
||||
+' style="text-decoration: none; color: #006;"'
|
||||
+' onclick="return new_query(this);">'
|
||||
+ ((typeof idx == "number")
|
||||
? ('<i>'+UncompactHtml(plt_search_data[idx][2])+'</i>')
|
||||
: manual)
|
||||
+ '</a>';
|
||||
}
|
||||
if (note)
|
||||
note = ' <span class="smaller">' + note + '</span>';
|
||||
result_links[i].innerHTML =
|
||||
'<a href="'
|
||||
+ UncompactUrl(search_results[n][1]) + '"'
|
||||
+ ' class="indexlink" tabIndex="2">'
|
||||
+ UncompactHtml(search_results[n][2]) + '</a>' + (note || "");
|
||||
'<a href="' + UncompactUrl(res[1]) + '"'
|
||||
+' class="indexlink" tabIndex="2">'
|
||||
+ UncompactHtml(res[2]) + '</a>' + (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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user