Initial commit: Klammertext source distribution

Curated source subset assembled by klammertext-dev's doc/make_dist.sh: the Klammermachine (mac), the Standard Klammer Set (sks), the commands (com), editor plugins and install guides (doc), a test subset (tst), and lib/bin placeholders. Builds with 'make -C com'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-18 18:48:23 +02:00
commit 2ba7ceee7a
272 changed files with 27634 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
function show_navigation_items(show_item) {
show_item = show_item === undefined ? true : false;
K.getv(".depthchoice").forEach(function (o) {
//K.visible(o, "hide");
K.get(o).hidden = !show_item;
});
["textshow", "next", "previous", "fit", "linkshow"].forEach(function (o) {
K.get("#"+o).hidden = !show_item;
});
}
function get_height(name) {
let div = K.get(name);
let result = 0;
if (div !== null) {
result = K.height(div);
}
return result;
}
function frame_resize() {
let nav = K.get("#nav");
let nav_height = (nav ? get_height(nav) : 0);
let content_height = window.innerHeight
- get_height("#title") - nav_height - get_height("#status") + 1;
K.height("#middle", content_height);
}
window.addEventListener("load", function (event) {
window.addEventListener("resize", function (e) {
frame_resize();
});
frame_resize();
if (typeof resize_toc === "function") resize_toc(true);
//let endspace_height = "calc(110% - " + K.height("#title")
// + " - " + K.height("#nav") + ")";
//K.style(".endspace", "height", endspace_height);
});

33
sks/document/js/help.js Normal file
View File

@@ -0,0 +1,33 @@
function modify_buttons_for_help(status) {
K.visible("#linkshow", status);
K.visible("#textshow", status);
K.visible("#searchtools", status);
K.get("#help").textContent = status == "show" ? "Help" : "Back";
}
function show_help() {
let header = K.get("#text h1");
if (header && header.textContent === "Navigation features") {
textshow();
modify_buttons_for_help("show");
frame_resize();
} else {
save_position();
K.get("#text").replaceWith(K.get("#help_page").cloneNode(true));
K.attr("#help_page", "id", "text");
K.visible("#toc", "hide");
K.visible("#resizer", "hide");
set_buttons("hide");
resize_text_width();
modify_buttons_for_help("hide");
frame_resize();
}
}
window.addEventListener("load", function (event) {
K.get("#help").addEventListener("click", function (e) {
event.preventDefault();
show_help();
});
define_keypress("H", "#help");
});

51
sks/document/js/level.js Normal file
View File

@@ -0,0 +1,51 @@
/* Open up the table of contents to a specified level in the hierarchy: */
/*
function show_all() {
let level_buttons = K.getv(".depthchoice");
level_buttons[level_buttons.length-1].click();
}
function show_highlighted(node) {
//let carets = K.getv(".caret");
let node_caret = node.parentNode.previousElementSibling;
console.log(node_caret);
}
*/
window.addEventListener("load", function (event) {
K.map(".depthchoice", function (depthchoice) {
depthchoice.addEventListener("click", function (event) {
//save_position();
let max_depth = K.text(event.srcElement);
K.map(".caret", function (e) {
let level = K.attr(e, "data-level");
let open = K.has_class(e, "caret-down");
if (level < max_depth) {
if (!open) {
e.click();
}
} else {
if (open) {
e.click();
}
}
});
//restore_position();
});
});
K.get("html").addEventListener("keypress", function (event) {
const max_depth = K.getv(".depthchoice").length;
const zero = 48; // Hah!
let depth = 1;
for (depth = 1; depth <= max_depth; depth += 1) {
if (event.which === zero + depth) {
K.get('.depthchoice[data-depth="' + depth + '"]').click();
}
}
});
highlight_headers_in_toc();
});

12
sks/document/js/list.txt Normal file
View File

@@ -0,0 +1,12 @@
fold.js
load.js
toc.js
resize_toc.js
document.js
resize_text.js
show_links.js
level.js
next_last.js
help.js
search.js
state.js

135
sks/document/js/load.js Normal file
View File

