Command Reference CIB jsMerge

Site: CIB eLearning
Course: CIB jsMerge
Book: Command Reference CIB jsMerge
Printed by: Guest user
Date: Wednesday, 1 May 2024, 3:46 PM

Scope of Delivery

Components

Software Scope

CIB jsMerge

 

WIN 32

CibJSMrg32.dll            CIB jsMerge-DLL for Win32, Application Interface

WIN 64

CibJSMerge64.dll

LINUX 32

libcibjsmrgux.so          CIB jsMerge for Linux

LINUX 64

libcibjsmrgux64.so

XML access

WIN 32

CibDataXml.dll                                         DLL to access XML-files

Xalan-C_1_5_0.dll                                    Tool DLL XML

xerces-c_2_2_0.dll                                   Tool DLL XML

WIN 64

CibDataXml64.dll

Xalan-C_1_5_0.dll

xerces-c_2_2_0.dll

LINUX 32

libcibdataxml.so (optional)   For XML-file access

libxerces-c.so.22    XML tool

libxalan-c1_5_0.so  XML tool

LINUX 64

libcibdataxml64.so (optional)

libxerces-c.so.22

libxalan-c1_5_0.so

CSV access

WIN 32

CibDataCsv.dll                                   DLL to access CSV-Files

WIN 64

CibDataCsv64.dll

LINUX 32

libcibdatacsv.so (optional)  CSV-File access

LINUX 64

libcibdatacsv64.so (optional)

Header File

CibJSMerge.h


Introduction

CIB jsMerge is a central component within the CIB office modules (CoMod) and is able to create dynamically generated documents using ODT file formats and JavaScript.

XML based open document formats like Open Document and Office Open XML are getting more and more popular, especially since Microsoft decided to use Office Open XML as the standard format for current versions of Microsoft Office.

Thus, for text programming, XML based open document formats are becoming an alternative to the commonly used Rich Text format (RTF). Various CIB modules currently process documents in the RTF-format, CIB jsMerge now adds the processing of ODT and DOCX formats.

CIB jsMerge interprets field instructions in document templates and merges with optional variable data. The resulting document contains the resolved field instructions and the additional merged data. This variable data can be supplied via CSV or XML files. Currently the ODT format is supported for templates. Using DOCX templates is possible but not fully implemented yet.


Accessing the CIB jsMerge DLL

Allgemein
Call via CIB runshell
Call via CIB job

Allgemein

CIB jsMerge can be accessed via the CIBJSMerge32.dll, using CIB runshell, CIB job or the technical interface (API).

All properties which can be used to access CIB jsMerge are described in detail in Technical Manual. Short description of the most important properties follows:

inputfile:
An .odt file can be set as input file here. This file represents the root document. Additional documents (templates) can be included in the root document.

outputfile:
The intended output filename of the resulting document can be specified here. The resulting document contains all the information merged from templates and the data supply.

scriptfile:
Global functions, written in the scripting language JavaScript can be defined in the script file. These global functions then are available in all templates. The script file has to be UTF-8 encoded.

licenseCompany:
This property sets the licensee from the license information. This property has to be set in a CIB jsMerge call.

licenseKey:
This property sets the license Key from the license information. This property has to be set in a CIB jsMerge call.

datafile:
Data supply can be a CSV file or a XML file. These files contain data that is used later on in the root document or it‘s embedded templates.

Notes:

The property names are case insensitive.
All the properties mentioned above can be passed via the script file.

Attention:
The script file has to be UTF-8 encoded.

Example scriptfile:

setProperty("inputfile", "./filename.odt");
setProperty("outputfile", "filename_out.odt");
setProperty("datafile", "test/control.csv");
setProperty("multidatafile", "1");


Call via CIB runshell

CIB jsMerge can be called via CIB runshell as follows:

Cibrsh.exe <property1>=<value1> <property2>=<value2> -js [<inputfile name><outputfile name>]

Example 1:
Cibrsh.exe scriptfile=myScript.js licenseCompany=licensee licenseKey=xxxx-xxxxx-xxxxxxxx datafile=data.csv –js input.odt output.odt


When calling CIB jsMerge via CIB runshell it is possible to insert inputfile and outputfile via property "inputfile" and "outputfile".

Example 2:
Cibrsh.exe scriptfile=myScript.js licenseCompany=Licensee licenseKey=xxxx-xxxxx-xxxxxxxx datafile=data.csv inputfile=input.odt outputfile=output.odt –js

 

Notes:

The properties licenseCompany and licenseKey have to be set for every call.

Properties can be set directly in the CIB runshell call (command line) or in the script file. The following rules apply:
If properties are set directly in the CIB runshell call, they by default take precedence over script file properties.

If the properties set in the script file should take effect, the override-parameter within the setProperty() command has to be set to "true".

Example:
For the CIB runshell call already shown above

Cibrsh.exe scriptfile=myScript.js licenseCompany=licensee licenseKey=xxxx-xxxxx-xxxxxxxx datafile=data.csv inputfile=input.odt outputfile=output.odt –js

The following is set in the script file "myScript":

