51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
enum LineType {
|
|
BLANK,
|
|
NORMAL,
|
|
}
|
|
|
|
export type LineData = {
|
|
line: string;
|
|
indent: string;
|
|
type: number;
|
|
level: number;
|
|
offsetHead: number;
|
|
offsetTail: number;
|
|
}
|
|
|
|
export function createLineData(line: string = '', indent: string = ' '): LineData {
|
|
return { line, indent, type: 0, level: 0, offsetHead: 0, offsetTail: 0 }
|
|
}
|
|
|
|
export function parseLine(lineData: LineData): LineData {
|
|
if ((typeof lineData !== 'object' || !lineData) || typeof lineData.type !== 'number' || typeof lineData.level !== 'number') throw new Error(`'lineData' must be an object with 'line' string, and 'type' and 'level' integer properties`)
|
|
if (typeof lineData.indent !== 'string' || lineData.indent.length === 0 || lineData.indent.length > 1) throw new Error(`'lineData.indent' must be a single-character string`)
|
|
if (typeof lineData.line !== 'string') throw new Error(`'lineData.line' must be a string`)
|
|
|
|
let type = LineType.BLANK
|
|
let level = 0
|
|
|
|
if (!lineData.line.length) {
|
|
// TODO: Not sure if this is necessary. If the previous line was a normal line, it makes the blank line a child of the normal line.
|
|
// If the previous line was a blank line, the blank line retains the same level.
|
|
if (lineData.type === LineType.NORMAL) level = lineData.level + 1
|
|
if (lineData.type === LineType.BLANK) level = lineData.level
|
|
|
|
lineData.type = type
|
|
lineData.level = level
|
|
lineData.offsetHead = 0
|
|
lineData.offsetTail = 0
|
|
} else {
|
|
type = LineType.NORMAL
|
|
|
|
while (lineData.line[level] === lineData.indent && level <= lineData.level + 1) ++level
|
|
lineData.type = type
|
|
lineData.level = level
|
|
lineData.offsetHead = level
|
|
lineData.offsetTail = level
|
|
|
|
while (lineData.line[lineData.offsetTail] && lineData.line[lineData.offsetTail] !== ' ') ++lineData.offsetTail
|
|
}
|
|
|
|
return lineData
|
|
}
|