@@ -0,0 +1,135 @@
function first_basename() {
let first = K.get(".navlink");
return first ? K.attr(first, "data-page") : null;
}
function scroll_to_target(target_name) {
var text = K.get("#text");
if (!text) return;
var folder_top = text.getBoundingClientRect().top;
var target = K.get(target_name);
if (target) {
var target_top = target.getBoundingClientRect().top;
var scroll_position = text.scrollTop + target_top - folder_top;
text.scrollTop = scroll_position;
}
highlight_visible_toc_sections();
}
function modify_links() {
var links = K.getv("#text a");
links.forEach(function(link) {
if (link.classList.contains("linkd") || link.querySelector("img")) {
return;
}
var href = link.getAttribute("href");
if (!href) return;
if (href.indexOf("http://") != -1 ||
href.indexOf("https://") != -1 ||
href.indexOf(".pdf") != -1 ||
href.indexOf("mailto:") != -1 ||
href.indexOf("/") == 0 ||
href.indexOf("#") != -1 ||
href.indexOf("..") == 0) {
return;
}
var parts = href.split('#');
var len = parts[0].length;
var page = parts[0].substring(0, len - 5);
var target = "#" + parts[1];
var span = document.createElement("span");
span.className = "panelink";
span.setAttribute("data-page", page);
span.setAttribute("data-target", target);
span.setAttribute("data-title", link.textContent);
span.textContent = link.textContent;
link.parentNode.replaceChild(span, link);
});
}
function show_text() {
K.visible("#search_page", "hide");
K.visible("#help_page", "hide");
K.visible("#text", "show");
K.style("#content", "background-color", "white");
K.text("#help", "Help");
highlight_visible_toc_sections();
}
function new_page_callback() {
show_text();
modify_links();
resize();
current_page_callback();
}
var image_timer;
var last_basename;
function current_page_callback() {
if (target_name == "#") {
return;
}
var selector = '.navlink[data-target="' + (target_name.split("#")[1] || "") + '"]';
var navlink = K.get(selector);
if (navlink) {
update_page_title(navlink);
}
resize();
scroll_to_target(target_name);
}
async function load_page_content(basename, new_page, callback) {
if (true || basename != current_basename()) {
var url = "pages/" + basename + ".html";
await K.load("#text", url);
callback();
}
else {
callback();
}
}
function load_page(basename, target, callback, push_state) {
var init_complete = false;
var push = typeof push_state !== "undefined";
var state, state_target;
if (init_complete) {
var parts = window.location.hash.toString().split("#");
state = {"basename" : parts[1], "target" : "#" + parts[2]};
state_target = "#" + basename + target;
if (push) {
history.pushState(state, "", state_target);
} else {
history.replaceState(state, "", state_target);
}
load_page_content(
basename, true,
function() {
target_name = target;
initialize = false;
callback(); } );
} else {
basename = first_basename();
state = {"basename" : basename, "target" : "#"};
state_target = "#" + basename + "#";
init_complete = true;
load_page_content(
basename, true,
function() {
target_name = target;
initialize = true;
callback(); } );
history.replaceState(state, "", state_target);
}
}

View File

@@ -0,0 +1,105 @@
/*
Enable the "Next" and "Previous" buttons to move through the table of
contents, making entries visible if necessary.
*/
function first_highlighted_navlink() {
let highlighted_titles = [...K.getv(".section-title.highlight")];
if (highlighted_titles.length === 0) {
return null;
}
return highlighted_titles[0].parentNode;
}
function make_navlink_visible(navlink) {
const elts = [...K.getv(".navlink, .caret")];
let i;
for (i = elts.indexOf(navlink); i >= 0; i -= 1) {
let elt = elts[i];
if (K.has_class(elt, "caret")) {
if (!K.has_class(elt, "caret-down")) {
toggle_caret(elt);
}
if (K.attr(elt, "data-level") === "0") {
break;
}
}
}
}
function show_button_status(id, active_p) {
//const inactive_color = "rgb(60%,60%,60%)";
//const inactive_color = "rgb(20%,20%,20%)";
const inactive_color = "transparent";
//const text_color = "white";
const text_color = "black";
const node = K.get(id);
if (active_p) {
K.style(node, "color", text_color);
//K.style(node, "color", "white");
K.style(node, "text-decoration", "none");
//K.style(node, "font-style", "normal");
} else {
K.style(node, "color", inactive_color);
K.style(node, "text-decoration", "none");
//K.style(node, "font-style", "italic");
}
}
function set_next_last_button_status() {
const navlinks = [...K.getv(".navlink")];
const top = headers_in_text()[0][0];
let status;
if (!top) {
status = [true, false];
}
else if (top.id === K.attr(navlinks[0], "data-target")) {
status = [true, false];
} else if (top.id === K.attr(navlinks[navlinks.length-1], "data-target")) {
status = [false, true];
} else {
status = [true, true];
}
show_button_status("#next", status[0]);
show_button_status("#previous", status[1]);
}
function next_navlink() {
let navlinks = [...K.getv(".navlink")];
let index = navlinks.indexOf(first_highlighted_navlink());
if (index < navlinks.length - 1) {
let next = navlinks[index + 1];
next.children[0].children[0].click();
//make_navlink_visible(next);
}
return index + 1;
}
function previous_navlink() {
let navlinks = [...K.getv(".navlink")];
let index = navlinks.indexOf(first_highlighted_navlink());
if (index > 0) {
let previous = navlinks[index - 1];
previous.children[0].children[0].click();
//make_navlink_visible(previous);
}
return index - 1;
}
window.addEventListener("load", function (event) {
K.get("#next").addEventListener("click", function (event) {
// hide_help();
const index = next_navlink();
resize_toc();
});
K.get("#previous").addEventListener("click", function (event) {
// hide_help();
const index = previous_navlink();
resize_toc();
});
define_keypress("N", "#next");
define_keypress("P", "#previous");
set_next_last_button_status();
});

View File

