Calculate Templates

Introduction

Linux OS conventionally stores application settings in text files located in the /etc directory, or, sometimes, in /var. Their formats vary from the usual "variable=value" to more complex C-like or XML structures.

This method may look very simple, but is highly efficient in assuring stability, since the filesystem accounts for all settings.

Usually, different Linux distributions have each their own utility to handle application settings. Though undoubtedly convenient, this approach has its limitations:
  • users get accustomed to the one setting tool (distribution-wise);
  • the number of settings that can be modified depends on the program interface;
  • direct editing of a configuration file is not easy, because the program rewrites it any time changes are made.

Working with templates in Calculate 2

Calculate 2 has been rewritten and is now substantially different from its first version, namely:
  • Templates are usually transferred by appending them to the system configuration files. All popular file formats are supported.
  • To be appended to configuration files, templates need to be converted to XML format. The template file format may differ from the config file.
  • Template files may contain headers describing the append method that will be applied.
  • Built-in variables are renamed according to type.

Installation templates

Instead of editing configuration files directly, Calculate utility creates templates.

File formats

Depending on the data storage method, the following file formats are accepted for templates:
  • apache, kde, bind, postfix, proftpd, samba, procmail, ldap, dovecot, xml_xfce, xml_xfcepanel, xml_gconf, xml_gconf_tree, compiz, plasma, squid, dhcp, openrc stand for the settings of commonly used applications
  • bin stands for binary
  • raw stands for raw text
  • patch stands for using regular expressions (Uses the special patch append type)

For kde, the '-','+' options are not handled for in-field elements.

Option names in openrc format are not case-sensitive.

Control records

Besides service settings stored in the original format, template files contain system notes, which may be of several types:

Variable

A variable is a text element of a template; its name will be replaced with a value in the corresponding configuration file.

A variable has thus a name, a value and a scope.
  • naming conventions: latin characters and digits
  • value: text that will replace the variable (created by Calculate)
  • scope: global for all templates or local for this template only

Variables include template variables and function variables.

Template variables are global-scope variables; that is, any Calculate template variable can be used in any template. No template can modify the value of such a variable.

Function variables, on the other hand, can be created as well as modified in a template. Their scope is the current template.

Whenever you need to transfer the values of the function variables from one template to another, a LIFO stack is used: that is where the push() template function stores the value from the current template, while the pop() template function will fetch this value to the second template.

LIFO stack

A LIFO (Last In, First Out) stack is used to store the values of function variables. Templates can access it globally; templates functions are used to handle it - push() for recording, pop() for reading. These functions are available in one template as well as in several ones.

Header

A header is a template control record which defines how the template will be merged into the system. The template header comes at the top of the template file and should look like this:

# Calculate option1=value1 option2 [option3=value3 ...]

The header may contain several lines; you must insert a backslash at the end of each line.

If there is no header, the settings of the template file are defined by default.

Acceptable options:
Format
  • format=[...] stands for the format of the template file (see File formats). It defaults to "raw", or "bin" for files containing binary data.
  • comment=[.] marks the beginning of a string commentary (e.g. "#").
Append
  • append=[join|before|after|replace|remove|skip|patch|clear] indicates the append method. By default, it is set according to the file format. If append=skip, the template is omitted. If append=clear for a file template, the config file will be cleared, file length is 0; for a template directory, files and directories in the config directory will be deleted recursively.
  • force deletes the existing files before recording a new config file. If the "symbolic" option is set, the rule is applied by default.
  • link=path indicates the path to the config files the template file will be appended to. By default, the path is the same.
    Example: "link=/etc/conf.d/net.example"
  • path=path Path to the directory storing the configuration file.
  • name=name Name of the configuration file.
  • mirror Append only if the configuration file exists. If it is defined by the "link" option and therefore does not exist, the target file is deleted.
  • symbolic Create a symlink to the file specified with the "link" option.
  • autoupdate When installing any package, the cl-update-config script is launched, which applies templates for this package. The configuration files of the installed package are protected; that is, if this file already exists in the system and is modified during package installation, it will not be relaced automatically. To replace the configuration files of the installed packages, the dispatch-conf command is used. If the template header includes the autoupdate option, the configuration file will be copied into the system after the template is applied. If this option is absent, you should use dispatch-conf to merge the modified configuration file.
  • exec Shell used to execute the configuration file provided by the template.
    Example: "exec=/bin/bash"
