Files
dealplustech/node_modules/micromark-extension-gfm-table/dev/lib/edit-map.js
Kunthawat 77ac4d2d05 feat: Upgrade to Astro with full PDPA compliance
PDPA Features:
 Cookie consent banner
 Consent logging API
 Admin dashboard
 Privacy Policy
 Terms & Conditions

Technical:
 Astro 5.x + Tailwind v4
 Docker on port 80
 SQLite database
 15 pages built

Ready for Easypanel deployment.
2026-03-12 10:01:04 +07:00

213 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @import {Event} from 'micromark-util-types'
*/
// Port of `edit_map.rs` from `markdown-rs`.
// This should move to `markdown-js` later.
// Deal with several changes in events, batching them together.
//
// Preferably, changes should be kept to a minimum.
// Sometimes, its needed to change the list of events, because parsing can be
// messy, and it helps to expose a cleaner interface of events to the compiler
// and other users.
// It can also help to merge many adjacent similar events.
// And, in other cases, its needed to parse subcontent: pass some events
// through another tokenizer and inject the result.
/**
* @typedef {[number, number, Array<Event>]} Change
* @typedef {[number, number, number]} Jump
*/
/**
* Tracks a bunch of edits.
*/
export class EditMap {
/**
* Create a new edit map.
*/
constructor() {
/**
* Record of changes.
*
* @type {Array<Change>}
*/
this.map = []
}
/**
* Create an edit: a remove and/or add at a certain place.
*
* @param {number} index
* @param {number} remove
* @param {Array<Event>} add
* @returns {undefined}
*/
add(index, remove, add) {
addImplementation(this, index, remove, add)
}
// To do: add this when moving to `micromark`.
// /**
// * Create an edit: but insert `add` before existing additions.
// *
// * @param {number} index
// * @param {number} remove
// * @param {Array<Event>} add
// * @returns {undefined}
// */
// addBefore(index, remove, add) {
// addImplementation(this, index, remove, add, true)
// }
/**
* Done, change the events.
*
* @param {Array<Event>} events
* @returns {undefined}
*/
consume(events) {
this.map.sort(function (a, b) {
return a[0] - b[0]
})
/* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */
if (this.map.length === 0) {
return
}
// To do: if links are added in events, like they are in `markdown-rs`,
// this is needed.
// // Calculate jumps: where items in the current list move to.
// /** @type {Array<Jump>} */
// const jumps = []
// let index = 0
// let addAcc = 0
// let removeAcc = 0
// while (index < this.map.length) {
// const [at, remove, add] = this.map[index]
// removeAcc += remove
// addAcc += add.length
// jumps.push([at, removeAcc, addAcc])
// index += 1
// }
//
// . shiftLinks(events, jumps)
let index = this.map.length
/** @type {Array<Array<Event>>} */
const vecs = []
while (index > 0) {
index -= 1
vecs.push(
events.slice(this.map[index][0] + this.map[index][1]),
this.map[index][2]
)
// Truncate rest.
events.length = this.map[index][0]
}
vecs.push(events.slice())
events.length = 0
let slice = vecs.pop()
while (slice) {
for (const element of slice) {
events.push(element)
}
slice = vecs.pop()
}
// Truncate everything.
this.map.length = 0
}
}
/**
* Create an edit.
*
* @param {EditMap} editMap
* @param {number} at
* @param {number} remove
* @param {Array<Event>} add
* @returns {undefined}
*/
function addImplementation(editMap, at, remove, add) {
let index = 0
/* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */
if (remove === 0 && add.length === 0) {
return
}
while (index < editMap.map.length) {
if (editMap.map[index][0] === at) {
editMap.map[index][1] += remove
// To do: before not used by tables, use when moving to micromark.
// if (before) {
// add.push(...editMap.map[index][2])
// editMap.map[index][2] = add
// } else {
editMap.map[index][2].push(...add)
// }
return
}
index += 1
}
editMap.map.push([at, remove, add])
}
// /**
// * Shift `previous` and `next` links according to `jumps`.
// *
// * This fixes links in case there are events removed or added between them.
// *
// * @param {Array<Event>} events
// * @param {Array<Jump>} jumps
// */
// function shiftLinks(events, jumps) {
// let jumpIndex = 0
// let index = 0
// let add = 0
// let rm = 0
// while (index < events.length) {
// const rmCurr = rm
// while (jumpIndex < jumps.length && jumps[jumpIndex][0] <= index) {
// add = jumps[jumpIndex][2]
// rm = jumps[jumpIndex][1]
// jumpIndex += 1
// }
// // Ignore items that will be removed.
// if (rm > rmCurr) {
// index += rm - rmCurr
// } else {
// // ?
// // if let Some(link) = &events[index].link {
// // if let Some(next) = link.next {
// // events[next].link.as_mut().unwrap().previous = Some(index + add - rm);
// // while jumpIndex < jumps.len() && jumps[jumpIndex].0 <= next {
// // add = jumps[jumpIndex].2;
// // rm = jumps[jumpIndex].1;
// // jumpIndex += 1;
// // }
// // events[index].link.as_mut().unwrap().next = Some(next + add - rm);
// // index = next;
// // continue;
// // }
// // }
// index += 1
// }
// }
// }