@@ -0,0 +1,129 @@
/* Toggling between text with the table of contents and the text without it */
function resize_text_width(toc_width) {
const displayed = displayed_text();
const style = window.getComputedStyle(displayed, null);
const offset = parseInt(style.getPropertyValue("padding-left"))
+ parseInt(style.getPropertyValue("padding-right"));
if (toc_width !== undefined) {
K.width(displayed, K.width("#middle") - toc_width - offset);//Sec - K.width("#resizer"));
} else {
/*
const style = window.getComputedStyle(displayed, null);
const offset = parseInt(style.getPropertyValue("padding-left"))
+ parseInt(style.getPropertyValue("padding-right"));
*/
K.width(displayed, K.width("#middle") - offset);
}
}
function get_top_header() {
return header_in_window("#text > p, #text > div");
}
function set_top_pos(top_header, original_top_pos) {
const new_top_pos = top_header.getBoundingClientRect().top;
const offset = original_top_pos - new_top_pos;
if (offset !== 0) {
//const text = K.get("#text");
const text = displayed_text();
text.scrollTo({top : text.scrollTop - offset});
}
}
function maintain_text_position(func) {
//const text_rect = K.get("#text").getBoundingClientRect();
const text_rect = displayed_text().getBoundingClientRect();
const top = text_rect.top - 10;
let top_elt;
let elt;
//for (let elt of K.get("#text").children) {
for (elt of displayed_text().children) {
if (K.top(elt) >= top) {
top_elt = elt;
break;
}
}
if (top_elt) {
let current_top = top_elt.getBoundingClientRect().top;
func.call();
set_top_pos(top_elt, current_top);
} else {
func.call();
}
}
function set_buttons(mode) {
let button;
for (button of ["#next", "#previous", "#fit"]) {
K.visible(button, mode);
}
for (button of K.getv(".depthchoice")) {
K.visible(button, mode);
}
}
function textshow() {
if (K.visible("#toc")) {
save_position();
K.visible("#toc", "hide");
K.visible("#resizer", "hide");
K.text("#textshow", "Table of contents");
set_buttons("hide");
resize_text_width();
//resize_toc();
resize_images();
} else {
K.visible("#toc", "show");
K.visible("#resizer", "show");
K.text("#textshow", "Text only");
/*
let fit_active = K.attr("#fit_check", "active");
if (fit_active === "false") {
K.get("#fit_check").click();
}
*/
//resize_images();
restore_position();
set_buttons("show");
resize_toc();
resize_images();
// Restore previous state:
/*
if (fit_active === "false") {
K.get("#fit_check").click();
}
*/
}
//resize_images();
//adjust_widths();
//center_elements();
//set_code_comment_width();
//set_imagecode_width();
// adjust_footnotes();
}
window.addEventListener("load", function (event) {
K.get("#textshow").addEventListener(
"click",
function (event) {
event.preventDefault();
maintain_text_position(textshow);
});
window.addEventListener(
"resize",
function (event) {
maintain_text_position(
function () {
resize_text_width();
resize_toc();
//resize_images();
});
});
define_keypress("T", "#textshow");
});

View File

@@ -0,0 +1,110 @@
/*
Resizing the pane of the table of contents to fit the titles, with
a draggable right edge to change the with of the table of contents pane.
*/
var resizer_width = 4;
var resizer_with_borders = 6;
function current_full_toc_width() {
var width = 0;
K.map(".section-title-text",
function (elt) {
width = Math.max(width, K.right(elt));
});
// Add room for scrollbar:
//width += K.hpad("#toc_items") * 3.0 + resizer_width;
let caret = K.get(".caret");
let caret_width = caret ? K.hpad(caret) : 16; // Need to adjust for now nested sections
width += K.hpad("#toc") + caret_width + K.hpad("#toc ul")
// + K.hpad("#toc_items") //* 1.5 // room for scroll bar
+ resizer_width + 8; // Room for scroll bar
return width;
}
function resize_toc(force_fit) {
if (K.visible("#toc") && (force_fit || K.attr("#fit_check", "active") === "true")) {
const toc_width = current_full_toc_width();
const text_width = K.width("#middle")
- toc_width - resizer_with_borders;
//K.width("#text", text_width);
K.width(displayed_text(), text_width);
K.width("#toc", toc_width);
//resize_captions();
resize_images();
//K.height(".resizer", Math.max(K.height("#toc"),
// K.height("#toc_items")));
//console.log("resize_toc: " + text_width, toc_width);
/*
resize_images();
adjust_widths();
center_elements();
set_annotate_max_width();
set_code_comment_width();
set_imagecode_width();
*/
}
}
function initResize(e) {
e.preventDefault();
window.addEventListener("mousemove", Resize, false);
window.addEventListener("mouseup", stopResize, false);
}
function Resize(e) {
e.preventDefault();
// If fit is on, turn it off if the divider is moved manually.
if (K.attr("#fit_check", "active") == "true") {
K.get("#fit_check").click();
}
maintain_text_position(
function () {
//const toc_width = Math.max(0, e.clientX) + K.hpad("#text") + resizer_width;
const toc_width = Math.max(0, e.clientX) + K.hpad(displayed_text()) + resizer_width;
K.width("#toc", toc_width);
//K.width("#text", K.width("#middle") - toc_width);
K.width(displayed_text(), K.width("#middle") - toc_width);
resize_images();
highlight_headers_in_toc();
});
}
function stopResize(event) {
if (event) {
event.preventDefault();
}
window.removeEventListener("mousemove", Resize, false);
window.removeEventListener("mouseup", stopResize, false);
}
window.addEventListener("load", function (event) {
K.get("#fit_check").addEventListener(
"click",
function (e) {
//console.log("fit_check click");
maintain_text_position(resize_toc);
if (K.attr(e.srcElement, "active") === "false") {
K.attr(e.srcElement, "active", "true");
} else {
K.attr(e.srcElement, "active", "false");
}
resize_toc();
localStorage.setItem("klammertext_fit", K.attr("#fit_check", "active"));
});
// The native <label for="fit_check"> behavior already forwards
// clicks to the checkbox. No additional handler needed.
K.get("#resizer").addEventListener("mousedown", initResize, false);
initResize(event);
stopResize();
resize_toc();
define_keypress("F", "#fit_check");
});

