BIKE - Copy Text from One or More Relatives of Selected Row

A macro for Jesse Grosjean's Bike Outliner.


Copies text relative to the selected row in Bike (by outline path)

Line(s) to copy Outline path
Selected row .
Parent of selected row ..
Subtree of selected row descendant-or-self::*
Inclusive path to selected row ancestor-or-self::*
Exclusive path to selected row ancestor::*
Other Using Outline Paths | Bike

BIKE - Copy Text from One or More Relatives of Selected Row (by outline path).kmmacros (17 KB)


Other Keyboard Maestro macros for BIKE Outliner


Expand disclosure triangle to view JS source
return (() => {
    "use strict";

    const main = () => {
        const doc = Application("Bike").documents.at(0);

        return doc.exists()
            ? (() => {
                const
                    selnID = doc.selectionRow.id(),

                    subPath = kmvar.local_PathFromRow,

                    outlinePath = `//@id="${selnID}"/${subPath}`,

                    from = doc.query({ outlinePath }),

                    formatName = formatTitle(
                        kmvar.local_ExportFormat
                    );

                return 0 < from.length
                    ? outlineFullLeft(
                        doc.export({
                            from,
                            as: `${formatName} format`,
                            all: false
                        })
                    )
                    : `No matches from selection for ${subPath}`
            })()
            : "";
    };


    // formatTitle :: String -> ("bike" | "OPML" | "plain text")
    const formatTitle = s => {
        // Normalised for API
        // (defaulting to "plain text")
        const k = s.toLocaleLowerCase();

        return k.includes("plain") || k.includes("xt")
            ? "plain text"
            : k.includes("opml")
                ? "OPML"
                : k.includes("bike") || k.includes("ml")
                    ? "bike"
                    : "plain text";
    };


    // outlineFullLeft :: String -> String
    const outlineFullLeft = txt => {
        // A plain text outline with any surplus
        // indentation pruned out.
        const
            xs = txt.split("\n"),
            rgxIndent = /^\s*/u,
            mindent = Math.min(
                ...xs.map(s => s.match(
                    rgxIndent)[0].length
                )
            );

        return xs.map(
            x => x.slice(mindent)
        )
            .join("\n");
    };

    // MAIN ---
    return main();
})();