From 2242ad44024fa74225b43582b52563b9fb366c6e Mon Sep 17 00:00:00 2001 From: hanishkvc Date: Wed, 26 Nov 2025 16:03:07 +0530 Subject: [PATCH] SimpleChatTCRV:Markdown:List: Allow split line items If the split lines dont have any empty lines inbetween and also remain within the block area of the list item which they belong to, then the split line will be appended to the corresponding list item, ELSE a new list item will be created. To help with same a generic keyed empty lines tracker logic has been added. TODO: Account similar semantic wrt paragraph related split lines --- .../public_simplechat/docs/changelog.md | 6 ++- tools/server/public_simplechat/typemd.mjs | 39 +++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/tools/server/public_simplechat/docs/changelog.md b/tools/server/public_simplechat/docs/changelog.md index 017e975abb..66bdffa20f 100644 --- a/tools/server/public_simplechat/docs/changelog.md +++ b/tools/server/public_simplechat/docs/changelog.md @@ -300,7 +300,11 @@ Chat Session specific settings * the user can change the default behaviour of tools being disabled and sliding window of 1 * program restart will reset these back to the default * Ui module cleanup to avoid duplicated/unneeded boiler plates, including using updated jsdoc annotations -* A simple minded basic Markdown to Html logic +* A simple minded basic Markdown to Html logic with support for + * headings + * lists (ordered, unordered, intermixed at diff leves) + * tables + * fenced code blocks ## ToDo diff --git a/tools/server/public_simplechat/typemd.mjs b/tools/server/public_simplechat/typemd.mjs index 1380835c35..125f68343b 100644 --- a/tools/server/public_simplechat/typemd.mjs +++ b/tools/server/public_simplechat/typemd.mjs @@ -28,7 +28,7 @@ export class MarkDown { /** @type {Array} */ endType: [], }, - /** @type {Object} */ + /** @type {Object} */ empty: { } } @@ -40,6 +40,23 @@ export class MarkDown { this.html = "" } + /** + * @param {string} key + * @param {string} line + */ + empty_tracker(key, line) { + if (this.in.empty[key] == undefined) { + this.in.empty[key] = 0 + } + let prev = this.in.empty[key] + if (line.trim().length == 0) { + this.in.empty[key] += 1 + } else { + this.in.empty[key] = 0 + } + return {prev: prev, cur: this.in.empty[key]} + } + unwind_list() { while (true) { let popped = this.in.list.endType.pop() @@ -52,10 +69,19 @@ export class MarkDown { } /** - * Process list one line at a time + * Process list one line at a time. + * * Account for ordered lists as well as unordered lists, including intermixing of the lists. + * at different list hierarchy levels. + * * Allow a list item line to be split into multiple lines provided the split lines retain + * the same or more line offset compared to the starting line of the item to which they belong. + * * if there is a empty line in between, then the new line will be treated as a new item. + * * allows for empty lines inbetween items. + * * currently there is no limit on the number of empty lines. + * but may bring in a limit later. * @param {string} line */ process_list(line) { + let emptyTracker = this.empty_tracker("list", line) // spaces followed by - or + or * followed by a space and actual list item let matchList = line.match(/^([ ]*)([-+*]|[a-zA-Z0-9]\.)[ ](.*)$/); if (matchList != null) { @@ -89,7 +115,7 @@ export class MarkDown { return true } else { if (this.in.list.offsets.length > 0) { - if (line.trim().length == 0) { + if (emptyTracker.cur > 0) { return true } let matchOffset = line.match(/^([ ]*)(.*)$/); @@ -100,7 +126,12 @@ export class MarkDown { if (matchOffset[1].length < lastOffset) { return false } - this.html += `
  • ${matchOffset[2]}
  • \n` + if ((emptyTracker.prev != 0) || (!this.html.endsWith("\n"))) { + this.html += `
  • ${matchOffset[2]}
  • \n` + } else { + let html = this.html + this.html = `${html.slice(0,html.length-"\n".length)} ${matchOffset[2]}\n` + } return true } }