A toggle script which alternates between:
- Pruning out any blank lines in the TaskPaper document, and
- adding blank lines to visually separate each document section.
(i.e. adding a blank line after any childless leaf which is the last in its sibling range)
Expand disclosure triangle to view JS source
(() => {
"use strict";
// Toggling separating space on and off between
// sections of a Taskpaper 3 document.
// A toggle script which alternates between:
// Pruning out any blank lines in the TaskPaper document.
// Adding a separating blank line after each document section.
// (i.e. adding a blank line after any childless leaf
// which is the last in its sibling range)
// Rob Trew @2022
// Ver 0.01
// ---------- TASKPAPER EVALUATION CONTEXT -----------
const tp3Context = editor => {
const tp3Main = () => {
const
outline = editor.outline,
gaps = outline.items.filter(
x => 0 === x.bodyString.trim().length
),
nEmpty = gaps.length;
return 0 < nEmpty ? (
outline.removeItems(gaps),
`Closed up ${nEmpty} empty lines.`
) : (() => {
const
sectionEnds = lastLeaves(outline.root),
nParts = sectionEnds.length;
return (
outline.groupUndoAndChanges(
() => sectionEnds.forEach(
leaf => leaf.parent
.appendChildren(
outline.createItem("")
)
)
),
`Added space after ${nParts} sections.`
);
})();
};
// ----------------- LAST LEAVES -----------------
// lastLeaves :: Item -> [Item]
const lastLeaves = item =>
// Any leaves, descending from the given item,
// which are the last in their sibling range.
item.hasChildren ? (() => {
const lastChild = item.lastChild;
return item.children.flatMap(lastLeaves)
.concat(
lastChild.hasChildren ? [] : lastChild
);
})() : [];
// ---
return tp3Main();
};
// ------------- JXA EVALUATION CONTEXT --------------
// main :: IO ()
const main = () => {
const
doc = Application("TaskPaper")
.documents.at(0);
return doc.exists() ? (
doc.evaluate({script: `${tp3Context}`})
) : "No document open in TaskPaper.";
};
// MAIN ---
return main();
})();