kueblc / LDT

Lightweight in browser syntax highlighting
https://kueblc.github.io/LDT/
159 stars 17 forks source link

Line numbering #4

Open kueblc opened 11 years ago

pygy commented 9 months ago

Hopefully this can be useful: Usage:

new TextareaDecorator(textarea, new Parser({/*...*/}))
gutter(textarea)

The gutter can be styled by targetting .ldt::before.

Demo:

live

Screen Recording 2024-01-20 at 15.28.38.webm

Code:

let stylesInjected = false
function injectStyles(){
    if (!stylesInjected) {
    stylesInjected = true
    document.head.append(
      Object.assign(
        document.createElement('style'), 
        {textContent: `
.ldt {
  --gutter-scale: 1;
  --gutter-content: "1";
  --gutter-extra-width: 3;
}
.ldt label {
  padding-left: 0;
}
.ldt, .ldt textarea {
  padding-left: calc((var(--gutter-scale) + var(--gutter-extra-width)) * 1ch);
/*   transition: padding-left .5s; */
}

.ldt::before{
  background-color: #f6f6f6;
  box-sizing: border-box;

  color: grey;
  content: var(--gutter-content);
  display: block;
  left: 0;
  padding-right: calc(var(--gutter-extra-width)/2 * 1ch);
  position: absolute;
  text-align: right;
  white-space: pre;
  width: calc((var(--gutter-scale) + var(--gutter-extra-width)) * 1ch);
/*   transition: width .5s; */
}`}
    ))
  }
}

function gutter(textarea) {
  injectStyles()

  const parent = textarea.parentElement.parentElement
  parent.addEventListener("input", update, false)
  update()

  function update() {
    const lines = textarea.rows - 2
    const size = Math.ceil(Math.log10(lines + 1))
    const content = "'"+Array.from({length: lines}, (_, i)=>`${i+1}`.padStart(size, ' ')).join("\\A ")+"'"
    parent.style.setProperty('--gutter-scale', size)
    parent.style.setProperty('--gutter-content', content)
  }
}

Edit: I've published it on NPM with a tweaked version of LDT as @pygy/ldt-esm.

Live example here