How to align lines in two variables?

I have 3 variables:


The variable Local_sourceSegments contains:

This is the first sentence.
This is the second sentence.
This is the third sentence.
This is the fourth sentence.
This is the fifth sentence.

The variable Local_targetSegments contains:

Dit is de eerste zin.
Dit is de tweede zin.
Dit is de derde zin.
Dit is de vierde zin.
Dit is de vijfde zin.

The variable Local_alignedSegments should contain:

<tu><tuv xml:lang="en-US"><seg>This is the first sentence.</seg></tuv><tuv xml:lang="nl-NL"><seg>Dit is de eerste zin.</seg></tuv></tu>
<tu><tuv xml:lang="en-US"><seg>This is the second sentence.</seg></tuv><tuv xml:lang="nl-NL"><seg>Dit is de tweede zin.</seg></tuv></tu>
<tu><tuv xml:lang="en-US"><seg>This is the third sentence.</seg></tuv><tuv xml:lang="nl-NL"><seg>Dit is de derde zin.</seg></tuv></tu>
<tu><tuv xml:lang="en-US"><seg>This is the fourth sentence.</seg></tuv><tuv xml:lang="nl-NL"><seg>Dit is de vierde zin.</seg></tuv></tu>
<tu><tuv xml:lang="en-US"><seg>This is the fifth sentence.</seg></tuv><tuv xml:lang="nl-NL"><seg>Dit is de vijfde zin.</seg></tuv></tu>

How can I align every line in Local_sourceSegments with the corresponding line in Local_targetSegments?

Here's one way to do it:

Combine Two Lists as Columns.kmmacros (23 KB)

Macro screenshot

1 Like

Use the new ability in Keyboard Maestro 11 to index variables with linefeed separators. Use [0] to get the count, and then a For Each action with Number Range collection to index over them.

Keyboard Maestro Actions.kmactions (3.8 KB)

Keyboard Maestro Export

Note that you don't really need the two Set Variable actions inside the For Each, that is just for clarity - the tokens could be inserted directly into the Append Variable action.

7 Likes

Thank you Neil, thank you Peter!

Peter, I downloaded Keyboard Maestro Actions.kmactions. I see that it is an action, but where do I find it/how do I run it? (I cannot see it in KM at all.) Thank you.

Double-click the downloaded file and it will be imported into the current macro.

Action files can be dragged in to any macro while editing the macros.

No one uses them except me :slight_smile:

:wave:t3: I do!

1 Like

and of course this is such a commonly needed pattern that languages like python have
built-in functions with names like zip or zipWith.

JS has nothing out of the box, but we can define a reusable one.

Assuming Keyboard Maestro 11, for example:

Source and target strings zipped together.kmmacros (3.5 KB)


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

    const main = () => 
        zipWith(
            src => tgt => [
                `<tu><tuv xml:lang="en-US"><seg>${src}</seg></tuv>`,
                `<tuv xml:lang="nl-NL"><seg>${tgt}</seg></tuv></tu>`
            ]
            .join("")
        )(
            kmvar.Local_sourceSegments.split("\n")
        )(
            kmvar.Local_targetSegments.split("\n")
        )
        .join("\n");

    // --------------------- GENERIC ---------------------

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => xs.map(
            (x, i) => f(x)(ys[i])
        ).slice(
            0, Math.min(xs.length, ys.length)
        );

    return main();
// })();
1 Like

I use action files, but in a different way.

Hum, I had never tried dragging them into a macro, but then again I rarely use drag-and-drop because, in general, I avoid the mouse due to ergo pain caused by years of mouse overuse.

I do, however, (in the Finder) select and open (⌘+o) action files which inserts the actions below the selected actions or at the end of the selected macro (if no actions are selected in the Keyboard Maestro Editor).

1 Like

You can also paste the xml values of whatever actions you want quick access to. (Stream Deck for the win!)

1 Like