fixes table splitter extraneous header at bottom on page split bug
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 1 Jun 2026 09:47:03 +0000 (09:47 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 1 Jun 2026 09:47:03 +0000 (09:47 +0000)
developer/authored/RT/layout/paginate_by_element.js
document/style_manual.html

index 3e3b894..2955b3b 100644 (file)
@@ -136,30 +136,36 @@ window.StyleRT.paginate_by_element = function () {
         first.appendChild(children[i].cloneNode(true));
       }
 
-      // Build rest fragment
-      const rest = el.cloneNode(false);
-      for (let i = bestCount; i < children.length; i++) {
-        rest.appendChild(children[i].cloneNode(true));
-      }
 
-      // Explicitly inject the starting index for ordered lists
-      if (el.tagName === 'OL') {
-        const currentStart = parseInt(el.getAttribute('start'), 10) || 1;
-        rest.setAttribute('start', currentStart + bestCount);
-      }
+      // Build rest fragment only if there are remaining items
+      let rest = null;
+      if (bestCount < children.length) {
+        rest = el.cloneNode(false);
+        for (let i = bestCount; i < children.length; i++) {
+          rest.appendChild(children[i].cloneNode(true));
+        }
 
-      // Forward split info
-      rest._splitInfo = {
-        type: 'list',
-        itemHeights: info.itemHeights,
-        overhead: info.overhead,
-        offset: start + bestCount
-      };
+        // Explicitly inject the starting index for ordered lists
+        if (el.tagName === 'OL') {
+          const currentStart = parseInt(el.getAttribute('start'), 10) || 1;
+          rest.setAttribute('start', currentStart + bestCount);
+        }
+
+        // Forward split info
+        rest._splitInfo = {
+          type: 'list',
+          itemHeights: info.itemHeights,
+          overhead: info.overhead,
+          offset: start + bestCount
+        };
+      }
 
       return { first, rest, firstHeight: bestHeight };
     };
   }
 
