Changed around line 1
- // Mapping of common Markdown patterns
Changed around line 18: class MarkdownToScroll {
- footnoteRef: /\[\^(\d+)\]/g,
- footnoteDef: /^\[\^(\d+)\]:\s*(.+)$/,
- // 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 codeBlockContent = "";
- let inTable = false;
- let tableContent = [];
+ let codeBlockContent = '';
+ let inList = false;
+ let listIndentLevel = 0;
- const line = lines[i];
-
- // Handle code blocks first
- if (line.startsWith("```")) {
+ let line = lines[i].trimEnd();
+
+ // Handle code blocks
+ if (line.startsWith('```')) {
- codeBlockContent = "";
+ codeBlockContent = '';
- scroll += this.convertCodeBlock(codeBlockContent.trim()) + "\n\n";
+ scroll += 'code\n' + codeBlockContent.trim() + '\n\n';
- codeBlockContent += line + "\n";
+ codeBlockContent += line + '\n';
- // 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';
- } else if (inTable) {
- scroll += this.convertTable(tableContent) + "\n\n";
- inTable = false;
- tableContent = [];
- // Process block-level patterns
- let processed = false;
-
- // Headers
+ // Handle headers
- 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
- scroll += "> " + this.convertInlineElements(blockquoteMatch[1]) + "\n";
- processed = true;
+ scroll += '> ' + this.convertInlineElements(blockquoteMatch[1]) + '\n';
+ continue;
- // Unordered Lists
+ // Handle lists
- if (ulMatch) {
- scroll += "- " + this.convertInlineElements(ulMatch[1]) + "\n";
- processed = true;
- }
-
- // Ordered Lists
- 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';
Changed around line 95: class MarkdownToScroll {
- 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;
+ });
- 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}`;
+ });
- .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');
- 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;
- }
-
- 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;
+ }