A pair of macros for Jesse Grosjean's Bike Outliner.
AZ ascending (or ZA descending) sort of the children of the selected row.
BikeSortingPairOfMacros.kmmacros (50.2 KB)
Expand disclosure triangle to view JS source
(() => {
"use strict";
// First draft of a `Sort children of selected line`
// for Bike.
// RobTrew @2022
// Ver 0.02
// --------------------- OPTION ----------------------
// Edit the option value below to `true` if you need a
// descending sort, or to `false` for ascending.
const orderZA = false;
// -------------- SORTED BIKE SIBLINGS ---------------
// main :: IO ()
const main = () => {
const doc = Application("Bike").documents.at(0);
return doc.exists() ? (() => {
const
rows = doc.rows,
parentRow = rows.where({
_and: [
{selected: true},
{_not: [{
name: ""
}]}
]
}).at(0);
return parentRow.exists() && (
0 < parentRow.rows.length
) ? (() => {
const
children = parentRow.rows.where(
{_not: [{
name: ""
}]}
),
sortOrder = orderZA ? (
flip(comparing(fst))
) : comparing(fst);
return sortBy(sortOrder)(
zip(
children.name()
)(
children.id()
)
)
.map(
nameID => (
rows.byId(nameID[1]).move({
to: parentRow
}),
nameID[0]
)
)
.join("\n");
})() : "No row with children selected.";
})() : "No documents open in Bike";
};
// --------------------- GENERIC ---------------------
// comparing :: Ord a => (b -> a) -> b -> b -> Ordering
const comparing = f =>
// The ordering of f(x) and f(y) as a value
// drawn from {-1, 0, 1}, representing {LT, EQ, GT}.
x => y => {
const
a = f(x),
b = f(y);
return a < b ? -1 : (a > b ? 1 : 0);
};
// flip :: (a -> b -> c) -> b -> a -> c
const flip = op =>
// The binary function op with
// its arguments reversed.
1 !== op.length ? (
(a, b) => op(b, a)
) : (a => b => op(b)(a));
// fst :: (a, b) -> a
const fst = tpl =>
// First member of a pair.
tpl[0];
// sortBy :: (a -> a -> Ordering) -> [a] -> [a]
const sortBy = f =>
// A copy of xs sorted by the comparator function f.
xs => xs.slice()
.sort((a, b) => f(a)(b));
// zip :: [a] -> [b] -> [(a, b)]
const zip = xs =>
// The paired members of xs and ys, up to
// the length of the shorter of the two lists.
ys => Array.from({
length: Math.min(xs.length, ys.length)
}, (_, i) => [xs[i], ys[i]]);
// MAIN ---
return main();
})();