The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

odfedit - replace tokens and do mail-merge in an Open Document file

SYNOPSIS

  odfedit [-v] <scriptfile
  odfedit [-v] [-e 'script'] scriptfiles...

Run odfedit --help for details.

DESCRIPTION

This command-line tool allows ODF::MailMerge to to be used in simple ways without writing Perl code.

Place-holder tokens of the form "{key}" are replaced with real content, either individually or as part of a "mail merge" function where records from a spreadsheet are used to instantiate multiple copies of a table.

A command script may be specified with -e option(s) and/or read from scriptfile(s), or if neither of those are given, read from stdin.

SCRIPT SYNTAX

Scripts are parsed similarly to Unix shell scripts:

    Command names and arguments are delimited by white space. "double quotes", 'single quotes' or \-escapes may be used for arguments with embedded spaces or special characters. #comments and blank lines are ignored

    Commands must be on a single logical line. Use \<newline> to fold long lines and semicolon (;) to separate commands on the same line.

DEFINITIONS

SPREADSHEET means the path of a .csv file or a spreadsheet (.ods, .xlsx, etc.) If a multi-sheet spreadsheet workbook is used, SPREADSHEET must be of the form "PATH!SHEETNAME" to specify which sheet to use. Spreadsheets may be used only if Libre Office is installed; and, due to an LO bug, LO may not be open interactively even for unrelated purposes. .csv files may always be used without issue.

COLSPEC means a spreadsheet column specifier: It may be an actual title, an identifier derived from a title by replacing offending characters with underscores, an absolute column letter ("A", "B" etc.) or a regular expression written as "/.../" which matches one title.

Any TOKEN argument has brackets added to form "{TOKEN}" unless the argument already contains the { and }. Literal { } or : characters may be used with \-escapes (such arguments should be 'single quoted' in the script).

COMMANDS

In general, scripts should first specify a skeleton .odt file, then replace {tokens} and/or perform mail-merge operations, and finally save to a different filename.

skeleton INPUTPATH # .odt, .ods etc. file

Read a document into memory.

It should contain static content and "{token}" strings (including the curly brackets) where content should be substituted.

save [-f] OUTPUTPATH # .odt etc.

Write the document to the specified path, which must not already exist unless the -f (force) option is specified.

subst-value TOKEN VALUE ...

Replace "{TOKEN}" with VALUE wherever it appears.

The result will have the same formatting as {TOKEN} in the skeleton (specifically, the format of the '{' character).

However if VALUE looks like a "[Styled content]" specifier as described in ODF::MailMerge then it is evaluated as such and may specify format overrides.

mail-merge PROTO-TOKEN SPREADSHEET

mail-merge PROTO-TOKEN -a aliasname=COLSPEC ... SPREADSHEET

First, a prototype Table is located which contains "{PROTO-TOKEN}" somewhere within it. The "{PROTO-TOKEN}" string is used only to locate the table in the skeleton and is immediately deleted so it will not affect the final result.

Then the prototype table is replicated once for each record in SPREADSHEET. Within each replicate, "{token}" fields are replaced with values from the corresponding spreadsheet record, using "token" (without the brackets) as a COLSPEC to identify which column value to use from the record.

    If -a option(s) are specified, then each aliasname becomes an alternate COLSPEC for the indicated column. Then the prototype table may contain "{aliasname}" instaed of "{The Actual Column Title}". aliasname must be an identifier, i.e. must start with a letter and contain only letters, digits, and underscores.

An error occurs if a "token" does not indicate any column in the spreadsheet.

mail-merge PROTO-TOKEN SPREADSHEET -k COLSPEC ... SPREADSHEET2

(Although not shown, each SPREADSHEET* arg may also be preceeded by -a options to define column aliases.)

In this form, some {token} values may be found in a specific record from a secondary spreadsheet; that specific record is selected using the values of certain columns in the current record from the primary sheet, indicated by the COLSPECs.

For example, to produce a company directory of department contacts for Payroll, Personnel, etc., the prototype table might contain tokens {Dept}, {Name}, {Email} and {Phone}.

However the primary spreadsheet could contain only "Dept" and "Name" columns, with "Email" and "Phone" values looked up in a secondary spreadsheet using the value of "Name" as the key. Here is how it works:

  For each record (i.e. row) in the primary spreadsheet:
    For each {token} in the prototype table:
      If "token" indicates a column in the current record:
        Substitute the value
      Else:
        Locate the record in the secondary spreadsheet which has values
        in the indicated COLSPECs ("Name" in the example) which match the
        corresponding values in the primary record.  An error occurs unless
        exactly one matching record is found.

        If "token" indicates a column in the selected secondary record
        then substitute the value, otherwise fail with an error.

Note that -a options may be used to alias uniquely-named columns so that the COLSPECs given with -k options will work to match the appropriate column in either spreadsheet.

Tertiary, etc. spreadsheets may be specified in additional command arguments; if "token" is not found in a secondary record, then the record in the next spreadsheet is selected which has values in columns indicated by (the next spreadsheet's) -k COLSPEC arguments which match those in the current secondary spreadsheet or, if not present, a predecessor spreadsheet.

Print the arguments to stdout, separated by spaces, quoting arguments which contain spaces or special characters.

SEE ALSO

It may be helpful to read docs for the following:

ODF::MailMerge

Spreadsheet::Edit

AUTHOR

Jim Avera (jim.avera at gmail)

LICENSE

CC0 1.0 / Public Domain. However this requires ODF::lpOD to function so as a practical matter you must comply with ODF::lpOD's license.