Command Reference CIB jsMerge
Site: | CIB eLearning |
Course: | CIB jsMerge |
Book: | Command Reference CIB jsMerge |
Printed by: | Guest user |
Date: | Sunday, 24 November 2024, 11:10 AM |
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
AllgemeinCall 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 |
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
AllgemeinScript 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:and much more }
Table inside the content field
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.
{#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. |
text(text) |
Copies the value of the passed parameter “text” to the resulting document. |
ref(variableName)
or |
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: |
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": |
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
AllgemeinresetRec(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
{#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
} else {‘x
} 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
{#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”)) {‘
{#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_Operatorshttp://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: Content Fields |
MS Office fields are not interpreted Interpreted: Content Fields |
Customizing
element-IDs / Names: |
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 |
Not
possible by design |
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: |
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) { … } |
INCLUDETEXT / EINFÜGENTEXT |
Inserts a text from a file. |
Please
see: Example: |
MERGEFIELD / SERIENDRUCKFELD |
Creates a placeholder with a name, which is later replaced by variable content. |
Please
see: Example: text(ref(“institute.EL_KIN_BEZ”)) |
MERGEREC / DATENSATZ |
Inserts the number of the current merge record. |
Please
see: Example: |
MERGEREC ? |
Returns Boolean "1" if there still is a merge record. By default it is set to "0". |
Please
see: Example: |
MERGEREC „tablealias“ |
Adds the number of the current record of a table. |
Please
see: Example: |
MERGEREC "?tablealias" |
Returns 0 if no further records are in this table. |
Please
see: Example: while(hasRec(„Persona“)) … |
NEXT / NÄCHSTER |
Goes to the next record or node in the data supply. |
Please
see: Example: |
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: Example: |
NEXT aliasname |
Proceeds to the next record or node in the data list described by the alias name |
Please
see: Example: |
NEXT –aliasname NEXT aliasname |
These two commands reset the data list to the 1st record. |
Please
see: Example: |
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:
or if(<condition>) |
QUOTE / ANGEBEN |
Inserts a text to the document. |
Please
see: Example: |
REF / REF |
Creates a placeholder with a name, that is later replaced by variable content. |
Please
see: Example: text(ref(“institute.EL_KIN_BEZ”)) |
REF "?variable" |
Returns "0" if the variable does not exist, else returns "1". |
Please
see: Example: |
SET / BESTIMMEN |
Assigns a new text to a text mark. |
Please
see: Example: |
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: |
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: |
= Ausdruck / Expression |
Calculates the result of a expression (= formulae) |
JavaScript formulae Examples: Attention: |
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“)) |
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”); |
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… |
{# while(<condition>) {…content… |
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