Compare commits

...

5 Commits

3
.gitignore vendored

@ -18,4 +18,5 @@ Icon
scribblings/*.js scribblings/*.js
scribblings/*.css scribblings/*.css
scribblings/*.html scribblings/*.html
scribblings/pollen/* scribblings/txexpr/*
txexpr/doc/*

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -305,4 +305,15 @@ tbody > tr:first-child > td > .together {
left: 0px; left: 0px;
top: 0px; top: 0px;
z-index: 1; z-index: 1;
} }
/* ---------------------------------------- */
/* For section source modules & tags */
.RPartExplain {
background: #eee;
font-size: 0.9rem;
margin-top: 0.2rem;
padding: 0.2rem;
text-align: left;
}

@ -0,0 +1,82 @@
/* For the Racket manual style */
AddOnLoad(function() {
/* Look for header elements that have x-source-module and x-part tag.
For those elements, add a hidden element that explains how to
link to the section, and set the element's onclick() to display
the explanation. */
var tag_names = ["h1", "h2", "h3", "h4", "h5"];
for (var j = 0; j < tag_names.length; j++) {
elems = document.getElementsByTagName(tag_names[j]);
for (var i = 0; i < elems.length; i++) {
var elem = elems.item(i);
AddPartTitleOnClick(elem);
}
}
})
function AddPartTitleOnClick(elem) {
var mod_path = elem.getAttribute("x-source-module");
var tag = elem.getAttribute("x-part-tag");
if (mod_path && tag) {
var info = document.createElement("div");
info.className = "RPartExplain";
/* The "top" tag refers to a whole document: */
var is_top = (tag == "\"top\"");
info.appendChild(document.createTextNode("Link to this "
+ (is_top ? "document" : "section")
+ " with "));
/* Break `secref` into two lines if the module path and tag
are long enough: */
var is_long = (is_top ? false : (mod_path.length + tag.length > 60));
var line1 = document.createElement("div");
var line2 = (is_long ? document.createElement("div") : line1);
function add(dest, str, cn) {
var s = document.createElement("span");
s.className = cn;
s.style.whiteSpace = "nowrap";
s.appendChild(document.createTextNode(str));
dest.appendChild(s);
}
/* Construct a `secref` call with suitable syntax coloring: */
add(line1, "\xA0@", "RktRdr");
add(line1, (is_top ? "other-doc" : "secref"), "RktSym");
add(line1, "[", "RktPn");
if (!is_top)
add(line1, tag, "RktVal");
if (is_long) {
/* indent second line: */
add(line2, "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0", "RktPn");
}
if (!is_top)
add(line2, " #:doc ", "RktPn");
add(line2, "'", "RktVal");
add(line2, mod_path, "RktVal");
add(line2, "]", "RktPn");
info.appendChild(line1);
if (is_long)
info.appendChild(line2);
info.style.display = "none";
/* Add the new element afterthe header: */
var n = elem.nextSibling;
if (n)
elem.parentNode.insertBefore(info, n);
else
elem.parentNode.appendChild(info);
/* Clicking the header shows the explanation element: */
elem.onclick = function () {
if (info.style.display == "none")
info.style.display = "block";
else
info.style.display = "none";
}
}
}