setProperty("inputfile", "./differentInput.odt", true);
setProperty("outputfile", "differentOutput.odt", false);
setProperty("datafile", "test/differentData.csv");


In this example the input file "differentInput.odt" from the script "myScript.js" is passed to CIB jsMerge because the override-parameter was set to "true". The property passed via the direct command line CIB runshell call is ignored in this case.

The output file "output.odt" and the data source "data.csv" are passed as specified in the direct command line CIB runshell call because the properties’ override parameters set in the script file are either set to "false" or have no override-parameter set.


Call via CIB job

Calling CIB jsMerge via CIB job is in the pipeline.

CIB Plug-In for LibreOffice / Apache OpenOffice

CIB software GmbH developed a plug-in for LibreOffice / Apache OpenOffice that provides additional functionality for including and working with fields. The plug-in can be added in the "Extension Manager" and is then available via a new menu bar item in LibreOffice / Apache OpenOffice.

This plug-in ports the known Microsoft Word functionality of including new fields via CTRL-F9 to LibreOffice / Apache OpenOffice. New fields can be inserted either by clicking the menu bar item "Neuer Block" or via the shortcut CTRL-F9. A field consists of two field markers - an opening and a closing bracket - that cannot be separated.

This extension helps with including fields but also assists in maintaining field integrity with common editing actions: it prevents deleting single field markers by mistake with the DEL or BACKSPACE keys. When cutting, pasting or copying selected fields or parts of fields, an existing field is cut, overwritten or copied as a whole. An invalid selection (for example when part of a field with only one field marker is selected) is extended in such a way that the complete field is inside the selection. Then the cutting, pasting or copying action can be repeated without losing field integrity.

Remarks:

  • In contrast to Microsoft Office, for performance reasons, there is no check while selecting text, whether fields were selected completely. Checking integrity is only done during the above mentioned editing actions.
  • The extension cannot predict every possible editing error. Less common editing actions like including specific content via the menu "include" are not part of this field integrity check. When including these contents the current selection is replaced, regardless whether all necessary field markers are included or not.
  • When using redo and undo functions (CTRL-Y, CTRL-Z) inconsistencies may also occur.

More detailed information about using fields can be found in chapters Syntax Basics: Using Fields and Syntax Basics: Mixed Script and Content Fields in this document. Please contact CIB sales if interested in the LibreOffice / Apache OpenOffice plug-in extension.


Syntax Basics

In this chapter, we will describe certain basics that are required to understand the following chapters and necessary to use the described text programming functions correctly. This includes using reserved characters as well as explaining fundamental terms.


Legend

The following table contains reserved characters for text programming and their description.

Note:
The terms used in the description field (e.g. script field) will be explained in more detail in the following chapters.

Character

Explanation

Description

{

}

Field marker

Inserted via CRTL-F9 in MS Word or via the CIB officeControlBlocks plug-in for LibreOffice. This always inserts a field, i.e. an area marked with an opening and a closing bracket.

{

}

Curly bracket

Normal textual bracket, usually always in pairs.

#

Start character script field

Marks a field as a script field. The content of this field will be interpreted by CIB jsMerge.

Escape-character LibreOffice

