SimpleChatTCRV:MarkDown:Cleanup overall initial go

Save copy of data being processed.

Try and sanitize the data passed for markdown to html conversion,
so that if there are any special characters wrt html in the passed
markdown content, it gets translated into a harmless text.

This also ensures that those text dont disappear, bcas of browser
trying to interpret them as html tagged content.

Trap any errors during sanitizing and or processing of the lines
in general and push them into a errors array. Callers of this
markdown class can decide whether to use the converted html or
not based on errors being empty or not or ...

Move the processing of unordered list into a function of its own.
Rather the ordered list can also use the same flow in general except
for some tiny changes including wrt the regex, potentially.
This commit is contained in:
hanishkvc 2025-11-26 03:45:34 +05:30
parent 654e234a4e
commit a1dc72ba66
1 changed files with 57 additions and 34 deletions

View File

@ -25,7 +25,11 @@ export class MarkDown {
/** @type {Array<number>} */ /** @type {Array<number>} */
listUnordered: [] listUnordered: []
} }
this.md = "" /**
* @type {Array<*>}
*/
this.errors = []
this.raw = ""
this.html = "" this.html = ""
} }
@ -40,6 +44,48 @@ export class MarkDown {
this.unwind_list_unordered() this.unwind_list_unordered()
} }
/**
* Process a unordered list one line at a time
* @param {string} line
*/
process_list_unordered(line) {
// spaces followed by - or + or * followed by a space and actual list item
let matchUnOrdered = line.match(/^([ ]*)[-+*][ ](.*)$/);
if (matchUnOrdered != null) {
let sList = 'none'
let listLvl = 0
if (this.in.listUnordered.length == 0) {
sList = 'same'
this.in.listUnordered.push(matchUnOrdered[1].length)
listLvl = this.in.listUnordered.length // ie 1
this.html += "<ul>\n"
} else {
if (this.in.listUnordered[this.in.listUnordered.length-1] < matchUnOrdered[1].length){
sList = 'same'
this.in.listUnordered.push(matchUnOrdered[1].length)
listLvl = this.in.listUnordered.length
this.html += "<ul>\n"
} else if (this.in.listUnordered[this.in.listUnordered.length-1] == matchUnOrdered[1].length){
sList = 'same'
} else {
sList = 'same'
while (this.in.listUnordered[this.in.listUnordered.length-1] > matchUnOrdered[1].length) {
this.in.listUnordered.pop()
this.html += `</ul>\n`
if (this.in.listUnordered.length == 0) {
break
}
}
}
}
if (sList == 'same') {
this.html += `<li>${matchUnOrdered[2]}</li>\n`
}
return true
}
return false
}
/** /**
* Try extract a table from markdown content, one line at a time. * Try extract a table from markdown content, one line at a time.
* This is a imperfect logic, but should give a rough semblance of a table many a times. * This is a imperfect logic, but should give a rough semblance of a table many a times.
@ -102,6 +148,9 @@ export class MarkDown {
* @param {string} line * @param {string} line
*/ */
process_line(line) { process_line(line) {
let elSanitize = document.createElement('div')
elSanitize.textContent = line
line = elSanitize.innerHTML
let lineA = line.split(' ') let lineA = line.split(' ')
if (this.in.preFenced.length > 0) { if (this.in.preFenced.length > 0) {
if (line == this.in.preFenced) { if (line == this.in.preFenced) {
@ -137,38 +186,7 @@ export class MarkDown {
this.html += `<pre class="${matchPreFenced[2]}">\n` this.html += `<pre class="${matchPreFenced[2]}">\n`
return return
} }
// spaces followed by - or + or * followed by a space and actual list item if (this.process_list_unordered(line)) {
let matchUnOrdered = line.match(/^([ ]*)[-+*][ ](.*)$/);
if ( matchUnOrdered != null) {
let sList = 'none'
let listLvl = 0
if (this.in.listUnordered.length == 0) {
sList = 'same'
this.in.listUnordered.push(matchUnOrdered[1].length)
listLvl = this.in.listUnordered.length // ie 1
this.html += "<ul>\n"
} else {
if (this.in.listUnordered[this.in.listUnordered.length-1] < matchUnOrdered[1].length){
sList = 'same'
this.in.listUnordered.push(matchUnOrdered[1].length)
listLvl = this.in.listUnordered.length
this.html += "<ul>\n"
} else if (this.in.listUnordered[this.in.listUnordered.length-1] == matchUnOrdered[1].length){
sList = 'same'
} else {
sList = 'same'
while (this.in.listUnordered[this.in.listUnordered.length-1] > matchUnOrdered[1].length) {
this.in.listUnordered.pop()
this.html += `</ul>\n`
if (this.in.listUnordered.length == 0) {
break
}
}
}
}
if (sList == 'same') {
this.html += `<li>${matchUnOrdered[2]}</li>\n`
}
return return
} }
this.unwind_list() this.unwind_list()
@ -180,9 +198,14 @@ export class MarkDown {
* @param {string} lines * @param {string} lines
*/ */
process(lines) { process(lines) {
this.raw = lines
let linesA = lines.split('\n') let linesA = lines.split('\n')
for(const line of linesA) { for(const line of linesA) {
this.process_line(line) try {
this.process_line(line)
} catch (err) {
this.errors.push(err)
}
} }
} }