Alternating line-by-line background colors


#1

I’d like to create a stylesheet that alternates background color on a line-by-line basis, e.g., white and light-green, similar to what you’d find on a traditional columnar accounting pad to make line differentiation visually easier.

How would I do this, assuming it is possible? Perhaps a script?

Thank you.


#2

I don’t think it’s possible without a script. With a script you can get started, though I’m not sure you’ll arive at a satisfactory solution. Here’s a quick start:

function EvenOddLineMarkerTaskPaperContextScript(editor, options) {
  function markEvenOddLines() {
    let items = editor.displayedItems
	editor.outline.undoManager.disableUndoRegistration()
    for (var i = 0; i < items.length; i++) {
      let item = items[i]
	  let mark = i % 2 ? 'odd' : 'even'
      item.setAttribute('line', mark)
    }
	editor.outline.undoManager.enableUndoRegistration()
  }

  markEvenOddLines()
  
  editor.outline.onDidChange(function(mutation) {
    setTimeout(markEvenOddLines, 0)
  })
}

Application("TaskPaper").documents[0].evaluate({
  script: EvenOddLineMarkerTaskPaperContextScript.toString()
})

If you run that script it will mark all lines in the frontmost editor with line=odd or line=even attributes. It will also setup an event handler to remark all editor lines anytime the outline model changes. You can then style based on those attributes like this:

item[line=even] {
  background-color: red;
}
item[line=odd] {
  background-color: green;
}

It’s a start! Drawbacks include:

  1. I think it will slow down typing in longer documents
  2. The script is using some private “undoManger” API … could change in future, though I wouldn’t expect this particular bit to change.
  3. Script only updates when content changes, if you just fold / focus the lines won’t be colored. Possible to fix with more private API, but if you really want. Let me know.