Access rights
  • chmod=XXX indicates the rights of access to the targeted file (e.g. "644"). By default, the rights respect the original file settings. If there is no such file, the template file settings will be respected.
  • chown=user:group is the owner and/or the group of the targeted file (e.g."root:root").
Conditions
  • variable[>|<|==|!=|>=|<=]value ... specifies conditions for merging the template into the system.
    Arithmetic operations may be combined using "AND" (&) (for calculate-lib>=2.2, "AND" as (&&)) and "OR" (||). In this case, AND will have the precedence over OR. Several space-separated conditions will be combined with the "AND" condition.

Tags

You can set your system based on your hardware, network settings and other conditions. To do so, you need to specify the variable tags instead of constant values in the template file.

Example of the /etc/conf.d/hostname file:

HOSTNAME="#-os_net_hostname-#" 

Conditional blocks

The template file may contain conditional blocks.

Conditional blocks are particular template text fragments that will be inserted if the regular expression is matching.

A regular expression is a method of checking expression values. The following data types are used as values:

  • variables are in-built Calculate variables.
  • numbers are integer and floating numbers; for the latter, a period '.' is used as separator.
  • strings are characters, digits, and special symbols.
  • version numbers are numbers; one or two periods are used as separators (e.g. 8.5.1).

Checking is performed with an arithmetic operation: >, <, ==, !=, >=, <= (more, less, equal, not equal, more or equal, less or equal). The data type is defined before comparing.

Several arithmetic operations may be combined using AND (&) and OR (?) conditions. AND has always the precedence over OR.

The conditional block must begin with the tag "#?variable1==value1(...)#" and end with "#variable1#", prepended to the line.

Example of a conditional block for the /etc/make.conf file:

#?os_arch_march==i686&os_linux_shortname==CLD#
   CFLAGS="-O2 -march=i686 -pipe" 
   CHOST="i686-pc-linux-gnu" 
#os_arch_march#

This example compares the variables "setup_march" and "setup_sys_shortname" are compared with the string values "i686" and "CLD", respectively. If the values of both variables should be the same, the block text will be put into the resulting file.

Functions

To create complex files that require calculations while processing, you will need functions. Similarly to variables, functions are inserted in the template using the "#-function()-#" syntax.

Functions which use the path to the file (path) in their arguments can assume the user directory '~' as the home directory.

The following functions are available:

belong(pkg_name) Check the name of the package if this package is being installed. Otherwise, the function will return a positive result.

pkg_name is the package name; optional argument. If the function has no argument, the argument will be assumed to be the name of the directory where the template with the belong() function is located.

The result depends on the value of the template variable cl_belong_pkg.
  • the value cl_belong_pkg - ''
    • the result is '1', regardless of whether the function has an argument or not
  • the value of cl_belong_pkg is 'package_name'
    • if the value of cl_belong_pkg matches the function argument, '1' is returned, otherwise ''
    • if the function has no argument, compare the value of cl_belong_pkg and the name of the directory where the template with the belong() function is located; if they match '1' is returned, otherwise ''

Example.
Template header 1:

# Calculate belong(nss_ldap)!=

Template header 2:

# Calculate belong(kdm)!=

  1. Overlap the template for the nss_ldap program: Set the value of the variable cl_belong_pkg to nss_ldap. Only Template1 will be applied.
  2. Overlap all templates. The cl_belong_pkg variable defaults to ''. Template1 and Template2 will be applied.
case(type,var) Output the value of the template variable with changing the case mode.
where:
  • type indicates the case mode: upper stands for the upper case, lower stands for the lower case, capitalize stands for first letter in upper case.
  • var is the template variable name.

Example. Print the host name in upper case:

#-case(upper,os_net_hostname)-#

disk(mount_point,name) Output the value of the hard disk option at system installation.
The function gets its value from the variable ('os_install_disk_' + name; if does not exist, then 'os_disk_'+ name), the os_install_disk_mount variable is used to find the required value (mount points at installation).

where:
  • mount_point is the mount point at installation.
  • name is the last element of the variables beginning with os_install_disk_/os_disk ('os_instll_disk_'/'os_disk_' + name).

variable values

os_install_disk_mount = ['swap', '/', '', '', '/var/calculate']
os_disk_grub ['0,0', '0,1', '0,2', '0,3', '0,4']

function
disk(/var/calculate,grub)

  • find /var/calculate in the variable os_install_disk_mount, get index 4
  • in the os_disk_grub variable, index 4, we get '0,4'
    The function disk(/var/calculate,grub) returns '0,4'

function
disk(/boot,grub)

  • /boot not found in the os_install_disk_mount variable, no index
  • if no index, find / in the os_disk_install variable, get index 1
  • in the os_disk_grub variable, index 1, get '0,1'
    The function disk(/boot,grub) returns '0,1'

Example.
Show disk for the grub bootloader:

#-disk(/boot,grub)-#

We get 0,1

env(service.var_name) Read values of the recorded template variable for the service. Data is fetched by processing files storing values of the template variables.

where:
  • service is the service name.
  • var_name is the service variable.
    The separator is period, '.'.
Examples:
  1. Read domain name for connection with the jabber server
    #-info(jabber,sr_jabber_host)-#
    

We get the value jabber.calculate.ru

exists(path,opt) Check for a file or a directory

If the file or the directory exists, '1' will be returned, otherwise ''

path is the path in the filesystem.
opt is optional.

Acceptable values for "opt":
  • root The path to the file will not include the chroot path. (The effective path will be the specified path, whatever the variables cl_chroot_path and cl_root_path)

Example. Check whether the /etc directory exists

#-exists(/etc)-#

'1' will be returned.

groups(group1,group2,..groupN) Checking if the user is in group1,group2, ..groupN

If the user is in at least one group, '1' is returned, otherwise ''

group1 .. groupN are group names.

Example. Check if the user is in the wheel group

#-groups(wheel)-#

If the user is in the wheel group, the result will be '1'

ini(var, value, opt) Record and read the value form the user configuration file (~/.calculate/ini.env).

Since version 2.2.20-r4, if the function is executed for setting the system, the configuration file will be located at @/etc/calculate/ini.env@

where:
  • var is the function variable name. The name must begin with a character and may contain (latin) characters and digits, as well as a period. The period is used as separator between the partition and the name of the variable to be stored in the configuration file.
  • value is the function variable value; the value is assigned to the function variable and recorded in the configuration file. If the second argument is absent, the variable is read from the configuration file; if the configuration file does not store the variable name, an empty value is recorded in the configuration.
    Since version 2.2.20-r4, if the argument is an empty string without quotes, the variable will be deleted. If the argument is an empty string in quotes, the value of the variable in the _ini file will be cleared_
  • opt is the option used for modifying the variable value; optional; accepted values are url, purl, unicode. If this argument is used, the second function argument must be empty.
Examples:
  1. Create the "test" variable and set it to 15; record it in a configuration file
    #-ini(test,15)-#
    
  1. Read the value of the previously stored test variable from the configuration file; replace the function with the value of the read variable, "15" in our case
    #-ini(test)-#
    
  1. Use the ini function with three argument, assuming that the ~/.calculate/ini.env file has a section
    [test]
    param = String option
    

then the function

#-ini(test.param,,unicode)-#

will return

\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440

while the function

#-ini(test.param,,url)-#

will return

%d0%a2%d0%b5%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9%20%d0%bf%d0%b0%d1%80%d0%b0%d0%bc%d0%b5%d1%82%d1%80

The purl differs from url as it transforms '/' into '%2F' code.

server(service.option,var) Read the value of the service option. Data is fetched by processing the /var/calculate/remote/server.env file

where:
  • service stands for the service name.
  • option is a service option.
  • var is the name of a function variable (optional).
    service and option are period-separated: '.'.
    If var, the function variable name is used, the returned value of the service option will be recorded in the function variable var.
    If var is not used, the resulting value of the service option will be inserted in the configuration file.
Examples:
  1. Read port value for connection to the jabber server
    #-server(jabber,port)-#
    
We get 5223
  1. Read port value for jabber connection and put it in the function variable jabber_port
    #-server(jabber,port,jabber_port)-#
    

The value of the jabber_port function variable is 5223.

list(var,index) Output a value by index from the variable.
where:
  • var stands for the name of a function variable or a template variable (the variable value must be a list).
  • index stands for the index used to search a value in the function variable or in the template variable (the first element would be indexed with 0, etc.)

Example.
Variable value
os_disk_dev = ['/dev/sda1', '/dev/sda2', '/dev/sda3', '/dev/sda4', '/dev/sda5']