View File

@@ -0,0 +1,84 @@
function adjust_search_input_pane() {
//if ($("#textshow").is(":visible")) {
if (K.visible("#textshow")) {
const search_input_width = 200;
//console.log(K.right("#textshow") + " " + K.right("#focus") + " " +
// K.right("#linkshow") + " " + K.right("#search_clear"));
const button_right = Math.max(
K.right("#textshow"), K.right("#focus"), K.right("#linkshow"), K.right("#search_clear"));
const help_left = K.left("#help");
//console.log("help_left: " + help_left);
//console.log("button_right: " + button_right);
//console.log("Search input: " + (help_left - button_right - 90));
let new_width = Math.min(search_input_width, help_left - button_right - 90);
if (new_width < 10) {
new_width = search_input_width;
}
K.width("#search_input", new_width);
}
}
function resize() {
/*
adjust_search_input_pane();
var height = $(window).height();
var title_height = K.height("#title");
var nav_height = K.height("#nav");
var status_height = K.height("#status");
K.height("#middle", height - title_height - nav_height - status_height + 1);
*/
//resize_text_width();
/*
set_annotate_max_width();
set_code_comment_width();
set_imagecode_width();
// adjust_footnotes();
adjust_slanted_header_table();
check_visible_link_boxes();
set_code_caption_width();
resize_images();
adjust_widths();
center_elements();
*/
}
/*
$(window).on("load", function() {
$(window).on("resize", function(event) {
console.log("RESIZE");
event.preventDefault();
resize();
//maintain_text_position(resize);
});
$("#toc").scroll( function() {
adjust_toc_slider_height();
});
//$("#toc").resizable({handles : "e"});
});
*/
window.addEventListener("load", function (event) {
window.addEventListener(
"resize",
function (event) {
event.preventDefault();
resize_images();
maintain_text_position(resize);
highlight_headers_in_toc();
/*
var top_header = get_top_header();
var original_pos = top_header.position().top;
resize();
set_top_pos(top_header, original_pos);
*/
});
resize();
//highlight_headers_in_toc();
});

313
sks/document/js/search.js Normal file
View File