In order to use reserved characters as the first character in a script field (e.g. #), they have to be escaped with the apostrophe.

Escape-character
 MS Word

In MS-Word, a content field must begin with the apostrophe to distinguish it from a standard MS-Word field.

|

Pipe-character

In LibreOffice, the field result is attached to the field instruction, separated by the pipe symbol“|”.


Using Fields

Allgemein
Script Fields
Content Fields

Allgemein

Fields are defined elements required for text programming in dynamic documents. During a merge run, CIB jsMerge interprets the fields used within a document and outputs them dynamically to the output file.

The fields used in this context are similar to MS-Word fields, but not identical. We distinguish between two types of fields, script fields and content fields. Their specific structure and usage are described in more detail in the following chapters.

A field is a special component within a document and has the following structure:

{ content }

 

Fields are parenthesized with these field markers: { } . Note that opening and closing bracket define the field and one cannot stand without the other, i.e. if you delete one, you delete the field.

Important:

Fields can only be added via the corresponding text editor commands.
Fields can only be added via the corresponding text editor commands. In MS-Word, this is CTRL-F9, in LibreOffice via the CIB officeControlBlocks plug-in button. Manually inserted curly brackets will not be interpreted as field markers.


Script Fields

Script fields contain one or several instructions of a script as well as additional meta data. Script fields always start with a hash character “#” and are structured like this:

 {#ScriptContent }

The “scriptContent” is interpreted by the script interpreter. This “scriptContent” can also be one or more nested fields.

Examples:

{# text(ref(“firstname”)) }
{# if(ref(“firstname”)!=””) text(ref(“firstname”)) }


Content Fields

Content fields are used to mark text content inside a script field as non-interpretable text content. This enables us to mix script and normal text content and let the script control which fields are written to the resulting document and which are not. Content fields have the following structure:

 {NonInterpretableTextContent }

or

 {NonInterpretableTextContent} (possible only in ODT)

“NonInterpretableTextContent” can be any text content that is supported by the text editor, i.e. in all formats (e.g. Rich Text) and formatting options (e.g. tables).

Attention:

The content field must not start with hash character “#” or it will be interpreted as a script field. In order to be able to start the text content with a hash character, we introduced the apostrophe (‘) as an escape character. After the apostrophe, any text content may follow (even the apostrophe).

Example:

{#1 } will be interpreted as a script field
{#1 } the hash character is escaped correctly

MoreExamples for content fields:

{This is the textcontent of this content field}
{The content can also contain a table:

Table inside the content field

and much more }
only in ODT templates the following content field works also: { content field without apostrophe}


Note about MS Word:

In MS Word one might want to use legacy MS Word fields like { DATE }. A legacy MS Word field is not interpreted by CIB jsMerge in any way. To distinguish content fields and legacy MS Word fields, CIB jsMerge only recognizes a content field if it is escaped with an apostrophe (‘).

Examples:

{ DATE }

Will not be processed by CIB jsMerge

{my content }

This is a content field. That writes the string “my content” to the resulting document.

{DATE }

This is also a content field that writes the string „DATE“ into the resulting document.


Mixed Script and Content Fields

The following examples show how script fields and content fields can be combined to a useful structure:

{# if(ref(“firstname“)== “Bob“) {Hello Bob!} else {‘Hello everybody!}  } 

Depending on the variable “firstname” either the text of the first content field “Hello Bob!” or the text of the second content field “Hello everybody” is written to the resulting document.

The next example uses a switch statement to output 3 different, alternative text snippets depending on the variable “firstname”.

{#switch(ref(“firstname“)) {
case “Bob“: {Hello Bob!} break; case “Alice” {Hello Alice!} break;
default: {Hello everybody!}  
}}

Quick Reference

Here is an overview of all CIB functions with a brief description:

Function

Description

fref(name, {formfieldAttributes})

This function extends the function “text(ref(name))”.  Additional, optional parameters can be passed.
“{formfieldAttributes}“: Attributes used to describe dialog fields; these are currently not interpreted.

text(text)

Copies the value of the passed parameter “text” to the resulting document.

ref(variableName) or
getData(variableName)

Returns the value of the variable “variableName”.

include(name, {includeAttributes})

Inserts the template “name” into the resulting document. “name” can be specified with a relative or absolute path. „{includeAttributes}“: can be specified optionally and control how the template has to be included.

picture(name)

This function is not yet implemented.

Adds the picture “name” to the resulting document. „name” can be specified with a relative or absolute path.

isEmptyRef(variableName)

This function returns “true” if “variableName” has a length of 0 or if the variable cannot be resolved. Otherwise it returns “false”.

existsRef(variableName)

Returns “true” if the variable “variableName” is defined, otherwise it returns “false”.

setData(variableName, value)

Sets the value of the variable “variableName” to the specified “value”.

formatDate(formatString, date)

Returns the formatting of “date” as specified in “formatString”.

deDate()

This function expects a date in the format:
"dd.MM.yyyy"

resetRec(tablealias)

Selects the first record within the table “tablealias” as current dataset.

hasRec(tablealias)

Returns “true” if the current record exists in the table “tablealias”, else it returns “false”.

nextRec(tablealias)

Selects the next entry in the table ”tablealias“.

mergeRec(tablealias)

Returns the number of the currently selected dataset in the table “tablealias“.


Functions




text(text)

The function text(text) copies the text read from the parameter “text” to the resulting document. The parameter can also be the return value of a function.
The text will be inserted with the same formatting options that are set for the start character (
{) of the corresponding script field.

Examples:

{# text(“Hello world”)}
{# text(ref(“myVariable”))}

Note:

If a text has multiple lines, it is possible to create new paragraphs using “\n”.


fref(name, {formfieldAttributes})

This function copies the content of the variable “name” to the resulting document. The behavior of this function differs from “text(ref(name))” in that it offers the option to specify additional parameters. This function should be preferred to the function “text(ref(name))”.The parameter „{formfieldAttributes}“ is going to be used to describe dialog fields to enable data capturing. Currently it is not interpreted and can be omitted.

include(name, { includeAttributes })

The function include() inserts the template with the specified filename “name” to the resulting document. The filename can contain the absolute path or a path relative to the current working directory. The file extension (e.g. .docx, .odt, .ott) can be omitted. In that case the format of the called template decides which name suffixes are searched for. In the case of ODT, it is also checked for *.odt, *.ott, *.ODT and *.OTT, in the case of DOCX for *.docx, *.docm, *.DOCX and *.DOCM.

For the optional parameter { includeAttributes } a hash-table is expected. The following options are supported within the hash-table:

The option "importPageSettings" controls which Page/Section properties should be applied in the current section of the result document. The following values for "importPageSettings" are possible:

  • "autoHeaderFooter": if headers and footers are defined in the imported template, they will be written to the result document. If no headers and footers are defined, the header/footer definitions of the calling template are used (if defined). Other section or page properties are not copied from the imported template.
  • "all": all section and page properties are copied from the imported template. This value could be used, for example, to concatenate several independent document parts with all their settings.
  • "none": Neither header/footer nor section or page properties will be copied from the imported template. Only the text content is inserted.

If "importPageSettings" is not specified, the default "autoHeaderFooter" will take effect.


Examples:

{# include(“abaustGruss2.odt”)}
{# include(“belehrungstext.odt”)}
{# include(“belehrungstext.odt”, {importPageSettings:”none”})}

ref(variableName) and getData(variableName)

These functions are identical and return the value of the variable “variableName“. To be able to use a variable in these functions it must exist in the data suppy or have been set with “setData”. If that is not the case, the surrounding function will terminate with an error.

Examples:

{# ref(“myVariable”)}
{# ref(“institute.EL_KIN_BEZ”)}
{# var i=1; ref(“institute.EL_KIN_BEZ” + i)}

If the “variableName” contains a special separator (this is by default a decimal point “.”), the variable is considered to be a table variable with the first part describing the table alias and the second part describing the name of the node that has to be selected within the table. If the variable cannot be resolved, this function causes the surrounding function to terminate with an error.

Attention:

If the return value should be further processed as a number, the ref has to be surrounded by the standard JavaScript function Number(). Otherwise the content of the variable will be as evaluated a string.

Example:

{# setData(“mySum”, 50)}
{# text(Number(ref(“mySum”)) + 10)}

isEmptyRef(variableName)

This Boolean function returns “true” if the variable “variableName” has a length of 0 or the variable is not resolved, otherwise it returns “false”. If the “variableName” contains a special separator (this is by default a decimal point “.”), the variable is considered to be a table variable with the first part describing the table alias and the second part describing the name of the node that has to be selected within the table.


existsRef(variableName)

This Boolean function returns “true” if the variable “variableName” is defined and exists in the data supply or has been set with “setData”. Otherwise it returns “false”. If the “variableName” contains a special separator (this is by default a decimal point “.”), the variable is considered to be a table variable with the first part describing the table alias and the second part describing the name of the node that has to be selected within the table.


setData(variableName, value)

The function setData() sets the value of the variable „variableName“ to “value“.

{# setdata(“myVariable”, “Hello”)}
{# var i=42; set(“myVariable” + i, “Hello”)}

If the “variableName” contains a special separator (this is by default a decimal point “.”), the variable is considered to be a table variable with the first part describing the table alias and the second part describing the name of the node that has to be selected within the table. It is possible to overwrite the value of a table variable.

formatDate(formatString, date)

The function “formatDate(formatString, date)“ returns the formatting of “date” as defined in „formatString“.

The following variants of “date“ are supported:


deDate() Function expects the date in this formatting
"dd.MM.yyyy" (dd and MM can be typed without a leading 0) or
"dd.MM." (if so the current year is added).
If there are errors in the string (e.g. missing the decimal points, no number, not a valid date like 30.2.12) there is a JavaScript Exception.
new Date()

Function returns the current date and the current time in this order: Year, month, day, hour, minute, second, millisecond.

Currently the follow formats are supported in "formatString":
"t", "d", "tt", "dd", "MM", "M", "jjjj", "yyyy", "jj", "yy", "HH", "H", "mm", "m", "ss", "s"


Examples:

{# text(formatDate(“jjjj”,deDate(“28.08.2012”)))}

Outputs „2012“ to the resulting document

{# text(formatDate(“tt.MM.jj”, new Date()))}

Outputs the current date to the resulting document using the specified formatting:"01.09.14"

{# text(formatDate(“jjjj”, enDate(“2012.08.10”)))}

Outputs „2012“ to the resulting document


Processing Data within Tables

Allgemein
resetRec(tablealias)
hasRec(tablealias)
nextRec(tablealias)
mergeRec(tablealias)
Characteristics of Dynamically Generated Tables


Allgemein


CIB jsMerge provides the ability to read one or more datasets (e.g. in a while-loop) out of custom tables and merge them into the result documents. This creates a dynamic table in the resulting document. The input-datasets can stem from CSV or XML data sources.

For the purpose of creating dynamic tables from that data a set of special functions has been implemented. A dynamic table is identified by a table alias name. This alias name is defined either via

  • Multi nodes in a XML data source or
  • the name of the CSV data source (when using a single CSV) or
  • The record in the control file of a multi CSV data source

The variable is called via the name defined in the data source („variableName“). To call a variable from a multi-data source the alias name has to be added as prefix to the variable name.


Example:

{#
ref(“<tablealias>.<variableName>”)}

As an illustration, the following example shows some of the functions introduced for processing tables:

{#while(hasRec(“Persons”)) {x

{#fref(“Persons.Salutation”))}

{#fref(“Persons.Name”))}

{#nextRec(“Persons”)}}}


Note

The functions „resetRec()“, „hasRec()“, „nextRec()“ and „mergeRec()“ can be used without “tablealias”(or with “tablealias”=null). In this case, these functions affect all dynamic tables used in the template project. Application examples would be serial letters or copies.


resetRec(tablealias)

The function "resetRec(tablealias)" positions to the first data record in the table "tablealias".

If this function is used without the parameter "tablealias" or with "tablealias"=null, all existing tables will be positioned to the first data record. This also sets all data record counters (=return value of the function "mergeRec(...)") to 1.


hasRec(tablealias)

The function „hasRec(tablealias)“ returns “true” if the current record exists in the table “tablealias”. If the table is empty or the end of the table is reached (e.g. after “nextRec()”) the function returns “false”.

If this function is used without the parameter “tablealias“ or with ”tablealias“=null, the function „hasRec()“ only returns “false” if the end of all tables has been reached. Otherwise the result is “true“.


nextRec(tablealias)

The function “nextRec(tablealias)“ selects the next entry in the table specified by “tablealias“.

This function behaves like “{ next tablealias }“ with the difference that it is necessary to access the variables of the selected dataset using the table alias name, i.e. the variables have to be called with the prefix:{#ref("<tablealias>.<variableName>"))}

Example:

{# text(ref(“Person.CustomerID”));
nextRec(“Person”);
text(ref(“Person.CustomerID”));}

In this example the „customerID“ of the first and the second dataset will be copied to the resulting document.

If the function „nextRec(tablealias)“ reaches the end of the table „tablealias“, it sets all variables of this table to an empty value    “” and the function „hasRec(tablealias)“ will return “false” the next time it is called and the counter „mergeRec(tablealias)“ is set to “0”. Any further calls of the function „nextRec(tablealias)“ will not change that state. If the function ”nextRec()“ is used without the parameter „tablealias“ or with „tablealias“=null, all tables will be set to the next record. In this case there is a global internal couter that counts all calls of “nextRec()”. This counter is initialized with 1 and will be reset to 1 by “resetRec()”. The counter will not increase if the end of all available tables has been reached.


mergeRec(tablealias)

The function „mergeRec(tablealias)“ returns the number of the currently selected dataset in the table “tablealias” (starting with 1 for the first selected dataset).

Example:

{#while(hasRec(“Persons”)) { if((Number(mergeRec(“Persons”)) % 2) == 0) {x

{#fref(“Persons.Salutation”)}

{#fref(“Persons.Firstname” + fref(“Persons.Lastname”)}

} else {x

{#fref(“Persons.Salutation”)}

{#fref(“Persons.Firstname” + ref(“Persons.Lastname”)}

} nextRec(“Persons”);}}

If this example is executed without the parameter “tablealias” or with “tablealias”=0, the function returns the state of the internal global counter used in the function “nextRec()”.If there is a table-overflow, „mergeRec(tablealias)“ is set to „0“.


Characteristics of Dynamically Generated Tables

The following special characteristics have to be considered when working with dynamically generated tables in LibreOffice:

to realize hidden paragraphs in LibreOffice there has to be a minimum of one character in the paragraph (an "x" in our examples here). This character then has to be formatted as "hidden". Paragraph markers cannot be set as "hidden" like in MS Word.

 

Note:
In the resulting document, every data record will be written in a separate table. In the input document, de paragraphs before the table have to be formatted as hidden so the optical representation in the output document looks like one table:

{#while(hasRec(“Persons”)) {x

{#fref(“Persons.Salutation”))}

{#fref(“Persons.Name”))}

{#nextRec(“Persons”)}}}

(please also see the example in chapter mergeRec(tablealias))

In contrast to MS Word, LibreOffice does not interpret these table rows as one table.

That also means that a defined table heading is not repeated on following pages if the table spans several pages.


Reserved Variables and Functions

The following variable names are currently not taken in CIB jsMerge. Their realization however is planned for future versions:

Function or Variable

Description

data

Name reserved, not yet implemented.

ERROR

Name reserved, not yet implemented.

OUTPUTMODE

Name reserved, not yet implemented.


JavaScript Control Structures

JavaScript instructions make up the biggest part of text programming. An extensive description of JavaScript syntax and usage is not covered in this document. A detailed overview is available in known online documentation for JavaScript like:

http://www.w3schools.com.
https://developer.mozilla.org/de/docs/JavaScript

The most relevant JavaScript control structures in the context of this command reference will be covered briefly in the following section. These structures are also realized accordingly in RTF programming.


Conditional Statements

Conditional statements are only executed if the specified condition is met. The syntax for a general if statement is:

if (condition) {
statement
}

To also control what happens when the condition is not met, the if statement can be combined with an else statement:

if (condition) {
statement1
}
else {
statement2
} 
For clarification, the example from chapter Mixed Script and Content Fields is repeated:

{# if(ref(“firstname“)== “Bob“) {Hello Bob!} else {‘Hello everybody!}  } 

If the value of the variable "firstname" is Bob, "Hello Bob" is output, else "Hello everybody" is output.

Loops

Loops are executed as long as a set condition is true. The syntax for the while loop is:

while (condition) {
statement
}

See also the example from chapter Processing Data within Tables:

{#while(hasRec(“Persons”)) {

{#fref(“Persons.Salutation”))}

{#fref(“Persons.Name”))}

{#nextRec(“Persons”)}}}


As long as data records are present in the data supply "Persons", the fref() functions specified in the table will be executed and the nextRec() function steps to the next data record in the data supply.

The combination of while-loop and if-statement is shown in chapter mergeRec(tablealias) and in the example in chapter Coming from RTF: Comparison of Functions.


Comparison Operators

All operators allowed in JavaScript (e.g. ==, !=, >, <). A detailed listing and explanation is available in online JavaScript documentation.

Examples:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

http://www.w3schools.com.
https://developer.mozilla.org/en-US/docs/Web/JavaScript

JavaScript Functions

Inside the templates and the script file it is possible to write functions in JavaScript. The conventions of JavaScript will not be covered in this document. For that, please refer to documentation available online like:
https://developer.mozilla.org/en-US/docs/Web/JavaScript

Custom functions can be defined directly in the template (= local function) or in (exactly) one script file that can be passed in a CIB jsMerge call (= global function).

The necessary functions are defined in a script block, e.g.:

{# myGlobalFunc = function(){ … } }


Global Functions

In the script file global functions and variables can be defined with the following syntax:

myGlobalFunc = function() { ... }

or

function myGlobalFunc() { ... }

or

i=42

Global functions and variables are valid throughout the document project. They can be overwritten by local functions/variables with the same name in a template. Then the global function/variable defined in the script file is no longer valid in this template (but in all other templates).

The function is referenced via myGlobalFunc(…). E.g. text(myGlobalFunc(…))

Local Functions

Inside the template local functions and variables can be defined with the following syntax:

{# this.myFunc = function() { ... }}
{# this.i = 42}

The advantage of local functions is that they are only valid in the template that they are defined in and are thus protected. They cannot be overwritten by functions of other templates. Other templates cannot see these functions, enabling the usage of functions and variables of the same name in different templates without interference.

The function is referenced with this.myFunc(…), e.g. text(this.myFunc(…))

Exporting Local Functions

Local functions and variables in a template can be exported using the following syntax:

{# this.exports.myFunc = function() { ... }}
{# this.exports.i = 42}

The function and the variable in the example above are also local within the template, but they are made available to all included templates as well. The function and the variable are protected for this template but can be overwritten in an included template. This only affects the function within the included template, not the function in the parent template that initially defined the function. This provides better write protection to functions like these.

This function, too, is referenced via this.myFunc(...), e.g. text(this.myFunc(...))

Support for JavaScript Functions

The possibility to extend the project or single templates with custom JavaScript functions provides a lot of flexibility for the user. However, this high degree of flexibility also implies greater individual responsibility regarding a user’s document project.

When referring to CIB Support, the current contractual situation between CIB and the customer has to be taken into account.

Attention:

It is possible for the user to overwrite standard CIB functions (e.g. fref()) with custom JavaScript code. This invalidates the functional description provided in this command reference. This makes care and maintenance for document projects a lot more complex.

We strongly recommend not to overwrite standard functions and to distinguish custom JavaScript functions by choosing a unique name.


Supported Content and Settings

ODF as well as Office Open XML describe a large amount of content elements and possible settings. Not all these elements and Settings are necessary for standard correspondence. The following listing provides an overview over supported elements:

Element or Setting

ODT Supported

DOCX Supported

Text and character formatting

Yes

Yes

Character style formatting

Yes

Yes

Paragraph and paragraph formatting

Yes

Yes

Table and table formatting

Basically yes. A dynamically created table is currently not created as one physical table.

Basically yes. A dynamically created table is currently not created as one physical table.

Page and section formatting

Yes

Yes

Header and footer

Yes

Not yet released

Graphics, text or frames

Yes

Yes

Lists and list properties / counter

Not released

Not released

Fields

Standard fields are not interpreted

Interpreted:
Script fields

Content Fields

MS Office fields are not interpreted

Interpreted:
Script fields

Content Fields

Customizing element-IDs / Names:
Some elements have IDs or Names, that have to be made unique when merging or if repeated.

The following elements are currently renamed:

Styles

No changes are made for:

Tables

Graphics

Lists

Bookmarks

The following elements are currently renamed:

Styles

No changes are made for:

Tables

Graphics

Lists

Bookmarks

Elements anchored to the page

Not possible by design
Recommendation:
Avoid elements anchored to the page

Not possible by design
Recommendation:
Avoid elements anchored to the page

Table of contents, index of images, bibliography

Not released

Not released

Embedded fonts

No

No


Coming from RTF: Comparison of Functions

For users that come from an MS Word and RTF environment it can be helpful to see how the already known field instructions in RTF are mapped to the ODT environment.


Mapping RTF Field Instructions to Script Logic

This section shows how RTF field instructions and their logic can be realized with the new scripting logic. The following table provides a list of all RTF fields, how they are processed by CIB merge and the corresponding realization in JavaScript scripting logic:

Field Instruction (en / de)

Description (from CIB merge technical reference)

ODT or script logic realization (JavaScript)

COMPARE / VERGLEICH

Compares 2 values and returns the numeric value 1 if the result is true, 0 (null) if the result is false.

JavaScript: Boolean comparison

Example: (a==b)

DATE / AKTUALDAT

Inserts the current date.

Please see:
formatDate(formatString, date).

IF / WENN

Compares arguments while taking into account certain conditions. Can be extended to a loop instruction (SOLANGE)

JavaScript: IF command

Example: if(a==b){ ... }else{ ...}

 

while(a==b) { … }
(for
SOLANGE)

INCLUDETEXT / EINFÜGENTEXT

Inserts a text from a file.

Please see:
include(name,
{includeAttributes})

Example:
include(„mydoc.odt“)

MERGEFIELD / SERIENDRUCKFELD

Creates a placeholder with a name, which is later replaced by variable content.

Please see:
fref(name,
{formfieldAttributes}) or
text(ref(name))

Example: text(ref(“institute.EL_KIN_BEZ”))

MERGEREC / DATENSATZ

Inserts the number of the current merge record.

Please see:
mergeRec()

Example:
mergeRec()

MERGEREC ?

Returns Boolean "1" if there still is a merge record. By default it is set to "0".

Please see:
hasRec()

Example:
hasRec()

MERGEREC „tablealias“

Adds the number of the current record of a table.

Please see:
mergeRec(tablealias)

Example:
mergeRec("Persons")

MERGEREC "?tablealias"

Returns 0 if no further records are in this table.

Please see:
hasRec(tablealias)

Example: while(hasRec(„Persona“)) …

NEXT / NÄCHSTER

Goes to the next record or node in the data supply.

Please see:
nextRec()

Example:
 
nextRec()

NEXT -

Resets all control files to record "zero". The variable contents are deleted. The values of the first record are first read with {NEXT}

Please see:
resetRec()

Example:
resetRec()

NEXT aliasname

Proceeds to the next record or node in the data list described by the alias name

Please see:
nextRec(tablealias)

Example:
nextRec(„Persons“)

NEXT –aliasname

NEXT aliasname

These two commands reset the data list to the 1st record.

Please see:
resetRec(tablealias)

Example:
resetRec(„Persons“)

NEXTIF / NWENN

Proceeds to the next record or node in the data supply if a certain condition is met.

Valid with merging and iterating lists.

JavaScript:
if(<condition>) nextRec()

or

if(<condition>)
    nextRec(tablealias)

QUOTE / ANGEBEN

Inserts a text to the document.

Please see:
text(text)

Example:
text(„Hello world“)

REF / REF

Creates a placeholder with a name, that is later replaced by variable content.

Please see:
fref(name,
{formfieldAttributes}) or
text(ref(name))

Example: text(ref(“institute.EL_KIN_BEZ”))

REF "?variable"

Returns "0" if the variable does not exist, else returns "1".

Please see:
existsRef(variableName)

Example:
 
existsRef(„<variable>“)

SET / BESTIMMEN

Assigns a new text to a text mark.

Please see:
setData(variableName, value)

Example:
setData(„myVar“, 1)

SKIPIF / ÜBERSPRINGEN

Skips a record or node in the data supply according to a condition and doesn't create an output document in the merge run for this record.

Only valid with merging. Not applicable with lists.

JavaScript:
if(<condition>) skip()

TIME / ZEIT

Inserts the current time.

TIME is always interpreted by CIB merge. In some cases it is desirable that CIB format does the replacement. Then the \* keep switch is used.

Please see:
formatDate(formatString, date).

= Ausdruck / Expression

Calculates the result of a expression (= formulae)

JavaScript formulae

Examples:
(3-1) or
(5*10) or
(10%2) or (Number(ref(“myNumber”)) + 10)

Attention:
in JavaScript the "+" operator is used per default for string concatenation. The operators have to be specified with Number() to force an addition.

 

Examples follow for how RTF expressions can be realized in script fields.

MS Office field instructions

Script logic (Examples in JavaScript)

Simple REF:

{ REF “institute.EL_KIN_BEZ” }

{# text(ref(“myVariable)) }

Simple SET:

{ SET myVar “Hello” }

{# setData(“myVar”, “Hello”) }

REF with Date format switch:

{ REF myDate \@ “tt.mm.jjjj” }

{# text(formatDate(“tt.mm.jjjj”, ref(“myDate”))) }

Simlple "IF-then" construct:

{ IF { REF “myVariable” } = “” “My variable is empty” }

{# if(ref(“myVariable)==””) {My variable is empty}}

The function would terminate here with an error if "myVariable" could not be resolved.

or

{# if(isEmptyRef(“myVariable)) {My variable is empty}}

The function would terminate with an error if "myVariable" could not be resolved.

Check if variable is empty:

{ IF { REF “myVariable” } != “” “{ REF myVariable”}}

{# if(!isEmptyRef(“myVariable”)) text(ref(“myVariable”)}

Simple "IF-then-else" construct:

{ IF <condition> “then-part” “else-part” }

{# if(<condition>) {‘then-part} else {‘else-part} }

Check if variable exists (and define it if it doesn't):

{ IF myVar = “myVar” {SET myVar “Hello” }}

or:

{ IF { REF ?myVarXXX } = 0 { SET myVarXXX “Hello” }}

Several of these constructs can be dealt with in a script field:

{#if(!existsRef(„myVar“))
  set(„myVar“, „Hello“);
if(!existsRef(„myVarXXX“))
  set(„myVarXXX“, „Hello“);
}

Simple calculation:

{ SET myVar { = 1 +2 + 3 }}

{# set(“myVar”, 1 + 2 + 3) }

Calculation with variable:

{ SET myVar { = { REF myNumber } + 2 + 3 }}

{# set(“myVar”, Number(ref(“myNumber”)) + 2 + 3) }

In JavaScript numeric variables have to be specified with "Number()" to differentiate from string variables. Default for "+" is a string concatenation.

String concatenation:

{ REF “var{ REF myNumber }}

{# text(ref(“var” + ref(myNumber))) }

SET-IF:

{ SET “myVar” { IF <condition> “She” “He” }}

{# setData(“myVar”, (<condition>)? “She” : “He”) }

or

{# if(<condition>) setData(“myVar”, “She”);
   else setData(“myVar, “He”);
}

Compare:

{ set “valid” { ={ COMPARE { REF a } = 1} && { COMPARE { REF b } = 2} && { COMPARE { REF c } = 3}}}

{# setData(“valid”, (ref(“a”)==1) && (ref(“b”)==2) && (ref(“c”)==3)) }

SOLANGE-loop:

{ if <condition> “…content…
{ next … }” \* SOLANGE }

{# while(<condition>) {…content…
{# nextRec(…) }}}

Next –aliasname:

{ next –aliasname }

{# resetRec(“aliasname”) }

Simple INCLUDETEXT:

{ INCLUDETEXT “template.rtf” }

{# include(“template.odt”) }


Example

The following describes a complete, short example of a CIB jsMerge run. The files used are printed in their entirety.

Starting point is the root document inputDoc.odt. Data is merged from a CSV file (Persons.csv) and additionally the template template.odt is included.

CIB jsMerge is called via CIB runshell on command line in this example. The properties are specified in the script file script.js:

Call:
Cibrsh.exe –js scriptfile=script.js

script.js:

Only the required properties for this example are specified in this script file. In this case, that is license information, name of the root document, name od the output file and name of the CSV file.

setProperty("licenseCompany", "Licensee", true);
setProperty("licenseKey", "xxxx-xxxxx-xxxxxxxx", true);
setProperty("inputfile", "./inputDoc.odt", true);
setProperty("outputfile", "./outputDoc.odt", true);
setProperty("datafile", "Persons.csv", true);

inputDoc.odt:

At the start of the root document the local function "upperCase" is defined. It is later called inside a "while" loop to print the names, included from "Persons.csv" in the third table column, in upper case. The next field instruction merges the current date to the result document via the function "formatDate()". Then the additional template "template.odt" is included via the field instruction "include()". The following construct dynamically creates a table using a "while" loop and fills it with the data from the data supply "Persons.csv". As many table rows are created as there are entries(records) in the file "Persons.csv". This is realized using the functions "hasRec()" and "nextRec()".

The first table column in the root document shows the usage of a "if" condition to choose the right salutation. The second column demonstrates the display of the "Persons" variable's value via the "fref()" function, while in the third column the value of the variable "lastname" is passed to the function "upperCase".

The document inputDoc.odt is printed on the following page.


inputDoc.odt

{ # this.upperCase = function(name) { text(name.toUpperCase());} }

 

Output of the current date:

Munich, the { #text(formatDate(„tt.MM.jj“, new Date() )) }

 

Include text from an additional template:

{ # include("template.odt") }

 

The following table is created dynamically via a while loop. Data from the CSV file Persons.csv are used and as many table rows created as there are records in the CSV file.

{ #while(hasRec(„Persons“)){ 'x

{#if(ref(„gender“)==“m“) { 'Mr } else{ 'Mrs } }

{ #fref(„firstname“) }

{ # this.upperCase (ref(„lastname“)) }

{ #nextRec(„Persons“) } } }


 

template.odt:

The content of the file "template.odt" is included in the root document at the position specified using the "include()" statement:

This is a text notice, defined in the template "template.odt" and included into the output file via the "include()" statement.


Persons.csv

This file is the data supply. In the first row the variable names are defined, the following rows contain the corresponding records.

Note:
The CSV file has to be UTF-8 encoded to correctly process special characters and Umlauts.

firstname;lastname;gender
Peter;Meier;m
Hans;Müller;m
Anne;Kurz;f Tim; Berg;m


outputDoc.odt:

After calling CIB jsMerge the document printed on the next page is created. All the data has been merged into this document as described above.


 

outputDoc.odt

Output of the current date:

Munich, the 01.09.14

 

Include text from an additional template:

This is a text notice, defined in the template "template.odt" and included into the output file via the "include()" statement.


The following table is created dynamically via a while loop. Data from the CSV file Persons.csv are used and as many table rows created as there are records in the CSV file.

Mr

Peter

MEIER

 

Mr

Hans

MÜLLER

 

Mrs

Anne

KURZ

 

Mr

Tim

BERG