Converting a text file

I should convert a file with some text to a new text file (extension .srt) with a specific format, so that I can import it as subtitles into video production software.

This is an example of the source text file:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras libero urna, consectetur ac libero sed, feugiat commodo

Praesent eget venenatis tellus, vel pellentesque.

Mauris ligula orci, ornare ut pharetra a, mattis quis
purus. Vestibulum ante ipsum primis in faucibus orci luctus

et ultrices posuere cubilia curae; Sed placerat scelerisque
ante ut volutpat. Curabitur placerat efficitur libero ut

Each line is separated by a line break, each subtitle is separated by a blank line.

The result, from the text above, should be this:

1
00:00:00,000 --> 00:00:03,000
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras libero urna, consectetur ac libero sed, feugiat commodo

2
00:00:03,000 --> 00:00:06,000
Praesent eget venenatis tellus, vel pellentesque.

3
00:00:06,000 --> 00:00:09,000
Mauris ligula orci, ornare ut pharetra a, mattis quis
purus. Vestibulum ante ipsum primis in faucibus orci luctus

4
00:00:09,000 --> 00:00:12,000
et ultrices posuere cubilia curae; Sed placerat scelerisque
ante ut volutpat. Curabitur placerat efficitur libero ut

Each subtitle starts with the subtitle number (starts from 1 and increment by 1)
the second line must contain the start time code (hh:mm:ss,mms), the string " --> " and the end time code.

Each timecode must be greater than three seconds than the previous one.

On the next line(s) the subtitle text.

I use KM for various things, but this is a little more complex than usual, I guess it will also need a dedicated script in AppleScript (?) ...

Thanks for the help!

Perhaps something like this ?

SRT from double-LF paras.kmmacros (3.9 KB)

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

    // main :: IO ()
    const main = () => {
        // e.g. three minute  interval.
        const interval = 3 * 60;

        const
            sourceText = Application(
                "Keyboard Maestro Engine"
            ).getvariable("sourceParas");

        return paras(sourceText).reduce(
            (a, para) => {
                const [i, from, s] = a;
                const
                    next = 1 + i,
                    to = timeStampFromIndex(
                        interval
                    )(next);

                return [
                    next,
                    to,
                    `${s}\n\n${next}\n${from},000` + (
                        ` --> ${to},000\n${para}`
                    )
                ];
            },
            // Initial accumulator
            [0, "00:00:00", ""]
        )[2].trim();
    };

    // -------------------- TIMESTAMP --------------------

    const timeStampFromIndex = interval =>
        i => hmsFromSeconds(interval * i)
        .map(k => `${k}`.padStart(2, "0"))
        .join(":");


    // hmsFromSeconds = Int -> (Int, Int, Int)
    const hmsFromSeconds = seconds => {
        const [totalMins, s] = quotRem(seconds)(60);

        return [...quotRem(totalMins)(60), s];
    };


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

    // quotRem :: Integral a => a -> a -> (a, a)
    const quotRem = m =>
        // The quotient, tupled with the remainder.
        n => [
            Math.trunc(m / n),
            m % n
        ];

    // paras :: String -> [String]
    const paras = s =>
        // A list of strings derived from a single
        // string delimited by double linefeed.
        0 < s.length ? (
            s.split(/\n\n/u)
        ) : [];

    // ---
    return main();
})();
3 Likes

Great! Thanks so much! Just one thing: I think there is just an error, instead of a timecode like this:

00:00:00,000 --> 00:00:03,000

I get:

00:00:00,000 --> 00:03:00,000

in practice, instead of increasing by 3 seconds, the macro increases by 3 minutes... can be fixed?

However great work and thanks again!

Ah yes – I read it too fast, and of course 3 minutes is an implausible interval : -)

Where the JS code now has:

        // e.g. three minute interval.
        const interval = 3 * 60;

you can edit it to:

        // e.g. three second interval.
        const interval = 3;
3 Likes

Many many thanks!

1 Like