@@ -0,0 +1,313 @@
/*
address article aside blockquote details dialog dd
div dl dt fieldset figcaption figure footer form
h1 h2 h3 h4 h5 h6 header hgroup hr li
main nav ol p section table ul td tr pre
*/
function blocks(root) {
let selector = [];
"blockquote kt-chapter div dd dt kt-part h1 h2 h3 h4 h5 li p td pre"
.split(" ").forEach(function (e) {
//selector.push("#pagecache .content_page " + e);
selector.push(root + " " + e);
});
return document.querySelectorAll(selector.join(", "));
}
function page_cache_blocks() {
return blocks("#pagecache .content_page");
}
function current_blocks() {
return blocks("#text");
}
function visible_toc_sections() {
let elements = current_blocks();
let last_heading = null;
let text_window = K.get("#text");
let text_top = text_window.scrollTop;
let text_bottom = text_top + K.height(text_window);
//console.log("text_top: " + text_top);
//console.log("text_bottom: " + text_bottom);
let result = [];
elements.forEach(function (elt) {
if (K.attr(elt, "data-level")) {
last_heading = elt;
//console.log("");
//console.log("LAST_HEADING:");
//console.log(last_heading);
}
//let elt_top = K.top(elt) - K.top(text_window);
let elt_top = elt.offsetTop; //
K.top(elt);
//console.log("");
//console.log("elt: " + elt_top);
//console.log(elt);
/*
if (elt_top >= text_top &&
elt_top <= text_bottom &&
!result.includes(last_heading)) {
*/
if (elt_top >= text_top &&
elt_top <= text_bottom) {
//console.log(" add: "
// + last_heading.children[0].textContent.trim());
if (!result.includes(last_heading)) {
result.push(last_heading);
}
}
});
if (result.length == 0) {
result.push(last_heading);
}
return result;
}
function buttons_before_search() {
//console.log("buttons_before_search()");
K.get("#search_clear").hidden = true;
K.get("#search_back_label").hidden = true;
K.get("#search_clear_input").hidden = true;
K.get("#search_label").hidden = false;
show_navigation_items();
}
function buttons_during_search() {
//console.log("buttons_during_search()");
K.get("#search_clear").hidden = true;
K.get("#search_back_label").hidden = false;
K.get("#search_clear_input").hidden = false;
K.get("#search_label").hidden = false;
show_navigation_items(false);
}
function buttons_after_search() {
//console.log("buttons_after_search()");
K.get("#search_clear").hidden = false;
K.get("#search_back_label").hidden = false;
K.get("#search_clear_input").hidden = false;
K.get("#search_label").hidden = false;
show_navigation_items();
}
function show_match(str) {
return "<span class=\"search_target\">" + str + "</span>";
}
function show_all_matches(page, rgx) {
//let cached_page = K.get("#pagecache #_page_" + id[2]);
let text_contents = page.innerHTML;
text_contents = text_contents.replaceAll(rgx, show_match);
page.innerHTML = text_contents;
}
function unhighlight_search_targets() {
K.getv(".search_target").forEach(function(e) {
e.outerHTML = e.innerHTML;
});
}
var saved_toc_width = 0;
function make_toc_visible(visible)
{
if (!visible) {
let current_width = K.width("#toc");
if (current_width > 0) {
saved_toc_width = current_width;
}
}
K.get("#toc").hidden = !visible;
K.get("#resizer").hidden = !visible;
if (visible) {
if (saved_toc_width > 0) {
K.width("#toc", saved_toc_width);
resize_text_width(saved_toc_width);
}
resize_toc();
} else {
resize_text_width();
}
}
function blocks_with_text(search_string) {
const rgx = new RegExp(search_string, "g");
const id_rgx = new RegExp("id=\"(.*?)\" data-basename=\"(.*?)\"");
let modified_blocks = [];
page_cache_blocks().forEach(function (o) {
let element_text = o.textContent;
if (element_text.search(rgx) > -1) {
//console.log(id_rgx);
//console.log(element_text);
let id = o.outerHTML.match(id_rgx);
//console.log("id: " + id);
//let element_contents = o.innerHTML;
let element_contents = o.outerHTML;
//element_contents = unhighlight_searches_in_text(element_contents);
//console.log(element_contents);
//console.log("\n----------------\n");
element_contents = element_contents.replaceAll(rgx, show_match);
//let modified = document.createElement("div");
//K.attr(modified, "class", "search_result");
let modified = document.createElement("a");
K.attr(modified, "class", "search_result");
K.attr(modified, "href", "#" + id[2] + "#" + id[1])
modified.innerHTML = element_contents;
modified_blocks.push(modified);
modified.addEventListener("click", function (event) {
event.preventDefault();
unhighlight_search_targets();
go_to_section(null, id[2], id[1], true, function() {
show_all_matches(displayed_text(), rgx);
});
make_toc_visible(true);
buttons_after_search();
});
}
});
return modified_blocks;
}
function search_heading(search_string, count) {
let heading = document.createElement("h1");
if (count > 0) {
heading.innerHTML = count + " occurrences of \"" + search_string + "\"";
} else {
heading.innerHTML = "No occurrences of \"" + search_string + "\"";
}
return heading;
}
function show_search_results(search_string) {
if (search_string.length === 0) {
return;
}
unhighlight_search_targets();
let search_page = K.get("#search_page");
search_page.innerHTML = "";
//search_page.style.width = K.width("#text");
let results = blocks_with_text(search_string);
search_page.append(search_heading(search_string, results.length));
if (results) {
results.forEach(function (o) {
search_page.append(o);
});
}
make_toc_visible(false);
buttons_during_search();
//let width = K.get("#text").clientWidth;
//console.log("outerWidth: " + width);
K.get("#text").replaceWith(search_page);
K.attr("#search_page", "id", "text");
search_page = document.createElement("div");
K.attr(search_page, "id", "search_page");
K.get("#pagecache").append(search_page);
}
window.addEventListener("load", function (event) {
K.get("#search_input").addEventListener("keyup", function (e) {
event.preventDefault();
let search_string = K.get("#search_input").value;
if (search_string.length > 0) {
let enter_key = 13;
if (e.which === enter_key) {
//console.log("save position with button");
unhighlight_search_targets();
save_position();
buttons_during_search();
//console.log("ENTER " + K.get("#search_input").value);
show_search_results(search_string);
}
}
});
K.get("#search_label").addEventListener("click", function (e) {
event.preventDefault();
let search_string = K.get("#search_input").value;
if (search_string.length > 0) {
//console.log("save position with return");
save_position();
buttons_during_search();
show_search_results(search_string);
} else {
let input_box = K.get("#search_input");
K.style(input_box, "background-color", "var(--nav_background_color)");
K.style(input_box, "font-style", "italic");
input_box.value = "Enter search text here";
setTimeout(function() {
K.style(input_box, "background-color", "white");
input_box.value = "";
K.style(input_box, "font-style", "normal");
}, 1500);
}
});
K.get("#search_clear").addEventListener("click", function (e) {
unhighlight_search_targets();
/*
text_elt.innerHTML = text_elt.innerHTML.replaceAll(id_rgx, "$1");
let text_contents = text_elt.innerHTML;
text_contents = text_contents.replaceAll(id_rgx, "$1");
text_elt.innerHTML = text_contents;
*/
//K.get("#search_clear").hidden = true;
buttons_before_search();
add_scrolling_to_text();
});
K.get("#search_clear_input").addEventListener("click", function (e) {
K.get("#search_input").value = "";
e.srcElement.hidden = true;
//K.attr("#text", "style", "background-color: var(--nav_background_color)");
//K.attr("#text", "style", "color: var(--nav_background_color)");
});
K.get("#search_back_label").addEventListener("click", function (e) {
//console.log("back");
make_toc_visible(true);
buttons_before_search();
add_scrolling_to_text();
restore_position();
unhighlight_search_targets();
});
K.get("html").addEventListener("keyup", function (event) {
let uppercase = "S".charCodeAt();
let lowercase = uppercase + 32;
if (search_not_active()) {
if (event.which === uppercase || event.which === lowercase) {
buttons_before_search();
K.get("#search_input").focus();
K.get("#search_input").value = "";
}
}
});
//define_keypress("B", "#search_back_label");
});