@ -20,7 +20,7 @@ var page_args =
function GetPageArg(key, def) { function GetPageArg(key, def) {
for (var i=0; i<page_args.length; i++) for (var i=0; i<page_args.length; i++)
if (page_args[i][0] == key) return unescape(page_args[i][1]); if (page_args[i][0] == key) return decodeURIComponent(page_args[i][1]);
return def; return def;
} }
@ -28,9 +28,13 @@ function MergePageArgsIntoLink(a) {
if (page_args.length == 0 || if (page_args.length == 0 ||
(!a.attributes["data-pltdoc"]) || (a.attributes["data-pltdoc"].value == "")) (!a.attributes["data-pltdoc"]) || (a.attributes["data-pltdoc"].value == ""))
return; return;
a.href.search(/^([^?#]*)(?:\?([^#]*))?(#.*)?$/); a.href = MergePageArgsIntoUrl(a.href);
}
function MergePageArgsIntoUrl(href) {
href.search(/^([^?#]*)(?:\?([^#]*))?(#.*)?$/);
if (RegExp.$2.length == 0) { if (RegExp.$2.length == 0) {
a.href = RegExp.$1 + "?" + page_query_string + RegExp.$3; return RegExp.$1 + "?" + page_query_string + RegExp.$3;
} else { } else {
// need to merge here, precedence to arguments that exist in `a' // need to merge here, precedence to arguments that exist in `a'
var i, j; var i, j;
@ -47,7 +51,7 @@ function MergePageArgsIntoLink(a) {
if (args[j] == page_args[i][0]) { exists = true; break; } if (args[j] == page_args[i][0]) { exists = true; break; }
if (!exists) str += "&" + page_args[i][0] + "=" + page_args[i][1]; if (!exists) str += "&" + page_args[i][0] + "=" + page_args[i][1];
} }
a.href = prefix + "?" + str + suffix; return prefix + "?" + str + suffix;
} }
} }
@ -127,8 +131,8 @@ function DoSearchKey(event, field, ver, top_path) {
if (event && event.keyCode == 13) { if (event && event.keyCode == 13) {
var u = GetCookie("PLT_Root."+ver, null); var u = GetCookie("PLT_Root."+ver, null);
if (u == null) u = top_path; // default: go to the top path if (u == null) u = top_path; // default: go to the top path
u += "search/index.html?q=" + escape(val); u += "search/index.html?q=" + encodeURIComponent(val);
if (page_query_string) u += "&" + page_query_string; u = MergePageArgsIntoUrl(u);
location = u; location = u;
return false; return false;
} }

@ -1,4 +1,2 @@
#lang info #lang setup/infotab
(define collection "txexpr") (define collection 'multi)
(define scribblings '(("scribblings/txexpr.scrbl" ())))
(define compile-omit-paths '("tests.rkt"))

@ -0,0 +1,3 @@
#lang setup/infotab
(define scribblings '(("scribblings/txexpr.scrbl" ())))
(define compile-omit-paths '("tests.rkt"))

@ -10,7 +10,7 @@
@author[(author+email "Matthew Butterick" "mb@mbtype.com")] @author[(author+email "Matthew Butterick" "mb@mbtype.com")]
@defmodule[#:multi (txexpr (submod txexpr safe))] @defmodule[txexpr]
A set of small but handy functions for improving the readability and reliability of programs that operate on tagged X-expressions (for short, @italic{txexpr}s). A set of small but handy functions for improving the readability and reliability of programs that operate on tagged X-expressions (for short, @italic{txexpr}s).

@ -83,7 +83,7 @@
(check-equal? (attrs->hash '((foo "bar")) '(foo "fraw")) '#hash((foo . "fraw"))) (check-equal? (attrs->hash '((foo "bar")) '(foo "fraw")) '#hash((foo . "fraw")))
(check-equal? (attrs->hash '((foo "bar")) '(foo "fraw") 'foo "dog") '#hash((foo . "dog"))) (check-equal? (attrs->hash '((foo "bar")) '(foo "fraw") 'foo "dog") '#hash((foo . "dog")))
(check-equal? (hash->attrs '#hash((foo . "bar")(hee . "haw"))) '((foo "bar")(hee "haw"))) ;(check-equal? (hash->attrs '#hash((foo . "bar")(hee . "haw"))) '((foo "bar")(hee "haw")))
(check-equal? (attr-ref '(p ((foo "bar"))) 'foo) "bar") (check-equal? (attr-ref '(p ((foo "bar"))) 'foo) "bar")
(check-equal? (attr-set '(p ((foo "bar"))) 'foo "fraw") '(p ((foo "fraw")))) (check-equal? (attr-set '(p ((foo "bar"))) 'foo "fraw") '(p ((foo "fraw"))))
@ -118,5 +118,5 @@
(check-equal? (call-with-values (λ() (splitf-txexpr split-this-tx (λ(x) (and (txexpr? x) (equal? 'meta (car x)))))) list) (check-equal? (call-with-values (λ() (splitf-txexpr split-this-tx (λ(x) (and (txexpr? x) (equal? 'meta (car x)))))) list)
(list '(root "hello" "world" (em "goodnight" "moon")) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3")))) (list '(root "hello" "world" (em "goodnight" "moon")) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3"))))
(check-equal? (txexpr->html '(root (script "3 > 2") "Why is 3 > 2?")) (check-equal? (xexpr->html '(root (script "3 > 2") "Why is 3 > 2?"))
"<root><script>3 > 2</script>Why is 3 &gt; 2?</root>") "<root><script>3 > 2</script>Why is 3 &gt; 2?</root>")
Loading…
Cancel
Save