/*
Element/section.js
- Processes <RT·section> tags.
- Applies counting hierarchical numbering, conditional alignment/indents,
- subdued dark red borders for top-level elements, and universal page breaks for chapters.
+ Expands <RT·section> macros into <RT·counter·step> primitives.
*/
-(function() {
+(function(){
- if (!window.RT) return;
+ if(!window.RT) return;
- const apply_style = function(title_node ,depth ,config) {
+ const apply_style = function(title_node ,depth ,config){
const base_size = 2.25;
const size = Math.max(1.1 ,base_size - (depth * 0.35));
const fade_opacity = Math.max(0.5 ,1 - (depth * 0.2));
- if (depth === 0) {
+ if(depth === 0){
title_node.style.textAlign = 'center';
title_node.style.paddingLeft = '0';
- // Firebrick provides sufficient chroma contrast against dark backgrounds
title_node.style.borderBottom = '2px solid #B22222';
title_node.style.paddingBottom = '0.5rem';
- } else {
+ }else{
title_node.style.textAlign = 'left';
title_node.style.paddingLeft = (depth * 1.5) + 'rem';
}
title_node.style.lineHeight = '1.2';
};
- RT.Element.add(function() {
+ RT.Element.add(function(){
const debug = window.RT.Debug || { log: function(){} };
- if (debug.log) debug.log('section' ,'Processing scoped sections with counting numbering');
+ if(debug.log) debug.log('section' ,'Expanding section macros');
const config = window.RT.layout_config || {};
const section_seq = document.querySelectorAll('RT·section, rt·section');
- if (section_seq.length === 0) return;
+ if(section_seq.length === 0) return;
const article = document.querySelector('RT·article, rt·article, RT·memo, rt·memo');
- if (article && !document.querySelector('rt·counter·make[counter="RT_section"]')) {
- const make = document.createElement('rt·counter·make');
+ if(article && !document.querySelector('RT·counter·make[counter="RT_section"], rt·counter·make[counter="RT_section"]')){
+ const make = document.createElement('RT·counter·make');
make.setAttribute('counter' ,'RT_section');
- // Utilizing CountingNumber to output 1.1.1 rather than 0.0.0
make.setAttribute('style' ,'CountingNumber');
make.setAttribute('mode' ,'scoped');
make.setAttribute('on-first-step' ,'0');
let section_idx = 0;
section_seq.forEach(section => {
- section.style.display = 'block';
-
let depth = 0;
let curr = section.parentElement;
- while (curr) {
- if (curr.tagName && curr.tagName.toLowerCase() === 'rt·section') {
+ while(curr){
+ const tag = (curr.tagName || '').toLowerCase();
+ if(tag === 'rt·section' || (tag === 'rt·counter·step' && curr.getAttribute('counter') === 'RT_section')){
depth++;
}
curr = curr.parentElement;
}
- // Force ALL top-level sections to start on a new page
- if (depth === 0) {
- if (!section.previousElementSibling?.tagName?.toLowerCase().includes('page-break')) {
- const pb = document.createElement('rt·page-break');
- section.parentNode.insertBefore(pb, section);
+ if(depth === 0){
+ if(!section.previousElementSibling?.tagName?.toLowerCase().includes('page-break')){
+ const pb = document.createElement('RT·page-break');
+ section.parentNode.insertBefore(pb ,section);
}
}
- const names = [];
- const children = Array.from(section.children);
- children.forEach(child => {
- if (child.tagName && child.tagName.toLowerCase() === 'rt·name') {
- names.push(child.innerHTML.trim());
- child.remove();
- }
- });
-
- const title_text = names.length > 0 ? names.join('<br>') : '•';
-
- const step = document.createElement('rt·counter·step');
+ const snap_id = section.id || ('section_snap_' + section_idx++);
+
+ const step = document.createElement('RT·counter·step');
step.setAttribute('counter' ,'RT_section');
+ step.setAttribute('splitable' ,'true');
+ step.id = snap_id;
- while (section.firstChild) {
- step.appendChild(section.firstChild);
- }
-
- const snap_id = 'section_snap_' + section_idx++;
- const snap = document.createElement('rt·counter·snapshot');
+ const snap = document.createElement('RT·counter·snapshot');
snap.setAttribute('counter' ,'RT_section');
snap.setAttribute('snapshot' ,snap_id);
+ step.appendChild(snap);
const title_node = document.createElement('div');
title_node.className = 'RT·section-title';
- if (!section.id) section.id = snap_id;
- const read = document.createElement('rt·counter·read');
- read.setAttribute('snapshot' ,snap_id);
-
+ const read_count = document.createElement('RT·counter·read');
+ read_count.setAttribute('snapshot' ,snap_id);
+
const title_content = document.createElement('span');
title_content.style.marginLeft = '0.75rem';
- title_content.innerHTML = title_text;
+
+ const read_name = document.createElement('RT·counter·read');
+ read_name.setAttribute('snapshot' ,snap_id);
+ read_name.setAttribute('key' ,'name');
+ title_content.appendChild(read_name);
- title_node.appendChild(read);
+ title_node.appendChild(read_count);
title_node.appendChild(title_content);
apply_style(title_node ,depth ,config);
+ step.appendChild(title_node);
- step.insertBefore(title_node ,step.firstChild);
- step.insertBefore(snap ,step.firstChild);
+ while(section.firstChild){
+ const child = section.firstChild;
+ if((child.tagName || '').toLowerCase() === 'rt·name'){
+ child.style.display = 'none';
+ }
+ step.appendChild(child);
+ }
- section.appendChild(step);
+ section.parentNode.replaceChild(step ,section);
});
});
(function(){
if(!window.RT){
- console.error("RT not defined - was RT-Style_make run?");
+ console.error("RT not defined. Was RT-Manuscript_make run?");
return;
}
const page_conf = (RT.config && RT.config.page) ? RT.config.page : {};
const page_height_limit = page_conf.height_limit || 1000;
- let measureContainer = null;
+ let measure_container = null;
- // =========================================================
// 1. DOM Measurement Utilities
- // =========================================================
- function getElHeight(el){
- const wasInDOM = el.parentNode !== null;
- if(!wasInDOM) document.body.appendChild(el);
+ function get_el_height(el){
+ const was_in_DOM = el.parentNode !== null;
+ if(!was_in_DOM) document.body.appendChild(el);
const rect = el.getBoundingClientRect();
const style = window.getComputedStyle(el);
const margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom);
- if(!wasInDOM) el.remove();
+ if(!was_in_DOM) el.remove();
return (rect.height || 0) + (margin || 0);
}
- function getMeasureContainer(){
- if(measureContainer && measureContainer.parentNode) return measureContainer;
- const article = document.querySelector('RT·article');
+ function get_measure_container(){
+ if(measure_container && measure_container.parentNode) return measure_container;
+ const article = document.querySelector('RT·article, rt·article');
if(!article){
const temp = document.createElement('div');
temp.style.visibility = 'hidden';
temp.style.position = 'absolute';
temp.style.width = '100%';
document.body.appendChild(temp);
- measureContainer = temp;
+ measure_container = temp;
return temp;
}
const container = document.createElement('div');
- const articleStyle = window.getComputedStyle(article);
+ const article_style = window.getComputedStyle(article);
container.style.visibility = 'hidden';
container.style.position = 'absolute';
- container.style.width = articleStyle.width;
- container.style.fontFamily = articleStyle.fontFamily;
- container.style.fontSize = articleStyle.fontSize;
- container.style.lineHeight = articleStyle.lineHeight;
- container.style.fontWeight = articleStyle.fontWeight;
+ container.style.width = article_style.width;
+ container.style.fontFamily = article_style.fontFamily;
+ container.style.fontSize = article_style.fontSize;
+ container.style.lineHeight = article_style.lineHeight;
+ container.style.fontWeight = article_style.fontWeight;
document.body.appendChild(container);
- measureContainer = container;
+ measure_container = container;
return container;
}
- function measureFragment(frag){
- const container = getMeasureContainer();
+ function measure_fragment(frag){
+ const container = get_measure_container();
container.appendChild(frag);
- const h = getElHeight(frag);
+ const h = get_el_height(frag);
container.removeChild(frag);
return h;
}
- // =========================================================
// Splitting Logic
- // =========================================================
- function isSplittable(el){
+ function is_splittable(el){
+ if(!el || el.nodeType !== Node.ELEMENT_NODE) return null;
- // Component Dictionary Execution
- const componentId = el.getAttribute('data-rt-component');
- if (componentId && window.RT.Component && window.RT.Component[componentId] && window.RT.Component[componentId].split) {
- return (remaining) => window.RT.Component[componentId].split(el, remaining, measureFragment);
+ const component_id = el.getAttribute('data-rt-component');
+ if(component_id && window.RT.Component && window.RT.Component[component_id] && window.RT.Component[component_id].split){
+ return (remaining) => window.RT.Component[component_id].split(el ,remaining ,measure_fragment);
}
- // Custom RT splitable attribute delegation
- if (el.hasAttribute('splitable') && window.RT.Splitter && window.RT.Splitter[el.tagName.toLowerCase()]) {
- return (remaining) => window.RT.Splitter[el.tagName.toLowerCase()](el, remaining, measureFragment, isSplittable);
+ if(el.hasAttribute('splitable') && window.RT.Splitter && window.RT.Splitter[(el.tagName || '').toLowerCase()]){
+ return (remaining) => window.RT.Splitter[(el.tagName || '').toLowerCase()](el ,remaining ,measure_fragment ,is_splittable);
}
- // Native HTML Fallbacks
-
- const tag = el.tagName;
+ const tag = (el.tagName || '').toUpperCase();
if(tag === 'UL' || tag === 'OL'){
- const items = Array.from(el.children).filter(c => c.tagName === 'LI');
+ const items = Array.from(el.children).filter(c => (c.tagName || '').toUpperCase() === 'LI');
if(items.length === 0) return null;
- const itemHeights = items.map(li => getElHeight(li));
- const emptyClone = el.cloneNode(false);
- const overhead = getElHeight(emptyClone);
+ const item_heights = items.map(li => get_el_height(li));
+ const empty_clone = el.cloneNode(false);
+ const overhead = get_el_height(empty_clone);
- el._splitInfo = { type: 'list' ,itemHeights ,overhead ,offset: 0 };
- return makeListSplitter(el ,el._splitInfo);
+ el._splitInfo = { type: 'list' ,itemHeights: item_heights ,overhead: overhead ,offset: 0 };
+ return make_list_splitter(el ,el._splitInfo);
}
if(tag === 'TABLE'){
const rows = tbody ? Array.from(tbody.rows) : Array.from(el.rows);
if(rows.length === 0) return null;
- const theadHeight = thead ? getElHeight(thead) : 0;
- const rowHeights = rows.map(row => getElHeight(row));
+ const thead_height = thead ? get_el_height(thead) : 0;
+ const row_heights = rows.map(row => get_el_height(row));
- const emptyClone = el.cloneNode(false);
- if(thead) emptyClone.appendChild(thead.cloneNode(true));
- emptyClone.appendChild(document.createElement('tbody'));
- const overhead = getElHeight(emptyClone) - theadHeight;
+ const empty_clone = el.cloneNode(false);
+ if(thead) empty_clone.appendChild(thead.cloneNode(true));
+ empty_clone.appendChild(document.createElement('tbody'));
+ const overhead = get_el_height(empty_clone) - thead_height;
- el._splitInfo = { type: 'table' ,rowHeights ,overhead ,theadHeight ,offset: 0 };
- return makeTableSplitter(el ,el._splitInfo);
+ el._splitInfo = { type: 'table' ,rowHeights: row_heights ,overhead: overhead ,theadHeight: thead_height ,offset: 0 };
+ return make_table_splitter(el ,el._splitInfo);
}
return null;
}
- function makeListSplitter(el ,info){
+ function make_list_splitter(el ,info){
return (remaining) => {
- const children = Array.from(el.children).filter(c => c.tagName === 'LI');
+ const children = Array.from(el.children).filter(c => (c.tagName || '').toUpperCase() === 'LI');
const start = info.offset;
- let bestCount = 0;
- let bestHeight = 0;
- const tempList = el.cloneNode(false);
+ let best_count = 0;
+ let best_height = 0;
+ const temp_list = el.cloneNode(false);
for(let i = 0; i < children.length; i++){
- const itemClone = children[i].cloneNode(true);
- tempList.appendChild(itemClone);
- const fragHeight = measureFragment(tempList);
- if(fragHeight <= remaining){
- bestCount = i + 1;
- bestHeight = fragHeight;
- } else {
- tempList.removeChild(itemClone);
+ const item_clone = children[i].cloneNode(true);
+ temp_list.appendChild(item_clone);
+ const frag_height = measure_fragment(temp_list);
+ if(frag_height <= remaining){
+ best_count = i + 1;
+ best_height = frag_height;
+ }else{
+ temp_list.removeChild(item_clone);
break;
}
}
- if(bestCount === 0) return { first: null ,rest: el ,firstHeight: 0 };
+ if(best_count === 0) return { first: null ,rest: el ,firstHeight: 0 };
const first = el.cloneNode(false);
- for(let i = 0; i < bestCount; i++){
+ for(let i = 0; i < best_count; i++){
first.appendChild(children[i].cloneNode(true));
}
let rest = null;
- if(bestCount < children.length){
+ if(best_count < children.length){
rest = el.cloneNode(false);
- for(let i = bestCount; i < children.length; i++){
+ for(let i = best_count; i < children.length; i++){
rest.appendChild(children[i].cloneNode(true));
}
- if(el.tagName === 'OL'){
- const currentStart = parseInt(el.getAttribute('start') ,10) || 1;
- rest.setAttribute('start' ,currentStart + bestCount);
+ if((el.tagName || '').toUpperCase() === 'OL'){
+ const current_start = parseInt(el.getAttribute('start') ,10) || 1;
+ rest.setAttribute('start' ,current_start + best_count);
}
rest._splitInfo = {
type: 'list'
,itemHeights: info.itemHeights
,overhead: info.overhead
- ,offset: start + bestCount
+ ,offset: start + best_count
};
}
- return { first ,rest ,firstHeight: bestHeight };
+ return { first: first ,rest: rest ,firstHeight: best_height };
};
}
- function makeTableSplitter(el ,info){
+ function make_table_splitter(el ,info){
const thead = el.querySelector('thead');
- const createShell = () => {
+ const create_shell = () => {
const shell = el.cloneNode(false);
if(thead) shell.appendChild(thead.cloneNode(true));
- const newTbody = document.createElement('tbody');
- shell.appendChild(newTbody);
+ const new_tbody = document.createElement('tbody');
+ shell.appendChild(new_tbody);
return shell;
};
const rows = tbody ? Array.from(tbody.rows) : Array.from(el.rows);
const start = info.offset;
- let bestCount = 0;
- let bestHeight = 0;
- const tempTable = createShell();
- const tempBody = tempTable.querySelector('tbody');
+ let best_count = 0;
+ let best_height = 0;
+ const temp_table = create_shell();
+ const temp_body = temp_table.querySelector('tbody');
for(let i = 0; i < rows.length; i++){
- tempBody.appendChild(rows[i].cloneNode(true));
- const h = measureFragment(tempTable);
+ temp_body.appendChild(rows[i].cloneNode(true));
+ const h = measure_fragment(temp_table);
if(h <= remaining){
- bestCount = i + 1;
- bestHeight = h;
- } else {
- tempBody.removeChild(tempBody.lastChild);
+ best_count = i + 1;
+ best_height = h;
+ }else{
+ temp_body.removeChild(temp_body.lastChild);
break;
}
}
- if(bestCount === 0) return { first: null ,rest: el ,firstHeight: 0 };
+ if(best_count === 0) return { first: null ,rest: el ,firstHeight: 0 };
- const first = createShell();
- const firstBody = first.querySelector('tbody');
- for(let i = 0; i < bestCount; i++){
- firstBody.appendChild(rows[i].cloneNode(true));
+ const first = create_shell();
+ const first_body = first.querySelector('tbody');
+ for(let i = 0; i < best_count; i++){
+ first_body.appendChild(rows[i].cloneNode(true));
}
let rest = null;
- if(bestCount < rows.length){
- rest = createShell();
- const restBody = rest.querySelector('tbody');
- for(let i = bestCount; i < rows.length; i++){
- restBody.appendChild(rows[i].cloneNode(true));
+ if(best_count < rows.length){
+ rest = create_shell();
+ const rest_body = rest.querySelector('tbody');
+ for(let i = best_count; i < rows.length; i++){
+ rest_body.appendChild(rows[i].cloneNode(true));
}
rest._splitInfo = {
,rowHeights: info.rowHeights
,overhead: info.overhead
,theadHeight: info.theadHeight
- ,offset: start + bestCount
+ ,offset: start + best_count
};
}
- return { first ,rest ,firstHeight: bestHeight };
+ return { first: first ,rest: rest ,firstHeight: best_height };
};
}
-
- // =========================================================
// RT ELEMENT SPLITTERS
- // =========================================================
window.RT.Splitter = window.RT.Splitter || {};
- window.RT.Splitter['rt·counter·step'] = function(el, remaining, measureFn, isSplittableFn) {
- const children = Array.from(el.children);
- let bestCount = 0;
- let bestHeight = 0;
- const tempContainer = el.cloneNode(false);
- let splitChildResult = null;
- let forcedBreak = false;
+ window.RT.Splitter['rt·counter·step'] = function(el ,remaining ,measure_fn ,is_splittable_fn){
+ const children = Array.from(el.childNodes);
+ let best_count = 0;
+ let best_height = 0;
+ const temp_container = el.cloneNode(false);
+ let split_child_result = null;
+ let forced_break = false;
- for (let i = 0; i < children.length; i++) {
+ for(let i = 0; i < children.length; i++){
const child = children[i];
- // Break on explicit splitting break
- if (child.tagName && child.tagName.toLowerCase() === 'rt·page-break') {
- forcedBreak = true;
- bestCount = i;
+ const tag = child.nodeType === Node.ELEMENT_NODE ? (child.tagName || '').toLowerCase() : '';
+ if(tag === 'rt·page-break' || tag === 'rt·page-break-primitive'){
+ forced_break = true;
+ best_count = i;
break;
}
- tempContainer.appendChild(child.cloneNode(true));
- const fragHeight = measureFn(tempContainer);
-
- if (fragHeight <= remaining) {
- bestCount = i + 1;
- bestHeight = fragHeight;
- } else {
- tempContainer.removeChild(tempContainer.lastChild);
- const childSplitter = isSplittableFn(child);
- if (childSplitter) {
- const childSplit = childSplitter(remaining - bestHeight);
- if (childSplit && childSplit.first) {
- splitChildResult = childSplit;
- bestHeight += childSplit.firstHeight;
- bestCount = i;
+ temp_container.appendChild(child.cloneNode(true));
+ const frag_height = measure_fn(temp_container);
+
+ if(frag_height <= remaining){
+ best_count = i + 1;
+ best_height = frag_height;
+ }else{
+ temp_container.removeChild(temp_container.lastChild);
+ const child_splitter = child.nodeType === Node.ELEMENT_NODE ? is_splittable_fn(child) : null;
+ if(child_splitter){
+ const child_split = child_splitter(remaining - best_height);
+ if(child_split && child_split.first){
+ split_child_result = child_split;
+ best_height += child_split.firstHeight;
+ best_count = i;
}
}
break;
}
}
- if (bestCount === 0 && !splitChildResult && !forcedBreak) {
- return { first: null, rest: el, firstHeight: 0 };
+ if(best_count === 0 && !split_child_result && !forced_break){
+ return { first: null ,rest: el ,firstHeight: 0 };
}
const first = el.cloneNode(false);
- first.setAttribute('continued', 'true');
- const splitId = 'split_' + Math.random().toString(36).substr(2, 9);
- first.setAttribute('split-id', splitId);
+ first.setAttribute('continued' ,'true');
+ const split_id = 'split_' + Math.random().toString(36).substr(2 ,9);
+ first.setAttribute('split-id' ,split_id);
- for (let i = 0; i < bestCount; i++) {
+ for(let i = 0; i < best_count; i++){
first.appendChild(children[i].cloneNode(true));
}
- if (splitChildResult) first.appendChild(splitChildResult.first);
+ if(split_child_result) first.appendChild(split_child_result.first);
let rest = null;
- if (bestCount < children.length || splitChildResult || forcedBreak) {
+ if(best_count < children.length || split_child_result || forced_break){
rest = el.cloneNode(false);
- rest.setAttribute('continuation', 'true');
- if (splitChildResult && splitChildResult.rest) rest.appendChild(splitChildResult.rest);
+ rest.setAttribute('continuation' ,'true');
+
+ if(split_child_result && split_child_result.rest){
+ if(Array.isArray(split_child_result.rest)){
+ split_child_result.rest.forEach(r_node => rest.appendChild(r_node));
+ }else{
+ rest.appendChild(split_child_result.rest);
+ }
+ }
- const startIndex = forcedBreak ? bestCount + 1 : (splitChildResult ? bestCount + 1 : bestCount);
- for (let i = startIndex; i < children.length; i++) {
+ const start_index = forced_break ? best_count + 1 : (split_child_result ? best_count + 1 : best_count);
+ for(let i = start_index; i < children.length; i++){
rest.appendChild(children[i].cloneNode(true));
}
- const makeTag = document.createElement('rt·counter·make');
- makeTag.setAttribute('counter', el.getAttribute('counter'));
- makeTag.setAttribute('continues', splitId);
+ const make_tag = document.createElement('RT·counter·make');
+ make_tag.setAttribute('counter' ,el.getAttribute('counter'));
+ make_tag.setAttribute('continues' ,split_id);
- rest = [makeTag, rest];
+ rest = [make_tag ,rest];
}
- return { first, rest, firstHeight: bestHeight };
+ return { first: first ,rest: rest ,firstHeight: best_height };
};
- // =========================================================
// PAGINATE 0: CHUNKING & INJECTING STRUCTURE
- // =========================================================
function paginate_0(){
if(debug.log) debug.log('paginate_0' ,'Running initial document chunking');
- const article_seq = document.querySelectorAll('RT·article');
+ const article_seq = document.querySelectorAll('RT·article, rt·article, RT·memo, rt·memo');
if(article_seq.length === 0){
debug.error('pagination' ,'No <RT·article> elements found. Pagination aborted.');
return;
const footnote_registry = {};
let footnote_counter = 1;
- // Strip and tag footnotes
Array.from(article_seq).forEach(article => {
const all_nodes = Array.from(article.querySelectorAll('*'));
- const raw_footnotes = all_nodes.filter(node => node.tagName.toLowerCase() === 'rt·footnote');
+ const raw_footnotes = all_nodes.filter(node => (node.tagName || '').toLowerCase() === 'rt·footnote');
raw_footnotes.forEach(fn => {
const id = footnote_counter++;
});
});
- function paginateArticle(article){
+ function paginate_article(article){
const raw_element_seq = Array.from(article.children).filter(el =>
- !['SCRIPT' ,'STYLE' ,'RT·PAGE'].includes((el.tagName || '').toUpperCase())
+ !['SCRIPT' ,'STYLE' ,'RT·PAGE' ,'RT·COUNTER·MAKE'].includes((el.tagName || '').toUpperCase())
);
+ const global_makes = Array.from(article.children).filter(el => (el.tagName || '').toUpperCase() === 'RT·COUNTER·MAKE');
+
if(raw_element_seq.length === 0) return;
const page_seq = [];
while(i < raw_element_seq.length){
const el = raw_element_seq[i];
- const splitter = isSplittable(el);
+ const splitter = is_splittable(el);
if(splitter){
const remaining = page_height_limit - current_h;
current_h += firstHeight;
if(rest){
- if (Array.isArray(rest)) {
- raw_element_seq.splice(i, 1, ...rest);
- } else {
- raw_element_seq.splice(i, 1, rest);
+ if(Array.isArray(rest)){
+ raw_element_seq.splice(i ,1 ,...rest);
+ }else{
+ raw_element_seq.splice(i ,1 ,rest);
+ }
+
+ if(current_h > 0){
+ page_seq.push(current_batch_seq);
+ current_batch_seq = [];
+ current_h = 0;
}
- // Force page boundary push because element spanned boundary
- page_seq.push(current_batch_seq);
- current_batch_seq = [];
- current_h = 0;
- continue;
- } else {
- raw_element_seq.splice(i, 1);
continue;
+ }else{
+ raw_element_seq.splice(i ,1);
+ continue;
}
- } else {
- if(current_batch_seq.length === 0){
+ }else{
+ if(current_h === 0){
const frame = document.createElement('RT·scroll-frame');
frame.style.display = 'block';
frame.style.overflowY = 'auto';
frame.appendChild(el);
current_batch_seq.push(frame);
i++;
- } else {
- // Element is split but first chunk fails to fit. Evict any stranded headings.
+ }else{
let backtrack_seq = [];
let backtrack_h = 0;
while(current_batch_seq.length > 0){
const last = current_batch_seq[current_batch_seq.length - 1];
- if(!/^H[1-6]$/i.test(last.tagName)) break;
+ if(!last.tagName || !/^H[1-6]$/i.test(last.tagName)) break;
const popped = current_batch_seq.pop();
backtrack_seq.unshift(popped);
- backtrack_h += getElHeight(popped);
+ backtrack_h += get_el_height(popped);
}
- if(current_batch_seq.length > 0){
+ if(current_h - backtrack_h > 0){
page_seq.push(current_batch_seq);
current_batch_seq = backtrack_seq;
current_h = backtrack_h;
- // Leave 'i' alone to re-evaluate 'el' against the fresh page sequence
- } else {
- // If only headings existed, accept the massive frame inline to avoid loops
+ }else{
+ current_batch_seq.push(...backtrack_seq);
+ current_h += backtrack_h;
+
const frame = document.createElement('RT·scroll-frame');
frame.style.display = 'block';
frame.style.overflowY = 'auto';
frame.style.maxHeight = page_height_limit + 'px';
frame.appendChild(el);
-
- current_batch_seq = backtrack_seq;
- current_h = backtrack_h;
-
current_batch_seq.push(frame);
i++;
}
continue;
}
- const h = getElHeight(el);
- const is_RT_page_break = el.tagName && el.tagName.toLowerCase() === 'rt·page-break';
- const is_RT_page_break_primitive = el.tagName && el.tagName.toLowerCase() === 'rt·page-break-primitive';
+ const h = get_el_height(el);
+ const tag = (el.tagName || '').toLowerCase();
+ const is_RT_page_break = tag === 'rt·page-break' || tag === 'rt·page-break-primitive';
- // Explicit Page Break Logic - Execute immediately without backward traversal
- if(is_RT_page_break || is_RT_page_break_primitive){
- if(current_batch_seq.length > 0){
+ if(is_RT_page_break){
+ if(current_h > 0){
page_seq.push(current_batch_seq);
current_batch_seq = [];
current_h = 0;
continue;
}
- // Standard Dimension Overflow Logic - Check for orphaned headers
- if( current_h + h > page_height_limit && current_batch_seq.length > 0 ){
+ if(current_h + h > page_height_limit && current_h > 0){
let backtrack_seq = [];
let backtrack_h = 0;
while(current_batch_seq.length > 0){
const last = current_batch_seq[current_batch_seq.length - 1];
- if(!/^H[1-6]$/i.test(last.tagName)) break;
+ if(!last.tagName || !/^H[1-6]$/i.test(last.tagName)) break;
const popped = current_batch_seq.pop();
backtrack_seq.unshift(popped);
- backtrack_h += getElHeight(popped);
+ backtrack_h += get_el_height(popped);
}
- if(current_batch_seq.length > 0){
+ if(current_h - backtrack_h > 0){
page_seq.push(current_batch_seq);
current_batch_seq = backtrack_seq;
current_h = backtrack_h;
- } else {
- // Document structure resolved entirely to sequential headings that breached bounds.
- current_batch_seq = backtrack_seq;
- current_h = backtrack_h;
+ }else{
+ current_batch_seq.push(...backtrack_seq);
+ current_h += backtrack_h;
}
}
article.innerHTML = '';
- // Inject global page counter initialization
- const page_counter_make = document.createElement('rt·counter·make');
+ global_makes.forEach(make => article.appendChild(make));
+
+ const page_counter_make = document.createElement('RT·counter·make');
page_counter_make.setAttribute('counter' ,'RT_page_number');
page_counter_make.setAttribute('style' ,'NaturalNumber');
page_counter_make.setAttribute('on-first-step' ,'1');
const batch = page_seq[p];
const page_el = document.createElement('RT·page');
+ page_el.style.minHeight = page_height_limit + 'px';
+ page_el.style.position = 'relative';
+ page_el.style.paddingBottom = '5rem';
+ page_el.style.boxSizing = 'border-box';
+
batch.forEach(item => page_el.appendChild(item));
- // Inject step and snapshot tags into the page
- const page_step = document.createElement('rt·counter·step');
+ const page_step = document.createElement('RT·counter·step');
page_step.setAttribute('counter' ,'RT_page_number');
page_el.appendChild(page_step);
const snapshot_name = `page_snap_${p + 1}`;
- const page_snap = document.createElement('rt·counter·snapshot');
+ const page_snap = document.createElement('RT·counter·snapshot');
page_snap.setAttribute('counter' ,'RT_page_number');
page_snap.setAttribute('snapshot' ,snapshot_name);
page_el.appendChild(page_snap);
- // Optional footer text injection reading the counter snapshot
const page_footer = document.createElement('div');
page_footer.className = 'RT·page-footer';
- const page_read = document.createElement('rt·counter·read');
+ page_footer.style.position = 'absolute';
+ page_footer.style.bottom = '1.5rem';
+ page_footer.style.left = '0';
+ page_footer.style.width = '100%';
+ page_footer.style.textAlign = 'center';
+
+ const page_read = document.createElement('RT·counter·read');
page_read.setAttribute('snapshot' ,snapshot_name);
page_footer.appendChild(page_read);
page_el.appendChild(page_footer);
}
}
- Array.from(article_seq).forEach(article => paginateArticle(article));
+ Array.from(article_seq).forEach(article => paginate_article(article));
- // Resolve footnotes inside the generated pages
Array.from(article_seq).forEach(article => {
- const rendered_pages = article.querySelectorAll('RT·page');
+ const rendered_pages = article.querySelectorAll('RT·page, rt·page');
Array.from(rendered_pages).forEach(page => {
const all_page_nodes = Array.from(page.querySelectorAll('*'));
- const markers = all_page_nodes.filter(node => node.tagName.toLowerCase() === 'rt·fn-marker');
+ const markers = all_page_nodes.filter(node => (node.tagName || '').toLowerCase() === 'rt·fn-marker');
if(markers.length === 0) return;
});
});
- if(measureContainer && measureContainer.parentNode){
- measureContainer.remove();
- measureContainer = null;
+ if(measure_container && measure_container.parentNode){
+ measure_container.remove();
+ measure_container = null;
}
}
- // =========================================================
- // PAGINATE 1: ABSORB DIMENSIONAL DELTA
- // =========================================================
function paginate_1(){
if(debug.log) debug.log('paginate_1' ,'Adjusting final page heights after component injections');
- const rendered_pages = document.querySelectorAll('RT·page');
+ const rendered_pages = document.querySelectorAll('RT·page, rt·page');
Array.from(rendered_pages).forEach(page => {
const actual_height = page.scrollHeight;
if(actual_height > page_height_limit){
});
}
- //----------------------------------------
- // Registration upon load
- //
-
window.RT.paginate_0 = paginate_0;
window.RT.paginate_1 = paginate_1;
-
})();