Autoformat all tables on a page
This commit is contained in:
parent
b59c6c8b58
commit
8680cc5a62
4 changed files with 84 additions and 28 deletions
|
|
@ -8,7 +8,7 @@ export class N2File extends CustomHTMLElement {
|
|||
:host {
|
||||
display: inline-grid;
|
||||
grid-template-columns: min-content min-content;
|
||||
align-items: center;
|
||||
align-items: end;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,13 +75,17 @@ export class N2PageNodeUI extends CustomHTMLElement {
|
|||
this.elNodeContent.addEventListener('input', event => this.contentChanged(event))
|
||||
this.elNodeContent.addEventListener('paste', async (event) => this.pasteHandler(event))
|
||||
this.elIconMarkdown.addEventListener('click', () => this.showMarkdown(!this.showMarkdown()))
|
||||
this.elIconTableFormat.addEventListener('click', () => {
|
||||
const from = this.elNodeContent.selectionStart
|
||||
const to = this.elNodeContent.selectionEnd
|
||||
const sel = this.elNodeContent.value.slice(from, to)
|
||||
|
||||
this.formatTable(sel)
|
||||
this.elIconTableFormat.addEventListener('click', event => {
|
||||
if (!event.shiftKey)
|
||||
this.elNodeContent.value = this.formatAllTables(this.elNodeContent.value)
|
||||
else {
|
||||
const from = this.elNodeContent.selectionStart
|
||||
const to = this.elNodeContent.selectionEnd
|
||||
const text = this.elNodeContent.value.slice(from, to)
|
||||
|
||||
const formatted = this.formatAllTables(text)
|
||||
this.elNodeContent.setRangeText(formatted, from, to, 'select');
|
||||
}
|
||||
})
|
||||
|
||||
this.showMarkdown(true)
|
||||
|
|
@ -164,37 +168,88 @@ export class N2PageNodeUI extends CustomHTMLElement {
|
|||
this.elNodeContent.selectionEnd = data.position.end
|
||||
this.elNodeContent.focus()
|
||||
}// }}}
|
||||
formatTable(t) {
|
||||
const lines = t.split(/\r?\n/)
|
||||
if (lines < 1)
|
||||
return
|
||||
|
||||
let first = -1
|
||||
let last = -1
|
||||
findTables(lines) {// {{{
|
||||
let tables = []
|
||||
let curr = { from: -1, to: -1 }
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const linecols = lines[i].split('|').length - 2 // Gives empty value in front of first pipe and after last one.
|
||||
|
||||
if (linecols >= 1) {
|
||||
if (curr.from == -1)
|
||||
curr.from = i
|
||||
curr.to = i
|
||||
} else if (linecols < 1 && curr.to > -1) {
|
||||
tables.push(curr)
|
||||
curr = { from: -1, to: -1 }
|
||||
}
|
||||
}
|
||||
|
||||
if (curr.from > -1)
|
||||
tables.push(curr)
|
||||
|
||||
return tables
|
||||
}// }}}
|
||||
formatAllTables(text) {// {{{
|
||||
const lines = text.split(/\r?\n/)
|
||||
const tables = this.findTables(lines)
|
||||
for (const table of tables) {
|
||||
const formattedLines = this.formatTable(lines.slice(table.from, table.to + 1))
|
||||
lines.splice(table.from, formattedLines.length, ...formattedLines)
|
||||
}
|
||||
|
||||
return lines.join("\n")
|
||||
}// }}}
|
||||
formatTable(lines) {// {{{
|
||||
let numColumns = 0
|
||||
let colwidth = []
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
// -1 for split, -1 because number of columns are one less than number of pipes.
|
||||
const columns = lines[i].split('|')
|
||||
const linecols = columns.length - 1 - 1
|
||||
const columns = lines[i].split('|').slice(1)
|
||||
const linecols = columns.length - 2
|
||||
numColumns = Math.max(numColumns, linecols)
|
||||
|
||||
if (linecols >= 1) {
|
||||
if (first == -1)
|
||||
first = i
|
||||
last = i
|
||||
continue
|
||||
// Keep count of column width.
|
||||
for (let j = 0; j < columns.length - 1; j++) {
|
||||
colwidth[j] = Math.max(colwidth[j] || 0, columns[j].trim().length)
|
||||
}
|
||||
|
||||
if (linecols < 1 && last > -1)
|
||||
break
|
||||
|
||||
// Keep count of column width
|
||||
}
|
||||
|
||||
console.log(first, last, columns)
|
||||
}
|
||||
// Build up each line correct.
|
||||
let extendHeader
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
// Build lines with columns.
|
||||
const cols = lines[i].split('|').slice(1, -1)
|
||||
|
||||
// Second line should be headers.
|
||||
if (i === 1) {
|
||||
extendHeader = true
|
||||
for (let j = 0; j < colwidth.length; j++) {
|
||||
extendHeader &= ((cols[j] || '').match(/^\s*[-]*\s*$/) !== null)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (i === 1 && extendHeader) {
|
||||
for (let j = 0; j < colwidth.length; j++)
|
||||
cols[j] = '-'.repeat(colwidth[j])
|
||||
|
||||
} else {
|
||||
for (let j = 0; j < colwidth.length; j++) {
|
||||
cols[j] = (cols[j] || '').trim()
|
||||
const cw = colwidth[j]
|
||||
const padWidth = cw - (cols[j]?.length || 0) // may be a column that doesn't exist on this line.
|
||||
cols[j] = cols[j] + ' '.repeat(padWidth > 0 ? padWidth : 0)
|
||||
}
|
||||
}
|
||||
|
||||
lines[i] = '│ ' + cols.join(' │ ') + ' │'
|
||||
}
|
||||
|
||||
return lines
|
||||
}// }}}
|
||||
}
|
||||
customElements.define('n2-nodeui', N2PageNodeUI)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue