Placeholder actions and panel menus in the Werk [2] Plugins can be programmed with scripts in the cscript language. This document describes the general syntax in cscript. A detailed documentation of functions implemented for cscript can be found here.

Scripts in cscript are constructed from a subset of keywords from the C programming language, and largely adhere its syntax. Generally, the following applies:

If a C compiler throws a syntax error on a cscript, the cscript does not conform. However, even if a C compiler does not find errors in a cscript, the cscript is not necesseraliy conform.

We will not give a full description of the C elements in cscript. Instead, we will focus on the differences between C and cscript. With these examples and the cscript Documentation, you should still be able to write your own scripts, even without prior knowledge on C.

Literature recommendations on C:

This example shows a classical Hello World program in cscript

Show an InDesign® message box with the text Hello World.

int main ()
{
    showmessage ("Hello World");
    return 0;
}

Work on a cscript program always starts with the main function. The function has to be of type int and , unlike C, may not take any parameters.

int main ()

If a script does not contain this function, it does not run.

A common error in the main program is a missing return at the end of the function. When a script is run by the plugins, the result of the main function (the value of return) is queried. If no value is explicitly returned, this returns an effectively random result, which may lead the plugin to assume the script exited with an error.

In addition to C style block comments (/* */), cscript also accepts line comments (//) introduced in C++.

/* 
    Multi-line comment
*/

// Comment until line break

The cscript language only knows three datatypes, int, float and char. You can take pointers to (int*, real*, char*) and arrays of (int [], float [], char []) these basic types. To improve readability of your cscripts, there are also a variety of module specific typenames, all of which resolve to int*.

The C keywords typedef, enum and struct are not defined in cscript. You cannot define your own data types.

Datatype Description
int, short, long integer, 4 Bytes (-2147483648 to 2147483647)

These are all equivalent. There is no unsigned as in C.

float, real Real values, 4 Byte

There are no double or unsigned as in C.

char Character, 1 Byte

There is no unsigned as in C.

• The following datatypes all resolve to int* and only serve to improve the readability of your scripts
Asset Used in the library module
DataPool Used in the library module
DBC Used in the sql module
Image Used in the image module
ItemList Used in the modules document, frame and itemlist, among others
ItemRef Used in the modules document, frame and itemlist, among others
Library Used in the library module
Link Used in the modules link and linklist
LinkList Used in the modules link and linklist, among others
List Used in the list module
Product Used in the modules product and productlist, among others
ProductList Used in the modules product and productlist, among others
Query Used in the query module
String Used in the string module
StringList Used in the stringlist module
SOAP Used in the image module
Table Used in the table module
XMLTree Used in the xmlquery module

Expressions are evaluated back to front. Otherwise, operators can be used as in C. The shift operators << and >> are not implemented.

The following calculation results in a seemingly unusual result. To get the expected result, use parentheses.

x = 20/10*2;    // evaluates to 1, not 4
x = (20/10)*2;  // this evaluates to 4

The table below lists all keywords defined in the C programming language. The struckthgough keywords are not defined in cscript.

Do not be surprised at how many keywords are not defined. You can still theoretically program anything in cscript, and despite the C language itself being relatively simple, it is powerful enough to implement complex applications such as InDesign® and the Werk [2] Plugins.

Keyword Description
auto Storage classes are not supported in cscript.
case switch-case constructs are not supported in cscript.
char
continue In for and while loops, continue has to be manually implemented using if-else constructs.
default switch-case constructs are not supported in cscript.
do
double
else
enum You cannot define custom datatypes in cscript.
extern Storage classes are not supported in cscript.
float
for
goto
if
int
long same as int
register Storage classes are not supported in cscript.
return
short same as int
sizeof
static Storage classes are not supported in cscript.
struct You cannot define custom datatypes in cscript.
switch
typedef You cannot define custom datatypes in cscript.
union You cannot define custom datatypes in cscript.
unsigned
void
while

You can use global variables in cscript. Global variables are defined and modified in the Settings panel.

    

Global variables can be used in scripts like any other variable. The following datatypes are supported:

The variables are read, when a connection to the datapool is established. Each InDesign® Instance has its own copy of this data. Changes to these values only apply locally. With the function system::commit_global, you can write the changed variables back to the datapool. Locally modified variables are marked red in the panel.

You can define a new global variable with . A dialog will pop up, asking you for name, description and type of the new variable. After clicking OK, a window will appear, asking you for the value of the default variable.

The description is displayed as a tooltip in the Settings panel when hovering over the variable name.

    

To administrate your entries, use the button in the first row in the list. The button tooltip will provide additional information.

    

The entries shown in the Settings list can also be edited directly via the data source:

The definitions of the variables and their values are stored in datafiles.xml (XML and SOAP) or in the table globals (ODBC and Oracle). The following table describes the required attributes of datafiles and globals.

Name Type Description
id int The ID is used to determine the datatype of the variable:

  -1 : char [8192]
  -2 : float
  -3 : int

The ID is not a primary key of the table! Use a combination of id and alias as the primary key :

  ALTER TABLE `globals` ADD PRIMARY KEY ( `id` , `alias` )

alias varchar (255) Name of the variable. Names have to start with a letter or a _, and may contain letters, numbers and _. Names are case sensitive.
path text Value of the variable. For numbers, the text has to contain a matching number string. A period (.) is expected as the decimal separator.
description text A description of the variable. The text is displayed in the yellow notes in the Settings panel.
enabled int This value is currently ignored.

Variable names have to be unique.

You can define up to 8192 global variables.

r/o Returns are performed in three cases:

  1. To determine global values (serror, file::get_nth, boo::get_master, ...). The return values are defined exactly once. Each additional call to the function overwrites the result.
  2. To read properties of script objects (string::get, link::crossref::name, ...). The return values are defined as long as the object whose property was retrieved is.
  3. In functions with an output parameter of type string, the char* pointer of the string parameter may be returned (frame::gettext). Of course, this is defined as long as the variable used in the call is not changed.

No memory has to be allocated for the function results. The functions simply return the value of a global addresss or an address within the queried object. Because of this, it is important to keep a few things in mind :

Direct use of a function with r/o return value.

showmessage ("%s", file::get_nth ("$DESKTOP", 0));

Assigning the result to a script variable

char * str;
:
str = file::get_nth ("$DESKTOP", 0);

The declaration and assignment can also be performed in a single step.

char * str = file::get_nth ("$DESKTOP", 0);

Copying the result into a local script variable.

char * str = alloc (1024); // oder char str [1024]
:
strcpy (str, file::get_nth ("$DESKTOP", 0));

These common mistakes are usually not found upon running the script, but they do modify foreign memory. Only when the actual owner of the affected memory accesses again, problems arise.

The return value must not be assigned to allocated variables. The variables change their value (address) and thus no longer point to the reserved memory. Memory reserved with alloc can no longer be released.

char * str = alloc (1024); // or char str [1024]
:
str = file::get_nth ("$DESKTOP", 0); // WRONG! str is an allocated variable.

The functions may not be used anywhere where their content is modified (such as the first parameter to strcat or strcpy).

strcat (file::get_nth ("$DESKTOP", 0), "pp"); // WRONG! The value of the result is mutated.

The contents may not be changed via the (less obvious) route through a locally defined variable.

char * str;
:
str = file::get_nth ("$DESKTOP", 0); // Everything alright so far
strcat (str, "pp");                  // WRONG! str is an r/o Variable

Variables that were assigned an r/o result may not be deleted. (Forbidden changes to variables and freeing of non-owned memory).

char * str;
:
str = file::get_nth ("$DESKTOP", 0); // Everything alright so far
:
release (str);                     // WRONG! r/o Variable may not be freed.

Following calls to a function with r/o results can overwrite the results of earlier calls. Never use these functions twice within the same expression.

wlog ("",
"'%s', '%s'\n",
file::get_nth ("$DESKTOP", 0),
file::get_nth ("$DESKTOP", 1)); // WRONG! Result of get_nth is possibly overwritten

Following calls to a function with r/o results can overwrite the results of earlier calls. Never use these functions twice within the same expression.

String str = string::alloc ();
char * s1;
:
s1 = frame::get_text (gFrame, str, 0, kEnd);
:
wlog ("", "%s\n", s1);
string::release (str);
wlog ("", "%s\n", s1); // WRONG! str has been freed already!