(function() {
- if (!window.RT) {
- console.error("RT not defined - was RT-Manuscript_make run?");
- return;
- }
- if (!window.RT.Element) {
- console.error("RT.Element not defined - was the state_manager run?");
- return;
- }
+ if (!window.RT) return;
+
+ const apply_style = function(a, config) {
+ a.style.textDecoration = 'none';
+ a.style.color = 'inherit';
+ a.style.display = 'block';
+
+ a.onmouseover = () => a.style.color = config.brand_primary || '#000';
+ a.onmouseout = () => a.style.color = 'inherit';
+ };
RT.Element.add( function() {
const debug = window.RT.Debug || { log: function(){} };
- const TOC_seq = document.querySelectorAll('rt·toc');
+ const config = window.RT.layout_config || {};
+ const TOC_seq = document.querySelectorAll('rt·toc, 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 (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}`);
- } 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;
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) {
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}`;
}
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
+ if (headings.length === 0) return;
- // Top-level list
const topList = document.createElement('ul');
topList.style.listStyle = 'none';
topList.style.paddingLeft = '0';
topList.style.marginBottom = '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.
+ const depth = item.level - start_level;
- // Ensure we have the correct nesting depth
while (listStack.length - 1 > depth) {
- // Pop until we are at the right depth
listStack.pop();
}
- // 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;
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';
li.style.marginTop = depth === 0 ? '1.25rem' : '0.25rem';
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';
+
+ apply_style(a, config);
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.
-*/
-
(function() {
+ if (!window.RT) return;
- if (!RT) {
- console.error("RT not defined – was RT-Manuscript_make run?");
- return;
- }
- if (!RT.Element) {
- console.error("RT.Element not defined – was the state_manager run?");
- return;
- }
-
- RT.Element.add( function() {
- const debug = RT.Debug || { log: function(){} };
-
- document.querySelectorAll('RT·chapter').forEach((el, index) => {
- if (debug.log) debug.log('chapter', `Processing chapter ${index + 1}`);
+ const apply_style = function(h1, config) {
+ // Styling can be inherited or explicitly enforced here.
+ // If you want chapters to have a distinct layout footprint, apply it.
+ h1.style.color = config.brand_primary;
+ };
+ RT.Element.add(function() {
+ const config = window.RT.layout_config || {};
+ document.querySelectorAll('RT·chapter').forEach((el) => {
const brk = document.createElement('RT·page-break');
const h1 = document.createElement('h1');
-
h1.innerHTML = el.innerHTML;
-
- if (el.className) {
- h1.className = el.className;
- }
+ 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);
- }
+ if (attr.name !== 'class') h1.setAttribute(attr.name, attr.value);
});
+ apply_style(h1, config);
el.parentNode.insertBefore(brk, el);
el.replaceWith(h1);
});
- })
-
+ });
})();
/*
- Processes <RT·code> tags.
- Uses the central config or CSS variables from the theme.
-
- Removes common indent from lines of code.
+ Element/code.js
+ Processes <RT·code> tags, enforcing alignment and typographic boundaries.
*/
-(function(){
-
- if (!RT) {
- console.error("RT not defined – was RT-Manuscript_make run?");
- return;
- }
- if (!RT.Element) {
- console.error("RT.Element not defined – was the state_manager run?");
- return;
- }
- RT.Element.add( function() {
- const RT = window.RT;
- const U = RT.Utility;
- const debug = RT.Debug;
-
- debug.log('code', 'Starting render cycle.');
+(function(){
+ if(!window.RT) return;
+
+ const apply_style = function(el ,is_block ,exact_px ,offset_px ,text_color ,overlay_color ,config){
+ el.style.fontFamily = "'Courier New', Courier, monospace";
+ el.style.backgroundColor = overlay_color;
+ el.style.color = text_color;
+
+ if(is_block){
+ el.style.display = 'block';
+ el.style.whiteSpace = 'pre';
+ el.style.fontSize = exact_px + 'px';
+ el.style.padding = '1.2rem';
+ el.style.margin = '1.5rem 0';
+ el.style.borderLeft = '4px solid ' + (config.brand_secondary || 'gold');
+ } else {
+ el.style.display = 'inline';
+ el.style.fontSize = exact_px + 'px';
+ el.style.padding = '0.1rem 0.35rem';
+ el.style.borderRadius = '3px';
+ el.style.verticalAlign = offset_px + 'px';
+ }
+ };
+
+ RT.Element.add(function(){
+ const U = window.RT.Utility;
+ const config = window.RT.layout_config || {};
const metrics = U.Font.measure_ink_ratio('monospace');
- document.querySelectorAll('rt·code').forEach((el) => {
- el.style.fontFamily = 'monospace';
+ const nodes = document.querySelectorAll('rt·code, RT·code');
- const computed = window.getComputedStyle(el);
- const accent = window.RT.theme('read', 'brand', 'secondary') || 'gold';
-
+ for(let i = 0; i < nodes.length; i++){
+ const el = nodes[i];
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 computed = window.getComputedStyle(el);
+ const is_text_light = U.Color.is_light(config.content_main);
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';
+ let exact_px = parseFloat(computed.fontSize) * metrics.ratio;
+ let offset_px = metrics.baseline_diff * (exact_px / 100);
- // --- Tag-Relative Auto-Dedent Logic ---
-
- // 1. Get Tag Indentation (The Anchor)
+ if(is_block){
+ exact_px *= 0.95;
let tagIndent = '';
const prevNode = el.previousSibling;
- if (prevNode && prevNode.nodeType === 3) {
+
+ if(prevNode && prevNode.nodeType === 3){
const prevText = prevNode.nodeValue;
const lastNewLineIndex = prevText.lastIndexOf('\n');
- if (lastNewLineIndex !== -1) {
+ if(lastNewLineIndex !== -1){
tagIndent = prevText.substring(lastNewLineIndex + 1);
- } else if (/^\s*$/.test(prevText)) {
+ } 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 = '';
- let commonIndent = null;
-
- if (contentLines.length > 0) {
- // Assume the first line sets the standard
+ if(contentLines.length > 0){
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
+ for(let k = 1; k < contentLines.length; k++){
+ const line = contentLines[k];
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
+ while(j < commonIndent.length && j < line.length && commonIndent[j] === line[j]) j++;
+ commonIndent = commonIndent.substring(0 ,j);
+ if(commonIndent.length === 0) break;
}
- } 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 = '';
-
- 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) {
- cleanedLines.pop();
- }
+ if(commonIndent.length > 0 && commonIndent.startsWith(tagIndent)){
+ const cleanedLines = rawLines.map(line => line.startsWith(commonIndent) ? line.replace(commonIndent ,'') : line);
+ 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');
} 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 {
- 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.');
- })
+
+ apply_style(el ,is_block ,exact_px ,offset_px ,text_color ,overlay ,config);
+ }
+ });
})();
/*
Element/endnote.js
Processes <RT·endnote> tags inline and dumps them when <RT·endnotes> is encountered.
- Creates bidirectional links between inline citations and the explicitly placed list.
*/
(function(){
- if(!window.RT){
- console.error("RT not defined");
- return;
- }
- if(!window.RT.Element){
- console.error("RT.Element not defined");
- return;
- }
+ if(!window.RT) return;
- function process_endnotes(){
- const debug = window.RT.Debug || { log: function(){} };
- if(debug.log){
- debug.log('endnote' ,'Processing endnotes sequentially');
- }
+ const apply_style = function(link, config) {
+ link.style.cursor = 'pointer';
+ link.style.color = config.brand_link || '#0056b3';
+ link.style.textDecoration = 'none';
+ };
- const article = document.querySelector('RT·article');
- if(!article){
- return;
- }
+ const apply_list_style = function(list_container, config) {
+ list_container.style.marginTop = '1rem';
+ list_container.style.borderTop = '1px solid ' + (config.surface_3 || '#ccc');
+ list_container.style.paddingTop = '1rem';
+ };
+
+ function process_endnotes(){
+ const config = window.RT.layout_config || {};
+ const article = document.querySelector('RT·article, rt·article, RT·memo, rt·memo');
+
+ if(!article) return;
- // Initialize the global EndNoteCounter at the top of the document
const initial_make = document.createElement('RT·counter·make');
- initial_make.setAttribute('counter' ,'EndNoteCounter');
- initial_make.setAttribute('style' ,'CountingNumber');
- initial_make.setAttribute('on-first-step' ,'0');
- article.insertBefore(initial_make ,article.firstChild);
+ initial_make.setAttribute('counter', 'EndNoteCounter');
+ initial_make.setAttribute('style', 'CountingNumber');
+ initial_make.setAttribute('on-first-step', '0');
+ article.insertBefore(initial_make, article.firstChild);
- // Fetch all tags in document order
- const nodes = document.querySelectorAll('RT·endnote, rt·endnote, RT·endnotes, rt·endnotes');
+ // Defensively targets both the standard RT namespace block and the unmigrated hyphen blocks.
+ const nodes = document.querySelectorAll('RT·endnote, rt·endnote, RT-endnote, rt-endnote, RT·endnotes, rt·endnotes, RT-endnotes, rt-endnotes');
let endnote_buffer = [];
let anchor_id_counter = 1;
const node = nodes[i];
const tag = node.tagName.toLowerCase();
- if(tag === 'rt·endnote'){
- // Restored original identifier format to match test expectations
+ if(tag === 'rt·endnote' || tag === 'rt-endnote'){
const snap_name = 'endnote_cite_' + anchor_id_counter;
const ref_text = node.innerHTML;
- // Build the inline replacement structure
const step = document.createElement('RT·counter·step');
- step.setAttribute('counter' ,'EndNoteCounter');
+ step.setAttribute('counter', 'EndNoteCounter');
const snapshot = document.createElement('RT·counter·snapshot');
- snapshot.setAttribute('counter' ,'EndNoteCounter');
- snapshot.setAttribute('snapshot' ,snap_name);
+ snapshot.setAttribute('counter', 'EndNoteCounter');
+ snapshot.setAttribute('snapshot', snap_name);
const link = document.createElement('a');
link.href = '#note_' + anchor_id_counter;
link.id = 'cite_' + anchor_id_counter;
link.innerHTML = '[<RT·counter·read snapshot="' + snap_name + '"></RT·counter·read>]';
- link.style.cursor = 'pointer';
- link.style.color = window.RT.theme ? window.RT.theme('read' ,'brand' ,'link') : '#0056b3';
- link.style.textDecoration = 'none';
+
+ apply_style(link, config);
step.appendChild(snapshot);
step.appendChild(link);
- node.parentNode.replaceChild(step ,node);
-
- endnote_buffer.push({
- id: anchor_id_counter
- ,text: ref_text
- ,snap: snap_name
- });
+ node.parentNode.replaceChild(step, node);
+ endnote_buffer.push({ id: anchor_id_counter, text: ref_text, snap: snap_name });
anchor_id_counter++;
- }
- else if(tag === 'rt·endnotes'){
+
+ } else if(tag === 'rt·endnotes' || tag === 'rt-endnotes'){
if(endnote_buffer.length === 0){
node.parentNode.removeChild(node);
continue;
const list_container = document.createElement('div');
list_container.className = 'RT_endnote_list';
- list_container.style.marginTop = '1rem';
- list_container.style.borderTop = '1px solid ' + (window.RT.theme ? window.RT.theme('read' ,'surface' ,'3') : '#ccc');
- list_container.style.paddingTop = '1rem';
+ apply_list_style(list_container, config);
for(let j = 0; j < endnote_buffer.length; j++){
const item = endnote_buffer[j];
wrapper.appendChild(list_container);
- // Inject a fresh counter make tag to zero out the counter for the next section
const counter_reset = document.createElement('RT·counter·make');
- counter_reset.setAttribute('counter' ,'EndNoteCounter');
- counter_reset.setAttribute('style' ,'CountingNumber');
- counter_reset.setAttribute('on-first-step' ,'0');
+ counter_reset.setAttribute('counter', 'EndNoteCounter');
+ counter_reset.setAttribute('style', 'CountingNumber');
+ counter_reset.setAttribute('on-first-step', '0');
wrapper.appendChild(counter_reset);
- node.parentNode.replaceChild(wrapper ,node);
+ node.parentNode.replaceChild(wrapper, node);
- // Clear the buffer for the next chapter
endnote_buffer = [];
}
}
}
- //----------------------------------------
- // Registration upon load
- //
-
window.RT.Element.add(process_endnotes);
})();
Currently built into the paginator
*/
+(function(){
+ if(!window.RT) return;
+ const apply_style = function(el, config) {};
+ // Footnote processing is structurally evaluated by the paginator.
+ // This closure exists strictly to validate the semantic footprint.
+ RT.Element.add(function() {
+ const config = window.RT.layout_config || {};
+ document.querySelectorAll('rt·footnote, RT·footnote').forEach(el => apply_style(el, config));
+ });
+})();
/*
Element/grid.js
- Compiles semantic tabular structures into a Cartesian GridState,
- then projects them using CSS Grid layout models.
+ Compiles semantic tabular structures into a Cartesian GridState.
*/
(function() {
+ if (!window.RT) return;
- if (!window.RT) {
- console.error("RT not defined - was RT-Manuscript_make run?");
- return;
- }
- if (!window.RT.Element) {
- console.error("RT.Element not defined - was the state_manager run?");
- return;
- }
-
- // 1. Internal Sparse Array Representation
class GridState {
constructor() {
this.cells = [];
}
insert(cell_data) {
- // cell_data: { element, type, x, y, x_extent, y_extent }
this.cells.push(cell_data);
if (cell_data.x_extent > this.max_x) this.max_x = cell_data.x_extent;
if (cell_data.y_extent > this.max_y) this.max_y = cell_data.y_extent;
}
}
-// 2. The Projection Dispatcher (Tier 2 -> Tier 3)
- function project_grid(container_node, grid_state, model, options = {}) {
- const debug = window.RT.Debug || { log: function(){}, error: function(){} };
+ const apply_style = function(el, cell, is_transposed, options, config) {
+ el.style.padding = '0.25rem 0.5rem';
+ el.style.margin = '0';
+ el.style.lineHeight = '1.3';
+
+ if (cell.type === 'x-label' || cell.type === 'y-label' || cell.type === 'name') {
+ el.style.fontWeight = '600';
+ }
+
+ if (cell.type === (is_transposed ? 'y-label' : 'x-label')) {
+ el.style.borderBottom = '2px solid ' + (config.border_strong || '#000');
+ }
+
+ if (cell.type === 'name') {
+ el.style.borderRight = '1px solid ' + (config.border_faint || '#ccc');
+ }
+
+ if (cell.type === 'data') el.style.textAlign = 'center';
+ if (cell.type === 'x-label') el.style.textAlign = 'center';
+
+ if (cell.type === (is_transposed ? 'x-label' : 'y-label') || cell.type === 'name') {
+ el.style.textAlign = 'right';
+ el.style.paddingRight = '0.5rem';
+ }
+ if (options && options.no_wrap) {
+ el.style.whiteSpace = 'nowrap';
+ el.style.padding = '0.15rem 0.5rem';
+ }
+ };
+
+ function project_grid(container_node, grid_state, model, options = {}) {
+ const config = window.RT.layout_config || {};
switch (model) {
case 'html-grid-direct':
- return render_model_html_standard(container_node, grid_state, options, false);
+ return render_model_html_standard(container_node, grid_state, options, false, config);
case 'html-grid-transpose':
- return render_model_html_standard(container_node, grid_state, options, true);
+ return render_model_html_standard(container_node, grid_state, options, true, config);
case 'html-grid-dictionary':
- return render_model_html_dictionary(container_node, grid_state, options);
- default:
- debug.error('Grid', `Unknown projection model requested: ${model}. Defaulting to direct.`);
- return render_model_html_standard(container_node, grid_state, options, false);
+ return render_model_html_dictionary(container_node, grid_state, options, config);
}
}
- // 2a. Standard & Transposed Cartesian Layout
- function render_model_html_standard(container_node, grid_state, options, is_transposed) {
- const debug = window.RT.Debug || { log: function(){}, error: function(){} };
+ function render_model_html_standard(container_node, grid_state, options, is_transposed, config) {
const wrapper = document.createElement('div');
wrapper.style.display = 'grid';
- // REMOVED: wrapper.style.gridAutoColumns = 'max-content';
wrapper.style.justifyContent = 'start';
wrapper.className = `RT_grid_container ${options.css_class || ''}`;
if (options.delimiters) {
- wrapper.style.borderLeft = '2px solid var(--RT·content-main)';
- wrapper.style.borderRight = '2px solid var(--RT·content-main)';
+ wrapper.style.borderLeft = '2px solid ' + (config.content_main || '#000');
+ wrapper.style.borderRight = '2px solid ' + (config.content_main || '#000');
wrapper.style.borderRadius = '5px';
wrapper.style.padding = '0.2rem';
wrapper.style.margin = '1rem 0';
el.style.gridRow = `${render_y + 1} / ${render_y_extent + 2}`;
el.className = `RT_grid_${cell.type}`;
- // Tightened baseline geometry & CSS collision defense
- el.style.padding = '0.25rem 0.5rem';
- el.style.margin = '0';
- el.style.lineHeight = '1.3';
-
- if (cell.type === 'x-label' || cell.type === 'y-label' || cell.type === 'name') {
- el.style.fontWeight = '600';
- }
-
- if (cell.type === (is_transposed ? 'y-label' : 'x-label')) {
- el.style.borderBottom = '2px solid var(--RT·border-strong)';
- }
-
- if (cell.type === 'name') {
- el.style.borderRight = '1px solid var(--RT·border-faint)';
- }
-
- if (cell.type === 'data') el.style.textAlign = 'center';
- if (cell.type === 'x-label') el.style.textAlign = 'center';
-
- if (cell.type === (is_transposed ? 'x-label' : 'y-label') || cell.type === 'name') {
- el.style.textAlign = 'right';
- el.style.paddingRight = '0.5rem';
- }
-
- if (options.no_wrap) {
- el.style.whiteSpace = 'nowrap';
- el.style.padding = '0.15rem 0.5rem';
- }
-
+ apply_style(el, cell, is_transposed, options, config);
wrapper.appendChild(el);
});
container_node.replaceWith(wrapper);
- execute_two_pass_measurement(wrapper, options, debug);
+ execute_two_pass_measurement(wrapper, options);
}
- // 2b. Typographic Dictionary Layout
- function render_model_html_dictionary(container_node, grid_state, options) {
- const debug = window.RT.Debug || { log: function(){}, error: function(){} };
+ function render_model_html_dictionary(container_node, grid_state, options, config) {
const wrapper = document.createElement('div');
wrapper.style.display = 'grid';
wrapper.style.gridAutoColumns = 'max-content';
el.style.gridRow = `${cell.y + 1} / ${cell.y_extent + 2}`;
el.className = `RT_grid_${cell.type}`;
- // Tightened baseline geometry & CSS collision defense
- el.style.padding = '0.25rem 0.75rem';
- el.style.margin = '0';
- el.style.lineHeight = '1.3';
-
- if (cell.type === 'x-label' || cell.type === 'y-label' || cell.type === 'name') {
- el.style.fontWeight = '600';
- }
-
- if (cell.type === 'x-label') {
- el.style.borderBottom = '2px solid var(--RT·border-strong)';
- }
-
- if (cell.type === 'name') {
- el.style.borderRight = '1px solid var(--RT·border-faint)';
- el.style.textAlign = 'right';
- }
-
- if (cell.type === 'data') {
- el.style.textAlign = 'left';
- }
-
- if (options.no_wrap) {
- el.style.whiteSpace = 'nowrap';
- }
+ apply_style(el, cell, false, options, config);
+ if (cell.type === 'data') el.style.textAlign = 'left';
wrapper.appendChild(el);
});
container_node.replaceWith(wrapper);
- execute_two_pass_measurement(wrapper, options, debug);
+ execute_two_pass_measurement(wrapper, options);
}
- // 2c. Common Measurement Logic
- function execute_two_pass_measurement(wrapper, options, debug) {
+ function execute_two_pass_measurement(wrapper, options) {
requestAnimationFrame(() => {
if (options.wrap_check) {
const data_cells = wrapper.querySelectorAll('.RT_grid_data, .RT_grid_name');
data_cells.forEach(cell => {
const computed = window.getComputedStyle(cell);
const line_height = parseFloat(computed.lineHeight) || (parseFloat(computed.fontSize) * 1.2);
-
const pTop = parseFloat(computed.paddingTop) || 0;
const pBot = parseFloat(computed.paddingBottom) || 0;
const content_height = cell.scrollHeight - pTop - pBot;
}
});
}
-
- if (wrapper.scrollWidth > wrapper.parentElement.clientWidth) {
- debug.error('Grid', 'Structural bounds exceeded: Grid width extends beyond viewport limits.');
- }
});
}
- // 3. Coordinate Arithmetic Parser
function parse_coordinate(attr_value, current_val) {
if (!attr_value) return { start: current_val, extent: current_val };
const parts = attr_value.split('-');
return { start, extent };
}
- // 4. The Semantic Dispatchers
RT.Element.add(function process_grids() {
- const debug = window.RT.Debug || { log: function(){} };
-
- // --- A. Native Grid Parser ---
document.querySelectorAll('RT·grid, rt·grid').forEach(node => {
const state = new GridState();
const model = node.getAttribute('model') || 'html-grid-direct';
const attr_x = e.getAttribute('x');
const attr_y = e.getAttribute('y');
- // Carriage return logic with state-aware redundancy check
if (major_axis === 'x') {
if (attr_y && !attr_x && attr_y !== String(cursor_y)) cursor_x = 0;
} else {
project_grid(node, state, model, { wrap_check: true });
});
- // --- B. Dictionary Parser ---
document.querySelectorAll('RT·dictionary, rt·dictionary').forEach(node => {
const state = new GridState();
const key_label = node.getAttribute('key');
project_grid(node, state, 'html-grid-dictionary', { wrap_check: true });
});
- // --- C. Relation Parser ---
document.querySelectorAll('RT·relation, rt·relation').forEach(node => {
const state = new GridState();
const layout_intent = node.getAttribute('layout-intention') || 'row-tuple';
project_grid(node, state, model, { wrap_check: true });
});
- // --- D. Matrix Parser ---
document.querySelectorAll('RT·matrix, rt·matrix').forEach(node => {
const state = new GridState();
const layout_intent = node.getAttribute('layout-intention') || 'row-vector';
project_grid(node, state, model, { wrap_check: false, no_wrap: true, delimiters: true });
});
-
});
})();
*/
(function(){
+ if(!window.RT) return;
- if(!window.RT){
- console.error("RT not defined. Was RT Manuscript make run?");
- return;
- }
- if(!window.RT.Element){
- console.error("RT.Element not defined. Was the stage manager run?");
- return;
- }
-
- window.MathJax = window.MathJax || {};
-
- window.MathJax.startup = {
- typeset: false
- };
-
- window.MathJax.options = {
- // Disable the screen-reader block to prevent duplicate text rendering
- enableAssistiveMml: false
- };
-
- window.MathJax.svg = {
- // Force paths to draw directly instead of referencing a global cache
- fontCache: 'none'
+ const apply_style = function(el, is_block, config) {
+ el.style.display = is_block ? 'block' : 'inline';
};
const scan_tags = function(){
- const debug = window.RT.Debug || { log: function(){} };
- if(debug.log) debug.log('math' ,'Processing math tags directly');
-
+ const config = window.RT.layout_config || {};
const math_elements = Array.from(document.querySelectorAll('RT·math'));
if(math_elements.length === 0) return;
- if(!window.MathJax || typeof window.MathJax.tex2svg !== 'function'){
- console.error("MathJax not loaded or synchronous tex2svg unavailable.");
- return;
- }
+ if(!window.MathJax || typeof window.MathJax.tex2svg !== 'function') return;
math_elements.forEach(el => {
const is_block = el.parentElement.tagName === 'DIV' ||
el.textContent.includes('\n') ||
el.parentElement.childNodes.length === 1;
- el.style.display = is_block ? 'block' : 'inline';
+ apply_style(el, is_block, config);
const raw_math = el.textContent;
- const svg_node = window.MathJax.tex2svg(raw_math ,{display: is_block});
+ const svg_node = window.MathJax.tex2svg(raw_math, {display: is_block});
- // Safety net: Strip the block manually if the config fails to catch it
const assistive = svg_node.querySelector('mjx-assistive-mml');
if(assistive) assistive.remove();
el.innerHTML = '';
el.appendChild(svg_node);
});
-
};
RT.load('Math/mathjax_svg');
RT.Element.add(scan_tags);
-
})();
/*
+ Element/term.js
Processes <RT·term> and <RT·neologism> tags.
- - Styles only the first occurrence of a unique term/neologism.
- - The "-em" variants (e.g., <RT·term-em>) are always styled.
- - Automatically generates IDs for first occurrences for future indexing.
*/
-(function() {
- if (!window.RT) {
- console.error("RT not defined - was RT-Manuscript_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(){}, 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;
- }
-
- // 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,
- `Emphasized occurrence: "${term_norm_s}" (<${tag_name_s}>)`
- );
+(function(){
+
+ if(!window.RT) return;
+
+ const apply_style = function(el ,is_neologism ,is_first ,config){
+ if(is_first){
+ el.style.fontStyle = 'italic';
+ el.style.fontWeight = is_neologism ? '600' : '500';
+ el.style.color = is_neologism ? config.brand_secondary : config.brand_primary;
+ el.style.paddingRight = '0.1em';
+ el.style.display = 'inline';
+ } else {
+ el.style.fontStyle = 'normal';
+ el.style.color = 'inherit';
+ el.style.fontWeight = 'inherit';
+ el.style.paddingRight = '';
+ el.style.display = '';
+ }
+ };
+
+ RT.Element.add(function(){
+ const config = window.RT.layout_config || {};
+ const seen_terms_dpa = new Set();
+ const selector_s = 'rt·term, rt·term-em, rt·neologism, rt·neologism-em';
+ const tags_dpa = document.querySelectorAll(selector_s);
+
+ for(let i = 0; i < tags_dpa.length; i++){
+ const el = tags_dpa[i];
+ 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) continue;
+
+ const term_norm_s = term_text_raw_s.toLowerCase();
+ 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 ,true ,config);
+
+ 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}`;
}
- } 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)}`);
+ } else {
+ apply_style(el ,is_neologism_b ,false ,config);
+ }
}
});
})();
+
/*
- Processes <RT·title> tags.
- Generates a standard document header block.
-
- Usage:
- <RT·title title="..." author="..." date="..." copyright="..."></RT·title>
+ Element/title.js
+ Processes <RT·title> tags and isolates internal styling logic.
*/
-(function() {
+(function(){
- if (!window.RT) {
- console.error("RT not defined - was RT-Manuscript_make run?");
- return;
- }
- if (!window.RT.Element) {
- console.error("RT.Element not defined - was the state_manager run?");
- return;
- }
+ if(!window.RT) return;
- RT.Element.add( function() {
- const debug = window.RT.Debug || { log: function(){} };
+ const apply_style = function(container ,h1 ,meta ,copy_div ,config){
+ container.style.textAlign = 'center';
+ container.style.marginBottom = '3rem';
+ container.style.marginTop = '2rem';
+ container.style.borderBottom = '1px solid ' + config.border_default;
+ container.style.paddingBottom = '1.5rem';
+
+ h1.style.margin = '0 0 0.8rem 0';
+ h1.style.border = 'none';
+ h1.style.padding = '0';
+ h1.style.color = config.brand_primary;
+ h1.style.fontSize = '2.5em';
+ h1.style.lineHeight = '1.1';
+ h1.style.letterSpacing = '-0.03em';
+
+ if(meta){
+ meta.style.color = config.content_muted;
+ meta.style.fontStyle = 'italic';
+ meta.style.fontSize = '1.1em';
+ meta.style.fontFamily = '"Georgia", "Times New Roman", serif';
+ }
+
+ if(copy_div){
+ copy_div.style.color = config.content_muted;
+ copy_div.style.fontSize = '0.9em';
+ copy_div.style.marginTop = '0.5rem';
+ }
+ };
+
+ RT.Element.add(function(){
+ const config = window.RT.layout_config || {};
+ const nodes = document.querySelectorAll('rt·title, RT·title');
- document.querySelectorAll('rt·title').forEach(el => {
+ for(let i = 0; i < nodes.length; i++){
+ const el = nodes[i];
const title = el.getAttribute('title') || 'Untitled Document';
const author = el.getAttribute('author');
const date = el.getAttribute('date');
const copyright = el.getAttribute('copyright');
- if (debug.log) debug.log('title', `Generating title block: ${title}`);
-
- // 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';
-
- // 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.appendChild(h1);
- // 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
-
+ let meta = null;
+ if(author || date){
+ meta = document.createElement('div');
const parts = [];
- if (author) parts.push(`<span style="font-weight:600; color:var(--RT·brand-secondary)">${author}</span>`);
- if (date) parts.push(date);
-
+ if(author) parts.push(`<span style="font-weight:600; color:${config.brand_secondary}">${author}</span>`);
+ if(date) parts.push(date);
meta.innerHTML = parts.join(' — ');
container.appendChild(meta);
}
- // 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
+ let copy_div = null;
+ if(copyright){
+ copy_div = document.createElement('div');
copy_div.innerHTML = `© ${copyright}`;
container.appendChild(copy_div);
}
- // Replace the raw tag with the generated block
+ apply_style(container ,h1 ,meta ,copy_div ,config);
el.replaceWith(container);
- });
+ }
});
})();
/*
Layout/article_tech_ref.js
- Applies base technical document styling in Phase 1,
- and applies structural page wrappers in Phase 3.
+ Compiles the layout configuration dictionary and establishes the macro-environmental boundaries.
*/
(function(){
- if (!window.RT) {
- console.error("RT not defined - was RT-Manuscript_make run?");
- return;
- }
+ if(!window.RT) return;
+
+ window.RT.layout_config = {};
- // 1. The Explicit Element Roster
const required_elements = [
'chapter'
,'code'
,'TOC'
];
- // Shared utility functions
- const t = function(...path) { return window.RT.theme('read', ...path); };
-
- const apply = function(selector, rules) {
- document.querySelectorAll(selector).forEach(el => {
- for (let p in rules) {
- if (typeof rules[p] === 'string' && rules[p].includes('!important')) {
- el.style.setProperty(p.replace(/[A-Z]/g, m => "-" + m.toLowerCase()), rules[p].replace(' !important', ''), 'important');
- } else {
- el.style[p] = rules[p];
- }
- }
- });
- };
-
- // =========================================================
- // Phase 1: Base Element & Article Styling
- // =========================================================
- function apply_base_styles() {
- const surface_0 = t('surface', '0');
- const surface_code = t('surface', 'code');
- const content_main = t('content', 'main');
- const brand_primary = t('brand', 'primary');
- const brand_secondary = t('brand', 'secondary');
- const brand_tertiary = t('brand', 'tertiary');
- const is_dark = t('meta', 'is_dark');
-
- const font_weight = is_dark === false ? "600" : "400";
-
- // Apply base geometry
- apply('body, html, RT·article', { overflowAnchor: "none !important" });
- apply('RT·article', {
- display: "block",
- fontFamily: "'Noto Sans JP', Arial, sans-serif",
- fontSize: "16px",
- lineHeight: "1.4",
- fontWeight: font_weight,
- maxWidth: "46.875rem !important",
- margin: "0 auto",
- backgroundColor: surface_0,
- color: content_main,
- boxSizing: "border-box !important"
- });
-
- // Default padding if pagination fails or is bypassed
- apply('RT·article:not(:has(RT·page))', { padding: "3rem !important" });
-
- // Apply specific element scales
- const element_styles = [
- [ 'RT·article h1', {
- fontSize: "1.5rem",
- textAlign: "center",
- color: brand_primary,
- fontWeight: "500",
- marginTop: "1.5rem",
- lineHeight: "1.15"
- }],
-
- [ 'RT·article h2', {
- fontSize: "1.25rem",
- color: brand_secondary,
- textAlign: "left",
- marginTop: "2rem",
- marginLeft: "0"
- }],
-
- [ 'RT·article h3', {
- fontSize: "1.125rem",
- color: brand_tertiary,
- textAlign: "left",
- marginTop: "1.5rem",
- marginLeft: "4ch"
- }],
-
- [ 'RT·article h4', {
- fontSize: "1.05rem",
- color: content_main,
- fontWeight: "600",
- textAlign: "left",
- marginTop: "1.25rem",
- marginLeft: "8ch"
- }],
-
- [ 'RT·article p, RT·article ul, RT·article ol', {
- color: content_main,
- textAlign: "justify",
- marginBottom: "1rem",
- marginLeft: "0"
- }],
-
- [ 'RT·article li', {
- marginBottom: "0.5rem"
- }],
-
- [ 'RT·article RT·code', {
- fontFamily: "'Courier New', Courier, monospace",
- backgroundColor: surface_code,
- padding: "0.125rem 0.25rem",
- color: content_main
- }],
-
- [ 'RT·article img', {
- maxWidth: "100%",
- height: "auto",
- display: "block",
- margin: "1.5rem auto"
- }],
-
- [ 'RT·article table', {
- width: "100%",
- borderCollapse: "collapse",
- marginBottom: "1.5rem"
- }],
-
- [ 'RT·article th, RT·article td', {
- verticalAlign: "top",
- padding: "0.75rem 1rem 0.75rem 0",
- textAlign: "left"
- }]
-
- ];
-
- element_styles.forEach(rule => apply(rule[0], rule[1]));
+ const t = function(...path){ return window.RT.theme('read' ,...path); };
+
+ function compile_configuration(){
+ window.RT.layout_config = {
+ surface_0: t('surface' ,'0')
+ ,surface_code: t('surface' ,'code')
+ ,content_main: t('content' ,'main')
+ ,brand_primary: t('brand' ,'primary')
+ ,brand_secondary: t('brand' ,'secondary')
+ ,brand_tertiary: t('brand' ,'tertiary')
+ ,border_default: t('border' ,'regular')
+ ,content_muted: t('content' ,'muted')
+ ,is_dark: t('meta' ,'is_dark')
+ ,font_weight: t('meta' ,'is_dark') === false ? "600" : "400"
+ ,font_family: "'Noto Sans JP', Arial, sans-serif"
+ ,brand_link: t('brand', 'link') || '#0056b3'
+ ,surface_3: t('surface', '3') || '#ccc'
+ ,border_strong: t('border', 'strong')
+ ,border_faint: t('border', 'faint')
+ };
}
- // =========================================================
- // Phase 3: Post-Pagination Styling
- // =========================================================
- function apply_page_styles() {
- const surface_0 = t('surface', '0');
- const brand_primary = t('brand', 'primary');
+ // Execute immediately
+ compile_configuration();
- // Strip internal padding so the pages can dictate the margin/padding layout
- apply('RT·article:has(RT·page)', { padding: "0 !important" });
+ function apply_macro_boundaries(){
+ const conf = window.RT.layout_config;
+ const article_seq = document.querySelectorAll('RT·article');
- // Style the actual page wrappers
- apply('RT·article RT·page', {
- position: "relative",
- display: "block",
- padding: "3rem",
- margin: "1.25rem auto",
- backgroundColor: surface_0,
- boxShadow: `0 0 0.625rem ${brand_primary}`
- });
+ for(let i = 0; i < article_seq.length; i++){
+ let style = article_seq[i].style;
+ style.display = "block";
+ style.fontFamily = conf.font_family;
+ style.fontSize = "16px";
+ style.lineHeight = "1.4";
+ style.fontWeight = conf.font_weight;
+ style.maxWidth = "46.875rem";
+ style.margin = "0 auto";
+ style.backgroundColor = conf.surface_0;
+ style.color = conf.content_main;
+ style.boxSizing = "border-box";
+
+ if(!article_seq[i].querySelector('RT·page')){
+ style.padding = "3rem";
+ } else {
+ style.padding = "0";
+ }
+ }
+
+ required_elements.forEach(name => RT.load('Element/' + name));
+
+ if(RT.Element && RT.PageStyle){
+ RT.Element.add(compile_configuration); // Re-evaluate on render pass
+ RT.Element.add(apply_macro_boundaries);
+ RT.PageStyle.add(apply_macro_boundaries);
+ }
+
+ const page_seq = document.querySelectorAll('RT·article RT·page');
+ for(let i = 0; i < page_seq.length; i++){
+ let p_style = page_seq[i].style;
+ p_style.position = "relative";
+ p_style.display = "block";
+ p_style.padding = "3rem";
+ p_style.margin = "1.25rem auto";
+ p_style.backgroundColor = conf.surface_0;
+ p_style.boxShadow = "0 0 0.625rem " + conf.brand_primary;
+ }
}
- //----------------------------------------
- // Registration upon load
- //
-
- // Load the element files
required_elements.forEach(name => RT.load('Element/' + name));
- if (RT.Element && RT.PageStyle) {
- RT.Element.add(apply_base_styles);
- RT.PageStyle.add(apply_page_styles);
- } else {
- console.error("RT.Element or RT.PageStyle not defined, was the stage_manager run?");
+ if(RT.Element && RT.PageStyle){
+ RT.Element.add(compile_configuration);
+ RT.Element.add(apply_macro_boundaries);
+ RT.PageStyle.add(apply_macro_boundaries);
}
})();
-echo "RT-style 2026-07-01 10:36:21 Z"
+echo "RT-style v5.0 2026-08-03 09:28:23 Z"
echo "Harmony v3.3 2026-06-21 13:20:18 Z"