// Core/loader.js
window.RT = window.RT || {};
-window.RT.Element = [];
window.RT.Module = window.RT.Module || new Set();
-
-
// 2. Establish the Debug System
window.RT.Debug = {
active_tokens: new Set([
-// Core/document_loaded.js
+// Core/stage_manager.js
-window.RT = window.RT || {};
-window.RT.Element = window.RT.Element || [];
-window.RT.Module = window.RT.Module || new Set();
+RT = RT || {};
+RT.Element = RT.Element || new Set();
(function(){
- const debug = window.RT.Debug || { log: function(){} };
+ const debug = RT.Debug || { log: function(){} };
let target_y = 0;
let is_reload = false;
function execute_pagination_and_scroll(){
debug.log('scroll' ,`Pagination layout starting.`);
- if(window.RT.paginate_by_element) window.RT.paginate_by_element();
+ if(RT.paginate_by_element) RT.paginate_by_element();
let final_target = target_y;
let use_hash = false;
function process_elements_and_layout() {
debug.log('lifecycle', 'Processing registered elements.');
- if (window.RT.Element && Array.isArray(window.RT.Element)) {
- while (window.RT.Element.length > 0) {
- const element_fn = window.RT.Element.shift();
+ if (RT.Element instanceof Set && RT.Element.size > 0) {
+ for (const element_fn of RT.Element) {
if (typeof element_fn === 'function') {
element_fn();
+ } else {
+ // Fallback warning if your debug utility is not available
+ if (RT.Debug?.warn) {
+ RT.Debug.warn('layout', 'Invalid element in RT.Element Set: ' + element_fn);
+ } else {
+ console.warn('Invalid element in RT.Element Set:', element_fn);
+ }
}
}
}
}
}
+
// Initial Execution
lock_layout();
configure_history();
document.addEventListener('DOMContentLoaded', process_elements_and_layout);
- // Structural Safety Net: restore visibility on load if layout engine hangs
+ // Safety Net: restore visibility on load if layout engine hangs
window.addEventListener("load", unlock_layout);
})();
<title>RT Style System: Reference Manual</title>
<script src="RT-Style_locator.js"></script>
<script>
- window.RT.theme_preference('inverse_wheat');
+ window.RT.theme_preference('inverse_wheat_DS');
window.RT.load('Layout/article_tech_ref');
</script>
</head>
*/
-window.RT = window.RT || {};
-
-window.RT.TOC = function(){
- const debug = window.RT.Debug || { log: function(){} };
- const TOC_seq = document.querySelectorAll('rt·toc');
-
- TOC_seq.forEach( (container ,TOC_index) => {
- container.style.display = 'block';
-
- // 1. Parse attribute: single number N or range A-B
- const attr_val = container.getAttribute('level');
- let start_level, end_level;
-
- if (attr_val) {
- const rangeMatch = attr_val.match(/^(\d)-(\d)$/);
- if (rangeMatch) {
- const a = parseInt(rangeMatch[1]);
- const b = parseInt(rangeMatch[2]);
- if (a >= 1 && a <= 6 && b >= 1 && b <= 6 && a <= b) {
- start_level = a;
- end_level = b;
- if (debug.log) debug.log('TOC', `TOC #${TOC_index} range: H${a}-H${b}`);
- } else {
- if (debug.log) debug.log('TOC', `Invalid range "${attr_val}" → implicit mode`);
- }
- } else {
- const single = parseInt(attr_val);
- if (!isNaN(single) && single >= 1 && single <= 6) {
- start_level = single;
- end_level = single;
- if (debug.log) debug.log('TOC', `TOC #${TOC_index} single level: H${single}`);
+(function() {
+
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
+
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+ const TOC_seq = document.querySelectorAll('rt·toc');
+
+ TOC_seq.forEach( (container ,TOC_index) => {
+ container.style.display = 'block';
+
+ // 1. Parse attribute: single number N or range A-B
+ const attr_val = container.getAttribute('level');
+ let start_level, end_level;
+
+ if (attr_val) {
+ const rangeMatch = attr_val.match(/^(\d)-(\d)$/);
+ if (rangeMatch) {
+ const a = parseInt(rangeMatch[1]);
+ const b = parseInt(rangeMatch[2]);
+ if (a >= 1 && a <= 6 && b >= 1 && b <= 6 && a <= b) {
+ start_level = a;
+ end_level = b;
+ if (debug.log) debug.log('TOC', `TOC #${TOC_index} range: H${a}-H${b}`);
+ } else {
+ if (debug.log) debug.log('TOC', `Invalid range "${attr_val}" -> implicit mode`);
+ }
} else {
- if (debug.log) debug.log('TOC', `Invalid level "${attr_val}" → implicit mode`);
+ const single = parseInt(attr_val);
+ if (!isNaN(single) && single >= 1 && single <= 6) {
+ start_level = single;
+ end_level = single;
+ if (debug.log) debug.log('TOC', `TOC #${TOC_index} single level: H${single}`);
+ } else {
+ if (debug.log) debug.log('TOC', `Invalid level "${attr_val}" -> implicit mode`);
+ }
}
}
- }
-
- // 2. Implicit mode (no attribute or invalid)
- if (start_level === undefined || end_level === undefined) {
- let context_level = 0;
- let prev = container.previousElementSibling;
- while (prev) {
- const match = prev.tagName.match(/^H([1-6])$/);
- if (match) {
- context_level = parseInt(match[1]);
- break;
+
+ // 2. Implicit mode (no attribute or invalid)
+ if (start_level === undefined || end_level === undefined) {
+ let context_level = 0;
+ let prev = container.previousElementSibling;
+ while (prev) {
+ const match = prev.tagName.match(/^H([1-6])$/);
+ if (match) {
+ context_level = parseInt(match[1]);
+ break;
+ }
+ prev = prev.previousElementSibling;
}
- prev = prev.previousElementSibling;
+ const target_level = Math.min(context_level + 1, 6);
+ start_level = target_level;
+ end_level = target_level;
+ if (debug.log) debug.log('TOC', `TOC #${TOC_index} implicit target: H${target_level}`);
}
- const target_level = Math.min(context_level + 1, 6);
- start_level = target_level;
- end_level = target_level;
- if (debug.log) debug.log('TOC', `TOC #${TOC_index} implicit target: H${target_level}`);
- }
-
- // 3. Collect all matching headings until a higher-level heading stops us
- const headings = [];
- let next_el = container.nextElementSibling;
- while (next_el) {
- const match = next_el.tagName.match(/^H([1-6])$/);
- if (match) {
- const found_level = parseInt(match[1]);
-
- // Stop if we hit a heading that is a parent of the lowest level we collect
- if (found_level < start_level) break;
-
- // Collect if within the requested range
- if (found_level >= start_level && found_level <= end_level) {
- // Ensure it has an id
- if (!next_el.id) {
- next_el.id = `TOC-ref-${TOC_index}-${found_level}-${headings.length}`;
+
+ // 3. Collect all matching headings until a higher-level heading stops us
+ const headings = [];
+ let next_el = container.nextElementSibling;
+ while (next_el) {
+ const match = next_el.tagName.match(/^H([1-6])$/);
+ if (match) {
+ const found_level = parseInt(match[1]);
+
+ // Stop if we hit a heading that is a parent of the lowest level we collect
+ if (found_level < start_level) break;
+
+ // Collect if within the requested range
+ if (found_level >= start_level && found_level <= end_level) {
+ // Ensure it has an id
+ if (!next_el.id) {
+ next_el.id = `TOC-ref-${TOC_index}-${found_level}-${headings.length}`;
+ }
+ headings.push({ el: next_el, level: found_level });
}
- headings.push({ el: next_el, level: found_level });
}
- }
- next_el = next_el.nextElementSibling;
- }
-
- // 4. Build the container (title + list)
- container.innerHTML = '';
- const title = document.createElement('h1');
- title.textContent = start_level === 1 ? 'Table of Contents' : 'Section Contents';
- title.style.textAlign = 'center';
- container.appendChild(title);
-
- if (headings.length === 0) return; // nothing to show
-
- // Top-level list
- const topList = document.createElement('ul');
- topList.style.listStyle = 'none';
- topList.style.paddingLeft = '0';
- container.appendChild(topList);
-
- // Stack of <ul> elements; index 0 = top-level list
- const listStack = [topList];
-
- for (const item of headings) {
- // Depth relative to start_level
- const depth = item.level - start_level; // 0 = top-level, 1 = sub-level, etc.
-
- // Ensure we have the correct nesting depth
- while (listStack.length - 1 > depth) {
- // Pop until we are at the right depth
- listStack.pop();
+ next_el = next_el.nextElementSibling;
}
- // If we need to go deeper, open new sub-lists inside the last <li>
- while (listStack.length - 1 < depth) {
- const parentList = listStack[listStack.length - 1];
- const lastLi = parentList.lastElementChild;
- if (lastLi) {
- const subList = document.createElement('ul');
- subList.style.listStyle = 'none';
- subList.style.paddingLeft = '1.5rem'; // indentation for nested items
- lastLi.appendChild(subList);
- listStack.push(subList);
- } else {
- // No parent <li> yet – stay at current depth (flatten)
- break;
+ // 4. Build the container (title + list)
+ container.innerHTML = '';
+ const title = document.createElement('h1');
+ title.textContent = start_level === 1 ? 'Table of Contents' : 'Section Contents';
+ title.style.textAlign = 'center';
+ container.appendChild(title);
+
+ if (headings.length === 0) return; // nothing to show
+
+ // Top-level list
+ const topList = document.createElement('ul');
+ topList.style.listStyle = 'none';
+ topList.style.paddingLeft = '0';
+ container.appendChild(topList);
+
+ // Stack of <ul> elements; index 0 = top-level list
+ const listStack = [topList];
+
+ for (const item of headings) {
+ // Depth relative to start_level
+ const depth = item.level - start_level; // 0 = top-level, 1 = sub-level, etc.
+
+ // Ensure we have the correct nesting depth
+ while (listStack.length - 1 > depth) {
+ // Pop until we are at the right depth
+ listStack.pop();
}
- }
- // Create the <li> for this heading
- const li = document.createElement('li');
- li.style.marginBottom = '0.5rem';
+ // If we need to go deeper, open new sub-lists inside the last <li>
+ while (listStack.length - 1 < depth) {
+ const parentList = listStack[listStack.length - 1];
+ const lastLi = parentList.lastElementChild;
+ if (lastLi) {
+ const subList = document.createElement('ul');
+ subList.style.listStyle = 'none';
+ subList.style.paddingLeft = '1.5rem'; // indentation for nested items
+ lastLi.appendChild(subList);
+ listStack.push(subList);
+ } else {
+ // No parent <li> yet - stay at current depth (flatten)
+ break;
+ }
+ }
+
+ // Create the <li> for this heading
+ const li = document.createElement('li');
+ li.style.marginBottom = '0.5rem';
- const a = document.createElement('a');
- a.href = `#${item.el.id}`;
- a.textContent = item.el.textContent;
- a.style.textDecoration = 'none';
- a.style.color = 'inherit';
- a.style.display = 'block';
+ const a = document.createElement('a');
+ a.href = `#${item.el.id}`;
+ a.textContent = item.el.textContent;
+ a.style.textDecoration = 'none';
+ a.style.color = 'inherit';
+ a.style.display = 'block';
- a.onmouseover = () => a.style.color = 'var(--RT·brand-primary)';
- a.onmouseout = () => a.style.color = 'inherit';
+ a.onmouseover = () => a.style.color = 'var(--RT·brand-primary)';
+ a.onmouseout = () => a.style.color = 'inherit';
- li.appendChild(a);
- // Add to the current deepest list
- listStack[listStack.length - 1].appendChild(li);
- }
+ li.appendChild(a);
+ // Add to the current deepest list
+ listStack[listStack.length - 1].appendChild(li);
+ }
+ });
});
-};
+
+})();
Processes <RT·chapter> tags.
Transforms the tag into an <RT·page-break> followed by an <h1> with the RT·chapter class.
*/
-window.RT = window.RT || {};
-window.RT.chapter = function(){
- const debug = window.RT.Debug || { log: function(){} };
+(function() {
- document.querySelectorAll('RT·chapter').forEach( (el ,index) => {
- if(debug.log) debug.log('chapter' ,`Processing chapter ${index + 1}`);
+ if (!RT) {
+ console.error("RT not defined – was RT-Style_make run?");
+ return;
+ }
+ if (!RT.Element) {
+ console.error("RT.Element not defined – was the state_manager run?");
+ return;
+ }
- const brk = document.createElement('RT·page-break');
- const h1 = document.createElement('h1');
+ RT.Element.add( function() {
+ const debug = RT.Debug || { log: function(){} };
- h1.innerHTML = el.innerHTML;
+ document.querySelectorAll('RT·chapter').forEach((el, index) => {
+ if (debug.log) debug.log('chapter', `Processing chapter ${index + 1}`);
- if(el.className){
- h1.className = el.className;
- }
- h1.classList.add('RT·chapter');
+ const brk = document.createElement('RT·page-break');
+ const h1 = document.createElement('h1');
- Array.from(el.attributes).forEach( (attr) => {
- if(attr.name !== 'class'){
- h1.setAttribute(attr.name ,attr.value);
+ h1.innerHTML = el.innerHTML;
+
+ if (el.className) {
+ h1.className = el.className;
}
+ h1.classList.add('RT·chapter');
+
+ Array.from(el.attributes).forEach((attr) => {
+ if (attr.name !== 'class') {
+ h1.setAttribute(attr.name, attr.value);
+ }
+ });
+
+ el.parentNode.insertBefore(brk, el);
+ el.replaceWith(h1);
});
+ })
- el.parentNode.insertBefore(brk ,el);
- el.replaceWith(h1);
- });
-};
+})();
Removes common indent from lines of code.
*/
-function code() {
- const RT = window.RT;
- const U = RT.Utility;
- const debug = RT.Debug;
+(function(){
- debug.log('code', 'Starting render cycle.');
+ if (!RT) {
+ console.error("RT not defined – was RT-Style_make run?");
+ return;
+ }
+ if (!RT.Element) {
+ console.error("RT.Element not defined – was the state_manager run?");
+ return;
+ }
- const metrics = U.Font.measure_ink_ratio('monospace');
-
- document.querySelectorAll('rt·code').forEach((el) => {
- el.style.fontFamily = 'monospace';
+ RT.Element.add( function() {
+ const RT = window.RT;
+ const U = RT.Utility;
+ const debug = RT.Debug;
- const computed = window.getComputedStyle(el);
- const accent = window.RT.theme('read', 'brand', 'secondary') || 'gold';
-
- const is_block = U.Dom.is_block_content(el);
- const parentColor = window.RT.theme('read', 'content', 'main');
- const is_text_light = U.Color.is_light(parentColor);
-
- const alpha = is_block ? 0.08 : 0.15;
- const overlay = is_text_light ? `rgba(255,255,255,${alpha})` : `rgba(0,0,0,${alpha})`;
- const text_color = is_text_light ? '#ffffff' : '#000000';
+ debug.log('code', 'Starting render cycle.');
- el.style.backgroundColor = overlay;
-
- if (is_block) {
- el.style.display = 'block';
+ const metrics = U.Font.measure_ink_ratio('monospace');
+
+ document.querySelectorAll('rt·code').forEach((el) => {
+ el.style.fontFamily = 'monospace';
- // --- Tag-Relative Auto-Dedent Logic ---
+ const computed = window.getComputedStyle(el);
+ const accent = window.RT.theme('read', 'brand', 'secondary') || 'gold';
- // 1. Get Tag Indentation (The Anchor)
- let tagIndent = '';
- const prevNode = el.previousSibling;
- if (prevNode && prevNode.nodeType === 3) {
- const prevText = prevNode.nodeValue;
- const lastNewLineIndex = prevText.lastIndexOf('\n');
- if (lastNewLineIndex !== -1) {
- tagIndent = prevText.substring(lastNewLineIndex + 1);
- } else if (/^\s*$/.test(prevText)) {
- tagIndent = prevText;
+ const is_block = U.Dom.is_block_content(el);
+ const parentColor = window.RT.theme('read', 'content', 'main');
+ const is_text_light = U.Color.is_light(parentColor);
+
+ const alpha = is_block ? 0.08 : 0.15;
+ const overlay = is_text_light ? `rgba(255,255,255,${alpha})` : `rgba(0,0,0,${alpha})`;
+ const text_color = is_text_light ? '#ffffff' : '#000000';
+
+ el.style.backgroundColor = overlay;
+
+ if (is_block) {
+ el.style.display = 'block';
+
+ // --- Tag-Relative Auto-Dedent Logic ---
+
+ // 1. Get Tag Indentation (The Anchor)
+ let tagIndent = '';
+ const prevNode = el.previousSibling;
+ if (prevNode && prevNode.nodeType === 3) {
+ const prevText = prevNode.nodeValue;
+ const lastNewLineIndex = prevText.lastIndexOf('\n');
+ if (lastNewLineIndex !== -1) {
+ tagIndent = prevText.substring(lastNewLineIndex + 1);
+ } else if (/^\s*$/.test(prevText)) {
+ tagIndent = prevText;
+ }
}
- }
- // 2. Calculate Common Leading Whitespace from Content
- const rawLines = el.textContent.split('\n');
-
- // Filter out empty lines for calculation purposes so they don't break the logic
- const contentLines = rawLines.filter(line => line.trim().length > 0);
-
- let commonIndent = null;
-
- if (contentLines.length > 0) {
- // Assume the first line sets the standard
- const firstMatch = contentLines[0].match(/^\s*/);
- commonIndent = firstMatch ? firstMatch[0] : '';
-
- // Reduce the commonIndent if subsequent lines have LESS indentation
- for (let i = 1; i < contentLines.length; i++) {
- const line = contentLines[i];
- // Determine how much of commonIndent this line shares
- let j = 0;
- while (j < commonIndent.length && j < line.length && commonIndent[j] === line[j]) {
- j++;
+ // 2. Calculate Common Leading Whitespace from Content
+ const rawLines = el.textContent.split('\n');
+
+ // Filter out empty lines for calculation purposes so they don't break the logic
+ const contentLines = rawLines.filter(line => line.trim().length > 0);
+
+ let commonIndent = null;
+
+ if (contentLines.length > 0) {
+ // Assume the first line sets the standard
+ const firstMatch = contentLines[0].match(/^\s*/);
+ commonIndent = firstMatch ? firstMatch[0] : '';
+
+ // Reduce the commonIndent if subsequent lines have LESS indentation
+ for (let i = 1; i < contentLines.length; i++) {
+ const line = contentLines[i];
+ // Determine how much of commonIndent this line shares
+ let j = 0;
+ while (j < commonIndent.length && j < line.length && commonIndent[j] === line[j]) {
+ j++;
+ }
+ commonIndent = commonIndent.substring(0, j);
+ if (commonIndent.length === 0) break; // Optimization
}
- commonIndent = commonIndent.substring(0, j);
- if (commonIndent.length === 0) break; // Optimization
+ } else {
+ commonIndent = '';
}
- } else {
- commonIndent = '';
- }
- // 3. Process Content
- // Rule: Only strip if the Common Indent contains the Tag Indent (Safety Check)
- // This handles the Emacs case: Tag is " ", Common is " ". " " starts with " ".
- // We strip " ", leaving the code flush left.
- let finalString = '';
+ // 3. Process Content
+ // Rule: Only strip if the Common Indent contains the Tag Indent (Safety Check)
+ // This handles the Emacs case: Tag is " ", Common is " ". " " starts with " ".
+ // We strip " ", leaving the code flush left.
+ let finalString = '';
- if (commonIndent.length > 0 && commonIndent.startsWith(tagIndent)) {
- const cleanedLines = rawLines.map(line => {
+ if (commonIndent.length > 0 && commonIndent.startsWith(tagIndent)) {
+ const cleanedLines = rawLines.map(line => {
// Strip the common indent from valid lines
return line.startsWith(commonIndent) ? line.replace(commonIndent, '') : line;
- });
+ });
- // Remove artifact lines (first/last empty lines)
- if (cleanedLines.length > 0 && cleanedLines[0].length === 0) {
- cleanedLines.shift();
- }
- if (cleanedLines.length > 0 && cleanedLines[cleanedLines.length - 1].trim().length === 0) {
+ // Remove artifact lines (first/last empty lines)
+ if (cleanedLines.length > 0 && cleanedLines[0].length === 0) {
+ cleanedLines.shift();
+ }
+ if (cleanedLines.length > 0 && cleanedLines[cleanedLines.length - 1].trim().length === 0) {
cleanedLines.pop();
- }
- finalString = cleanedLines.join('\n');
+ }
+ finalString = cleanedLines.join('\n');
+ } else {
+ // Fallback: Code is to the left of the tag or weirdly formatted.
+ // Just trim the wrapper newlines.
+ finalString = el.textContent.trim();
+ }
+
+ el.textContent = finalString;
+ // --- End Indentation Logic ---
+
+ el.style.whiteSpace = 'pre';
+ el.style.fontSize = (parseFloat(computed.fontSize) * metrics.ratio * 0.95) + 'px';
+ el.style.padding = '1.2rem';
+ el.style.margin = '1.5rem 0';
+ el.style.borderLeft = `4px solid ${accent}`;
+ el.style.color = 'inherit';
} else {
- // Fallback: Code is to the left of the tag or weirdly formatted.
- // Just trim the wrapper newlines.
- finalString = el.textContent.trim();
+ el.style.display = 'inline';
+ const exactPx = parseFloat(computed.fontSize) * metrics.ratio * 1.0;
+ el.style.fontSize = exactPx + 'px';
+ el.style.padding = '0.1rem 0.35rem';
+ el.style.borderRadius = '3px';
+ const offsetPx = metrics.baseline_diff * (exactPx / 100);
+ el.style.verticalAlign = offsetPx + 'px';
+ el.style.color = text_color;
}
+ });
+
+ debug.log('code', 'Render cycle complete.');
+ })
- el.textContent = finalString;
- // --- End Indentation Logic ---
-
- el.style.whiteSpace = 'pre';
- el.style.fontSize = (parseFloat(computed.fontSize) * metrics.ratio * 0.95) + 'px';
- el.style.padding = '1.2rem';
- el.style.margin = '1.5rem 0';
- el.style.borderLeft = `4px solid ${accent}`;
- el.style.color = 'inherit';
- } else {
- el.style.display = 'inline';
- const exactPx = parseFloat(computed.fontSize) * metrics.ratio * 1.0;
- el.style.fontSize = exactPx + 'px';
- el.style.padding = '0.1rem 0.35rem';
- el.style.borderRadius = '3px';
- const offsetPx = metrics.baseline_diff * (exactPx / 100);
- el.style.verticalAlign = offsetPx + 'px';
- el.style.color = text_color;
- }
- });
-
- debug.log('code', 'Render cycle complete.');
-}
-
-window.RT = window.RT || {};
-window.RT.code = code;
+})();
// developer/authored/RT/element/constraint.js
-window.RT = window.RT || {};
-
-window.RT.constraint = function(){
- document.querySelectorAll('rt·constraint').forEach( (el) => {
- el.style.display = 'block';
- el.style.borderLeft = `4px solid ${window.RT.theme('read', 'state', 'warning')}`;
- el.style.backgroundColor = window.RT.theme('read', 'surface', '1');
- el.style.padding = '1rem';
- el.style.margin = '1.5rem 0';
- el.style.color = window.RT.theme('read', 'content', 'main');
+(function() {
+
+ if (!RT) {
+ console.error("RT not defined – was RT-Style_make run?");
+ return;
+ }
+ if (!RT.Element) {
+ console.error("RT.Element not defined – was the state_manager run?");
+ return;
+ }
+
+ RT.Element.add( function(){
+ document.querySelectorAll('RT·constraint').forEach( (el) => {
+ el.style.display = 'block';
+ el.style.borderLeft = `4px solid ${RT.theme('read', 'state', 'warning')}`;
+ el.style.backgroundColor = RT.theme('read', 'surface', '1');
+ el.style.padding = '1rem';
+ el.style.margin = '1.5rem 0';
+ el.style.color = RT.theme('read', 'content', 'main');
+ });
});
-};
+
+})();
+
-window.RT = window.RT || {};
-window.RT.Counter = window.RT.Counter || {};
-
-window.RT.dict_instance = {};
-window.RT.dict_snapshot = {};
-
-function clone_state(state) {
- return {
- counter: state.counter,
- stack: [...state.stack],
- empty: [...state.empty],
- separator: state.separator,
- 'separator-placement': state['separator-placement'],
- style: state.style,
- 'on-first-step': state['on-first-step'], // The literal string authored
- count: state.count
- };
-}
-
-window.RT.Counter.parse_and_count = function (root_node) {
- window.RT.dict_instance = {};
- window.RT.dict_snapshot = {};
-
- function to_roman(num) {
- if (num < 1) return num.toString();
- const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
- let roman = '';
- for (let i in lookup) {
- while (num >= lookup[i]) {
- roman += i;
- num -= lookup[i];
+/*
+ Processes <RT·Counter·*> tags.
+ Calculates numbering, maintains the stack, manages snapshots, and outputs values for read tags.
+*/
+
+(function() {
+
+ if (!RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
+
+ RT.Counter = RT.Counter || {};
+ RT.dict_instance = RT.dict_instance || {};
+ RT.dict_snapshot = RT.dict_snapshot || {};
+
+ RT.Element.add( function() {
+ const debug = RT.Debug || { log: function(){} };
+ if (debug.log) debug.log('counter', 'Processing counters');
+
+ const root_node = document.documentElement;
+
+ function clone_state(state) {
+ return {
+ counter: state.counter,
+ stack: [...state.stack],
+ empty: [...state.empty],
+ separator: state.separator,
+ 'separator-placement': state['separator-placement'],
+ style: state.style,
+ 'on-first-step': state['on-first-step'],
+ count: state.count
+ };
+ }
+
+ function to_roman(num) {
+ if (num < 1) return num.toString();
+ const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
+ let roman = '';
+ for (let i in lookup) {
+ while (num >= lookup[i]) {
+ roman += i;
+ num -= lookup[i];
+ }
}
+ return roman;
}
- return roman;
- }
- function parse_first_step(val_str, style, counter_name) {
- if (!val_str) return 1;
+ function parse_first_step(val_str, style, counter_name) {
+ if (!val_str) return 1;
- let num = NaN;
+ let num = NaN;
- if (style === 'alpha') {
- if (/^[a-z]$/.test(val_str)) {
- num = val_str.charCodeAt(0) - 96;
- }
- } else if (style === 'Alpha') {
- if (/^[A-Z]$/.test(val_str)) {
- num = val_str.charCodeAt(0) - 64;
- }
- } else if (style === 'roman' || style === 'Roman' || style === 'roman-outline') {
- let is_upper = (style === 'Roman' || style === 'roman-outline');
- let regex = is_upper ? /^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/ : /^m*(cm|cd|d?c{0,3})(xc|xl|l?x{0,3})(ix|iv|v?i{0,3})$/;
-
- if (regex.test(val_str)) {
- const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
- let temp = val_str.toUpperCase();
- num = 0;
- let i = 0;
- while (i < temp.length) {
- if (i + 1 < temp.length && lookup[temp.substring(i, i + 2)]) {
- num += lookup[temp.substring(i, i + 2)];
- i += 2;
- } else {
- num += lookup[temp[i]];
- i++;
+ if (style === 'alpha') {
+ if (/^[a-z]$/.test(val_str)) {
+ num = val_str.charCodeAt(0) - 96;
+ }
+ } else if (style === 'Alpha') {
+ if (/^[A-Z]$/.test(val_str)) {
+ num = val_str.charCodeAt(0) - 64;
+ }
+ } else if (style === 'roman' || style === 'Roman' || style === 'roman-outline') {
+ let is_upper = (style === 'Roman' || style === 'roman-outline');
+ let regex = is_upper ? /^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/ : /^m*(cm|cd|d?c{0,3})(xc|xl|l?x{0,3})(ix|iv|v?i{0,3})$/;
+
+ if (regex.test(val_str)) {
+ const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1};
+ let temp = val_str.toUpperCase();
+ num = 0;
+ let i = 0;
+ while (i < temp.length) {
+ if (i + 1 < temp.length && lookup[temp.substring(i, i + 2)]) {
+ num += lookup[temp.substring(i, i + 2)];
+ i += 2;
+ } else {
+ num += lookup[temp[i]];
+ i++;
+ }
}
}
+ } else {
+ if (/^\d+$/.test(val_str)) {
+ num = parseInt(val_str, 10);
+ }
}
- } else {
- if (/^\d+$/.test(val_str)) {
- num = parseInt(val_str, 10);
- }
- }
- if (isNaN(num) || num < 1) {
- console.error(`RT-Style Layout Error: Type mismatch. Invalid 'on-first-step' value '${val_str}' for style '${style}' in counter '${counter_name}'.`);
- return 1;
+ if (isNaN(num) || num < 1) {
+ console.error(`RT-Style Layout Error: Type mismatch. Invalid 'on-first-step' value '${val_str}' for style '${style}' in counter '${counter_name}'.`);
+ return 1;
+ }
+ return num;
}
- return num;
- }
- function format_count(num, style, depth) {
- if (style === 'roman') return to_roman(num).toLowerCase();
- if (style === 'Roman') return to_roman(num);
- if (style === 'Alpha') return String.fromCharCode(64 + num);
- if (style === 'alpha') return String.fromCharCode(96 + num);
-
- if (style === 'roman-outline') {
- const levels = ['Roman', 'Alpha', 'Natural', 'alpha', 'roman'];
- const current_style = levels[depth % levels.length];
- return format_count(num, current_style, 0);
+ function format_count(num, style, depth) {
+ if (style === 'roman') return to_roman(num).toLowerCase();
+ if (style === 'Roman') return to_roman(num);
+ if (style === 'Alpha') return String.fromCharCode(64 + num);
+ if (style === 'alpha') return String.fromCharCode(96 + num);
+
+ if (style === 'roman-outline') {
+ const levels = ['Roman', 'Alpha', 'Natural', 'alpha', 'roman'];
+ const current_style = levels[depth % levels.length];
+ return format_count(num, current_style, 0);
+ }
+
+ return num.toString();
}
-
- return num.toString();
- }
- function walk(node) {
- if (node.nodeType !== Node.ELEMENT_NODE) return;
-
- const tag = node.tagName.toLowerCase();
- let pushed_name = null;
-
- if (tag === 'RT·Counter·make'.toLowerCase()) {
- const name = node.getAttribute('counter');
- if (name) {
- const style = node.getAttribute('style') || 'Natural';
- const on_first_step_str = node.getAttribute('on-first-step');
-
- let first_step_int = parse_first_step(on_first_step_str, style, name);
-
- window.RT.dict_instance[name] = {
- counter: name,
- stack: [0],
- empty: [true],
- separator: node.getAttribute('separator') || '.',
- 'separator-placement': node.getAttribute('separator-placement') || 'embedded',
- style: style,
- 'on-first-step': on_first_step_str || '1',
- on_first_step_int: first_step_int, // Stored internally for execution
- count: ''
- };
- }
- } else if (tag === 'RT·Counter·indent'.toLowerCase()) {
- const name = node.getAttribute('counter');
- if (name && window.RT.dict_instance[name]) {
- window.RT.dict_instance[name].stack.push(0);
- window.RT.dict_instance[name].empty.push(true);
- pushed_name = name;
- }
- } else if (tag === 'RT·Counter·step'.toLowerCase()) {
- const name = node.getAttribute('counter');
- if (name && window.RT.dict_instance[name]) {
- const state = window.RT.dict_instance[name];
- const depth = state.stack.length - 1;
-
- if (state.empty[depth]) {
- state.stack[depth] = (depth === 0) ? state.on_first_step_int : 1;
- state.empty[depth] = false;
- } else {
- state.stack[depth] += 1;
+ function walk(node) {
+ if (node.nodeType !== Node.ELEMENT_NODE) return;
+
+ const tag = node.tagName.toLowerCase();
+ let pushed_name = null;
+
+ if (tag === 'rt·counter·make') {
+ const name = node.getAttribute('counter');
+ if (name) {
+ const style = node.getAttribute('style') || 'Natural';
+ const on_first_step_str = node.getAttribute('on-first-step');
+
+ let first_step_int = parse_first_step(on_first_step_str, style, name);
+
+ RT.dict_instance[name] = {
+ counter: name,
+ stack: [0],
+ empty: [true],
+ separator: node.getAttribute('separator') || '.',
+ 'separator-placement': node.getAttribute('separator-placement') || 'embedded',
+ style: style,
+ 'on-first-step': on_first_step_str || '1',
+ on_first_step_int: first_step_int,
+ count: ''
+ };
}
-
- const formatted_stack = state.stack.map((val, index) =>
- format_count(val, state.style, index)
- );
-
- let count_str = formatted_stack.join(state.separator);
- if (state['separator-placement'] === 'embedded-after') {
- count_str += state.separator;
+ } else if (tag === 'rt·counter·indent') {
+ const name = node.getAttribute('counter');
+ if (name && RT.dict_instance[name]) {
+ RT.dict_instance[name].stack.push(0);
+ RT.dict_instance[name].empty.push(true);
+ pushed_name = name;
}
+ } else if (tag === 'rt·counter·step') {
+ const name = node.getAttribute('counter');
+ if (name && RT.dict_instance[name]) {
+ const state = RT.dict_instance[name];
+ const depth = state.stack.length - 1;
+
+ if (state.empty[depth]) {
+ state.stack[depth] = (depth === 0) ? state.on_first_step_int : 1;
+ state.empty[depth] = false;
+ } else {
+ state.stack[depth] += 1;
+ }
+
+ const formatted_stack = state.stack.map((val, index) =>
+ format_count(val, state.style, index)
+ );
+
+ let count_str = formatted_stack.join(state.separator);
+ if (state['separator-placement'] === 'embedded-after') {
+ count_str += state.separator;
+ }
+
+ state.count = count_str;
+ }
+ } else if (tag === 'rt·counter·snapshot') {
+ const counter_name = node.getAttribute('counter');
+ const snapshot_name = node.getAttribute('snapshot');
- state.count = count_str;
- }
- } else if (tag === 'RT·Counter·snapshot'.toLowerCase()) {
- const counter_name = node.getAttribute('counter');
- const snapshot_name = node.getAttribute('snapshot');
-
- if (counter_name && snapshot_name && window.RT.dict_instance[counter_name]) {
- const state = window.RT.dict_instance[counter_name];
- const depth = state.stack.length - 1;
-
- if (state.empty[depth]) {
- console.error(`RT-Style Layout Error: Attempted to snapshot an empty counter '${counter_name}' at snapshot '${snapshot_name}'. A person must use <RT·Counter·step> before taking a snapshot.`);
- } else {
- window.RT.dict_snapshot[snapshot_name] = clone_state(state);
+ if (counter_name && snapshot_name && RT.dict_instance[counter_name]) {
+ const state = RT.dict_instance[counter_name];
+ const depth = state.stack.length - 1;
+
+ if (state.empty[depth]) {
+ console.error(`RT-Style Layout Error: Attempted to snapshot an empty counter '${counter_name}' at snapshot '${snapshot_name}'. A person must use <RT·Counter·step> before taking a snapshot.`);
+ } else {
+ RT.dict_snapshot[snapshot_name] = clone_state(state);
+ }
}
}
- }
- let child = node.firstElementChild;
- while (child) {
- walk(child);
- child = child.nextElementSibling;
- }
+ let child = node.firstElementChild;
+ while (child) {
+ walk(child);
+ child = child.nextElementSibling;
+ }
- if (pushed_name) {
- window.RT.dict_instance[pushed_name].stack.pop();
- window.RT.dict_instance[pushed_name].empty.pop();
+ if (pushed_name) {
+ RT.dict_instance[pushed_name].stack.pop();
+ RT.dict_instance[pushed_name].empty.pop();
+ }
}
- }
- walk(root_node);
-};
-
-window.RT.Counter.do_snapshot = function (root_node) {
- return;
-};
-
-window.RT.Counter.read = function (root_node) {
- const reads = root_node.querySelectorAll('RT·Counter·read');
- for (let i = 0; i < reads.length; i++) {
- const snapshot_name = reads[i].getAttribute('snapshot');
- const key = reads[i].getAttribute('key') || 'count';
-
- if (snapshot_name && window.RT.dict_snapshot[snapshot_name]) {
- const value = window.RT.dict_snapshot[snapshot_name][key];
- reads[i].innerHTML = (value !== undefined) ? value : `[Missing key: ${key}]`;
- } else {
- reads[i].innerHTML = `[Unknown snapshot: ${snapshot_name}]`;
- console.error(`RT-Style Layout Error: <RT·Counter·read> failed. No snapshot named '${snapshot_name}' found in the dictionary.`);
+ walk(root_node);
+
+ const reads = root_node.querySelectorAll('RT·Counter·read');
+ for (let i = 0; i < reads.length; i++) {
+ const snapshot_name = reads[i].getAttribute('snapshot');
+ const key = reads[i].getAttribute('key') || 'count';
+
+ if (snapshot_name && RT.dict_snapshot[snapshot_name]) {
+ const value = RT.dict_snapshot[snapshot_name][key];
+ reads[i].innerHTML = (value !== undefined) ? value : `[Missing key: ${key}]`;
+ } else {
+ reads[i].innerHTML = `[Unknown snapshot: ${snapshot_name}]`;
+ console.error(`RT-Style Layout Error: <RT·Counter·read> failed. No snapshot named '${snapshot_name}' found in the dictionary.`);
+ }
}
- }
-};
+ });
+
+})();
-// developer/authored/RT/element/crossref.js
-window.RT = window.RT || {};
-
-window.RT.crossref = function(){
- document.querySelectorAll('rt·crossref').forEach( (el) => {
- el.style.color = window.RT.theme('read', 'brand', 'link');
- el.style.textDecoration = 'underline';
- el.style.cursor = 'pointer';
- el.style.fontWeight = '500';
+/*
+ Processes <rt·crossref> tags.
+ Applies default styling and interaction cues using the active RT theme.
+*/
+
+(function() {
+
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
+
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+ if (debug.log) debug.log('crossref', 'Processing cross-references');
+
+ document.querySelectorAll('rt·crossref').forEach( (el) => {
+ el.style.color = window.RT.theme('read', 'brand', 'link');
+ el.style.textDecoration = 'underline';
+ el.style.cursor = 'pointer';
+ el.style.fontWeight = '500';
+ });
});
-};
+})();
-window.RT = window.RT || {};
-
-window.RT.endnote = function(){
- const citations = document.querySelectorAll('rt·cite');
- if(citations.length === 0) return;
-
- const article = document.querySelector('rt·article');
- if(!article) return;
-
- // 1. Ensure the H1 is a direct child of the article so the TOC can see it
- let endnotesHeader = document.getElementById('endnotes-header');
- if (!endnotesHeader) {
- endnotesHeader = document.createElement('h1');
- endnotesHeader.id = 'endnotes-header';
- endnotesHeader.innerText = 'Endnotes';
- article.appendChild(endnotesHeader);
- }
+/*
+ Processes <rt·cite> tags and generates an <rt·endnotes> section.
+ Creates bidirectional links between inline citations and the generated endnotes list.
+*/
+
+(function() {
- // 2. Locate or generate the endnotes list container
- let endnoteContainer = document.querySelector('rt·endnotes');
- if(!endnoteContainer) {
- endnoteContainer = document.createElement('rt·endnotes');
- article.appendChild(endnoteContainer);
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
}
-
- // 3. Ensure the list structure exists
- if(!endnoteContainer.querySelector('ol')) {
- endnoteContainer.innerHTML = '<ol></ol>';
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
}
-
- const list = endnoteContainer.querySelector('ol');
- // Process each inline citation
- citations.forEach((cite, index) => {
- const refNum = index + 1;
- const refText = cite.getAttribute('ref') || cite.innerHTML;
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+ if (debug.log) debug.log('endnote', 'Processing endnotes');
+
+ const citations = document.querySelectorAll('rt·cite');
+ if(citations.length === 0) return;
+
+ const article = document.querySelector('rt·article');
+ if(!article) return;
+
+ // 1. Ensure the H1 is a direct child of the article so the TOC can see it
+ let endnotesHeader = document.getElementById('endnotes-header');
+ if (!endnotesHeader) {
+ endnotesHeader = document.createElement('h1');
+ endnotesHeader.id = 'endnotes-header';
+ endnotesHeader.innerText = 'Endnotes';
+ article.appendChild(endnotesHeader);
+ }
+
+ // 2. Locate or generate the endnotes list container
+ let endnoteContainer = document.querySelector('rt·endnotes');
+ if(!endnoteContainer) {
+ endnoteContainer = document.createElement('rt·endnotes');
+ article.appendChild(endnoteContainer);
+ }
- cite.innerHTML = `<a href="#note-${refNum}" id="cite-${refNum}">[${refNum}]</a>`;
- cite.style.cursor = 'pointer';
- cite.style.color = window.RT.theme('read', 'brand', 'link');
- cite.style.textDecoration = 'none';
-
- // Append the corresponding entry into the endnotes list
- const li = document.createElement('li');
- li.id = `note-${refNum}`;
- li.innerHTML = `${refText} <a href="#cite-${refNum}" style="text-decoration:none;">↩</a>`;
- list.appendChild(li);
+ // 3. Ensure the list structure exists
+ if(!endnoteContainer.querySelector('ol')) {
+ endnoteContainer.innerHTML = '<ol></ol>';
+ }
+
+ const list = endnoteContainer.querySelector('ol');
+
+ // Process each inline citation
+ citations.forEach((cite, index) => {
+ const refNum = index + 1;
+ const refText = cite.getAttribute('ref') || cite.innerHTML;
+
+ cite.innerHTML = `<a href="#note-${refNum}" id="cite-${refNum}">[${refNum}]</a>`;
+ cite.style.cursor = 'pointer';
+ cite.style.color = window.RT.theme('read', 'brand', 'link');
+ cite.style.textDecoration = 'none';
+
+ // Append the corresponding entry into the endnotes list
+ const li = document.createElement('li');
+ li.id = `note-${refNum}`;
+ li.innerHTML = `${refText} <a href="#cite-${refNum}" style="text-decoration:none;">↩</a>`;
+ list.appendChild(li);
+ });
+
+ // Style the container
+ endnoteContainer.style.display = 'block';
+ endnoteContainer.style.marginTop = '1rem';
+ endnoteContainer.style.borderTop = `1px solid ${window.RT.theme('read', 'surface', '3')}`;
+ endnoteContainer.style.paddingTop = '1rem';
});
-
- // Style the container
- endnoteContainer.style.display = 'block';
- endnoteContainer.style.marginTop = '1rem';
- endnoteContainer.style.borderTop = `1px solid ${window.RT.theme('read', 'surface', '3')}`;
- endnoteContainer.style.paddingTop = '1rem';
-};
+
+})();
/*
Processes <RT·math> tags.
- JavaScript: math()
- HTML Tag: <RT·math> (parsed as rt·math)
+ Prepares the content with appropriate MathJax delimiters and loads the MathJax library.
*/
-function math(){
- // querySelector treats 'rt·math' as case-insensitive for the tag
- document.querySelectorAll('rt·math').forEach(el => {
- if (el.textContent.startsWith('$')) return;
-
- const is_block = el.parentElement.tagName === 'DIV' ||
- el.textContent.includes('\n') ||
- el.parentElement.childNodes.length === 1;
-
- const delimiter = is_block ? '$$' : '$';
- el.style.display = is_block ? 'block' : 'inline';
- el.textContent = `${delimiter}${el.textContent.trim()}${delimiter}`;
- });
- // MathJax must find its config at window.MathJax
- window.MathJax = {
- tex: {
- inlineMath: [['$', '$']],
- displayMath: [['$$', '$$']]
- }
- };
+(function() {
+
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
+
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+ if (debug.log) debug.log('math', 'Processing math tags and loading MathJax');
+
+ // querySelector treats 'rt·math' as case-insensitive for the tag
+ document.querySelectorAll('rt·math').forEach(el => {
+ if (el.textContent.startsWith('$')) return;
- const script = document.createElement('script');
- script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
- script.async = true;
- document.head.appendChild(script);
-}
+ const is_block = el.parentElement.tagName === 'DIV' ||
+ el.textContent.includes('\n') ||
+ el.parentElement.childNodes.length === 1;
+
+ const delimiter = is_block ? '$$' : '$';
+ el.style.display = is_block ? 'block' : 'inline';
+ el.textContent = `${delimiter}${el.textContent.trim()}${delimiter}`;
+ });
+
+ // MathJax must find its config at window.MathJax
+ window.MathJax = window.MathJax || {
+ tex: {
+ inlineMath: [['$', '$']],
+ displayMath: [['$$', '$$']]
+ }
+ };
+
+ // Prevent multiple script injections if the element pipeline runs more than once
+ if (!document.querySelector('script[src*="mathjax@3"]')) {
+ const script = document.createElement('script');
+ script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
+ script.async = true;
+ document.head.appendChild(script);
+ }
+ });
-window.RT = window.RT || {};
-window.RT.math = math;
+})();
-// developer/authored/RT/element/symbol.js
-window.RT = window.RT || {};
-
-window.RT.symbol = function(){
- document.querySelectorAll('rt·symbol').forEach( (el) => {
- el.style.fontFamily = '"Courier New", Courier, monospace';
- el.style.fontWeight = '600';
- el.style.padding = '0 0.1em';
+/*
+ Processes <rt·symbol> tags.
+ Applies standard monospaced formatting to code symbols inline.
+*/
+
+(function() {
+
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
+
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+ if (debug.log) debug.log('symbol', 'Processing symbols');
+
+ document.querySelectorAll('rt·symbol').forEach( (el) => {
+ el.style.fontFamily = '"Courier New", Courier, monospace';
+ el.style.fontWeight = '600';
+ el.style.padding = '0 0.1em';
+ });
});
-};
+
+})();
- The "-em" variants (e.g., <RT·term-em>) are always styled.
- Automatically generates IDs for first occurrences for future indexing.
*/
+(function() {
-window.RT = window.RT || {};
-
-window.RT.term = function() {
- const RT = window.RT;
-
- const debug = RT.Debug || {
- log: function() {}
- ,warn: function() {}
- ,error: function() {}
- };
-
- const DEBUG_TOKEN_S = 'term';
-
- try {
- // Track seen terms so only the first occurrence is decorated
- const seen_terms_dpa = new Set();
-
- // Inside the apply_style function
- const apply_style = (el, is_neologism_b) => {
- el.style.fontStyle = 'italic';
- el.style.fontWeight = is_neologism_b ? '600' : '500';
- el.style.color = is_neologism_b
- ? window.RT.theme('read', 'brand', 'secondary')
- : window.RT.theme('read', 'brand', 'primary');
- el.style.paddingRight = '0.1em';
- el.style.display = 'inline';
- };
-
- const clear_style = (el) => {
- el.style.fontStyle = 'normal';
- el.style.color = 'inherit';
- el.style.fontWeight = 'inherit';
- el.style.paddingRight = '';
- el.style.display = '';
- };
-
- const selector_s = [
- 'rt·term'
- ,'rt·term-em'
- ,'rt·neologism'
- ,'rt·neologism-em'
- ].join(',');
-
- const tags_dpa = document.querySelectorAll(selector_s);
-
- debug.log(DEBUG_TOKEN_S, `Scanning ${tags_dpa.length} term tags`);
-
- tags_dpa.forEach(el => {
- const tag_name_s = el.tagName.toLowerCase();
- const is_neologism_b = tag_name_s.includes('neologism');
- const is_explicit_em_b = tag_name_s.endsWith('-em');
-
- const term_text_raw_s = (el.textContent || '').trim();
- if (!term_text_raw_s.length) {
- debug.warn(DEBUG_TOKEN_S, `Empty term tag encountered: <${tag_name_s}>`);
- return;
- }
-
- // Normalize text for uniqueness tracking
- const term_norm_s = term_text_raw_s.toLowerCase();
-
- // Slug for ID generation (simple + stable)
- const slug_s = term_norm_s.replace(/\s+/g, '-');
-
- const is_first_occurrence_b = !seen_terms_dpa.has(term_norm_s);
-
- if (is_explicit_em_b || is_first_occurrence_b) {
- apply_style(el, is_neologism_b);
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
- if (!is_explicit_em_b && is_first_occurrence_b) {
- seen_terms_dpa.add(term_norm_s);
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){}, warn: function(){}, error: function(){} };
+ const DEBUG_TOKEN_S = 'term';
+
+ try {
+ // Track seen terms so only the first occurrence is decorated
+ const seen_terms_dpa = new Set();
+
+ const apply_style = (el, is_neologism_b) => {
+ el.style.fontStyle = 'italic';
+ el.style.fontWeight = is_neologism_b ? '600' : '500';
+ el.style.color = is_neologism_b
+ ? window.RT.theme('read', 'brand', 'secondary')
+ : window.RT.theme('read', 'brand', 'primary');
+ el.style.paddingRight = '0.1em';
+ el.style.display = 'inline';
+ };
+
+ const clear_style = (el) => {
+ el.style.fontStyle = 'normal';
+ el.style.color = 'inherit';
+ el.style.fontWeight = 'inherit';
+ el.style.paddingRight = '';
+ el.style.display = '';
+ };
+
+ const selector_s = [
+ 'rt·term',
+ 'rt·term-em',
+ 'rt·neologism',
+ 'rt·neologism-em'
+ ].join(',');
+
+ const tags_dpa = document.querySelectorAll(selector_s);
+
+ debug.log(DEBUG_TOKEN_S, `Scanning ${tags_dpa.length} term tags`);
+
+ tags_dpa.forEach(el => {
+ const tag_name_s = el.tagName.toLowerCase();
+ const is_neologism_b = tag_name_s.includes('neologism');
+ const is_explicit_em_b = tag_name_s.endsWith('-em');
+
+ const term_text_raw_s = (el.textContent || '').trim();
+ if (!term_text_raw_s.length) {
+ debug.warn(DEBUG_TOKEN_S, `Empty term tag encountered: <${tag_name_s}>`);
+ return;
+ }
- if (!el.id) {
- el.id = `def-${is_neologism_b ? 'neo-' : ''}${slug_s}`;
+ // Normalize text for uniqueness tracking
+ const term_norm_s = term_text_raw_s.toLowerCase();
+
+ // Slug for ID generation (simple + stable)
+ const slug_s = term_norm_s.replace(/\s+/g, '-');
+
+ const is_first_occurrence_b = !seen_terms_dpa.has(term_norm_s);
+
+ if (is_explicit_em_b || is_first_occurrence_b) {
+ apply_style(el, is_neologism_b);
+
+ if (!is_explicit_em_b && is_first_occurrence_b) {
+ seen_terms_dpa.add(term_norm_s);
+
+ if (!el.id) {
+ el.id = `def-${is_neologism_b ? 'neo-' : ''}${slug_s}`;
+ debug.log(
+ DEBUG_TOKEN_S,
+ `First occurrence: "${term_norm_s}" -> id="${el.id}"`
+ );
+ } else {
+ debug.log(
+ DEBUG_TOKEN_S,
+ `First occurrence: "${term_norm_s}" (existing id="${el.id}")`
+ );
+ }
+ } else if (is_explicit_em_b) {
debug.log(
- DEBUG_TOKEN_S
- ,`First occurrence: "${term_norm_s}" -> id="${el.id}"`
- );
- } else {
- debug.log(
- DEBUG_TOKEN_S
- ,`First occurrence: "${term_norm_s}" (existing id="${el.id}")`
+ DEBUG_TOKEN_S,
+ `Emphasized occurrence: "${term_norm_s}" (<${tag_name_s}>)`
);
}
- } else if (is_explicit_em_b) {
- debug.log(
- DEBUG_TOKEN_S
- ,`Emphasized occurrence: "${term_norm_s}" (<${tag_name_s}>)`
- );
+ } else {
+ // Subsequent mentions render as normal prose
+ clear_style(el);
}
- } else {
- // Subsequent mentions render as normal prose
- clear_style(el);
- }
- });
-
- debug.log(DEBUG_TOKEN_S, `Unique terms defined: ${seen_terms_dpa.size}`);
- } catch (e) {
- debug.error('error', `term failed: ${e && e.message ? e.message : String(e)}`);
- }
-};
+ });
+
+ debug.log(DEBUG_TOKEN_S, `Unique terms defined: ${seen_terms_dpa.size}`);
+ } catch (e) {
+ debug.error('error', `term failed: ${e && e.message ? e.message : String(e)}`);
+ }
+ });
+
+})();
-// Element/theme_selector.js
-
-window.RT = window.RT || {};
-window.RT.Element = window.RT.Element || [];
-
-window.RT.Element.push(function build_theme_selector() {
- document.querySelectorAll('rt·theme-selector').forEach((el) => {
-
- const active_theme = window.RT.theme('read', 'meta', 'name');
- const available_themes = Object.keys(window.RT.theme_library || {});
-
- const container = document.createElement('div');
- container.style.position = 'fixed';
- container.style.top = '10px';
- container.style.right = '10px';
- container.style.zIndex = '1000';
- container.style.background = '#222';
- container.style.padding = '10px';
- container.style.border = '1px solid #555';
- container.style.color = 'white';
- container.style.fontFamily = 'sans-serif';
-
- let html_content = `<b>Theme Selection</b><br>`;
-
- if (available_themes.length === 0) {
- html_content += `<small>No themes found in library.</small>`;
- } else {
- available_themes.forEach(theme_name => {
- const is_checked = active_theme === theme_name ? 'checked' : '';
- html_content += `
- <label>
- <input type="radio" name="RT·theme" value="${theme_name}" ${is_checked}> ${theme_name}
- </label><br>
- `;
- });
- }
+/*
+ Processes <rt·theme-selector> tags.
+ Builds a floating UI for the user to switch active themes.
+*/
+
+(function() {
+
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
- container.innerHTML = html_content;
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+ if (debug.log) debug.log('theme_selector', 'Building theme selectors');
- container.addEventListener('change', (e) => {
- if(e.target.name === 'RT·theme') {
- localStorage.setItem('RT-Style·theme_preference', e.target.value);
- // Reloading applies the new preference via theme_preference() in the <head>
- location.reload();
+ document.querySelectorAll('rt·theme-selector').forEach((el) => {
+
+ const active_theme = window.RT.theme('read', 'meta', 'name');
+ const available_themes = Object.keys(window.RT.theme_library || {});
+
+ const container = document.createElement('div');
+ container.style.position = 'fixed';
+ container.style.top = '10px';
+ container.style.right = '10px';
+ container.style.zIndex = '1000';
+ container.style.background = '#222';
+ container.style.padding = '10px';
+ container.style.border = '1px solid #555';
+ container.style.color = 'white';
+ container.style.fontFamily = 'sans-serif';
+
+ let html_content = `<b>Theme Selection</b><br>`;
+
+ if (available_themes.length === 0) {
+ html_content += `<small>No themes found in library.</small>`;
+ } else {
+ available_themes.forEach(theme_name => {
+ const is_checked = active_theme === theme_name ? 'checked' : '';
+ html_content += `
+ <label>
+ <input type="radio" name="RT·theme" value="${theme_name}" ${is_checked}> ${theme_name}
+ </label><br>
+ `;
+ });
}
- });
- el.replaceWith(container);
+ container.innerHTML = html_content;
+
+ container.addEventListener('change', (e) => {
+ if(e.target.name === 'RT·theme') {
+ localStorage.setItem('RT-Style·theme_preference', e.target.value);
+ // Reloading applies the new preference via theme_preference() in the <head>
+ location.reload();
+ }
+ });
+
+ el.replaceWith(container);
+ });
});
-});
+
+})();
Usage:
<RT·title title="..." author="..." date="..." copyright="..."></RT·title>
*/
-window.RT = window.RT || {};
-window.RT.title = function() {
- const debug = window.RT.Debug || { log: function(){} };
-
- document.querySelectorAll('rt·title').forEach(el => {
- const title = el.getAttribute('title') || 'Untitled Document';
- const author = el.getAttribute('author');
- const date = el.getAttribute('date');
- const copyright = el.getAttribute('copyright');
+(function() {
+
+ if (!window.RT) {
+ console.error("RT not defined - was RT-Style_make run?");
+ return;
+ }
+ if (!window.RT.Element) {
+ console.error("RT.Element not defined - was the state_manager run?");
+ return;
+ }
- if (debug.log) debug.log('title', `Generating title block: ${title}`);
+ RT.Element.add( function() {
+ const debug = window.RT.Debug || { log: function(){} };
+
+ document.querySelectorAll('rt·title').forEach(el => {
+ const title = el.getAttribute('title') || 'Untitled Document';
+ const author = el.getAttribute('author');
+ const date = el.getAttribute('date');
+ const copyright = el.getAttribute('copyright');
- // Container
- const container = document.createElement('div');
- container.style.textAlign = 'center';
- container.style.marginBottom = '3rem';
- container.style.marginTop = '2rem';
- container.style.borderBottom = '1px solid var(--RT·border-default)';
- container.style.paddingBottom = '1.5rem';
+ if (debug.log) debug.log('title', `Generating title block: ${title}`);
- // Main Title (H1)
- const h1 = document.createElement('h1');
- h1.textContent = title;
- h1.style.margin = '0 0 0.8rem 0';
- h1.style.border = 'none'; // Override standard H1 border
- h1.style.padding = '0';
- h1.style.color = 'var(--RT·brand-primary)';
- h1.style.fontSize = '2.5em';
- h1.style.lineHeight = '1.1';
- h1.style.letterSpacing = '-0.03em';
+ // Container
+ const container = document.createElement('div');
+ container.style.textAlign = 'center';
+ container.style.marginBottom = '3rem';
+ container.style.marginTop = '2rem';
+ container.style.borderBottom = '1px solid var(--RT·border-default)';
+ container.style.paddingBottom = '1.5rem';
- container.appendChild(h1);
+ // Main Title (H1)
+ const h1 = document.createElement('h1');
+ h1.textContent = title;
+ h1.style.margin = '0 0 0.8rem 0';
+ h1.style.border = 'none'; // Override standard H1 border
+ h1.style.padding = '0';
+ h1.style.color = 'var(--RT·brand-primary)';
+ h1.style.fontSize = '2.5em';
+ h1.style.lineHeight = '1.1';
+ h1.style.letterSpacing = '-0.03em';
- // Metadata Row (Author | Date)
- if (author || date) {
- const meta = document.createElement('div');
- meta.style.color = 'var(--RT·content-muted)';
- meta.style.fontStyle = 'italic';
- meta.style.fontSize = '1.1em';
- meta.style.fontFamily = '"Georgia", "Times New Roman", serif'; // Classy serif
+ container.appendChild(h1);
- const parts = [];
- if (author) parts.push(`<span style="font-weight:600; color:var(--RT·brand-secondary)">${author}</span>`);
- if (date) parts.push(date);
+ // Metadata Row (Author | Date)
+ if (author || date) {
+ const meta = document.createElement('div');
+ meta.style.color = 'var(--RT·content-muted)';
+ meta.style.fontStyle = 'italic';
+ meta.style.fontSize = '1.1em';
+ meta.style.fontFamily = '"Georgia", "Times New Roman", serif'; // Classy serif
- meta.innerHTML = parts.join(' — ');
- container.appendChild(meta);
- }
+ const parts = [];
+ if (author) parts.push(`<span style="font-weight:600; color:var(--RT·brand-secondary)">${author}</span>`);
+ if (date) parts.push(date);
- // Copyright Row
- if (copyright) {
- const copy_div = document.createElement('div');
- copy_div.style.color = 'var(--RT·content-muted)';
- copy_div.style.fontSize = '0.9em';
- copy_div.style.marginTop = '0.5rem';
- // Automatically injects the copyright symbol
- copy_div.innerHTML = `© ${copyright}`;
- container.appendChild(copy_div);
- }
+ meta.innerHTML = parts.join(' — ');
+ container.appendChild(meta);
+ }
- // Replace the raw tag with the generated block
- el.replaceWith(container);
+ // Copyright Row
+ if (copyright) {
+ const copy_div = document.createElement('div');
+ copy_div.style.color = 'var(--RT·content-muted)';
+ copy_div.style.fontSize = '0.9em';
+ copy_div.style.marginTop = '0.5rem';
+ // Automatically injects the copyright symbol
+ copy_div.innerHTML = `© ${copyright}`;
+ container.appendChild(copy_div);
+ }
+
+ // Replace the raw tag with the generated block
+ el.replaceWith(container);
+ });
});
-};
+
+})();
'crossref'
];
- // Trigger file loading immediately
- required_elements.forEach(name => RT.load('Element/' + name));
-
// 2. The Extracted Styling Function
function apply_article_styles() {
const t = function(...path) { return window.RT.theme('read', ...path); };
element_styles.forEach(rule => apply(rule[0], rule[1]));
}
- // 3. The Core Layout Entry Function
- function article_tech_ref(){
-
- // Execute the extracted style generator first
- apply_article_styles();
+ //----------------------------------------
+ // stuff done when article_tech_ref is loaded
+ //
+
+ // load the element files
+ required_elements.forEach(name => RT.load('Element/' + name));
- // Dynamically enqueue the semantic processors
- required_elements.forEach(name => {
- if (typeof RT[name] === 'function') {
- RT.Element.push(RT[name]);
- } else {
- RT.Debug.warn('layout', 'Required element function missing: RT.' + name);
- }
- });
+ if (RT.Element) {
+ RT.Element.add(apply_article_styles);
+ } else {
+ console.error("RT.Element not defined, was the state_manager run?");
}
- // 4. Register the layout function immediately upon parsing
- RT.Element = RT.Element || [];
- RT.Element.push(article_tech_ref);
-
})();
--- /dev/null
+// Theme/inverse_wheat_DS.js
+
+window.RT = window.RT || {};
+window.RT.theme_library = window.RT.theme_library || {};
+
+window.RT.theme_library['inverse_wheat_DS'] = {
+ meta: {
+ is_dark: true,
+ name: "Inverse Wheat"
+ },
+ surface: {
+ 0: "oklch(0.157 0 0)",
+ 1: "oklch(0.198 0 0)",
+ 2: "oklch(0.221 0 0)",
+ 3: "oklch(0.240 0 0)",
+ input: "oklch(0.210 0 0)",
+ code: "oklch(0.204 0 0)",
+ select: "oklch(0.358 0.073 88)"
+ },
+ content: {
+ main: "oklch(0.927 0.050 97)",
+ muted: "oklch(0.699 0.030 78)",
+ subtle: "oklch(0.522 0.022 82)",
+ inverse: "oklch(0.157 0 0)"
+ },
+ brand: {
+ primary: "oklch(0.841 0.173 85)",
+ secondary: "oklch(0.827 0.135 78)",
+ tertiary: "oklch(0.795 0.081 66)",
+ link: "oklch(0.865 0.177 90)"
+ },
+ border: {
+ faint: "oklch(0.280 0.018 78)",
+ regular: "oklch(0.386 0.028 82)",
+ strong: "oklch(0.533 0.041 77)"
+ },
+ state: {
+ success: "oklch(0.671 0.168 137)",
+ warning: "oklch(0.767 0.159 68)",
+ error: "oklch(0.591 0.172 24)",
+ info: "oklch(0.661 0.078 232)"
+ },
+ syntax: {
+ keyword: "oklch(0.825 0.146 72)",
+ string: "oklch(0.804 0.132 122)",
+ func: "oklch(0.756 0.134 39)",
+ comment: "oklch(0.573 0.035 78)"
+ },
+ page: {
+ width: "6.5in",
+ min_height: "9in",
+ padding: "0.5in 1in",
+ margin: "20px auto",
+ bg_color: "oklch(0.95 0.02 90)",
+ border_color: "oklch(0.85 0.02 90)",
+ text_color: "oklch(0.20 0.02 25)",
+ shadow: "0 4px 15px rgba(0,0,0,0.1)"
+ },
+ custom_css: `
+ img.rt-diagram { filter: invert(1) hue-rotate(180deg); }
+ `
+};
(function() {
const themes = [
- 'inverse_wheat',
- 'golden_wheat',
- 'wheat'
+ 'inverse_wheat'
+ ,'inverse_wheat_DS'
+ ,'golden_wheat'
+ ,'wheat'
];
themes.forEach(theme_name => {