mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-12 09:32:30 -05:00
1012dbc3c4
Document Outline Spike GitOrigin-RevId: adc315a3546147eb10c7a40ae70f9cab1cbf7b8d
50 lines
1.2 KiB
JavaScript
50 lines
1.2 KiB
JavaScript
const COMMAND_LEVELS = {
|
|
section: 0,
|
|
subsection: 1,
|
|
subsubsection: 2
|
|
}
|
|
|
|
function matchOutline(content) {
|
|
const lines = content.split('\n')
|
|
const flatOutline = []
|
|
lines.forEach((line, lineId) => {
|
|
const match = line.match(/\\(?<command>[sub]*section)\{(?<title>[^}]+)\}/)
|
|
if (!match) return
|
|
const {
|
|
groups: { command, title }
|
|
} = match
|
|
flatOutline.push({
|
|
line: lineId + 1,
|
|
title,
|
|
level: COMMAND_LEVELS[command]
|
|
})
|
|
})
|
|
return flatOutline
|
|
}
|
|
|
|
function nestOutline(flatOutline) {
|
|
let parentOutlines = {}
|
|
let nestedOutlines = []
|
|
flatOutline.forEach(outline => {
|
|
const parentOutline = parentOutlines[outline.level - 1]
|
|
if (!parentOutline) {
|
|
// top level
|
|
nestedOutlines.push(outline)
|
|
} else if (!parentOutline.children) {
|
|
// first outline in this node
|
|
parentOutline.children = [outline]
|
|
} else {
|
|
// push outline to node
|
|
parentOutline.children.push(outline)
|
|
}
|
|
parentOutlines[outline.level] = outline
|
|
})
|
|
return nestedOutlines
|
|
}
|
|
|
|
function parseOutline(content) {
|
|
const flatOutline = matchOutline(content)
|
|
return nestOutline(flatOutline)
|
|
}
|
|
|
|
export default parseOutline
|