View File

@@ -0,0 +1,44 @@
function show_link_boxes(show) {
K.map("a", function(elt) {
if (show) {
K.remove_class(elt, "undisplayed_link");
K.add_class(elt, "displayed_link");
localStorage.setItem("klammertext_links", "true");
} else {
K.remove_class(elt, "displayed_link");
K.add_class(elt, "undisplayed_link");
localStorage.setItem("klammertext_links", "false");
}
});
K.map(".pagelink", function(elt) {
if (show) {
K.remove_class(elt, "undisplayed_link");
K.add_class(elt, "displayed_link");
} else {
K.remove_class(elt, "displayed_link");
K.add_class(elt, "undisplayed_link");
}
});
}
window.addEventListener("load", function (event) {
K.get("#linkshow_check").addEventListener("click", function (event) {
let box = K.get("#linkshow_check");
if (K.attr(box, "active") === "false") {
K.attr(box, "active", "true");
show_link_boxes(true);
} else {
K.attr(box, "active", "false");
show_link_boxes(false);
}
});
/*
K.get("#linkshow_check_label").addEventListener("click", function (event) {
K.get("#linkshow_check").click();
});
*/
define_keypress("L", "#linkshow_check");
});

201
sks/document/js/state.js Normal file
View File

@@ -0,0 +1,201 @@
[save_position, restore_position] = function () {
let basename = "";
let top_heading_id = "";
let y_offset = 0;
let toc_width = 0;
let save = function () {
console.log("\n");
console.log("save_position");
basename = window.location.toString().split("#")[1];
let top_heading = first_highlighted_navlink();
console.log("top heading:");
console.log(top_heading);
if (!top_heading) {
return;
}
top_heading_id = K.attr(top_heading, "data-target");
//y_offset = Math.round(K.top(top_heading) - K.top("#text"));
let textw = K.get("#text");
//y_offset = textw.scrollHeight -textw.scrollTop;
y_offset = K.get("#text").scrollTop;
console.log("y_offset: " + y_offset);
toc_width = K.width("#toc");
console.log("toc_width: " + toc_width);
console.log("save_position: " + basename + " " + top_heading_id + " " + y_offset);
}
let restore = function () {
let page = K.get("#pagecache #_page_" + basename);
K.get("#text").innerHTML = page.innerHTML;
resize_text_width(toc_width);
K.get("#text").scrollTo(0, y_offset);
}
return [save, restore];
}();
function page_cache_id(name) {
return "_page_" + name;
}
async function cache_pages() {
if (K.get("#pagecache").children.length === 0) {
K.style("#pagecache", "display", "none");
const pagecache = K.get("#pagecache");
let loads = [];
pages_basenames().forEach(function (p) {
let page = document.createElement("div");
loads.push(K.load(page, "pages/" + p + ".html"));
K.attr(page, "id", page_cache_id(p));
K.attr(page, "class", "content_page");
pagecache.append(page);
});
let help_page = document.createElement("div");
loads.push(K.load(help_page, "pages/help.html"));
K.attr(help_page, "id", "help_page");
pagecache.append(help_page);
let search_page = document.createElement("div");
K.attr(search_page, "id", "search_page");
pagecache.append(search_page);
await Promise.all(loads);
}
}
window.addEventListener("popstate", function (event) {
const parts = window.location.toString().split("#");
const basename = parts[1];
const target = parts[2];
if (basename && target) {
if (K.get("#help").textContent === "Back") {
if (!K.visible("#toc")) {
textshow();
}
modify_buttons_for_help("show");
frame_resize();
} else {
go_to_section(null, basename, target, true);
}
}
});
window.addEventListener("load", async function (event) {
let last_location = localStorage.getItem("klammertext_location");
let last_fit_check = localStorage.getItem("klammertext_fit");
let last_links_check = localStorage.getItem("klammertext_links");
await cache_pages();
K.getv("#toc .caret[data-level='0']").forEach(function (o) {
if (!K.has_class(o, "caret-down")) {
o.click();
}
});
// Set initial hash so the browser back button can return to the first page
if (!window.location.hash) {
let first = K.get(".navlink");
if (first) {
let basename = K.attr(first, "data-page");
let target = K.attr(first, "data-target");
history.replaceState(null, null, "#" + basename + "#" + target);
}
}
if (last_location) {
localStorage.setItem("klammertext_reload", "true");
let parts = last_location.split(":");
//console.log("\n");
//console.log("load parts:");
//console.log(parts);
go_to_section(null, parts[0], parts[1], true);
}
resize_toc(true);
// Restore fit and links states directly (not via .click()) to avoid
// desync with the browser's checkbox state restoration on refresh.
if (last_fit_check === "true") {
K.attr("#fit_check", "active", "true");
K.get("#fit_check").checked = true;
} else {
K.attr("#fit_check", "active", "false");
K.get("#fit_check").checked = false;
}
resize_toc();
if (last_links_check === "true") {
K.attr("#linkshow_check", "active", "true");
K.get("#linkshow_check").checked = true;
show_link_boxes(true);
} else {
K.attr("#linkshow_check", "active", "false");
K.get("#linkshow_check").checked = false;
}
/*
if (last_location) {
const parts = last_location.toString().split("#");
console.log("parts:");
console.log(parts);
//go_to_section(null, parts[1], parts[2]);
}
*/
/*
let hash = "#" + basename;
if (target) {
hash += "#" + target;
}
*/
//save_position();
/*
let last_location = localStorage.getItem("klammertext_location");
console.log("last_location from storage: " + last_location);
if (last_location && last_location != window.location.toString()) {
//history.replaceState(last_location.toString(), "");
const parts = last_location.toString().split("#");
const basename = parts[1];
const target = parts[2];
window.location.hash = "#" + basename + "#" + target;
console.log("last_location: " + basename + " " + target);
//go_to_section(null, basename, target);
let locator = "#toc .navlink[data-target='" + target + "'] .section-title-text";
console.log(locator);
let title = K.get(locator);
console.log("title");
console.log(title);
title.click();
}
*/
});
/*
function get_position() {
const basename = window.location.toString().split("#")[1];
return [basename, K.get("#text").scrollTop];
}
function set_position(basename, y) {
K.get("#text").innerHTML = K.get("#_page_" + basename).innerHTML;
K.get("#text").scrollTo(0, y);
}
*/