+
+
   function makeTableSplitter(el, info) {
     const thead = el.querySelector('thead');
     const createShell = () => {
@@ -205,19 +211,22 @@ window.StyleRT.paginate_by_element = function () {
         firstBody.appendChild(relevantRows[i].cloneNode(true));
       }
 
-      const rest = createShell();
-      const restBody = rest.querySelector('tbody');
-      for (let i = bestCount; i < relevantRows.length; i++) {
-        restBody.appendChild(relevantRows[i].cloneNode(true));
-      }
+      let rest = null;
+      if (bestCount < relevantRows.length) {
+        rest = createShell();
+        const restBody = rest.querySelector('tbody');
+        for (let i = bestCount; i < relevantRows.length; i++) {
+          restBody.appendChild(relevantRows[i].cloneNode(true));
+        }
 
-      rest._splitInfo = {
-        type: 'table',
-        rowHeights: info.rowHeights,
-        overhead: info.overhead,
-        theadHeight: info.theadHeight,
-        offset: start + bestCount
-      };
+        rest._splitInfo = {
+          type: 'table',
+          rowHeights: info.rowHeights,
+          overhead: info.overhead,
+          theadHeight: info.theadHeight,
+          offset: start + bestCount
+        };
+      }
 
       return { first, rest, firstHeight: bestHeight };
     };
@@ -256,9 +265,14 @@ window.StyleRT.paginate_by_element = function () {
           current_batch_seq.push(first);
           current_h += firstHeight;   // exact measured height
 
-          // Replace original with remainder
-          raw_element_seq.splice(i, 1, rest);
-          // Do not increment i - rest will be processed next
+          if (rest) {
+            // Replace original with remainder
+            raw_element_seq.splice(i, 1, rest);
+          } else {
+            // Element is completely consumed
+            raw_element_seq.splice(i, 1);
+          }
+          // Do not increment i - the next element is now at index i
         } else {
           // Not even one item fits on this page
           if (current_batch_seq.length === 0) {
index befc746..ebaf512 100644 (file)
@@ -2,7 +2,7 @@
 <html lang="en">
   <head>
     <meta charset="UTF-8">
-    <title>RT Style System: Reference Manual</title>
+    <title>The RT semantic HTML tags</title>
     <script src="setup.js"></script>
     <script>
       window.StyleRT.include('RT/theme');
   <body>
 
     <RT-article>
-      <RT-title author="Gemini" date="2026-01-14" title="RT Style System: Reference Manual"></RT-title>
+      <RT-title author="Thomas Walker Lynch" date="2026-06-01 09:28 UTC" title="The RT semantic HTML tags"></RT-title>
 
-      <RT-TOC level="1"></RT-TOC>
+      <RT-TOC level="1-2"></RT-TOC>
 
-      <h1> Table of Custom Tags </h1>
+      <h1> Table of custom tags </h1>
 
-      <h2>Style Tag Reference</h2>
+      <h2>Style tag reference</h2>
 
       <table>
         <thead>
             <td>Article container.</td>
           </tr>
 
+          <tr>
+            <td><RT-code>&lt;RT-memo&gt;</RT-code></td>
+            <td>Alternative strict print layout container.</td>
+          </tr>
+
           <tr>
             <td><RT-code>&lt;RT-title&gt;</RT-code></td>
-            <td>
-              Title block and metadata.
-            </td>
+            <td>Title block and metadata.</td>
           </tr>
 
           <tr>
             <td>Inline or block math.</td>
           </tr>
 
+          <tr>
+            <td><RT-code>&lt;RT-symbol&gt;</RT-code></td>
+            <td>Technical or mathematical symbol wrapper.</td>
+          </tr>
+
+          <tr>
+            <td><RT-code>&lt;RT-constraint&gt;</RT-code></td>
+            <td>Architectural limits or hard requirement block.</td>
+          </tr>
+
+          <tr>
+            <td><RT-code>&lt;RT-crossref&gt;</RT-code></td>
+            <td>Context-aware internal link.</td>
+          </tr>
+
+          <tr>
+            <td><RT-code>&lt;RT-cite&gt;</RT-code></td>
+            <td>Inline reference marker.</td>
+          </tr>
+
+          <tr>
+            <td><RT-code>&lt;RT-endnotes&gt;</RT-code></td>
+            <td>Container for extracted citations.</td>
+          </tr>
+
           <tr>
             <td><RT-code>&lt;RT-page&gt;</RT-code></td>
             <td>Automatically inserted pagination tag.</td>
           </tr>
+
+          <tr>
+            <td><RT-code>&lt;rt-theme-selector&gt;</RT-code></td>
+            <td>Floating widget for hot-swapping themes.</td>
+          </tr>
         </tbody>
       </table>
 
-      <h1>Architecture Overview</h1>
+      <h1>Architecture overview</h1>
       <p>
-        The <RT-term>RT Style System</RT-term> is a client-side, JavaScript-driven publishing framework designed to turn raw HTML into high-readability technical documentation. Unlike standard CSS frameworks, RT uses JavaScript to handle complex layout tasks like <RT-neologism>ink-ratio balancing</RT-neologism> and dynamic pagination.
+        The <RT-term>RT Style System</RT-term> is a client-side, JavaScript-driven publishing framework designed to turn raw HTML into high-readability technical documentation. RT uses JavaScript to handle complex layout tasks like <RT-neologism>ink-ratio balancing</RT-neologism> and dynamic pagination, operating quite differently than standard CSS frameworks.
+      </p>
+
+      <h2>The document header</h2>
+      <p>
+        The document header must bootstrap the RT Style engine before the body renders. An author places <RT-code>setup.js</RT-code> in the directory and includes it via a script tag at the top of the document. Following this, the <RT-code>window.StyleRT.include</RT-code> directives pull in the necessary modules, such as the theme and the specific layout orchestrator (e.g., <RT-code>RT/layout/article_tech_ref</RT-code>).
       </p>
 
       <h2>Pulling style files into a document</h2>
-      <p> Put `setup.js` in the directory, and include it at the top of the document,
-        `setup.js` points at the style files and is installation specific.</p>
+      <p>
+        Put `setup.js` in the directory, and include it at the top of the document. `setup.js` points at the style files and is installation specific.
+      </p>
         
-
-      <h1>Semantic Tags</h1>
+      <h1>Semantic tags</h1>
       <p>
         The system relies on a specific set of custom tags in the <RT-code>RT-</RT-code> namespace to separate structure from presentation.
       </p>
 
       <h2>Terminology</h2>
 
-      <h3>Conventional Terms</h3>
+      <h3>Conventional terms</h3>
       <p>
         Use <RT-code>&lt;RT-term&gt;</RT-code> for standard, industry accepted technical terms. The system decorates only the first occurrence of each unique term so that the first appearance functions as a definition point, and later appearances do not overload the page with styling.
       </p>
 
       <h3>Neologisms</h3>
       <p>
-        Use <RT-code>&lt;RT-neologism&gt;</RT-code> for terms invented specifically for the current document or project. Neologisms are styled more strongly than conventional terms, visually distinguishing "jargon you should know" from "jargon we just made up."
+        Use <RT-code>&lt;RT-neologism&gt;</RT-code> for terms invented specifically for the current document or project. Neologisms are styled more strongly than conventional terms, visually distinguishing "jargon you should know" from "jargon we newly created."
       </p>
 
       <RT-code>
         <em>Renders as:</em> We define the <RT-neologism>Hyper Tape</RT-neologism> as a construct...
       </p>
 
-      <h3>First Occurrence Rule</h3>
+      <h3>First occurrence rule</h3>
       <p>
         The term system is intentionally conservative. For the tags <RT-code>&lt;RT-term&gt;</RT-code> and <RT-code>&lt;RT-neologism&gt;</RT-code>, only the first occurrence of a unique term is decorated. Subsequent mentions are rendered as normal prose.
       </p>
         Uniqueness is tracked by normalizing the term text (trimmed, then lowercased). This means that <RT-code>Symbol</RT-code> and <RT-code>symbol</RT-code> count as the same term.
       </p>
 
-      <h3>Forced Emphasis Variants</h3>
+      <h3>Forced emphasis variants</h3>
       <p>
         Sometimes a later mention of a term should be emphasized again. For that purpose, the system provides explicit emphasis tags:
       </p>
         These variants are always decorated, even if the term appeared earlier.
       </p>
 
-      <h3>Automatic Definition Anchors</h3>
+      <h3>Automatic definition anchors</h3>
       <p>
-        For first occurrences, the term module automatically assigns an <RT-code>id</RT-code> attribute if one does not already exist. This creates stable anchors for future indexing and linking.
+        For first occurrences, the term module automatically assigns an <RT-code>id</RT-code> attribute if one lacks existence. This creates stable anchors for future indexing and linking.
       </p>
 
       <RT-code>
         The first occurrence will be given an id similar to <RT-code>def-symbol</RT-code>. For neologisms, an additional marker is used, for example <RT-code>def-neo-hyper-tape</RT-code>.
       </p>
 
-      <h2>Technical Content</h2>
+      <h2>Technical content</h2>
 
       <h3>Code</h3>
       <p>
-        Use <RT-code>&lt;RT-code&gt;</RT-code>. If placed inline, it acts like a span. If placed as a block (with newlines), it acts like a pre formatted block with a theme aware border.
+        Use <RT-code>&lt;RT-code&gt;</RT-code>. When placed inline, it functions as a span. When placed as a block (with newlines), it functions as a pre formatted block with a theme aware border. The engine will automatically strip common leading whitespace so that the text aligns relative to the indentation of the <RT-code>&lt;RT-code&gt;</RT-code> tag itself.
       </p>
       
       <RT-code>
         # Block Code Example
         def hello():
-        return "World"
+            return "World"
       </RT-code>
 
       <h3>Mathematics</h3>
         f(x) = \sum_{i=0}^{n} x_i
       </RT-math>
 
-      <h1>Navigation & Layout</h1>
+      <h2>Architectural notation and constraints</h2>
 
-      <h2>Automatic Table of Contents</h2>
+      <h3>Symbols</h3>
+      <p>
+        Use <RT-code>&lt;RT-symbol&gt;</RT-code> for specialized technical or mathematical symbols. This enforces a consistent font-weight and character spacing across different browser engines, ensuring that these symbols avoid anti-aliasing artifacts often seen with standard Unicode glyphs in technical documentation.
+      </p>
+
+      <h3>Constraints</h3>
+      <p>
+        Use <RT-code>&lt;RT-constraint&gt;</RT-code> to explicitly highlight physical limitations, memory boundaries, or structural constraints within a system. This tag triggers a unique block-display, rendering with a distinct background shade and a left-hand rule, visually separating hard requirements from descriptive prose.
+      </p>
+
+      <h3>Cross-references</h3>
+      <p>
+        Use <RT-code>&lt;RT-crossref&gt;</RT-code> for internal structural linking between sections. This tag provides context-aware linking, managing anchor states to jump across soft-limit boundaries seamlessly.
+      </p>
+
+      <h2>Citations and endnotes</h2>
+      <p>
+        The system manages academic and technical references through a paired tag approach, ensuring citations are extracted and formatted before the layout engine calculates page boundaries.
+      </p>
+      
+      <h3>Inline citations</h3>
+      <p>
+        An author places <RT-code>&lt;RT-cite ref="Author, Source"&gt;&lt;/RT-cite&gt;</RT-code> inline within the text. The engine transforms this into a superscript bracketed number, establishing a bi-directional link.
+      </p>
+
+      <h3>Endnote generation</h3>
+      <p>
+        The <RT-code>&lt;RT-endnotes&gt;</RT-code> container functions as the destination for all extracted citations. If an author places this tag at the bottom of the article, the engine populates it with an ordered list of references. Should the author omit the tag, the semantic parser will dynamically generate and append it as a top-level child of the article.
+      </p>
+
+      <h1>Navigation and layout</h1>
+
+      <h2>Automatic table of contents</h2>
       <p>
         Use <RT-code>&lt;RT-TOC&gt;</RT-code> to insert a generated table of contents. The tag scans the document <em>forward</em> from its current position to collect headings.
       </p>
 
-      <h3>Explicit Mode</h3>
+      <h3>Explicit mode (Specific levels or ranges)</h3>
       <p>
-        Use the <RT-code>level="N"</RT-code> attribute to target a specific heading depth.
+        Use the <RT-code>level</RT-code> attribute to target a specific heading depth or a range of depths.
       </p>
       <ul>
         <li><RT-code>&lt;RT-TOC level="1"&gt;</RT-code>: Collects all <RT-code>&lt;h1&gt;</RT-code> elements until the end of the document. Best for the main document index.</li>
+        <li><RT-code>&lt;RT-TOC level="1-3"&gt;</RT-code>: Collects all <RT-code>&lt;h1&gt;</RT-code>, <RT-code>&lt;h2&gt;</RT-code>, and <RT-code>&lt;h3&gt;</RT-code> elements, nesting them structurally.</li>
         <li><RT-code>&lt;RT-TOC level="2"&gt;</RT-code>: Collects all <RT-code>&lt;h2&gt;</RT-code> elements until it encounters the next <RT-code>&lt;h1&gt;</RT-code>. Best for chapter summaries.</li>
       </ul>
 
-      <h3>Implicit Mode</h3>
+      <h3>Implicit mode</h3>
       <p>
-        If no level is specified, the TOC scans backwards to find the nearest heading (for example H1) and assumes you want to collect children one level deeper (for example H2).
+        If no level is specified, the TOC scans backwards to find the nearest heading (for example H1) and assumes an author wants to collect children one level deeper (for example H2).
       </p>
       <p>
-        <em>Note: Implicit mode can fail if placed before the first heading of a section. Use explicit levels for robust results.</em>
+        <em>Note: Implicit mode has a probability to fail if placed before the first heading of a section. Use explicit levels for robust results.</em>
       </p>
 
-      <h2>The Title Block</h2>
+      <h2>The title block</h2>
       <p>
         Use <RT-code>&lt;RT-title&gt;</RT-code> as the first element in your <RT-code>&lt;body&gt;</RT-code> (before the article container). This tag generates a standardized, styled header block with the document title and metadata.
       </p>
         <li><RT-code>title</RT-code> (Required): The main heading of the document.</li>
         <li><RT-code>author</RT-code> (Optional): The author's name. Renders in a bold accent color.</li>
         <li><RT-code>date</RT-code> (Optional): The publication or revision date.</li>
+        <li><RT-code>copyright</RT-code> (Optional): Appends a copyright notice to the bottom of the title block.</li>
       </ul>
 
       <h3>Example</h3>
       <RT-code>
         <RT-title 
-          title="RT Style System: Reference Manual" 
-          author="Gemini" 
-          date="2026-01-14">
+          title="The RT semantic HTML tags" 
+          author="Thomas Walker Lynch" 
+          date="2026-06-01 09:28 UTC"
+          copyright="2026 Reasoning Technology">
         </RT-title>
       </RT-code>
 
       <p>
-        <em>Renders as:</em> A centered, high contrast H1 followed by a serif styled metadata row containing the author and date.
+        <em>Renders as:</em> A centered, high contrast H1 followed by a serif styled metadata row containing the author and date, and a smaller copyright note.
       </p>
 
-      <h2>The Article Container</h2>
+      <h2>Layout containers</h2>
+
+      <h3>The article container</h3>
       <p>
-        The root element must be <RT-code>&lt;RT-article&gt;</RT-code>. This is the boundary for the pagination logic.
+        The primary root element for documentation is <RT-code>&lt;RT-article&gt;</RT-code>. This establishes the boundary for the standard typography rules and the dynamic pagination logic.
+      </p>
+
+      <h3>The memo container</h3>
+      <p>
+        Alternatively, use <RT-code>&lt;RT-memo&gt;</RT-code> for strict print formatting. This sets the document width to a strict 6.5 inches (standard 8.5 inch page with 1-inch margins), overrides theme colors to enforce black text on a white background, and sets the typography to a 12pt serif font (Times New Roman) suitable for formal documentation.
       </p>
 
       <h2>Pagination</h2>
       <p>
         <RT-neologism>Soft Limit Pagination</RT-neologism>: The system attempts to keep headers with their following paragraphs. It will break a page early rather than stranding a header at the bottom.
       </p>
+      <p>
+        <RT-neologism>Fragment Splitting</RT-neologism>: When confronted with large unbroken data structures, the paginator acts intelligently to split `<ol>`, `<ul>`, and `<table>` elements across multiple pages to maximize space efficiency without breaking the document structure.
+      </p>
 
       <h1>Debugging</h1>
 
-      <h2>Debug Tokens</h2>
+      <h2>Debug tokens</h2>
       <p>
         RT provides a lightweight debug logging system in <RT-code>utility.js</RT-code>. Logging is controlled by a set of active debug tokens. Each log message is assigned a token, and the message prints only if that token is enabled.
       </p>
         Examples of common tokens include <RT-code>style</RT-code>, <RT-code>layout</RT-code>, <RT-code>pagination</RT-code>, <RT-code>selector</RT-code>, <RT-code>config</RT-code>, and <RT-code>term</RT-code>.
       </p>
 
-      <h2>How Logging is Gated</h2>
+      <h2>How logging is gated</h2>
       <p>
         Normal log and warning output are gated. The methods <RT-code>debug.log(token,message)</RT-code> and <RT-code>debug.warn(token,message)</RT-code> will print only when the token exists in <RT-code>debug.active_tokens</RT-code>.
       </p>
         This prevents the console from being flooded during normal use, while still allowing deep visibility during development.
       </p>
 
-      <h2>Errors are Always Printed</h2>
+      <h2>Errors are always printed</h2>
       <p>
         Errors are treated differently. The method <RT-code>debug.error(token,message)</RT-code> always prints, regardless of token state. These messages represent failures that require attention.
       </p>
 
-      <h2>Enabling and Disabling Tokens</h2>
+      <h2>Enabling and disabling tokens</h2>
       <p>
-        Tokens may be enabled or disabled in two ways: by editing the <RT-code>active_tokens</RT-code> set in <RT-code>utility.js</RT-code>, or at runtime by calling:
+        Tokens have permission to be enabled or disabled in two ways: by editing the <RT-code>active_tokens</RT-code> set in <RT-code>utility.js</RT-code>, or at runtime by calling:
       </p>
 
       <RT-code>
         <li><strong>Light:</strong> <RT-code>style/theme_light_gold.js</RT-code></li>
       </ul>
 
+      <h2>Theme selector widget</h2>
+      <p>
+        Including the tag <RT-code>&lt;rt-theme-selector&gt;&lt;/rt-theme-selector&gt;</RT-code> anywhere in the DOM will generate a floating widget in the upper right corner of the window, permitting the user to hot-swap the visual theme and automatically persist the choice via local storage.
+      </p>
+
       <h1>Manifest</h1>
       <RT-code>
         1. style_orchestrator.js    (Example/default footer script)
         window.StyleRT.style_orchestrator();
       </script>
 
-      <h1>RT Conventions</h1>
+      <h1>RT conventions</h1>
       <p> Headings are first letter capitalized. Remaining words are as they would be in English prose.</p>
 
       <h1>Exercises</h1>
         </li>
         <li>
           <p>
-            <strong>TOC Generation:</strong> What happens if one places an <RT-code>&lt;RT-TOC&gt;</RT-code> tag without a level attribute before the first heading of a section?
+            <strong>TOC Generation:</strong> What happens if a person places an <RT-code>&lt;RT-TOC&gt;</RT-code> tag without a level attribute before the first heading of a section?
           </p>
         </li>
         <li>