Autoformat all tables on a page
This commit is contained in:
parent
b59c6c8b58
commit
8680cc5a62
4 changed files with 84 additions and 28 deletions
|
|
@ -42,6 +42,7 @@
|
||||||
table {
|
table {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
margin-top: 14px;
|
||||||
|
|
||||||
th {
|
th {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ html {
|
||||||
"tree hum content content ding"
|
"tree hum content content ding"
|
||||||
"tree hum blank blank ding"
|
"tree hum blank blank ding"
|
||||||
;
|
;
|
||||||
grid-template-columns: min-content minmax(16px, 1fr) minmax(min-content, 820px) 80px minmax(16px, 1fr);
|
grid-template-columns: min-content minmax(16px, 1fr) minmax(min-content, calc(900px - 120px)) 120px minmax(16px, 1fr);
|
||||||
grid-template-rows:
|
grid-template-rows:
|
||||||
min-content min-content 48px 1fr;
|
min-content min-content 48px 1fr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export class N2File extends CustomHTMLElement {
|
||||||
:host {
|
:host {
|
||||||
display: inline-grid;
|
display: inline-grid;
|
||||||
grid-template-columns: min-content min-content;
|
grid-template-columns: min-content min-content;
|
||||||
align-items: center;
|
align-items: end;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,13 +75,17 @@ export class N2PageNodeUI extends CustomHTMLElement {
|
||||||
this.elNodeContent.addEventListener('input', event => this.contentChanged(event))
|
this.elNodeContent.addEventListener('input', event => this.contentChanged(event))
|
||||||
this.elNodeContent.addEventListener('paste', async (event) => this.pasteHandler(event))
|
this.elNodeContent.addEventListener('paste', async (event) => this.pasteHandler(event))
|
||||||
this.elIconMarkdown.addEventListener('click', () => this.showMarkdown(!this.showMarkdown()))
|
this.elIconMarkdown.addEventListener('click', () => this.showMarkdown(!this.showMarkdown()))
|
||||||
this.elIconTableFormat.addEventListener('click', () => {
|
this.elIconTableFormat.addEventListener('click', event => {
|
||||||
|
if (!event.shiftKey)
|
||||||
|
this.elNodeContent.value = this.formatAllTables(this.elNodeContent.value)
|
||||||
|
else {
|
||||||
const from = this.elNodeContent.selectionStart
|
const from = this.elNodeContent.selectionStart
|
||||||
const to = this.elNodeContent.selectionEnd
|
const to = this.elNodeContent.selectionEnd
|
||||||
const sel = this.elNodeContent.value.slice(from, to)
|
const text = this.elNodeContent.value.slice(from, to)
|
||||||
|
|
||||||
this.formatTable(sel)
|
|
||||||
|
|
||||||
|
const formatted = this.formatAllTables(text)
|
||||||
|
this.elNodeContent.setRangeText(formatted, from, to, 'select');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.showMarkdown(true)
|
this.showMarkdown(true)
|
||||||
|
|
@ -164,37 +168,88 @@ export class N2PageNodeUI extends CustomHTMLElement {
|
||||||
this.elNodeContent.selectionEnd = data.position.end
|
this.elNodeContent.selectionEnd = data.position.end
|
||||||
this.elNodeContent.focus()
|
this.elNodeContent.focus()
|
||||||
}// }}}
|
}// }}}
|
||||||
formatTable(t) {
|
|
||||||
const lines = t.split(/\r?\n/)
|
|
||||||
if (lines < 1)
|
|
||||||
return
|
|
||||||
|
|
||||||
let first = -1
|
findTables(lines) {// {{{
|
||||||
let last = -1
|
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 numColumns = 0
|
||||||
let colwidth = []
|
let colwidth = []
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
// -1 for split, -1 because number of columns are one less than number of pipes.
|
// -1 for split, -1 because number of columns are one less than number of pipes.
|
||||||
const columns = lines[i].split('|')
|
const columns = lines[i].split('|').slice(1)
|
||||||
const linecols = columns.length - 1 - 1
|
const linecols = columns.length - 2
|
||||||
numColumns = Math.max(numColumns, linecols)
|
numColumns = Math.max(numColumns, linecols)
|
||||||
|
|
||||||
if (linecols >= 1) {
|
// Keep count of column width.
|
||||||
if (first == -1)
|
for (let j = 0; j < columns.length - 1; j++) {
|
||||||
first = i
|
colwidth[j] = Math.max(colwidth[j] || 0, columns[j].trim().length)
|
||||||
last = i
|
}
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linecols < 1 && last > -1)
|
// Build up each line correct.
|
||||||
break
|
let extendHeader
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
// Build lines with columns.
|
||||||
|
const cols = lines[i].split('|').slice(1, -1)
|
||||||
|
|
||||||
// Keep count of column width
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(first, last, columns)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
customElements.define('n2-nodeui', N2PageNodeUI)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue