Convert text file to variables for further processing

Hi

I need to process a lot of pdf-forms.
In this process I would like to extract the pdf-form data. This can be done with PDFtk (https://www.pdflabs.com/tools/pdftk-server/).
It returns a textfile (or output to variable) like this:

FieldType: Button
FieldName: Std-farve
FieldFlags: 49154
FieldValue: 1
FieldJustification: Left
FieldStateOption: 0
FieldStateOption: 1
FieldStateOption: Blå
FieldStateOption: Grå
FieldStateOption: Off

FieldType: Button
FieldName: Individuel-Dato
FieldFlags: 0
FieldJustification: Left
FieldStateOption: Off
FieldStateOption: Yes

FieldType: Button
FieldName: Individuel-farve
FieldFlags: 0
FieldJustification: Left
FieldStateOption: Off
FieldStateOption: Yes

FieldType: Choice
FieldName: Std-antal
FieldFlags: 4325378
FieldValue: 100
FieldValueDefault: 100
FieldJustification: Left
FieldStateOption: 100
FieldStateOption: 1000
FieldStateOption: 150
FieldStateOption: 200
FieldStateOption: 300
FieldStateOption: 400
FieldStateOption: 50
FieldStateOption: 500
FieldStateOption: 600
FieldStateOption: 700
FieldStateOption: 800
FieldStateOption: 900

FieldType: Text
FieldName: Pris i alt
FieldFlags: 1
FieldValue: Kr. 1050,-
FieldJustification: Left

FieldType: Text
FieldName: Individuel-farve-txt
FieldFlags: 8388608
FieldJustification: Left

FieldType: Text
FieldName: Individuel-øvrige-ønsker-txt
FieldFlags: 8388608
FieldJustification: Left

FieldType: Text
FieldName: Tlf
FieldFlags: 8388610
FieldValue: 40404040
FieldJustification: Left

FieldType: Text
FieldName: Leveringsadresse
FieldFlags: 8388610
FieldValue: Enghavevej 9 d
FieldJustification: Left

FieldType: Text
FieldName: Firmanavn
FieldFlags: 8388610
FieldValue: Registreret Revisionsanpartsselskab
FieldJustification: Left

FieldType: Text
FieldName: FSR-medlemsnummer
FieldFlags: 8388610
FieldValue: 554466
FieldJustification: Left

FieldType: Text
FieldName: Kontaktperson
FieldFlags: 8388610
FieldValue: Preben Graungaard
FieldJustification: Left

FieldType: Text
FieldName: Postnr
FieldFlags: 8388610
FieldValue: 7100
FieldJustification: Left

FieldType: Text
FieldName: Mailadresse
FieldFlags: 8388610
FieldValue: revi@g-revision.dk
FieldJustification: Left

FieldType: Text
FieldName: By
FieldFlags: 8388610
FieldValue: Vejle
FieldJustification: Left

FieldType: Text
FieldName: Bemærkninger
FieldFlags: 4096
FieldJustification: Left

FieldType: Button
FieldName: Individuel-øvrige-ønsker
FieldFlags: 0
FieldJustification: Left
FieldStateOption: Off
FieldStateOption: Yes

FieldType: Button
FieldName: Send
FieldFlags: 65536
FieldJustification: Left

What I would like was to convert each form-field to a variable.
The name of the variable should be FieldName and the value should be FieldValue.
If a FieldValue is not present for the form-field it should just be set to blank.

I do not now how to go about this.
Hope somebody has some good ideas.

In a (Sierra) JavaScript for Automation action, you could write something like this (changing the filePath, or getting it from a KM variable).

(() => {
    'use strict';

    let formFields = (strLines) => {
        let dctParse = strLines.split(/[\r\n]/)
            .reduce((a, x) => {

                if (x === '---') {
                    let completed = a.current;

                    return (completed.FieldName) ? {
                        current: {},
                        vars: a.vars.concat(completed)
                    } : a;
                } else {
                    let blnKeyFound = ['FieldName:', 'FieldValue:']
                        .reduce(
                            (found, k) => found || x.indexOf(k) === 0,
                            false
                        );

                    if (blnKeyFound) {
                        let [k, v] = x.split(': ');
                        a.current[k] = v;
                    }
                    return a;
                }
            }, {
                current: {},
                vars: []
            });

        return dctParse.vars.concat(dctParse.current);
    }

    // readFile :: FilePath -> maybe String
    let readFile = strPath => {
        let error = $(),
            str = ObjC.unwrap(
                $.NSString.stringWithContentsOfFileEncodingError(
                    $(strPath)
                    .stringByStandardizingPath,
                    $.NSUTF8StringEncoding,
                    error
                )
            );
        return error.code ? error.localizedDescription : str;
    };


    let lstVars = formFields(readFile('~/Desktop/sampleData.txt'));

    if (lstVars.length > 0) {
        let kme = Application('Keyboard Maestro Engine');

        return lstVars.map(dct => {
            let k = dct.FieldName,
                v = dct.FieldValue || '';

            kme.setvariable(k, {
                to: v
            })

            return k + '=' + v;
        });
    }
})();

(For pre-Sierra (ES5) JavaScript for Automation, you could back-compile it to:

(function () {
    var d = function (a) {
        a = a.split(/[\r\n]/).reduce(function (a, d) {
            if ("---" === d) {
                var c = a.current;
                return c.FieldName ? {
                    current: {},
                    vars: a.vars.concat(c)
                } : a;
            }
            var e = d.split(": "),
                c = e[0],
                e = e[1];
            return -1 !== ["FieldName", "FieldValue"]
                .indexOf(c) && (a.current[c] = e), a;
        }, {
            current: {},
            vars: []
        });
        return a.vars.concat(a.current);
    }(function (a) {
        var b = $();
        a = ObjC.unwrap($.NSString.stringWithContentsOfFileEncodingError($(a)
            .stringByStandardizingPath, $.NSUTF8StringEncoding, b));
        return b.code ? b.localizedDescription : a;
    }("~/Desktop/sampleData.txt"));
    if (0 < d.length) {
        var f = Application("Keyboard Maestro Engine");
        return d.map(function (a) {
            var b = a.FieldName;
            a = a.FieldValue || "";
            f.setvariable(b, {
                to: a
            });
            return b + "=" + a;
        });
    }
})();
1 Like

Thanks. This does just what I wanted.

1 Like

I just uploaded the below macro, which provides a complete solution with options for selecting source data input.
It uses a RegEx based method, rather than a JXA script based method.

If you, or anyone, have any questions about this macro, please post in the above macro topic.

1 Like

Hi Michael

Thanks. This is more complete and versatile solution.

1 Like