#-list(os_disk_dev,1)-#

The function tag will be replaced with '/dev/sda2'.

If an element is prompted which is not on the list, template overlap will break with an error. Since version 2.2.17 an empty line is returned.

load(arg,path,opt) Show file information.
where:
arg is the type of file contents.
path is the path to the file.
opt is optional.

Acceptable "opt" values:
  • root The path to the file will not include the chroot path. (The effective path will be the specified path, whatever the variables cl_chroot_path and cl_root_path)

Acceptable "arg" values:

  • ver File contents, version name.
  • num File contents, number.
  • char File contents, string.
  • empty Result, file contents without commented (comments marked with # or ;) nor empty lines.
Acceptable "path" values:
  • path Absolute or relative path to the file.

Example. Print the contents of /proc/cpuinfo at the point where the function is declared.

#-load(char,/proc/cpuinfo)-#

module(name_space) Get the template variables for a package or performing the package methods using its api module, or perform one particular method for all package with an api module

where:
  • name_space is the name space for the api module.

The name space for getting variables consists of period separated elements.
The first element of the name space is the package name. The package name is the name of an installed package with an api module (a dash '-' should be replaced with an underscore '').
The first element of the name space is set to 'all' for all packages (reserved name).
Example of the first element for the _calculate-ldap
package.

calculate_ldap

The second element of the name space is the api method name or 'var' which is a reserved name for the name space of the package template variables.

Example of the first and the second element for the calculate-ldap package for getting access to variables.

calculate_ldap.var

Example of the first and the second element for the calculate-ldap package for getting the result of processing with the is_setup() method for the api module (checking if the package is installed).

calculate_ldap.is_setup

The third element of the name space is, in most cases, the name space for getting the value of a template variable.

Example of a name space for getting the value of the template variable cl_name for the calculate-ldap package

calculate_ldap.var.cl_name

Using the function - examples:
Get the value of the template variable cl_name (package name) for the calculate-ldap package

#-module(calculate_ldap.var.cl_name)-#

Calculate returns

calculate-ldap

Check if the calculate-ldap package is set for work

#-module(calculate_ldap.is_setup)-#

if the package is set correctly, we get the value

1

Check if all installed packages with api module are set for work

#-module(all.is_setup)-#

if all packages are well set, we get the value

1

pkg (category/package) Print the version of an installed package,
where:
  • category stands for the package category
  • package stands for the package name

As a compatible mode, you can specify the package name only; in this case the template will be processed with a lesser speed.

Example. Print the version of an installed package (e.g. 4.2.4).

#-pkg(kde-base/kdelibs)-#

It means that kdelibs-4.2.4 is installed.

push(var, value) Put the variable value in the LIFO stack.

where:
  • var stands for a function variable name. The name must begin with a character and may contain (latin) characters and digits. This variable is creating while processing the configuration file.
  • value stands for the value of the function variable; the value is assigned to the function variable and put in the LIFO stack. If there is no second argument, the variable value will be recorded in the stack.
Examples:
  1. Create the "test" variable and set it to 15; record in the LIFO stack.
    #-push(test,15)-#
    
  1. Record the value of the previously created variable test in the stack.
    #-push(test)-#
    
pop(var) Fetch a value from the LIFO stack and assign it to a variable.
  • var stands for a function variable name. The name must begin with a character and may contain (latin) characters and digits. This variable is creating while processing the configuration file.
Examples:
  1. Create the "test" variable and set it to 15; record it in the LIFO stack.
    #-push(test,15)-#
    
  1. Get the value from the stack and assign it to the test2 variable.
    #-pop(test2)-#
    

It is possible to fetch the value from the LIFO stack in the current template as well as in any other template.
Once the value is fetched, it will be removed from the stack.

replace(old, new, var) In the var variable value, replaces old with new,
where:
  • old is a text string; each entry of old in the variable value will be replaced with new
  • new is the text that will replace _ old_ in the variable value
  • var is the name of a function variable or a template variable

The old and new strings must be put either in double or in single quotes.

Control records (\', \", \n, \r, \t, \) are handled in the text in double quotes.
Text in single quotes will not be processed.

Example.
The template variable ur_signature is set to

Calculate Ltd.\n4, Stachek sq., Saint-Petersburg, Russian Federation\nhttp://www.calculate.ru\n+7 812 3363632\n+7 495 7727678

when executing the function

#-replace('\n',"\n",ur_signature)-#

the following text will be inserted at the insertion point ("\n" will be replaced with a line feed):

Calculate Ltd.
4, Stachek sq., Saint-Petersburg, Russian Federation
http://www.calculate.ru
+7 812 3363632
+7 495 7727678

rnd(type,len) displays a random symbol string.
where:
  • type stands for used symbols; accepted values are: num for numbers, pas for numbers and characters, uuid for numbers and characters from a to f (uuid has been added since 2.2.17).
  • len stands for the number of symbols.

Example. Print 3 random digits (e.g. 372).

#-rnd(num,3)-#

sum(var,sum_print, sum_out) are calculated shift values. This function was developed for the setting of Plasma (KDE).

where:
  • var is the name of the "sum" function variable. The name must begin with a character, but may contain both (latin) characters and digits. This variable is created while processing the configuration file.
  • sum_print are arithmetic expressions whose result will be shown at the place where the function is declared. If there is no argument, no value will be output. Addition "+", substraction "-", division "/" and multiplication "*" are supported. Other function variables may be included in the arithmetic expression, as well as template variables.
  • sum_out is an arithmetic expression whose result will be assigned to the "var" variable (the first argument of the function). If there is no third argument, the "var" variable will get the value of the second argument.
Examples:
  1. Create a variable named "clock" and set it to 15. No result output.
    #-sum(clock,,15)-#
    
  1. Create a variable named "bt", set it to the value of the "clock" variable and print the result.
    #-sum(bt,clock)-#
    
  1. Place a button on the panel; its width would be "35" pixels, with a "4" pixels indentation on edges:
    #-sum(bt,bt+2,bt+35+2)-#
    

Append methods

There are several methods of appending the template file to the original system file:
  • join: the main method, when the two files are merged together. This is explained in detail in Joining scheme.
  • before: the template is prepended to the original file.
  • after: the template is appended to the original file.
  • replace: the template is rewritten and replaces the original file.
  • delete: there is no append, the original file is deleted.
  • remove: instead of append, the original file is removed.
Modifying the template before append, for the "before", "after", "replace" methods:
  • if control records exist, they will be handled
  • if a header exists, it will be handled
  • if header has the format option, the control records "+, -, !" will be handled

Default rules

The default append method is set depending on the file format.
"samba" files, "bind" files and suchlike default to the "join" method, "raw" and "bin" to "replace". For an empty file, the "delete" rule is applied by default: that is, the targeted file is removed from the system.

These rules may be changed by setting the "append" option of the template file header.

Location

File naming conventions

The template file names may contain conditionals: if the conditions they set are true, the template file will be merged into the system. As in a web link, conditions are separated from the name with a question mark (?), which may be followed by conditional operators; you will find their detailed description in Conditional blocks (see above).

Arithmetic operations may be combined using AND (&) and OR (?) conditions. AND has the precedence over OR.

Example:

grub.conf?os_linux_shortname==CDS?os_linux_shortname==CLD

In this example, the template file will set the bootloader for Calculate Linux Desktop as well as for Calculate Directory Server.

If the template file header contains conditional operators, both conditionals must be true for Calculate to merge the template file into the system.

Directory naming conventions

Naming conventions for directories are similar to those for files. If the conditions set by a conditional are true, the directory will be merged into the system, otherwise it will be skipped with all its contents.

Access rights

After append, the rights of access to the configuration files are set according to the following precedence rules:
  • if the configuration file already exists, its access rights will be preserved
  • if the configuration file does not exist, the rights will be set to 644 for a file and to 755 for a directory
  • If the "chmod" or "chown" variable is set in the template file header, the rights will be changed accordingly

To create symlinks, use the "link + symbolic" options for the template file header.

If the template file contains not only a header, but also a body, the original file will be modified according to the append rules.

Calculate will not merge broken links, i.e. links pointing to a non-existing file (directory), if the "force" option is not specified explicitly.

Join scheme

Joining is modifying the original settting file accordingly to the template file settings.

While joining, all contents of the original file and of the template file are split into elements: scopes, variables, lists, split lists, comments, control records (see below).

The template file must be written in the syntax of the original file. All original file elements will be remain at their place. Any comments included in the template file will not be moved.

Append rules

Elements can be joined, replaced or deleted:

Join

  • Any elements absent in the original file are appended at the end of the scope. If there is a line feed before an appended element, the line feed would be added after the inserted element. Otherwise, the feed line is prepended to the inserted element.
  • If joining a split list, the absent elements are appended after the last split list element of the configuration file.

Replace

  • The current element value is replaced with a new one. Format is fetched from the template file.

Delete

  • The element is deleted together with the line feed placed before it.

Defaul append rules

These append rules apply to elements with one name, located in one template scope.

If differences found, the following rules are applied by default:
  • Scopes: contents of the two scopes are joined (+).
  • Variables: variable values are replaced (-).
  • Lists: lists contents are replaced (-).
  • Split lists: similar to the rule of variable joining, list values are replaced (-).

Change append rules

To change default append rules, the following control symbols are prepended to the element name in the template file:
  • "+" Elements are joined (for scopes and lists); only unique elements will remain after joining.
  • "-" The element's value is replaced.
  • "!" The element is deleted.
    In CXmlConf, these rules of describing a template file are tagged as "<action>".

CXmlConf format

CXmlConf is a versatile format used for description of configuration files. It allows to customize the settings of many common config files in Linux/Unix.

A setting description XML file splits the configuration file into several logical structures, or elements that can be joined again later. After joining, the file can be restored to its initial state, though there are exceptions (see Join scheme).

The syntax used to describe elements is shown below:

<cxmlconf>
  <head>
    <ver>format version</ver>
    <format>config file format</format>
  </head>
  <body>
    [<area>...</area>... <field>..</field>]
  </body>
</cxmlconf>

Where:
  • ver stands for the formatting version
  • format indicates the configuration file format (is defined by common applications)

All elements (see below) are put inside the <body/> element.

Scopes

The scopes of configuration files delimitate the variable namespaces. They may contain logical structures, including other scopes (e.g. {{Filename|named.conf}}).

Scopes are handled as shown below:

<area>
  <caption>
    <name>Scope name</name>
    <action>join|replace|drop</action>
    <quote>Start of scope (header)</quote>
    <quote>End of scope description</quote>
  </caption>

  [<field></field>...]

</area>

Variables

The syntax for handling variables is:

<field type="var">
  <name>variable name</name>
  <value>variable value</value>
  <action>join|replace|drop</action>
  <quote>Original description</quote>
</field>

In some configuration files such as /etc/openldap/slapd.conf you would find the following structure:

index   cn              pres,sub,eq
index   sn              pres,sub,eq
index   uid             pres,sub,eq

In this case, the first and the second part make the variable name, while the third part makes its value.

The line

index   cn              pres,sub,eq

will look like this in XML format:

<field type="var">
  <name>indexcn</name>
  <value>pres,sub,eq</value>
  <quote>index   cn              pres,sub,eq</quote>
</field>
<field type="br" \>

Lists

Like for the named.conf file, the "listen-on" block may contain only values - that is, block values and not variable values.

The syntax for indicating values is as follows:

<field type="list">
  <name>hostsallow</name>
  <value>192.168.0.0/24</value>
  <value>127.</value>
  <action>join|replace|drop</action>
  <quote>Original list</quote>
</field>

where the original text of the value description is preserved inside the "<quote>" block, without a final line feed.

Split lists

The setting file for the Apache server can contain an "Include" instruction which allows to make the source file modular. Cases like this are described as "Split lists" in "CXmlConf".

Split lists are defined in the following structure:

<field type="seplist">
  <name>Include</name>
  <value>/etc/apache2/modules.d/*.conf</value>
  <action>join|replace|drop</action>
  <quote>Original list</quote>
</field>

Comments

When configuration files are joined, the comments to the original file remain intact.

Comments of any type are placed in "<comment>"; in the text you put in "<quote/>", the comment and line feed symbols are preserved:

<field type="comment">
  <quote>Original commentary</quote>
</field>

Comments cannot be nested (i.e. you cannot describe them in any other comment structures)

Control elements

The syntax for a line feed is as follows:

<field type="br">
  <quote>separators (spaces, tabulation)</quote>
</field>

where
  • "quote" contains format elements (such as spaces, tabulation...)

XML format

Supported XML format

We presently support the formats xml_xfce (XML file for configuration of XFCE window manager), xml_xfcepanel (XML file for configuring panels of XFCE window manager), xml_gconf (XML file for GNOME configuration)

Differences from CXmlConf format

  • XML files are stored and handled without being converted to another format.
  • All rules, functions and variables apply to the XML template file as they would to an ordinary template, but for joining XML elements.

Joining XML elements

To join XML elements in a XML template, the 'action' attribute of XML elements is used.

Accepted attribute values are:
  • action="join" The elements will be joined (by default).
  • action="replace" The template element will replace the file element.
  • action="drop" The file element will be deleted.

xml_xfce format

This format includes "channel" and "property" elements.

"channel" elements store the file name and version.

"channel" elements contain "property" elements.

Example of a "channel" element:

<channel name="xfwm4" version="1.0">
  <property name="general" type="empty">
  .....
  </property>
</channel>

Example of a "property" element:

<property name="wrap_workspaces" type="bool" value="false"/>

Each "property" element has the type attribute.

If "array", this element as well as its internal elements will be replaced with elements from the template;
otherwise the elements will be joined.

Example type="array":

<property name="workspace_names" type="array">
  <value type="string" value="Workspace 1"/>
  <value type="string" value="Workspace 2"/>
  <value type="string" value="Workspace 3"/>
  <value type="string" value="Workspace 4"/>
</property>

xml_xfcepanel format

This format includes the elements "panels", "panel", "properties", "property", "items", and "item".

If "items", this element as well as its internal elements will be replaced with elements from the template;
otherwise the elements will be joined.

Example of an "items" element:

<items>
  <item name="xfce4-mixer-plugin" id="9"/>
  <item name="clock" id="10"/>
  <item name="separator" id="52"/>
  <item name="actions" id="12"/>
</items>

xml_gconf format

This format includes "entry" elements.
If the "entry" element has a "ltype" (list) or a type="string" attribute, this element as well as its internal elements will be replaced with elements from the template;
otherwise the elements will be joined.

The "mtime" attribute of the "entry" element shows the time when the "entry" element was modified, in seconds.

Example of a xml_gconf template:

# Calculate format=xml_gconf
<?xml version="1.0"?>
<gconf>
        <entry name="rgba_order" mtime="1235158855" type="string">
              <stringvalue>rgb</stringvalue>
       </entry>
       <entry name="dpi" mtime="1235162438" type="float" value="86">
       </entry>
       <entry name="hinting" mtime="1235266915" type="string">
               <stringvalue>full</stringvalue>
       </entry>
       <entry name="antialiasing" mtime="1235266915" type="string">
               <stringvalue>rgba</stringvalue>
       </entry>
</gconf>

xml_gconf_tree format

This format includes "dir" and "entry" elements with their attributes.

The attributes will be appended in case of 'join' append.

When the template is appended to the configuration file, the "entry" elements of the configuration file will be replaced with the corresponding "entry" elements of the template.

The "mtime" attribute of the "entry" element shows the time of the change in seconds.

Example of a xml_gconf template:

# Calculate format=xml_gconf_tree
<?xml version="1.0"?>
<gconf>
    <dir name="desktop">
        <dir name="gnome">
            <dir name="volume_manager">
                <entry name="percent_used" mtime="1285580987" schema="/schemas/desktop/gnome/volume_manager/percent_used"/>
                        </dir>
                </dir>
        </dir>
<gconf>

Practical examples

The template file runs as follows:

# Calculate format=xml_xfce
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-session" version="1.0">
  <property name="general" type="empty" action="drop">
    <property name="FailsafeSessionName" type="empty"/>
    <property name="SessionName" type="string" value="Default"/>
    <property name="SaveOnExit" type="bool" value="true"/>
  </property>   
</channel>

The line <property name="general" type="empty" action="drop"> says that this element, as well as the elements it contains, will be deleted.

As the result, we get the following file:

<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-session" version="1.0">
</channel>

Patch format

The patch format is used for handling configuration files with Python regular expressions.

Features

The patch format handles the configuration file according to the template ( patch append type), though the template is not appended to the configuration file.

Description

The patch format syntax is shown below:

# Calculate format=patch
<reg>python regular expression 1</reg>
<text>text 1 which will replace the regexp</text>
<reg>python regular expression 2</reg>
<text>text 2 which will replace the regexp</text>
...

Example:

# Calculate format=patch
<reg>TEXT</reg>
<text>TEXT_CONFIG</text>

This template will replace TEXT with TEXT_CONFIG in the configuration file.

Thank you!