How to get parent node as text

I want something similar like

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

return doc.exists()
    ? doc.export({
        from: doc.selectionRow(),
        all: false,
        as: "plain text format"
    })
        .trim()
    : "";

from @complexpoint shared in How to get current selected line as text without keybind hacks

but to get parent task

i.e. here:

I would get this value: get app.thepakt.com building with the new tanstack etc.

I think .containerRow() is the method you need:

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

return doc.exists()
    ? doc.export({
        from: doc.selectionRow.containerRow(),
        all: false,
        as: "plain text format"
    })
        .trim()
    : "";
1 Like

that works well, thanks

1 Like

Another approach to these questions is to use an outline path (relative to the selected line) with a macro like the one below.

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


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();
})();
2 Likes