------------------------------------------------------------
commit 81741f0c7cfb41cadb0ba486bbc5173025ccbbba
Author: ffff:72.234.190.31 <ffff:72.234.190.31@importer.scroll.pub> Date: Sat Nov 16 00:07:17 2024 +0000 Updated index.scroll diff --git a/index.scroll b/index.scroll index dcd1248..9e7d4c2 100644 --- a/index.scroll +++ b/index.scroll @@ -1,4 +1,3 @@ buildHtml claude.html editButton /edit.html -scrollVersionLink ------------------------------------------------------------
commit 8dac0a7b23b5c6ee742246bc9f24dfc1baefea80
Author: ffff:72.234.190.31 <ffff:72.234.190.31@importer.scroll.pub> Date: Sat Nov 16 00:07:07 2024 +0000 Updated index.scroll diff --git a/index.scroll b/index.scroll index 9e7d4c2..dcd1248 100644 --- a/index.scroll +++ b/index.scroll @@ -1,3 +1,4 @@ buildHtml claude.html editButton /edit.html +scrollVersionLink ------------------------------------------------------------
commit 1ac6288c67fee526ddee5197c2a0cccfa16e353b
Author: ffff:72.234.190.31 <ffff:72.234.190.31@importer.scroll.pub> Date: Sat Nov 16 00:06:56 2024 +0000 Updated index.scroll diff --git a/index.scroll b/index.scroll index 7f3dc1b..9e7d4c2 100644 --- a/index.scroll +++ b/index.scroll @@ -1,3 +1,3 @@ buildHtml claude.html -editButton +editButton /edit.html ------------------------------------------------------------
commit 5577d0b1e8c729a0143d7965f434e45eccecdb2c
Author: ffff:72.234.190.31 <ffff:72.234.190.31@importer.scroll.pub> Date: Sat Nov 16 00:06:47 2024 +0000 Updated index.scroll diff --git a/index.scroll b/index.scroll index 8e7cd22..7f3dc1b 100644 --- a/index.scroll +++ b/index.scroll @@ -1,2 +1,3 @@ buildHtml claude.html +editButton ------------------------------------------------------------
commit 65c8feb964ff35bb1b6f94fe417332853e7a3d6d
Author: Breck Yunits <breck7@gmail.com> Date: Fri Nov 15 14:05:21 2024 -1000 diff --git a/latex.js b/latex.js index 652fcdf..536672e 100644 --- a/latex.js +++ b/latex.js @@ -1,192 +1,197 @@ class LaTeXToScroll { constructor() { this.blockCommands = { - section: "# ", - subsection: "## ", - subsubsection: "### ", - paragraph: "*", - begin: { - itemize: "- ", - enumerate: "1. ", - quote: "> ", - verbatim: "code\n", - center: "center\n", - figure: "figure\n", - }, + 'section': '# ', + 'subsection': '## ', + 'subsubsection': '### ', + 'paragraph': '*', + 'begin': { + 'itemize': '- ', + 'enumerate': '1. ', + 'quote': '> ', + 'verbatim': 'code\n', + 'center': 'center\n', + 'figure': 'figure\n', + } }; this.inlineCommands = { - textbf: "*", - textit: "_", - texttt: "`", - emph: "_", - href: "link", + 'textbf': '*', + 'textit': '_', + 'texttt': '`', + 'emph': '_', + 'href': 'link' }; } convert(latex) { let scroll = latex; - + // Remove comments - scroll = scroll.replace(/%.*$/gm, ""); - + scroll = scroll.replace(/%.*$/gm, ''); + + // Handle \input commands first + scroll = this.convertInputCommands(scroll); + // Handle block environments scroll = this.convertEnvironments(scroll); - + // Handle section commands scroll = this.convertSections(scroll); - + // Handle inline formatting scroll = this.convertInlineCommands(scroll); - + // Handle special characters scroll = this.convertSpecialCharacters(scroll); - - // Handle lists - scroll = this.convertLists(scroll); - - // Handle images - scroll = this.convertImages(scroll); - + // Handle citations and references scroll = this.convertCitations(scroll); - + // Clean up extra whitespace scroll = this.cleanupWhitespace(scroll); - + return scroll; } + convertInputCommands(text) { + // Match \input{filename} with or without .tex extension + const inputRegex = /\\input\{([^}]+)\}/g; + return text.replace(inputRegex, (match, filename) => { + // Remove .tex extension if present and add .scroll + const scrollFile = filename.replace(/\.tex$/, '') + '.scroll'; + return `${scrollFile}`; + }); + } + convertEnvironments(text) { let result = text; - + // Match begin/end environment blocks const envRegex = /\\begin\{(\w+)\}([\s\S]*?)\\end\{\1\}/g; - + result = result.replace(envRegex, (match, env, content) => { - const prefix = this.blockCommands.begin[env] || ""; - - if (env === "itemize" || env === "enumerate") { + const prefix = this.blockCommands.begin[env] || ''; + + if (env === 'itemize' || env === 'enumerate') { return this.convertListItems(content, env); - } else if (env === "verbatim") { - return `${prefix}${content.trim()}`; - } else if (env === "figure") { + } else if (env === 'verbatim') { + return `code\n${content.trim()}`; + } else if (env === 'figure') { return this.convertFigure(content); } - + // Indent content for environments that need it const indentedContent = content .trim() - .split("\n") - .map((line) => " " + line) - .join("\n"); - + .split('\n') + .map(line => ' ' + line) + .join('\n'); + return `${prefix}${indentedContent}\n`; }); - + return result; } + convertListItems(content, type) { + const marker = type === 'itemize' ? '- ' : '1. '; + return content + .split('\\item') + .slice(1) // Skip first empty element + .map(item => marker + item.trim()) + .join('\n') + '\n'; + } + convertSections(text) { let result = text; - + // Convert section commands - Object.keys(this.blockCommands).forEach((cmd) => { - if (cmd === "begin") return; - const regex = new RegExp(`\\\\${cmd}{([^}]+)}`, "g"); + Object.keys(this.blockCommands).forEach(cmd => { + if (cmd === 'begin') return; + const regex = new RegExp(`\\\\${cmd}{([^}]+)}`, 'g'); result = result.replace(regex, (match, content) => { return `${this.blockCommands[cmd]}${content.trim()}\n`; }); }); - + return result; } convertInlineCommands(text) { let result = text; - + // Convert inline formatting commands - Object.keys(this.inlineCommands).forEach((cmd) => { - const regex = new RegExp(`\\\\${cmd}{([^}]+)}`, "g"); + Object.keys(this.inlineCommands).forEach(cmd => { + const regex = new RegExp(`\\\\${cmd}{([^}]+)}`, 'g'); result = result.replace(regex, (match, content) => { - if (cmd === "href") { - const [url, text] = content.split("}{"); - return `${text}\n link ${url} ${text}`; + if (cmd === 'href') { + // Handle \href{url}{text} + const [url, linkText] = content.split('}{'); + return `${linkText.replace('}', '')}\n link ${url} ${linkText.replace('}', '')}`; } const marker = this.inlineCommands[cmd]; return `${marker}${content}${marker}`; }); }); - + return result; } convertSpecialCharacters(text) { const charMap = { - "\\&": "&", - "\\%": "%", - "\\$": "$", - "\\#": "#", - "\\_": "_", - "\\{": "{", - "\\}": "}", - "~": " ", - "``": '"', - "''": '"', + '\\&': '&', + '\\%': '%', + '\\$': '$', + '\\#': '#', + '\\_': '_', + '\\{': '{', + '\\}': '}', + '~': ' ', + '``': '"', + "''": '"' }; - + let result = text; - Object.keys(charMap).forEach((char) => { - result = result.replace( - new RegExp(char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - charMap[char], - ); + Object.keys(charMap).forEach(char => { + result = result.replace(new RegExp(char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), charMap[char]); }); - + return result; } - convertListItems(content, type) { - const marker = type === "itemize" ? "- " : "1. "; - const lines = content - .split("\\item") - .slice(1) // Skip first empty element - .map((item) => marker + item.trim()) - .join("\n"); - return lines + "\n"; - } - convertFigure(content) { // Extract image path and caption const includegraphicsRegex = /\\includegraphics(?:\[.*?\])?\{([^}]+)\}/; const captionRegex = /\\caption\{([^}]+)\}/; - - const imagePath = content.match(includegraphicsRegex)?.[1] || ""; - const caption = content.match(captionRegex)?.[1] || ""; - + + const imagePath = content.match(includegraphicsRegex)?.[1] || ''; + const caption = content.match(captionRegex)?.[1] || ''; + return `image ${imagePath}\n caption ${caption}\n`; } convertCitations(text) { let result = text; - + // Convert \cite{key} to ^key - result = result.replace(/\\cite\{([^}]+)\}/g, "^$1"); - + result = result.replace(/\\cite\{([^}]+)\}/g, '^$1'); + // Convert \ref{key} to ^key - result = result.replace(/\\ref\{([^}]+)\}/g, "^$1"); - + result = result.replace(/\\ref\{([^}]+)\}/g, '^$1'); + return result; } cleanupWhitespace(text) { - return ( - text - .replace(/\n\s*\n\s*\n/g, "\n\n") // Remove extra blank lines - .replace(/[ \t]+$/gm, "") // Remove trailing whitespace - .trim() + "\n" - ); // Ensure single newline at end + return text + .replace(/\n\s*\n\s*\n/g, '\n\n') // Remove extra blank lines + .replace(/[ \t]+$/gm, '') // Remove trailing whitespace + .trim() + '\n'; // Ensure single newline at end } } -// module.exports = LaTeXToScroll; +// For Node.js environment +if (typeof module !== 'undefined' && module.exports) { + module.exports = LaTeXToScroll; +} diff --git a/markdown.js b/markdown.js index b417866..7c13a78 100644 --- a/markdown.js +++ b/markdown.js @@ -1,6 +1,5 @@ class MarkdownToScroll { constructor() { - // Mapping of common Markdown patterns this.blockPatterns = { header: /^(#{1,6})\s+(.+)$/, horizontalRule: /^[\*\-_]{3,}$/, @@ -19,118 +18,76 @@ class MarkdownToScroll { strikethrough: /~~(.+?)~~/g, link: /\[([^\]]+)\]\(([^)]+)\)(?:\{([^}]+)\})?/g, image: /!\[([^\]]*)\]\(([^)]+)\)(?:\{([^}]+)\})?/g, - footnoteRef: /\[\^(\d+)\]/g, - footnoteDef: /^\[\^(\d+)\]:\s*(.+)$/, }; } convert(markdown) { - // Split into lines for block-level processing - let lines = markdown.trim().split("\n"); - let scroll = ""; + if (!markdown) return ''; + + let lines = markdown.toString().trim().split('\n'); + let scroll = ''; let inCodeBlock = false; - let codeBlockContent = ""; - let inTable = false; - let tableContent = []; + let codeBlockContent = ''; + let inList = false; + let listIndentLevel = 0; for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - - // Handle code blocks first - if (line.startsWith("```")) { + let line = lines[i].trimEnd(); + + // Handle code blocks + if (line.startsWith('```')) { if (!inCodeBlock) { inCodeBlock = true; - codeBlockContent = ""; + codeBlockContent = ''; continue; } else { - scroll += this.convertCodeBlock(codeBlockContent.trim()) + "\n\n"; + scroll += 'code\n' + codeBlockContent.trim() + '\n\n'; inCodeBlock = false; continue; } } if (inCodeBlock) { - codeBlockContent += line + "\n"; + codeBlockContent += line + '\n'; continue; } - // Handle tables - if (line.startsWith("|")) { - if (!inTable) { - inTable = true; - tableContent = []; - } - if (!this.blockPatterns.tableDelimiter.test(line)) { - tableContent.push(line); - } + // Handle horizontal rules + if (this.blockPatterns.horizontalRule.test(line)) { + scroll += '---\n\n'; continue; - } else if (inTable) { - scroll += this.convertTable(tableContent) + "\n\n"; - inTable = false; - tableContent = []; } - // Process block-level patterns - let processed = false; - - // Headers + // Handle headers const headerMatch = line.match(this.blockPatterns.header); if (headerMatch) { - scroll += - "#".repeat(headerMatch[1].length) + - " " + - this.convertInlineElements(headerMatch[2]) + - "\n\n"; - processed = true; - } - - // Horizontal Rule - if (this.blockPatterns.horizontalRule.test(line)) { - scroll += "---\n\n"; - processed = true; + scroll += '#'.repeat(headerMatch[1].length) + ' ' + + this.convertInlineElements(headerMatch[2]) + '\n\n'; + continue; } - // Blockquotes + // Handle blockquotes const blockquoteMatch = line.match(this.blockPatterns.blockquote); if (blockquoteMatch) { - scroll += "> " + this.convertInlineElements(blockquoteMatch[1]) + "\n"; - processed = true; + scroll += '> ' + this.convertInlineElements(blockquoteMatch[1]) + '\n'; + continue; } - // Unordered Lists + // Handle lists const ulMatch = line.match(this.blockPatterns.unorderedList); - if (ulMatch) { - scroll += "- " + this.convertInlineElements(ulMatch[1]) + "\n"; - processed = true; - } - - // Ordered Lists const olMatch = line.match(this.blockPatterns.orderedList); - if (olMatch) { - scroll += "1. " + this.convertInlineElements(olMatch[1]) + "\n"; - processed = true; - } - - // Footnote Definitions - const footnoteMatch = line.match(this.blockPatterns.footnoteDef); - if (footnoteMatch) { - scroll += - "^" + - footnoteMatch[1] + - " " + - this.convertInlineElements(footnoteMatch[2]) + - "\n"; - processed = true; - } - - // Regular paragraphs - if (!processed && line.trim()) { - scroll += "* " + this.convertInlineElements(line) + "\n\n"; + if (ulMatch || olMatch) { + const content = (ulMatch || olMatch)[1]; + const marker = ulMatch ? '- ' : '1. '; + scroll += marker + this.convertInlineElements(content) + '\n'; + continue; } - // Preserve blank lines - if (!line.trim()) { - scroll += "\n"; + // Handle regular paragraphs + if (line.trim()) { + scroll += '* ' + this.convertInlineElements(line) + '\n\n'; + } else { + scroll += '\n'; } } @@ -138,69 +95,42 @@ class MarkdownToScroll { } convertInlineElements(text) { - let result = text; - - // Convert images before links (to avoid nested parsing issues) - result = result.replace( - this.inlinePatterns.image, - (match, alt, src, title) => { - let scroll = `\nimage ${src}`; - if (alt) scroll += `\n caption ${alt}`; - return scroll; - }, - ); + if (!text) return ''; + let result = text.toString(); + + // Convert images before links + result = result.replace(this.inlinePatterns.image, (match, alt, src, title) => { + let scroll = `\nimage ${src}`; + if (alt) scroll += `\n caption ${alt}`; + return scroll; + }); // Convert links - result = result.replace( - this.inlinePatterns.link, - (match, text, url, title) => { - let scroll = text + "\n link " + url + " " + text; - if (title) scroll += "\n title " + title; - return scroll; - }, - ); + result = result.replace(this.inlinePatterns.link, (match, text, url) => { + return `${text}\n link ${url} ${text}`; + }); // Convert other inline elements result = result - .replace(this.inlinePatterns.bold, "*$1*") - .replace(this.inlinePatterns.italic, "_$1_") - .replace(this.inlinePatterns.code, "`$1`") - .replace(this.inlinePatterns.strikethrough, "strike $1") - .replace(this.inlinePatterns.footnoteRef, "^$1"); + .replace(this.inlinePatterns.bold, '*$1*') + .replace(this.inlinePatterns.italic, '_$1_') + .replace(this.inlinePatterns.code, '`$1`') + .replace(this.inlinePatterns.strikethrough, 'strike $1'); return result; } - convertCodeBlock(content) { - return "code\n" + content; - } - - convertTable(tableContent) { - let scroll = "table\n"; - scroll += " data\n"; - - // Convert each table row to CSV format - tableContent.forEach((row) => { - const cells = row - .split("|") - .filter((cell) => cell.trim()) // Remove empty cells from start/end - .map((cell) => cell.trim()) - .map((cell) => this.convertInlineElements(cell)) - .join(","); - scroll += " " + cells + "\n"; - }); - - return scroll; - } - cleanup(scroll) { - return ( - scroll - .replace(/\n{3,}/g, "\n\n") // Remove extra blank lines - .replace(/[ \t]+$/gm, "") // Remove trailing whitespace - .trim() + "\n" - ); // Ensure single newline at end + return scroll + .replace(/\n{3,}/g, '\n\n') // Remove extra blank lines + .replace(/[ \t]+$/gm, '') // Remove trailing whitespace + .replace(/\^undefined\n/g, '') // Remove undefined references + .replace(/\n\n+/g, '\n\n') // Normalize multiple newlines + .trim() + '\n'; // Ensure single newline at end } } -// module.exports = MarkdownToScroll; +// For Node.js environment +if (typeof module !== 'undefined' && module.exports) { + module.exports = MarkdownToScroll; +} ------------------------------------------------------------
commit 091f117da86925c7598a457df6c85398d8532f74
Author: ffff:72.234.190.31 <ffff:72.234.190.31@hub.scroll.pub> Date: Fri Nov 15 22:32:37 2024 +0000 Updated claude.html diff --git a/claude.html b/claude.html index 0491b68..a6170bf 100644 --- a/claude.html +++ b/claude.html @@ -23,7 +23,7 @@ "Helvetica Neue", Arial, sans-serif; line-height: 1.6; padding: 2rem; - padding-top: 1rem; + padding-top: 0.2rem; max-width: 1400px; margin: 0 auto; background-color: var(--gray-100); ------------------------------------------------------------
commit a9f73861d3625c0b5838f2897fd7af44ed831b88
Author: ffff:72.234.190.31 <ffff:72.234.190.31@hub.scroll.pub> Date: Fri Nov 15 22:32:19 2024 +0000 Updated claude.html diff --git a/claude.html b/claude.html index 5aad4c3..0491b68 100644 --- a/claude.html +++ b/claude.html @@ -33,7 +33,7 @@ h2 { text-align: center; color: var(--gray-700); - margin-bottom: 1rem; + margin-bottom: 0.2rem; margin-top: 0; } ------------------------------------------------------------
commit c751f7b9004e4deb7574ed040280137302269e2a
Author: ffff:72.234.190.31 <ffff:72.234.190.31@hub.scroll.pub> Date: Fri Nov 15 22:32:07 2024 +0000 Updated claude.html diff --git a/claude.html b/claude.html index b19388f..5aad4c3 100644 --- a/claude.html +++ b/claude.html @@ -23,6 +23,7 @@ "Helvetica Neue", Arial, sans-serif; line-height: 1.6; padding: 2rem; + padding-top: 1rem; max-width: 1400px; margin: 0 auto; background-color: var(--gray-100); ------------------------------------------------------------
commit e0541c6b4c5c80e9d420f628ef7c0f04c5b38bcf
Author: ffff:72.234.190.31 <ffff:72.234.190.31@hub.scroll.pub> Date: Fri Nov 15 22:31:52 2024 +0000 Updated claude.html diff --git a/claude.html b/claude.html index 3f9fb3b..b19388f 100644 --- a/claude.html +++ b/claude.html @@ -33,6 +33,7 @@ text-align: center; color: var(--gray-700); margin-bottom: 1rem; + margin-top: 0; } .container { ------------------------------------------------------------
commit f050db2e8eab55421729c8f43ed3e0103e52389b
Author: ffff:72.234.190.31 <ffff:72.234.190.31@hub.scroll.pub> Date: Fri Nov 15 22:31:42 2024 +0000 Updated claude.html diff --git a/claude.html b/claude.html index c85b4aa..3f9fb3b 100644 --- a/claude.html +++ b/claude.html @@ -32,7 +32,7 @@ h2 { text-align: center; color: var(--gray-700); - margin-bottom: 2rem; + margin-bottom: 1rem; } .container {