301
sks/document/js/toc.js Normal file
View File

@@ -0,0 +1,301 @@
function current_page_headers() {
let result = K.getv([1,2,3,4,5].map(function (o) {
return "#text h" + o;
}));
result = [...result];
["kt-part", "kt-chapter"].forEach(function (tag) {
let elt = K.get("#text " + tag);
if (elt) {
result.push(elt);
}
});
return result;
}
function add_navlink_mapping(navlink_map, navlink) {
let target = K.attr(navlink, "data-target");
navlink_map[target] = navlink.children[0];
return navlink_map;
}
function headers_in_text() {
//const headers = [...K.getv("h1,h2,h3,h4")];
const headers = current_page_headers();
//const text_rect = K.get("#text").getBoundingClientRect();
const text_rect = displayed_text().getBoundingClientRect();
const top = text_rect.top;
const bottom = top + text_rect.height;
let visible = [];
let invisible = [];
headers.forEach(function (h) {
const header_rect = h.getBoundingClientRect();
const header_bottom = header_rect.bottom;
if (header_bottom > top && header_bottom < bottom) {
visible.push(h);
} else {
invisible.push(h);
}
});
//console.log("headers_in_text: " + visible.length
// + " " + invisible.length);
return [visible, invisible];
}
function open_highlighted_sections(node) {
//console.log("open_highlighted_sections");
let parent = node.parentNode;
while (parent && parent.id != "toc_items") {
//console.log(parent.id);
//console.dir(parent);
//console.log(parent);
//console.log(parent.children);
let carets = [...parent.children].filter(function (node) {
return K.has_class(node, "caret")
&& !K.has_class(node, "caret-down");
});
carets.forEach(function (c) {
c.click();
});
//console.log("carets: ")
//console.log(carets);
parent = parent.parentNode;
}
}
function open_visible() {
//console.log("open_visible");
let open_sections = visible_toc_sections();
if (open_sections.length === 1 && !open_sections[0]) {
return;
}
//console.log("open_sections:");
//console.log(open_sections);
open_sections.forEach(function (e) {
//console.log("visible: " + e);
let section_id = K.attr(e, "id");
let navlink = K.get(".navlink[data-target=\"" + section_id + "\"]");
if (navlink) {
open_highlighted_sections(navlink);
}
});
}
var last_visible = [];
//function find_visible_element(node) {
// [...node.children].forEach(function (o) {
function highlight_headers_in_toc() {
let navlink_map = {};
[...K.getv(".navlink")].forEach(
function (o) { add_navlink_mapping(navlink_map, o); });
[...K.getv(".highlight")].forEach(function (o) {
K.remove_class(o, "highlight");
});
let [visible, invisible] = headers_in_text();
/*
console.log("-");
console.log("visible: ");
console.log(visible);
console.log("visible length: " + visible.length + " " + visible);
console.log("invisible: ");
console.log(invisible);
console.log("invisible length: " + invisible.length + " " + invisible);
console.log("-");
*/
let max_level = 0;
if (visible.length > 0) {
visible.forEach(function (h) {
if (h.id) {
K.add_class(navlink_map[h.id], "highlight");
//console.log(h);
max_level = Math.max(max_level, parseInt(K.attr(h, "data-level")));
}
});
}
//console.log("max_level: ", max_level);
if (invisible.length > 0) {
invisible.forEach(function (h) {
if (h.id) {
K.remove_class(navlink_map[h.id], "highlight");
}
});
}
//if (toc_count === 0) {
/*
if (visible.length !== 0) {
//console.log("last visible: " + last_visible);
//last_visible = visible[visible.length - 1];
last_visible = visible[0];
} else {
//console.log("None visible; setting:")
//console.log(last_visible);
//visible = [last_visible];
}
console.log("visible");
console.log(visible);
*/
//console.log("last_visible:");
//console.log(last_visible);
if (visible.length === 0 && last_visible.id && navlink_map[last_visible.id]) {
// No headers are visible; use the header of the displayed element
//console.log("setting visiblity of " + last_visible.id);
K.add_class(navlink_map[last_visible.id], "highlight");
/*
last_visible.forEach(function (h) {
K.add_class(navlink_map[h.id], "highlight");
});
*/
}
if (visible.length !== 0) {
//console.log("set last visible: " + last_visible.id);
//last_visible = visible[visible.length - 1];
last_visible = visible[visible.length - 1];
}
open_visible();
}
/*
function update_hash() {
const first_highlighted_navlink = K.get(".section-title.highlight").parentNode;
const basename = K.attr(first_highlighted_navlink, "data-page");
const target = K.attr(first_highlighted_navlink, "data-target");
window.location.hash = "#" + basename + "#" + target;
}
*/
var navigation_interval = null;
function go_to_section(elt, basename_arg, target_arg, force_reload, on_loaded) {
const basename = basename_arg || K.attr(elt, "data-page");
const target = target_arg || (elt ? K.attr(elt, "data-target") : null);
const parts = window.location.toString().split("#");
let hash = "#" + basename;
if (target) {
hash += "#" + target;
}
let basepage = K.get("#_page_" + basename);
if (!basepage) {
return;
}
if (navigation_interval) {
clearInterval(navigation_interval);
navigation_interval = null;
}
var retries = 0;
const max_retries = 100;
navigation_interval = setInterval(function() {
if (!K.get("#text") || parts[1] != basename || force_reload) {
displayed_text().innerHTML = K.get("#_page_" + basename).innerHTML;
resize_images();
if (!force_reload) {
unhighlight_search_targets();
}
}
force_reload = false;
var target_element = document.getElementById(target);
if (!target_element) {
if (++retries > max_retries) {
clearInterval(navigation_interval);
navigation_interval = null;
}
return;
}
clearInterval(navigation_interval);
navigation_interval = null;
if (on_loaded) {
on_loaded();
}
let text_div = displayed_text();
text_div.scrollTop = target_element.offsetTop - text_div.offsetTop;
remove_toc_highlighting();
highlight_headers_in_toc();
set_next_last_button_status();
set_link_listeners();
window.location.hash = hash;
localStorage.setItem("klammertext_location", `${basename}:${target}`);
}, 10);
K.get("#help").textContent = "Help";
}
function toggle_caret(node) {
//console.trace();
node.parentElement.querySelector(".nested").classList.toggle("active");
node.classList.toggle("caret-down");
resize_toc();
}
function add_scrolling_to_text() {
K.get("#text").addEventListener("scroll", function (event) {
//event.preventDefault();
//console.log("scroll " + K.get("#text").scrollTop);
highlight_headers_in_toc();
//show_all_highlighted();
});
}
window.addEventListener("load", function (event) {
var toggler = document.getElementsByClassName("caret");
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function(event) {
toggle_caret(event.srcElement);
});
}
K.map(".section-number, .section-title-text", function(elt) {
elt.addEventListener("click", function (event) {
event.preventDefault();
buttons_before_search();
const caret = event.srcElement.parentNode.parentNode.parentNode.firstChild;
if (caret.nodeName !== "#text") {
const caret_down = K.has_class(caret, "caret-down");
if (!caret_down) {
toggle_caret(caret);
}
}
go_to_section(elt.parentNode.parentNode);
});
});
add_scrolling_to_text();
/*
K.get("#text").addEventListener("scroll", function (event) {
//event.preventDefault();
console.log("scroll " + K.get("#text").scrollTop);
highlight_headers_in_toc();
//show_all_highlighted();
});
*/
//highlight_headers_in_toc();
//open_visible();
//show_all_highlighted();
});