Programming Cab Printers
Programming Cab Printers
JScript
2
Copyright
This documentation as well as translation hereof are property of cab Produkttechnik GmbH & Co. KG. The
replication, conversion, duplication or divulgement of the whole manual or parts of it for other intentions than
its original intended purpose demand the previous written authorization by cab.
Editor
Regarding questions or comments please contact cab Produkttechnik GmbH & Co. KG.
Topicality
Due to the constant further development of our products discrepancies between documentation and product
can occur. Please check www.cab.de for the latest update.
Deliveries and performances are effected under the General conditions of sale of cab.
Edition
04/2022
Contents 3
Contents
1 Basics 8
1.1 Why JScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 How to read this manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3 Download the code samples and cabLabel S3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4 What else to read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.5 JScript-enabled devices since 1995 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.6 Editing JScript files under Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.7 How we support you . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5 Special functions 51
5.1 Syntax of the special functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.1.1 Include in square brackets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.1.2 Pass function parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.1.3 Use field names as special function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.1.4 No nestings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.2 Hiding elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.2.1 Conditional visibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.3 Ask the operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.4 Dynamic date and time functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.5 Adding a time offset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.6 Using counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.7 Remember the counter value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.8 Calculations and comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.9 Format strings or numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.10 Avoid rounding errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.11 Inserting UNICODE characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.12 Single buffer mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
8 Access to databases 72
8.1 Connecting to the cab Windows service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.2 Stand alone sulution: using a local SQLite file . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.3 Get a value from a database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
8.4 Splitting the database response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Contents 5
10 Diagnostic options 80
10.1 Monitor Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
10.2 Log incoming data into a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
10.3 Preview a label without printing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
14 Appendix 129
14.1 A typical JScript label in detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
14.2 Short view on special functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
14.3 Error codes for the Esc s command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
List of Tables
1 Basics
You are just start reading an introduction to the JScript printer language. This document is not a complete
textbook, but should people who already have experience in the use of programming languages have a fast
overview of the most important basics and commands of the JScript language. At the end of the document,
you will also see “abc”, the Advanced BASIC Compiler. It is available in nearly all cab printers1 and allows a high
degree of automation without that a separate PC would be required.
JScript offers very extensive possibilities for direct programming the cab printer.
JScript is system-independent. No matter if your JScript file is stored on an Apple Macintosh, a Linux computer,
a Windows PC, an AS400 or a PLC, the cab printers understand all common formats.2
JScript allows access to databases. And this both online and also offline. For online access to databases,
the printer needs the Software cab Database Connector, which is available as a service on a Windows
system. This can, but does not have to, be the same PC or server on which the database is running. The
actual access is via OLEDB/ODBC. cab Database Connector works as an intermediary between databases
and printers. Several printers can be connected simultaneously to one installation of the cab Database
Connector. Offline the printer is able to use a SQLite database.3
JScript allows extensive calculations By embedding BASIC code, they can also be extended almost indefi-
nitely. This leads to a flexibility that is otherwise rarely found in label printers.
You can secure processes. Entries can be checked by the printer. Data can be transferred directly, signed and
encrypted from systems like SAP, so that faulty operator inputs (e.g. – typing errors) are avoided. If labels
are printed, this information can securely be fed back to your system in order to guarantee a complete
documentation of created labels. All this directly through the printer.
This guide is a quick start into JScript programming. Read everything that helps you and skip parts you do
� not need. This is not a comprehensive textbook. Much will only shown shortened.
As manufacturer we offer you an extensive training program for our printers. This also includes a training course
for direct programming of our label printer.
This guide summarizes the most important points of the one-day JScript programming training session and can
be used without attending the training for self-study.
The dates of the JScript workshops can be found on the Internet:
https://www.cab.de/en/info/trainings/overview/#jscript
We are aware that it will not be possible for everyone to work on an individual training, be it in our training center
in Karlsruhe or by one of our trainers on site. Therefore, this manual tries to to bring JScript closer to many
readers even without much previous experience. Also the specialists find answers to more complex topics, e.g.
1
Only the two smallest printers Mach 1 and Mach 2 do not have an integrated Advanced BASIC compiler. They also do not process
JScript and must be operated via a Windows PC (GDI devices).
2
JScript works line-oriented and accepts both a line end <CR><LF> (Microsoft Windows), <LF> (Linux) or <CR> (Apple Mac OS). However,
the format should not change within the same file.
3
Prerequisite is a printer with X4 mainboard and a firmware version 5.25 or higher. New firmware can be installed on cab printers
without registration or extra costs via the cab website.
1 Basics 9
“How do I print a hazard symbol contextually?”, which is related to the topic “conditional visibility” (it is explained
on page 53).
So don’t despair if you can’t follow every detail in this manual. As the number of pages increases, so does the
complexity and the necessary previous experience. If you get stuck in the middle of the manual, don’t worry
about it. If you make it to the summary on page 50 you have already understood the most important basics of
JScript.
The listings printed here in this book are mostly attached to the PDF file. In the PDF Reader click on the indicator
of the embedded attachments (download icon with file name) and download the files from the PDF instead of
laboriously typing them. The file name of embedded attachments is displayed below the listings in light blue
font. This procedure to access the listing by click (or double-click) to save (or open) was tested with the PDF
Readers Adobe Reader DC and Sumatra PDF. Should you find out that the code examples cannot be downloaded
directly from this PDF, your reader’s JavaScript Action functions may be prohibited.
Many of our customers also use the software cabLabel S3, which comes with our printers and is also available free
of charge as cabLabel S3 Lite from our website. It can be used to create the JScript label files.
https://www.cab.de/cablabel
This book therefore occasionally contains screenshots and hints on how cabLabel S3 can generate certain
JScript elements. A typical use case is often the creation of a layout template in cabLabel S3 Lite and the
later filling with data from the production process using the replace command (see section 4.4.4 starting with
page 48).
The programming manual for SQUIX, MACH 4S, EOS2/EOS5, HERMES Q, PX Q should always be within easy
reach for additional reading. The programming manual offers a complete reference of all JScript and abc �
commands on over 650 pages.
You can find the manual on the cab website:
https://www.cab.de/en/programming
Both together, this document and the comprehensive reference “Programming Manual”, can help you getting
started with JScript.
This manual is intended for the newer devices with a mainboard of X4 Series (or newer). You can recognize these
devices by their colored touch displays, which are not built into the older models. If the control is still via keys
below the display, or is the touch display monochrome, you have a device of an older mainboard generation in
front of you.
Older devices do not support some of the commands described here in the manual. Refer to Programming
Manual for A+ and X-Series, MACH4, PX, Hermes+, Hermes C, EOS1/EOS4, which commands are also used by the
older models.
10 1 Basics
2011 - 2018
2006 - 2017
2001 - 2006
1995 - 2005
Figure 1.1: cab has been building printers that can be controlled with JScript since 1995
Since January 2020, no devices have been produced that do not have at least a mainboard of the X4 genera-
tion.
Figure 1.1 shows an example of the different series each with a 4 inch tabletop printer.
1995 was the birth of the first cab thermal transfer printer and at the same time the first use of JScript as printer
language. The Apollo was produced until the middle of 2005. Apollo printers had a two-line text display and four
keys for operation.
From 2001 to 2006, the A series supplemented and replaced the Apollo. A series printers, like the Apollo, only
had a text display. The four keys of the Apollo were replaced by a navigator pad, the metal housing by a more
modern housing made of industrial plastic.
In 2006, the A+ printers were the first having one identical mainboard for all printers of the series, the ”X2
board”. On its single core CPU runs a monolithic firmware. All printers of the A+ series have a Navigator Pad
(cross-shaped control button) and a graphic display. Not before 2017 the production of the A+ table printers
ended.
With the EOS we entered new territory in two aspects. The two printers EOS1 and EOS4 were the first ones
made completely out of plastic by cab as a new kind of compact industrial printers. On the other hand, the
X3 Board first offers a Linux substructure. This opened up a wide field for future enhancements to the printer
functions.
As the flagship of the next generation, the SQUIX was first sold in 2016. It’s touch display is colored and the user
interface has been completely redesigned. All models of this series, including the HERMES Q and PX Q series have
the identical X4 mainboard with a powerful processor and Linux as a substructure.
To edit the JScript files you can use any text editor, but we recommend the free editor Notepad++. This editor
allows you to work with a printer with the help of the extension NppFTP – directly to the printer via a local network
(see section 2.6 from page 14). You can find extensions in Notepad++ via the menu item “Extensions” and install
then via “Plugin administration . . . ”.
1 Basics 11
https://notepad-plus-plus.org/
Figure 1.2: Notepad++ allows you to colorize the source code individually. Click on “Languages”, then on “Own Language define . . . ”
and “import” the one linked here as a XML file. � JScript-Highlighting.xml
The open dialogue with our customers and partners is an important part of our success. You get from cab
not only innovative marking technology for the industrial use, we also give you free access to our instructions.
Nevertheless, self-study is not always the most efficient way to a labeling solution.
Talk to us. Besides the possibility of an individual solution for training you, we also offer you the possibility
to work on your project together to plan and realize them. The direct contact to our developers, support
staff and trainers will help you to complete projects faster and more reliably – and thus will end up reducing
costs.
12 2 Communication with the printer
Before we can turn our attention to the printer language, we need to clarify briefly how you can reproduce the
mentioned examples on a cab printer.
Here are just a few of the possibilities. There are still significantly more possibilities, but this manual should focus
on the pure concentrate printer language. For the interfaces and their optimal use please refer to the interface
manual of the respective printer model.
To actively work through this manual you only need one way to get your JScript code into the printer.
This can be done with a USB stick, witch can be useful if you still have little or no experience with computer
technology and networks. More convenient is the access via the network, but in some cases considerable prior
knowledge is required. Decide for yourself how to connect to your printer.
The easiest way is to use a storage medium that you can read and write on the printer as well as on your computer,
e.g. a USB memory stick. First format the storage medium on the computer, so you still need to add the four main
directories “fonts”, “images”, Create “labels” and “misc” directly in the root directory.
If this seems too complicated, then plug in the storage medium simply freshly formatted into the cab printer. If
the printer is switched on it creates the necessary directories independently. You can use the storage medium
then after this, just plug it back into your computer and copy the JScript files on it.
If the contents of e.g. a USB memory stick are not immediately displayed on the printer you can switch to the
USB memory each time you select the menu item “load label” (see figure 2.1 on page 13), or you can set USB as
default. Then the printer always searches for files in the USB memory first. The default memory must be selected
correctly if you give the printer the command to load of a label, but do not specify the storage location itself (see
section 4.4.3 for details on page 47).
Label jobs are pure text files4 with a file extension “.lbl”. It is important that the extension is actually “.lbl”. Are you
using a Windows operating system and is the display of the file extension deactivated (for Windows the default
state), a created text file would probably have the double extension “.lbl.txt”, but which the printer cannot do
anything with.
However, before you run to buy an Apple Macintosh or a Linux PC, you can simply activate the display of the file
extension under Windows in the folder display options. How this works exactly tells you your favorite search
engine on the internet.
The text file, which ends not on “.txt” but correctly on “.lbl” must be placed in the correct subdirectory of the
storage medium. It is the “labels” directory.
The two images 2.1 and 2.2 show this behavior of the printer for the two copied files “richtig.lbl” and “falsch.lbl.txt”.
4
“Pure text files” are files that consist of pure 8-bit text, no files from WYSIWYG editors like Microsoft Word or OpenOffice Writer. For
professionals: use UTF-8 encoded files without BOM.
2 Communication with the printer 13
Figure 2.1: Via the gray gear wheel symbol and the blue memory stick button you get to the menu “Storage”. Here you can see the data
stored in the subfolder “labels” to load copied JScript label files.
Figure 2.2: There are two files on the disk. The file richtig.lbl can also be selected for printing. The file falsch.lbl.txt however has the
ending .txt, which is for a cab printer not accepted as label file (see figure 2.1). Even if the file saved in your Windows operating
system is displayed as “falsch.lbl” – do not let Microsoft make fun of you! The printout has been created by the “Print file list”
menu item in the “Storage” menu.
14 2 Communication with the printer
On the printer, press the gray button with the gear wheel (Settings menu). You will get into a menu, where you
can now select the blue symbol with the memory stick. In the following menu you can load a label with “Load
label”, it will display a list of all files located in the directory “labels” and end on “.lbl”.
If the file you copied there does not appear, please check the correct file name spelling including the extension.
Using the menu item “Print file list” you can also print a listing of all files, output directly to the printer. However,
make sure that the material is sufficiently wide in the printer.
To transfer pure programming data via USB cable requires additional software. It is therefore not advisable
to start with the printer in this way to be addressed. USB connection can be used when you only want to use
labeling software or printing with the Windows driver.
You are familiar with TCP/IP networks, even if you have never read the term. TCP/IP is the protocol on which
the Internet is based. It describes the connection technology between individual devices on the network.
This can be your PC, but also hubs, switches, routers, cell towers and of course cab printers are “network
devices”.
Each network device has a unique name (experts call it MAC address) and an IP address. The IP address allows
to address the device in the network.
When you press the gray gear icon on the printer’s main screen you get to the menu “Settings” (see Figure 2.1,
second illustration from left). There you will find a yellow info icon in the upper left corner that shows you infor-
mation about the printer. Among many other information you can see the IP address of the printer. Let’s assume
that the printer shows “192.168.10.1” as the IP address. IP addresses usually consist of four numbers, each with a
dot in between. Remember these numbers and enter them in your favorite Internet browser, if this device (means
the PC on which the Browser is running) is connected to the printer via the network.
If your browser is connected to the printer, you will see, after entering the IP address of the printer, an overview
page of the printer. On the left side of this page you will find a live view of the printer’s touch screen, which you
can access with the mouse to operate the printer. Just like an “Internet remote control” already installed in the
printer. If you are looking for a username and a password, both are “admin”, if you have not changed this in the
printer settings (which you should do for security reasons).
A visual remote control is handy – but you can’t use it to learn JScript. Instead of the browser, open a file manager
(or an FTP software) and enter the following line:
ftp://ftpcard:card@192.168.10.1
Your file manager should now show you the printer’s storage. It will always display the storage that you have
selected as default in the “Storage” menu. So leave your USB memory stick in the printer and select “USB” as stan-
dard. You can then send your label file via FTP (you can find an explanation of the protocol online in the Wikipedia).
This way you can write files to your USB device without constantly having to unplug it.
2 Communication with the printer 15
You can then access the files with the extension “.lbl”, which you can find in the folder “labels”, via the menu item
“Load label” and execute the JScript code.
Advice: Connect a USB keyboard to the second USB plug on the printer. By pressing F2 you will directly get
into the Load label dialog. �
Instead of copying the files via FTP to the printer and then printing them via calling up the printer’s menu you
can also use a shortcut. The printer allows besides the FTP user name “ftpcard” also the user name “ftpprint”
with the password “print”.
ftp://ftpprint:print@192.168.10.1
The big difference is that the printer will print all files you send via the special upload user “ftpprint” to the
printer, but executes them immediately without saving them to the storage. So the files are just interpreted
as JScript code, and are not placed into the “labels” folder. With this special procedure the file name includ-
ing the file extension is not relevant. As an exception, you can even use the file “falsch.lbl.txt” to bring it to
execution.
However, the FTP protocol was not developed for this purpose. An FTP software therefore assumes that
an uploaded file will then be stored in the FTP directory of the printer and exists there. However, you will
never be able to download as a user “ftpprint” from the printer, and also folders can neither be called nor
created.
Depending on the software you use for the file upload, it can lead to confusion sometimes. If in doubt, use a
tolerant software or do not use this shortcut to print the JScript files directly.
In the following three more common methods we will show how to install a cab printer into a production
environment. We start with the the most obvious way to send JScript code directly over the network and to
receive answers from the printer.
After that we will show how to connect the printer to a file server, which then makes the label jobs available. If
there are several printers within production, this is an excellent opportunity for keeping all printers always on the
same level by simply setting the file server which is then accessed by all printers.
Finally OPC UA shall be mentioned briefly. We will not discuss this protocol in detail, but here lies a large part of
the future, which is to be “Industry 4.0”.
The cab printer allows direct TCP/IP communication on port 9100. If this doesn’t mean anything to you, just skip
this section. For readers with a lot of experience in network technology this function of the printer should not be
concealed. Otherwise come with the two previously mentioned methods (use a storage medium or transfer via
FTP) should be enough to work through this manual.
If you are very familiar with network technology you can open a Telnet session on port 9100 of the printer and
enter the JScript lines there directly. Or you copy from the instructions into the session window. Under Windows,
a Telnet client is available, but hidden in the Windows feature configuration. You must therefore either activate
the Telnet function of Microsoft Windows or use a foreign software like PuTTY.
If you are using Windows 10 and want to feel like a hacker please right-click on the Windows icon in the lower left
corner and select “Windows PowerShell (Administrator)”. In the Windows PowerShell window enter the following
command:
Dism /online /Enable-Feature /FeatureName:TelnetClient /All
After that you can close the PowerShell window (use the command “exit”) and open it again without administrator
rights. Let us guess your printer has the IP address 192.168.10.1, enter the following command to start a telnet
session:
telnet 192.168.10.1 9100
From now on, your keyboard entries are no longer displayed, but directly transfered via the network to port
9100 of your printer. The answers of the printer appear on your window. Try it out and type into the Telnet
session the keys Esc and s . The printer should answer with a string that looks something like this: “Y-
000000N”.
Figure 2.3: The Telnet client PuTTY offers a comfortable way to direct connection to the printer. Select RAW as connection type, the IP
address of your printer and port 9100 (not 23). You can use the Save settings also for later use.
The WebDAV protocol has been developed for a long time, the Web-based Distributed Authoring and Versioning
(see Wikipedia).
This is not intended to explain how to set up a WebDAV server, but is the job of the administrators, who are
responsible for the provision of data in Corporate network with security. It shall only be briefly explained what
advantage it brings to connect the printers via the WebDAV function.
If your printer has no function to use an external WebDAV server as a data source your firmware is probably not up
to the latest version. First with firmware 5.33 WebDAV was added to the cab printers. To update the firmware
of your printer to the latest, there are two possibilities. The easiest way is to use the web interface by entering the �
printer’s IP address in the browser, and there use the “help” menu. In the help menu you can find a routine to
check if the printer’s firmware is still up-to-date. If the firmware of the printer does not correspond to the latest
version, the routine offers this directly to correct. Just follow the instructions.
The option described above requires an access to the cab servers in the Internet. If this is not possible from
the printer, you can download the current firmware also always from the website www.cab.de to your PC and
then upload it with the appropriate firmware updater software to the printer (if the printer is not connected
to a network, you can load the Update also via a USB memory stick or via a USB cable from a Windows com-
puter).
To use WebDAV as a storage location, you must activate the option in the Storage menu (see figure 2.1 on page 13).
There is the menu item “default memory”, where you must first select WebDAV. If WebDAV is is selected, further
menu items appear, with which you can change the address of the WebDAV server. And you can enter the user
name and password. If you search for a file and click on “Load label”, the label will be loaded by the printer from
the WebDAV server and the files will be downloaded from the subdirectory “labels” on the WebDAV store for
printing. The WebDAV storage then works as if the files were stored on the internal memory (IFFS) or a storage
medium on the printer (USB memory stick or SD memory card). Multiple printers can share one WebDAV server
at the same time. A big benefit if you have to distribute label files to a lot of printers, being sure that all will access
the same actual version of your files.
18 2 Communication with the printer
It is still more a marketing slogan, “we are in the industry 4.0 age”, but what does this mean? The very latest
industrial revolution connects machines intelligently. In this “Internet of Things”, standards are needed with
which the individual devices/things can communicate with each other. A mature standard is the Open Platform
Communications standard. Based on this older standard the next generation is OPC Unified Architecture,
OPC UA.
Since this is a standardized approach to communication, it can be assumed that machine control systems (PLC) of
various manufacturers should all have the ability to use OPC UA to communicate with a cab printer.
The big advantage is certainly the standardization, so that the Integration of a device like a cab printer is faster than
if you have to create the interface each time new from scratch and implement it in the controller.
But an OPC UA connection has other advantages as well. As a modern standard, OPC UA is secure and scalable.
This means that you can communicate between individual devices on a small scale as well as globally with a
connection to a cloud - all defined in the standard. All this with the latest encryption technology, OPC UA is
secured and controlled in access.
A small overview of the possibilities provided by cab printers (OPC UA speaks here of an information model) can
be found on our website:
https://www.cab.de/en/news/news/opcua/
The OPC UA standard allows observing a variable, e.g. the remaining amount of thermal transfer foil on the
printer, in a simple way from a machine control system. The advantage of monitoring with OPC UA is that the
values are subscribed from the printer, correctly the printer’s build-in OPC UA Server. If a value changes the printer
automatically informs the subscriber. Man does not have to poll the status of the printer in a continuous loop,
but is informed by the printer about status changes. A much lower network load.
In addition, many things can be done via “methods”. This way it is not even necessary to learn JScript anymore.
A label layout can be created using the cabLabel software and a method provided for loading and printing a label
format file do the rest. Fields on the label are provided automatically as variables in the OPC UA information
model and can be specifically changed before a label is printed.
Thus complex tasks such as the use of layout templates and then filling it with data from the production process
without JScript knowledge is possible. But please do not put this manual aside to concentrate from now on only
on OPC UA. With JScript all cab printers still have a very powerful direct access, mastering it will pay off in any
case.
3 Basic structure of JScript 19
With JScript you can communicate directly with a cab printer. The language works line-oriented as a stream of
bytes (8-bit data stream). Each line must be terminated with a <CR> or <LF> or both.5 Only when a line is finished
it is evaluated.
If the JScript interpreter has received a complete line, the first letter of this line is examined more closely. The
letters are case sensitive. The letter determines which command should be executed in the printer. Lower and
upper case letters have different meanings. The rest of the line are the parameters for the command, e.g. position
and size of a graphic or the name of a TrueType font to be loaded.
Lower case letters usually refer to global settings that affect the printer per se and are not limited to the currently
active label.
However, if the printer is switched off, it loses the data specified by lower case properties or settings. At the next
start, the printer settings are taken from the printer’s internal default values that can be changed via the menu
options on the printer.
Example: The letter “f” triggers a label feed (formfeed). This corresponds to pressing the green symbol on the
printer.
f
As another example, we can use the lowercase letter “t” to create a test print.
t
Please note that the lines must be terminated with a <CR> or <LF> or both together. For the sake of easy
readability, we have omitted the representation here. You can create a <CR> by pressing the ←- key (line �
break).
Capital letters always refer to the label currently in memory. The capital letter J starts a new label (job start).
This command must be the first capital letter command, otherwise an error message will be displayed on the
printer.
With the “A” command (quantity) the internal creation is stopped and a corresponding number of labels is
printed. After that, a label to be newly designed must first be started again with “J” before other capital letters
are accepted.
A typical label could look something like this.
5
<CR> and <LF> stands for the two ASCII characters Carriage Return and Line Feed. In most text editors these are normally not directly
visible. Special ASCII editors (like Notepad++, Microsoft’s Visual Studio Code or Github’s Atom Editor) can display them. Make sure
to always have an end of line at the end of a JScript file. Otherwise, the last line may not be processed and an error message may
appear at the printer if JScript data is sent again (which then mixes with the unfinished line to form a code that is incomprehensible
to the printer).
20 3 Basic structure of JScript
1 J
2 S 0, 0, 68, 71, 100
3 T 20, 20, 0, 3, 10;Yummy Joghurt
4 B 20, 30, 0, EAN13, SC2;456712349876
5 A 1
In the example above you see the commands “J”, “S”, “T”, “B” and “A” in the first position of the lines.
You define a new job (J = job start),
define the label size (S = page size),
write a text (T = text)
and a barcode on the label (B = barcode).
One copy is printed (A = number).
Behind the command character, as shown in the example, there are more specifications. These are the parameters
of the commands, which will be discussed later in this manual.
Special functions are used within the content of a text. They are put in square brackets.
Example:
1 J
2 S 0, 0, 68, 71, 100
3 T 20, 20, 0, 3, 5;Bottled on:
4 T 20, 30, 0, 5, 8;[DATE]
5 A 1
In the example two texts are placed on the label. The second text contains the special command [DATE]. Here
the printer inserts the current date.
Within the square brackets is either the function name, which is case-sensitive, or a reference, i.e. a field name. A
function name can, but need not, be followed by further parameters, which are separated from the function
name by a colon and from each other by commas.
A special function with arguments can look like this:
1 J
2 S 0, 0, 68, 71, 100
3 T 20, 20, 0, 3, 5;Best before:
4 T 20, 30, 0, 5, 8;[MONTH02:0,6]/[YYYY:0,6]
5 A 1
In line 4, arguments are attached to the special command. Their exact meaning is described in a later chapter. In
this example, they cause a date offset by 0 days and 6 months.
The chapter 5 starting on page 51 deals with the topic in detail and also gives examples of how you can use
special functions to insert, for example, user queries, counters or a calculated date.
3 Basic structure of JScript 21
3.5 Comments
A comment line starts with a semicolon as command character (first character of the line). After that any
content can follow, which is evaluated as comment and is not executed. See listing 3.1 line 2, 4, 6 and 8 as an
example.
1 J
2 ; define page size
3 S 0, 0, 68, 71, 100
4 ; fixed text
5 T 20, 20, 0, 3, 5;best before:
6 ; the printer calculate a date with 6 month shift
7 T 20, 30, 0, 5, 8;[MONTH02:0,6]/[YYYY:0,6]
8 ; print one label
9 A 1
Listing 3.1: Comment lines start with a semicolon � Comments.lbl
JScript is designed to be read and understood quickly by humans. For this reason, JScript has been designed from
the beginning to be as tolerant as possible to spaces and blank lines. Use this freedom to make your self-created
code readable so that you (or another person) can maintain the code more easily later.
There are no design rules for this. However, JScript is based on the following rules, which you must fol-
low:
1. Each line contains exactly one command as first character of the line.
2. Each line must be terminated with an end-of-line character (<CR>, <LF> or both).
3. Blank lines are ignored, any number of blank lines can be inserted.
4. After the command (first character of the line) and after a comma, any number of blank lines are allowed.
This does not apply to special commands.
5. After the semicolon that follows the parameters, the content begins immediately. Blanks become part of
the content here!
6. Comments are allowed as comment lines, starting with a semicolon.
In order to make the code especially readable, the following conventions are followed in this manual wherever
possible, in addition to the JScript specifications.
• Comments are always before the content to which they refer.
• If a comment refers to several lines (JScript commands), an empty line is inserted after the last command
line.
• Each comma separating parameter is followed by at least one space.
• Within a command, all lines are filled up with additional spaces after a comma so that the comma is below
the comma in lines with the same command.6
• The parameters for the position of the reference point and the angle are aligned with each other across
commands (applies to the T, B, I and G command lines).
• A command character is followed either directly by the field name (with colon and semicolon) or at least
one space.
6
In your editor, use a non-proportional font in order to arrange the codes according to the conventions.
22 3 Basic structure of JScript
JScript was designed so that a simple ASCII text editor is sufficient to program most labels. However, labels do
not always consist only of text that can be created with simple editors, but in some cases graphics/logos must
be transferred to the printer. In order to be able to communicate quickly with the printer without confusing it,
an additional ASCII special character has been allowed, character number 27, also known as escape character,
abbreviated as Esc .
Tip: If you use the editor Notepad++7 you can insert an Esc character simply by using the key combination
Shift ⇑ and Esc .
It is possible at any time during communication with the printer to send the escape commands, which are
immediately processed without waiting for the end of the line.
Escape commands start with the ASCII character Esc , decimal 27, hexadecimal 1B16 . This is followed by at least
one more character, e.g. “t”. Together they form the escape command, which is cut out of the rest of the JScript
code.
Escape commands do not have to be embedded in JScript, they can also be sent separately to the printer via
another interface. For example, JScript data can be transmitted via TCP/IP, while a PLC can query the status via
RS232 using Escape commands.
Sending the character string Esc p1 to one of the printer’s interfaces, for example, corresponds to pressing the
Pause key on the printer. With Esc p0 you would end the pause again so that the printer continues its work. A
list of the most important ESC commands can be found starting on page 67, all commands are included in the
programming manual which you can download from the cab web page.
If the possibilities of JScript are not sufficient, you can also use the integrated BASIC. The cab printer has an
Advanced BASIC compiler (“abc”) built into the firmware, which compiles the embedded code and executes it
independently from the JScript interpreter.
This manual here is mainly about JScript. Advanced BASIC is covered in a separate chapter starting on page
100. However, you should already have some experience with the BASIC language. For normal printer use, you
can work without BASIC, because even calculations can be performed directly in JScript, as will be explained in
detail in later chapters.
7
The editor Notepad++ can be used free of charge under Microsoft Windows. It is a powerful open source editor and can be downloaded
from the website www.notepad-plus-plus.org.
3 Basic structure of JScript 23
Figure 3.1: The result of the Advanced BASIC program from listing 3.2
1 <ABC>
2 PRINT "m m"
3 PRINT "J Flower Power"
4 PRINT "S l1; 0, 0, 68, 71, 100"
5 PRINT "H 25"
6 PRINT "O R"
7 PRINT "G 25, 24, 270;L: 40, 2, r, r"
8 PRINT "G 25, 64, 45;L: 30, 2, r, r [S:60,0,45]"
9 FOR angle = 0 TO 355 STEP 5
10 PRINT "G 25, 24, ", angle, ";L: 20, 0.25, r, a"
11 NEXT
12 PRINT "G 75, 24, 270;L: 40, 2, r, r"
13 PRINT "G 75, 64, 45;L: 30, 2, r, r [S:60,0,45]"
14 FOR angle = 0 TO 330 STEP 30
15 PRINT "G 75, 24, ", angle, ";C: 20, 5, 5 [S:25,50,100]"
16 PRINT "G 75, 24, ", angle, ";C: 20, 5, 0.25"
17 NEXT
18 PRINT "A 1"
19 </ABC>
Listing 3.2: Example for the use of BASIC � FlowerPower.lbl
24 4 The typical structure of a label
100 mm
68 mm
71 mm
The minimal label consists of three lines (don’t forget <CR> at the end of the line!) and looks like this:
1 J
2 S 0, 0, 68, 71, 100
3 A 1
Listing 4.1: Formfeed Deluxe
The label is started with “J” (Job Start). Then “S” is used to determine the label size (Size).
If the label is shifted from 0 mm to the right and 0 mm down, a 68 mm long label is printed. Together with the
3 mm gap, the distance from the beginning of the label to the beginning of the next label is 71 mm. The label is
100 mm wide (see illustration 4.1).
Thus the command has the following structure:
S displacement to the right, displacement downwards, height, height + gap, width
A detailed description of the most important commands can be found in the Appendix. All commands can be
found in the comprehensive programming guide for JScript.
The printer can use millimeters or inches as the unit of measurement, depending on the selected country setting
in the printer settings. Except for the USA country setting, millimeters is assumed.
One copy is printed, “A” stands for number and simultaneously terminates label creation in the printer mem-
ory.
Before the “A” command, the contents (texts, barcodes, graphics, etc.) would have to be inserted, because a
blank label alone is not very useful.
4 The typical structure of a label 25
However, it is better to use the following extended template for a label in JScript (listing 4.2).
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, 0
5 O R
6 A 1
Listing 4.2: A minimal label with the most important information � Minimal.lbl
for the Anglo-American unit use inches (Imperial or Historical units) to not be surprised by the printer’s country
settings. If “USA” is selected as country, the unit of measurement is set to inches by default. All other country
settings set millimeters as the unit of measurement. The “m” command permanently overwrites this preset until
the next restart of the printer.
Other printer languages often work with the dots of the print bar for position or length specifications. How-
ever, JScript always uses the selected measurement system (millimeters or inches), so your data does not �
depend on the resolution of the print bar. A big advantage of the cab printer language.
26 4 The typical structure of a label
8 mm
9 mm 63 mm
53 mm 35 mm 50 mm
100 mm
Figure 4.2: A decorative label that should only be printed in the light background area. By cleverly defining the page size in the JScript
code, the printer will report an error if, for example, a barcode gets past from the permitted area.
With “J” the description of the label is started. When a “J” command is received, the printer forgets everything it
has stored for the current label and starts again from scratch.
The “S” line additionally defines the use of different label sensor types (here the see-through detection by a
prefixed parameter “l1”, the lower case letter l followed by the number 1). This additional information must be
separated with a semicolon from the following parameters describing the dimensions. The other values are
separated from each other by a comma. If decimal numbers are to be used, a dot must always be used as
� decimal separator, even if the printer is set to Germany, for example.
There are a total of four options for recognizing the beginning of the label. “l0” selects the reflex light barrier from
below, “l1” selects the transmitted light barrier, “l2” selects the reflex light barrier from above (if available), and “e”
does not detect the gap, but uses only the length specification (continuous material).
The remaining parameters are as already mentioned:
S start detection;shift right, shift down, height, height + gap, width
Speed and heat are set with the “H” command. The speed is replaced by the value from the JScript command,
but the value for the heat is added to the default value in the printer. Maximum up to the limits -20 and +20.
Examine the following line
H 150, 2
it sets the speed to 150 mm/s. However, the heat is only set to +2 if the default value in the printer is 0. If 2 is also
set in the printer, the total heat value is 4.
Print speed and heat must be adjusted for the respective label material. To protect the print head, it is recom-
mended to select the lowest possible heat.
The quality of the printout depends strongly on the correct combination of label and ribbon. If foil (ribbon)
and label don’t fit together, a print result should not be squeezed out of the printer by excessive heat, it �
would drastically reduce the lifetime of the print head. Overheated printheads are not covered under
warranty!
The print speed mainly influences the print quality (precisely print image). The lower the speed, the cleaner the
print. If the application allows slow printing (there is enough time), you should use this and not set the printing
speed too high.
Too little heat will cause the print to fade, while too much heat will cause the print to smear and increase wear
on the print head.
Change the heat values to -10, -5, 0, 5 and 10 respectively and print one copy. The effect of the temperature
setting should be clearly visible.
With the command “O” you can activate one or more options. The most frequently used option is probably “R”,
which outputs the label rotated by 180° (R = rotated). Other useful options are “S” for single buffer operation or
“T” for tear-off mode. “U” can be used to prevent pause reprinting so that no label can be printed twice with the
printer’s repeat key (Unique).
See the programming guide for details on the options. There you will find a complete list and more detailed
explanations of all options.
If several options are desired, they are separated by a comma.
O R, T
In this case, the label would be output rotated by 180° in tear-off mode. This combination is common in tear-off
mode, since the label is not upside down when the operator removes it.
In the following, the visible elements of a label layout will be described with their most important parame-
ters. This enumeration is far from being complete, but is not intended to replace the programming instruc-
tions.
4.3.1 Texts
Texts are integrated into a label by the command “T”. Following are the parameters:
1. X-position (from left edge to right).
2. Y-position (from top edge to bottom).
3. Rotation angle (integer counterclockwise).
4. Font number (e.g. 3 = Swiss 721, 5 = Swiss 721 bold, 596 = Monotype 821).
5. Font size, as distance between p-line and k-line (length d in figure 4.3).
6. Options, separated by commas (s = oblique, i = italic, n = inverse, b = bold, qn=compressed8 ).
7. The actual content separated by semicolon.
4 The typical structure of a label 29
Figure 4.3: Font lines9 and scheme of a print type. The dimension d corresponds to the font height specified in the fifth parameter of the
T command and is also called cone height.
For texts, the position always refers to the baseline of the font. All other objects (e.g. barcodes or graphics)
are described in position by their upper left corner. �
You can see in the listing 4.3 that both the specification pt12 and the specification 4.5 were used for the font size.
The line m m turns 4.5 into a font size of 4.5 mm. Placing pt in front of a font size specification allows JScript to pro-
cess this size in “DTP point”, a unit of measurement often used in typesetting. For example, common text editors
use the unit point for entering font sizes. See Wikipedia for further explanations.
For decimal fractions, always use the period as a separator between the integer part and the decimal part (US
notation).
The comma is used in JScript only as a separator for parameters and must not be used for numbers!
�
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, -2
5 T 45, 25, 45, 3, pt12;Wind
6 T 45, 25, 315, 3, pt12;mühlen
7 T 45, 25, 225, 3, pt12;mahlen
8 T 45, 25, 135, 3, pt12;Mehl
9 T 44, 42, 90, 3, 4.5, b;für
10 T 48, 42, 90, 3, 4.5, b;Brote
11 A 1
Listing 4.3: Example for angle specifications and font styles � Windmill.lbl
8
For compression, an integer from 10 to 1000 must be used for the n. Text that is not compressed has the option “q100”. If the text is to
be compressed to 80 %, you must use “q80” as an option.
9
By Brian Ammon, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=2349540
30 4 The typical structure of a label
In addition to the fonts supplied, it is also possible to use your own fonts. For this purpose, these fonts must be
of the type TrueType.
Load the font to the printer in the subdirectory fonts before you use the font in a label. The printer will
look for the font in the default memory. If the default memory is set to USB, a font stored in IFFS10 is not
10
IFFS is the name of the printer’s internal non-volatile memory (Internal Flash File System). This is case-sensitive and file names longer
than 8 characters can be used.
4 The typical structure of a label 31
found.
To use a TrueType font we first have to load the font into RAM (volatile memory) and assign a font number. This
is done with the “M l” and the “F” command.
In listing 4.4 the free fonts Linux Libertine11 and Linux Biolinum are used and first loaded into RAM (lines 4 to 10).
Then, in line 18, number 11 is assigned to the font family Linux Libertine so that these fonts can be used from line
22 on.
When loading the TrueType files, “M l fnt” is followed by the name of the file without file extension, separated by
a semicolon. When assigning fonts, after the “F” command use the font number and, separated by a semicolon,
the name of the font family. If you do not know the names of the font families, you can also assign the file name
of the normal font to the font number. So the two lines 18 and 19 could also be
18 F 11;LinLibertine_Rah
19 F 13;LinBiolinum_Rah
The special function [J:r45] aligns the text right-aligned on an imaginary length of 45 mm. With [J:c100] the
heading is centered on the label.
It is interesting that we loaded six font styles into memory (lines 4 to 10), but only assigned two font numbers.
Nevertheless, we can still use all six fonts. The cab printers search for a bold or italic font that belongs to the
same font family with the options b and i. Just assign a font number to the default (Regular) and use the options
for bold or italics.
Notice that all fonts have the same font size of 5 mm? However, some fonts appear to be of different height and
strength. The auxiliary lines in the example have a distance of 5 mm to each other. You can immediately see
that the font size does not correspond to the visible height, because the p-line is not visible due to the missing
descenders (for an explanation see figure 4.3).
One more hint. Some TrueType fonts are of enormous size and usually occupy unnecessarily much memory. The
font Arial UNICODE MS, for example, has the special characters for many languages of the world on board, but
11
You can download both fonts here: https://sourceforge.net/projects/linuxlibertine/
32 4 The typical structure of a label
these are usually not used in the actual label. It is better to use a font that is reduced to the specific application
in order to save memory and reduce the preparation time in the printer.
42 ; headline
43 T 0, 5, 0, 3, 5, u;Linux Libertine und Linux Biolinum Schriften[J:c100]
44
45 ; don't print, just create an internal preview bitmap
46 A [PREVIEW]
Listing 4.4: Using some custom fonts � TrueType.lbl
34 4 The typical structure of a label
Figure 4.6: In cabLabel S3 a height of 5.0 mm was chosen for the font. This specification is later sent to the printer in JScript code. The
cap height is only 3.91 mm and the descender is 1.09 mm. cabLabel S3 Pro shows you these values in a help bubble when
you move the mouse pointer over the gray text below the values.
Figure 4.7: A handwriting gives an empathic impression on a name badge. A free font from the designer Kimberly Geswein was used
here. � IndieFlower-Regular.ttf
4 The typical structure of a label 35
4.3.3 Textboxes
Text boxes are frameless rectangles that are filled with text, available since firmware 5.37 for all printers using an
X4 mainboard. They are defined with the W command to specify their width and height, and the reference point
for placement on the label is the upper left corner. Unlike a simple text element, the text in a text box is wrapped
in multiple lines. Thus, the text always remains within the box. HTML markup can be used for further styling.
Because this all sounds quite complicated here is an example (listing 4.5).
1 m m
2 J
3 S l1;0,0,68,71,100
4 T 10,10,0,3,3,s,n;HTML formatted text box
5 W:Textbox;10,10,0,80,48,3,3;<HTML>
6 <h1>New Textbox made by SQUIX</h1>
7 A SQUIX is able to render formatted text boxes since firmware 5.37, but an A<sup>+</sup…
> printer is not.
8 <hr>
9 <p align=justify>The text box is 80 mm wide and 48 mm high. What is interesting here is…
the reference point. Unlike normal text elements, it is not the baseline of the …
text, but the upper left corner of the box.</p>
10 Text can also be rendered <b>bold</b>, <i>italic</i>, <sup>high</sup>, <sub>low</sub>, …
<u>underlined</u>, <s>strikethrough</s> or <big>larger</big>. A <b><i>combination</i…
></b> is also possible.
11 </HTML>
12 G 10,10,0;R:80,48,0.25
13 A 1
Listing 4.5: Think of a text box as a blank page in a web browser that the printer fills to fit within its dimensions. � Textbox.lbl
Figure 4.8: The listing 4.5 leads to this result. As can be clearly seen, the line break is not taken over, but must be specified by an HTML
command like <br> or <p>. . . </p>.
The most important tags available in the W command, as the (usually enclosing) HTML language elements are
also called, are shown in the table 4.1.
36 4 The typical structure of a label
To make the JScript code more readable there is an exception for the W command. The JScript interpreter does
not recognize an end of line between the tags <HTML> and </HTML>. Thus, longer content in the W command
can be written across multiple lines if you frame it appropriately in a <HTML> tag pair. In the listing 4.5 this can
be seen (lines 5 to 19).
Please note that a textbox is always drawn without a border. In the example (listing 4.5), the frame is drawn
separately by line 20 to show the positioning. A single text element is inserted in line 4. It is rendered with the
additional parameters s and n to slant and invert the text. You can see in the figure 4.8 that the text sits exactly on
the top edge of the text box. With the T command, the 10,10,0,. . . refers to the baseline of the text. With a
rotation of 0°, the text is set at the coordinate (10/10) on the baseline.
Inside the text box, which also has its anchor point at the coordinate (10/10) and a rotation of 0°, the text is placed
in such a way that a minimum distance to the edge remains. By the way, the distance to the left and to the top is
the same here. However, since the text used in the example does not reach completely to the k-line (see also
Figure 4.3), the distance to the top appears larger.
It is not possible in the W command to set the baseline of the first letter as an anchor point. If you want to align
text horizontally, you should not mix the T and W commands if possible.
A text box distributes the text without any knowledge of the language used. Thus, the printer cannot hyphen-
ate, but only breaks the text where there are spaces. However, there is a special character in the Unicode
character set which is not printed. It carries an information that the text can be hyphenated at exactly this
position.
4 The typical structure of a label 37
The cab printers use this special character in the W command to insert hyphenation. The special character is
the Unicode character No. 173. Four ways allow its use in the W command. You can use the Unicode special
command [U:173], its hexadecimal notation [U:$AD] or the two other abbreviations, based on HTML,
­ and ­.
1 J
2 S 0,0,68,71,100
3 H 100,0
4 W 10,65,90,60,5,3,2.3;Neil and Buzz left a flag at the moon in 1969 landing at
5 W 15,10,0,15,40,3,4;Mare Tran­quil­li[U:173]ta[U:$AD]tis
6 A 1
Listing 4.6: There are several ways to indicate where hyphenation may occur. All of them represent the Unicode character “SOFT
HYPHEN”. � Silbentrennung.lbl
Figure 4.9: Listing 4.6 shows multiple ways to indicate a position for hyphenation.
4.3.5 Barcodes
Barcodes offer a wide range of possible parameters. The topic alone is so complex that more than 100 pages of
the programming manual deal with barcodes.
Basically, JScript has the B command to create a barcode. It has the parameters:
1. X-position (from left edge to right).
2. Y-position (from top edge to bottom).
3. Rotation angle (only multiples of 90° allowed).
4. The type of barcode, e.g. Code128, EAN-13, Datamatrix or QR Code.
5. Options directly appended to the type with the plus sign (without comma in between).
6. The size whose parameters depend on the type.
7. After a semicolon the content of the barcode.
It is strongly recommended to use the programming guide to read all parameters for the respective barcode
type. We will only look at a Datamatrix, a QR Code and a Code128 here to show the creation of three common
barcodes as an example.
38 4 The typical structure of a label
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 100, 1
5 B 10, 10, 0, DATAMATRIX+COLS18+ROWS18, 1;Hallo Welt!
6 B 10, 48, 0, CODE128, 8, 0.15;grosse Buchstaben - grosse Wirkung
7 B 10, 58, 0, code128, 8, 0.15;kleine Buchstaben - keine Wirkung
8 B 50, 5, 0, QRCode, 0.75;https://www.cab.de/de/kennzeichnung/etikettendrucker/squix
9 A 1
Listing 4.7: Examples of some barcodes � Barcodes.lbl
Figure 4.10: Label with several barcodes (created with listing 4.7)
Let’s look at the example in listing 4.7. The first barcode creates a data matrix with a fixed 18x18 matrix. The
following two lines each generate a Code128, but with the difference that capitalized type specifications
generate a plain text line in addition to the barcode (only for 1-D codes). The last line with a B command
generates a QR Code. As with the Datamatrix, upper/lower case is not relevant here because the printer does not
generate a text line for 2-D codes.
For Datamatrix and QR Code, the size specification is the module size, i.e., the edge length of the smallest square
(called module) that makes up the codes.
For Code128, two size specifications are required. The first defines the height (in the example 8 mm), the second
specification is the width of the smallest bar (here 0.15 mm).
If a code is specified in capital letters, i.e. with a plain text line, the font below the barcode is calculated with
the specified height. Although both Code128 commands require a height of 8 mm, the height of the bars in the bar-
code generated in line 6 is therefore lower than in the barcode from line 7 (from listing 4.7).
Module width and line width are related to the resolution of the print bar, because with a thermal transfer
� printer no dots can be heated proportionally (there are no half dots).
The printer automatically determines the number of heating points that comes closest to the specified value. If
the same label is printed on a 203 dpi and a 300 dpi printer, the widths of the barcodes and the sizes of the 2-D
codes may differ. The smaller the barcode, the more clearly the effect is visible.
4 The typical structure of a label 39
https://github.com/zxing/zxing/wiki/Barcode-Contents#
wi-fi-network-config-android-ios-11
Try it out for your own WLAN network. If you do not have one at hand, your printer can provide you a
WLAN hotspot. Can you connect your smartphone automatically, just by using the camera appa ?
a
On iPhones Apple has built this feature into the camera app. If you are using an Android smartphone this will not work on all
models. However, you can download several barcode scanner apps from the Google App Store that offer this feature.
4.3.6 Images
For the images to be integrated into a label, the limitations of thermal transfer printing technology apply.
Individual dots are calculated, which are either printed or not printed (black and white), there are no fractions of
dots (no gray representation).
Once this is accepted, it becomes clear that color or grayscale image formats such as JPEG are not particularly
suitable for printing as an image on a label. Better suited are black and white formats such as those that can
be stored as PNG (Portable Network Graphics). The integration is done with the I command (capital letter I like
Image).
40 4 The typical structure of a label
Figure 4.11: Drawing of a woman folding a napkin (line 5 from listing 4.9) � Mechthild.png
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 100, 0
5 I 25, 5, 0, 1, 1,a;Mechthild
6 A 1
Listing 4.9: Positioning of an image � Bitmapgrafik.lbl
In listing 4.9 the two magnification factors and the parameter a are used to use the autoload function. The
parameters of I mean (line no. 5):
1. X-position (from left edge to right).
2. Y-position (from top edge to bottom).
3. Rotation angle (only multiples of 90° allowed).
4. Magnification factor in X dimension (integer from 1 to 10).
5. Magnification factor in Y dimension (integer from 1 to 10).
6. Option a to load the file automatically.
7. The file name separated by a semicolon (with or without file extension)
The image must be located in the subdirectory images. If no matching image is found, the output is omitted
without an error message. The file extension is added by the printer itself if it is not specified. Allowed are the
extensions ASC, BMP, GIF, IMG, MAC, PCX, PNG and TIF.
Images are always distributed 1:1 to the points on the print bar (integer magnifications of up to 10x
� are possible). Therefore images are always printed in different sizes on printers with different resolu-
tions!
4 The typical structure of a label 41
In addition to a graphic, you can also integrate a QR code that contains the address of your website as
content (e.g. “https://www.cab.de”). If you would like to view a sample code for orientation, Figure 4.17
on page 49 shows you how to integrate a logo and a QR code into a product sticker. The source code for
Figure 4.17 can be found in the listing 4.12 on page 45. Of interest are lines 8 and 21.
If you want to include the image data in the print job, JScript offers the format ASC. This is a special format for
black and white graphics, which only works with the ASCII characters 0-9 and A-F.
You can read the exact structure of the format in the programming guide, but it is recommended to use cabLabel
S3 for the calculation. In cabLabel’s printer configuration, set the image output to IMG ASCII and write the print
data to a file (button “Memory card” in the ribbon menu). The figure 4.12 shows the setting in cabLabel S3. In
listing 4.10 you see a sample code and its output in figure 4.13.
After the image is transferred to the printer’s RAM using the autoload option, the image is placed in the printer
as if the image file were in fixed memory (e.g. on a USB stick). However, this is only possible until the printer is
switched off or all image data is removed from RAM using e IMG;*.
42 4 The typical structure of a label
Figure 4.12: The image format IMG ASCII means that the generated JScript file can be edited in ASCII editors.
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 100, 2
5 G 45, 10, 340;C: 40, 10, 44[S:100,50,80]
6 G 40, 35, 0;C: 30, 30, 2
7 G 40, 35, 0;C: 10, 10, 1
8 G 60, 35, 0;C: 10, 10, 1
9 G 40, 40, 0;C: 4, 4, 4
10 G 60, 40, 0;C: 4, 4, 4
11 G 38, 52, 350;L: 15, 3, r, r
12 A 1
Listing 4.11: Graphic elements form a face � Gesicht.lbl
Up to now we have only built a label statically. In other words, we wrote the elements (text, barcodes, etc.) with
fixed content into a label as a JScript file.
We will now look at an alternative approach, the separation of content and layout. To do this, we first create a
layout whose content corresponds to what will later be printed. But the content is only a placeholder and will be
replaced by the actual content before printing.
In order for a content to be dynamically changed (replaced), we need a reference to the content so that the
printer knows later where to make a content change.
To include such a reference, a field name, which must start with a letter and may consist of letters and numbers,
separated by a colon and a semicolon, is placed after the JScript command. Sounds complicated, looks like this
(lines 18 to 21 in listing 4.12)
1 ; usual header
2 m m
3 J
4 S l1;0, 0, 68, 70, 100
5 H 150, 0
6
7 ; static elements
8 I 72, 2, 0, 1, 1,a;cab-logo
9 T 4, 52, 0, 3, 3;Part number:
10 T 4, 30, 0, 3, 3;Product name:
11 T 4, 41, 0, 3, 3;Resolution:
12 T 4, 9, 0, 5, 5.4;cab Produkttechnik
13 T 4, 12.5, 0, 3, 2.5;Wilhelm-Schickard-Str. 14
14 T 4, 15, 0, 3, 2.5;76131 Karlsruhe
15 G 0, 18, 0;L: 100, 0.2, s, s
16
The example names four elements with the field names PARTNO, PROD, RESOL and SERNR. The first three are text
elements, the last one is a QR code.
The last line with the content is important:
A [PREVIEW]
46 4 The typical structure of a label
Figure 4.15: A text field was created in cabLabel S3. It is first called “Text20”. You can change the field name on the General tab (this is
where “SERNO” is set). If you want to reuse content as described in section 4.4.2, use the Data Source tab in cabLabel S3 to
create the link.
This does not trigger printing, but creates an internal bitmap. This can be viewed in the browser at the following
address:
https://192.168.10.1/cgi-bin/bitmap
Where 192.168.10.1 is the IP address of the printer (here you must enter the address of your printer). If the
connection to the printer is set to unencrypted (you can specify this in the printer settings), you must use
http instead of https. Since the SQUIX an encrypted connection is possible, the A+ and Hermes+ printers com-
municate only unencrypted, and they are not capable of preview graphics using the A [PREVIEW] com-
mand.
Note: Technically correct, this type of “field name” is called an identifier. In colloquial language it is often also re-
ferred to as a variable. However, variables or data fields usually have a data type. JScript does not know any data
types, the field names serve only as reference (pointer) to the content of a line. Strictly speaking, the content is al-
ways a character string, which the JScript interpreter converts into a number if required.
Assigning a field name alone does not bring progress. However, the names offer two main possibilities for
dynamic design. On the one hand, the contents can be changed later, on the other hand, a content can be used
several times in a label.
For multiple use, we simply use the field name like a special function and write the field name in square brackets.
This makes it possible, for example, to add a self-selected font and size to a barcode, as the example in listing 4.13
illustrates.
4 The typical structure of a label 47
Figure 4.16: The upper barcode has a plain text line generated by the printer, the lower barcode has its own formatting. The field
name SELFMADE ensures that the correct content is always printed under the barcode if you change it later with only one
R command. (Created by listing 4.13.)
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, 0
5 O R
6 ; if the barcodetyp is written in capital letters, the printer will add a plain text
7 B 10, 10, 0, CODE128, 18, 0.2;Der Drucker bestimmt die Schriftart
8 ; no capital letters - no additional plain text unterneath
9 B:SELFMADE; 10, 30, 0, code128, 18, 0.2;Wir entscheiden lieber selbst
10 ; a selfmade plain text allows custom font and format
11 T 12, 52, 0, 3, 4, b, s;[SELFMADE]
12 A 1
Listing 4.13: Multiple use of a content by reference to the field name � BarcodeMitTextzeile.lbl
In line 7 a Code128 is printed, which the printer adds a plain text line. But this makes the code smaller in height
and we have no influence on the font size or the font style. Line 9 therefore prints a Code128 without a plain text
line, but gives the code a field name “SELFMADE”. This is used in the following text line to insert the contents
of the barcode and thus to reuse the text “Wir entscheiden lieber selbst”. The big advantage of this procedure
is that both the barcode and the corresponding plain text line can later be assigned new content with a single
command (see section 4.4.4).
After we are satisfied with the label layout, we upload the layout template to the subdirectory labels on the printer
(e.g. via FTP upload). To do this, you can specify the following address in the Windows file browser:
ftp://ftpcard:card@192.168.10.1/
48 4 The typical structure of a label
An FTP user ftpcard always accesses the printer’s default memory. This can point to the internal IFFS, or an
external USB or SD-CARD root directory.
Here it is assumed that the password still has the default setting card. This default should be changed for security
reasons! Therefore you have to use the IP of your printer instead of 192.168.10.1 and your password instead of
card which you have set in the printer settings.
If an external storage medium is used, it should contain the subdirectories fonts, images, labels and misc
in order to be accepted by the printer. If these directories do not exist, the printer will create them auto-
matically. However, files are not automatically moved to the appropriate directories. They are simply not
found.
The storage medium should be formatted with FAT16 or FAT32. However, FAT16 has a limitation of 8 capital
letters for the file name, so you should format the storage media with FAT32 (explanations about the formats can
be found in the Wikipedia).
In internal memory (IFFS) and when using FAT32 formatted external media, the maximum length of file names is
limited to 50, even if the formats would allow more. There is not enough space in the printer’s display to display
more than 50 Unicode characters, the file names would be truncated.
In our example we save the layout as:
labels/LayoutVorlage.lbl
The label stored in the printer memory can be loaded with a JScript command:
M l LBL;Dateiname
The M initiates all accesses to the memory. As parameter follows “l LBL;” (lower case l followed by the capital
letters LBL and a semicolon). The small l stands for load and LBL for a JScript file. The file name must not have an
extension, otherwise the file will not be found.13
Loading a layout alone makes little sense for dynamic printing projects. Now the values/contents are to be
changed. To do this, use the Replace Command R. If all values are newly set, the printout can be made.
The field name is added to the R, separated by a semicolon, and the new content is inserted at the position to
which the field name points. The old content is always replaced. The result is shown in figure 4.17.
13
With M l LBL;filename.LBL the printer would search for filename.LBL.LBL.
4 The typical structure of a label 49
Figure 4.18: cabLabel S3 makes creating a layout template easy. By checking Generate Replace template you will not only get the JScript
code for the layout, but also an example of a control file for e.g. a PLC.
1 M l LBL;LayoutVorlage
2 R PARTNO;5977008
3 R PROD;SQUIX 4/600MP
4 R RESOL;600 dpi
5 R SERNR;164162038304
6 A 1
Listing 4.14: The layout template is loaded. Subsequently, contents are updated. � Replace.lbl
50 4 The typical structure of a label
We learned how to create a layout and how to change the elements contained in it later. Of course, you could
also print a label written in JScript without the detour of uploading, re-reading and modifying. In any case,
the printing is only triggered by the final capital letter A. So JScript only starts printing when we enter an A
command.
Using this mnemonic “J SHOT BIG A” you can easily remember the correct order of the typical commands of a
label.
1. With J the job is started.
2. With S you set the size so that the printer knows how to arrange the following elements.
3. With H you define the print speed and the heat level.
4. Use O to select options such as 180° rotation.
5. Then follow with W (or T) the text boxes (or elements),
6. with B the barcodes,
7. with I the images and
8. with G the graphic elements (circles, lines, rectangles).
The commands T, B, I and G can be mixed with each other, their sequence is arbitrary as long as S, H and O
precede them.
9. With A the output is then started.
Labels can be completed without printing with the A command.
A [NOPRINT]
Afterwards the content can be adapted dynamically with the Replace command, e.g. by a PLC.
After an A command are until the next J command no longer allows for object-generating uppercase
� commands (after print preparation, contents can only be changed, but no new elements can be added).
5 Special functions 51
5 Special functions
A dynamic label is not only the possibility to change the contents of a label with the Replace command. With its
special functions, JScript offers an extremely wide range of possibilities, for example to have the printer calculate
contents.
Basically, special functions can only be used within a content (e.g. in a text, a barcode or a file name for a
graphic). The special functions then have an effect on the content similar to a function in other programming
languages. The special function is indicated by enclosing square brackets. The square brackets are removed
from the contents with the special function contained therein and replaced by a return value if the called special
function returns a return value.
This can look like this, for example:
T 20, 10, 0, 3, 8;Today is [DATE].
Here a text is printed, at position (20,10) with the font Swiss 721 (font number 3) and a font size of 8 units. In the
content [DATE] is removed and replaced by the current date, the return value of the special function DATE. The
text around it is retained, so that the label contains a complete sentence (including the dot at the end), which
always contains the date of printing.14
The function can also evaluate one or more parameters (called arguments in programming languages), depending
on the special function. The DATE function can handle up to three arguments.
T 20, 20, 0, 3, 8;Tomorrow is [DATE:1].
For the DATE function, the first argument gives a date offset in days. Positive values indicate the future. The second
argument gives the offset in months, the third in years. The values can be mixed.
T 20, 30, 0, 3, 8;Next month we have [DATE:0,1].
T 20, 40, 0, 3, 8;Next year we have [DATE:0,0,1].
T 20, 50, 0, 3, 8;Yesterday was [DATE:-1].
14
If multiple labels are printed without using the single-buffer mode, and if a print started the day before is continued, the date of the
previous day will be printed.
52 5 Special functions
If a field name is written in square brackets which does not correspond to one of the existing special functions,
then the system searches for a JScript line whose content was marked with exactly this name. The return value is
the content to which the field name points.
T:Name; 20, 10, 0, 3, 4;Fischers Fritze[I]
T 20, 15, 0, 3, 4;[Name] fischt frische Fische.
In this example the function name is required, but it does not exist. The JScript interpreter then searches for a
field name Name and finds it one line above. Thus the sentence “Fischers Fritze fischt frische Fische.” is printed (a
common german tongue twister).
The special function I makes the entire line invisible. Therefore only the sentence from the lower line appears on
the label (see section 5.2).
Such a referencing via the field name can also be used with one or two parameters. If parameters are used, they
cut out a section of the return value. The first parameter is the position from which characters are taken. The
second parameter specifies the number of characters.
If start position and length are specified for a field name referencing, these parameters must be separated
� from the field name by commas, not by a colon as is done for function names.
For clarification another example.
T:Name; 20, 10, 0, 3, 4;Fischers Fritze[I]
T 20, 15, 0, 3, 4;[Name,10,5] fischt frische Fische.
5.1.4 No nestings
Special functions cannot be nested. This means, that no further special function may be used as argument of a
special function. It is therefore not allowed to use the following code:
; totally wrong!
T:Anzahl; 20, 10, 0, 3, 4;4[I]
T 20, 15, 0, 3, 4;Twice of [Anzahl] is [*:2,[Anzahl]].
But some functions allow field names as arguments, but you must not use brackets. The following code would
be allowed:
; so much better...
T:Anzahl; 20, 10, 0, 3, 4;4[I]
T 20, 15, 0, 3, 4;Twice of [Anzahl] is [*:2,Anzahl].
5 Special functions 53
We have already seen that you can make the line invisible with [I]. This way you can hide lines, which are needed
only for passing values. Here is an example to illustrate this.
T:GEWICHT; 0, 0, 0, 3, 5;10[I]
T 30, 20, 0, 3, 8;Gewicht: [GEWICHT] kg
In this case we reference the first line by a field name GEWICHT, to which a PLC can be connected. E.g. by
R GEWICHT;20
you can set the weight to 20 kg. The invisibility is preserved in such a case, only the actual value is changed
from 10 to 20. The line with the text in front and behind is printed, but a PLC only has to pass the pure numerical
value.
The I function allows one more optional argument. If it is 0, the line will not be invisible. Thus a conditional
visibility is realizable, as shown in listing 5.1.
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, 0
5 T:drink; 5, 20, 0, 3, 10;Apple juice
6 T:sugar; 0, 0, 0, 3, 3;98[I]
7
8 ; Do not hide if sugar > 0
9 T 5, 30, 0, 3, 5;Sugar content: [sugar] g/l[I:!sugar]
10
11 ; Hide if sugar > 0
12 T 5, 30, 0, 3, 3;Warning: This drink is not suspected of promoting[I:sugar]
13 T 5, 35, 0, 3, 3;obesity in children![I:sugar]
14
15 A 1
16 R drink;Mineral water
17 R sugar;0
18 A 1
Listing 5.1: Conditional Visibility � Conditional-Invisible.lbl
A field name must be used as argument. If the content, to which the field name refers, differs from 0 (nu-
meric zero), the condition becomes true and the [I:Fieldname] special function unfolds its effect. By placing
an exclamation mark in front of the field name, the condition is reversed (invisible if content is numerically
zero).
Always use numeric values (0 and 1) or a logical operation, but never a string. The strings “true”, “false”, “yes”, “no”,
“to” and “off” are all identical for the JScript interpreter (they numerically correspond to zero).
In this way, images (e.g. danger symbols) can also be shown or hidden selectively.
54 5 Special functions
Here is another example. Labels with a width of 80 mm and a height of 20 mm are processed to create name
tags for sticking on. The data comes from a software which sends the following file to the printer (listing
5.2).
1 M l LBL;LayoutNamensschilder
2
3 R Company;Musterfirma GmbH
4 R Sex;male
5 R Name;Anton Müller
6 A 1
7 R Name;Bernhardt Schmidt
8 A 1
9 R Sex;female
10 R Name;Lydia Weber
11 A 1
12
13 R Company;Firma hinterm Deich AG
14 R Sex;female
15 R Name;Antonia Fischer
16 A 1
Listing 5.2: JScript code as it could be sent by a database system � Namensschilder.lbl
What could the corresponding layout look like? A possible solution would be listing 5.3.
1 m m
2 J
3 S 0, 0, 20, 23, 80
4 H 100, 5
5
6 ; variables (all invisible)
7 T:Company; 0, 0, 0, 3, 4;Beispielfirma GmbH[I]
8 T:Sex; 0, 0, 0, 3, 4;female[I]
9 T:Name; 0, 0, 0, 3, 4;Martina Musterfrau[I]
10
11 ; the logic part
12 T:WennMann; 0, 0, 0, 3, 4;[==:Sex,male][I]
13
14 ; name with salutation
15 T 5, 10, 0, 3, 6, b;Mr. [Name][I:!WennMann]
16 T 5, 10, 0, 3, 6, b;Ms. [Name][I:WennMann]
17
18 ; company name
19 T 5, 15, 0, 3, 4;[Company]
20
21 A [Preview]
Listing 5.3: The layout template for the name tags contains two texts, of which only one is printed at a time
� LayoutNamensschilder.lbl
In lines 7 to 9, three invisible texts are created, into which the Replace command is later used to write. In line 12 a
string comparison takes place. If the character string “male” is in the field Sex, the return value of the compare
function is 1, otherwise 0.
The lines 15 and 16 are interesting: Here “Mr. …” is printed, but this print becomes invisible if the content of the
5 Special functions 55
field WennMann does not differ (exclamation mark) from 0 (numeric zero). If we want to print a text, we must not
hide it, so the condition must be reversed by the preceding exclamation mark. We use the same logic in line 16,
where we hide the text “Ms. …”, if the condition WennMann is true.
The question mark leads to a dialog prompt on the printer display. The operator can then enter an answer on the
display, accept the default value, or make an entry using a USB keyboard or USB barcode scanner.
T:AUFTRAG; 0, 0, 0, 3, 5;[I][?:scan production docket]
With this line of code, “scan production docket” is shown on the display and the operator must enter a value. He
can use a USB barcode scanner for this purpose. The (scanned) value can be used later in the JScript code with
[AUFTRAG].
After the text to be displayed, a default value can be passed, separated by commas, which the operator then only
has to confirm by tapping the ENTER button.
T 0, 0, 0, 3, 5;[I][?:enter password,123456]
After the default value, you specify how often the specification is used before it must be re-entered. The de-
fault value is 1, so the input must be re-entered after each print. The last entered value is used as the new
default value, so that the operator only has to tap the ENTER symbol when the same entry is used several
times.
T 0, 0, 0, 3, 5;[I][?:enter PIN,0000,1,M!1111]
Here a four-digit input consisting of digits without spaces is required. A fourth parameter starting with “M”
describes the permitted characters (input-mask). The exclamation mark prohibits the use of a space, the digit
1 stands for a number (more precisely a single digit). So the query here must consist of exactly four digits and
must not contain a space.
The special function to query the display can be provided with many more arguments, for example to allow only
a fixed number of certain characters. In the appendix you will find a more detailed description in the table on
page 137.
We have already learned about the date function DATE. It inserts the current date, always in the format that
corresponds to the country setting on the printer.
If you want to define the format yourself, e.g. the month as two digits followed by a dash and a four-digit year
value, you have to combine several other date functions.
T 20, 30, 0, 3, 8;Filled on: [MONTH02]/[YYYY]
All date functions allow up to three arguments, which give the offset in days, months and years.
T 20, 40, 0, 3, 8;Best before: [MONTH02:0,6]/[YYYY:0,6]
A date is output here as before, but with a 6-month offset. The offset must be carried out in the same way for
each function if several functions are combined into one display.
Time functions allow an offset in up to three arguments, hours, minutes and seconds.
T 20, 50, 0, 3, 8;Three hours ahead it will be [H024:3]:[MIN:3].
Counters are created with the SER function. The arguments are:
1. First value (will be printed onto the first label).
2. Increment value (steps between each label).
3. Stepping frequency (after this amoung of labels a stepping is done).
The start value must be specified, the two further arguments are assumed by the printer to be 1 if they are not
specified.
The counter works like a mechanical numbering machine. When using the function SER, the first argument also
determines the maximum number of digits by preceding zeros. Thus [SER:001] counts starting from 001 up
to 999 and then falls back to the value 000. As a mechanical work would behave. Thus, the counter returns 001,
002, 003, 004, …, 997, 998, 999, 000, 001, 002, …
If you don’t want leading zeros in print, you have to use the D Use function for the minimum number of digits
to be printed. But this can only work with a calculation with which SER function the C and D are compatible
Functions not. In the code example in listing 5.5 we see such a solution in line 7, where additionally an addition
with a start value from a query was realized.
This operation is equivalent to a value added from outside and used as a starting value. Unfortunately the code
in listing 5.4 does not work like this.
1 m m
2 J
3 O R
4 S l1; 0, 0, 68, 71, 100
5 T:start; 0, 0, 0, 3, 5;[I][?:Enter start value,98]
6 ; That will be a complete flop:
7 T 10, 50, 0, 5, 40;[SER:start]
8 A 4
Listing 5.4: The serial number function must not be used in this way � Serienfehler.lbl
The idea would be that a starting value could be entered by the user. In principle a good idea, but the SER
Function does not support referencing.
But there is hope (listing 5.5).
1 m m
2 J
3 O R
4 S l1; 0, 0, 68, 71, 100
5 T:start; 0, 0, 0, 5, 5;[?:Enter start value,98][I]
6 T:offset; 0, 0, 0, 5, 5;[SER:000][I]
7 T 10, 50, 0, 5, 40;[+:start,offset][D:1,0]
8 A 4
Listing 5.5: Setting a counter value the right way � Counter-start-value.lbl
If the operator accepts the default value of 98, the printer delivers four labels with the imprint 98, 99, 100, 101.
The D function makes sure that no leading zeros are printed.
As shown in the previous example, you can also do calculations in JScript. There are the functions +, -, *, /, %
and many others. The special functions = and == compare the numeric value or string for equality. See the
Programming Guide for a complete list.
Here is a small example (listing 5.6 and figure 5.1).
58 5 Special functions
1 m m
2 J
3 S l1; 0, 0, 68, 70, 100
4 H 150, 0
5
6 T:VAR1; 5, 20, 0, 5, pt20;42
7 T:VAR2; 5, 30, 0, 5, pt20;[*:6,7]
8 T 15, 45, 0, 5, pt20;=
9 G 10, 33, 270;L: 15, 2, s, a
10 T 8, 60, 0, 5, 10;[=:VAR1,VAR2]
11
12 T 55, 20, 0, 5, 10;[VAR1]
13 T 55, 30, 0, 5, 10;[VAR2]
14 T 75, 45, 0, 5, 10;==
15 G 68, 33, 270;L: 15, 2, s, a
16 T 65, 60, 0, 5, 10;[==:VAR1,VAR2]
17
18 A 1
Listing 5.6: Comparison of numerical values � Numvergleich.lbl
It shows the multiplication (line 7 as [*:6,7]), the value comparison (left as [=:VAR1,VAR2]) and the
string comparison (right as [==:VAR1,VAR2]). If you compare the values, 42.00 is identical with 42, if you
compare the strings “42.00” with “42”, there is no match. Here you have to be a bit careful what you compare and
how.
For clarification once again with strings as contents of the fields (listing 5.7 and illustration 5.2).
5 Special functions 59
Figure 5.2: Apples and pears both yield 0 when converted to numerical values, which is numerically identical
1 m m
2 J
3 S l1; 0, 0, 68, 70, 100
4 H 150, 0
5
6 T:VAR1; 5, 20, 0, 5, pt20;Äpfel
7 T:VAR2; 5, 30, 0, 5, pt20;Birnen
8 T 15, 45, 0, 5, pt20;=
9 G 10, 33, 270;L: 15, 2, s, a
10 T 8, 60, 0, 5, 10;[=:VAR1,VAR2]
11
12 T 55, 20, 0, 5, 10;[VAR1]
13 T 55, 30, 0, 5, 10;[VAR2]
14 T 75, 45, 0, 5, 10;==
15 G 68, 33, 270;L: 15, 2, s, a
16 T 65, 60, 0, 5, 10;[==:VAR1,VAR2]
17
18 A 1
Listing 5.7: String comparison � Stringvergleich.lbl
If you want to format a number, it must be the result of a calculation. If there is no calculation at hand, you can
multiply by 1 or add 0. Formatting is then done with the D Function, which expects the number of integer and
decimal places as arguments. With the C function you can still define how to fill up to the required number of
digits in the front.
60 5 Special functions
Assuming [value] points to 123.4567, then [*:1,value][C:0][D:5,0] returns the result “00123”. Note
that the dot is considered a decimal separator, even if the country setting is Germany instead of the USA.
[*:1,value][C: ][D:5,2] returns “ 123.45”, with two leading spaces and without commercial round-
ing.
If you want a defined rounding instead of truncation, you can use the R function.
[*:1,value][C: ][D:5,2][R:m] would yield “ 123.46”.
If there are more places before the decimal point than given, all places are printed.
[*:1,value][C: ][D:1,3][R:m] returns “123.457”.
Without the C and/or D Function rounds the function R always to two places.
[*:1,value][R:m] would result in “123.46”.
A character string can be freed from leading or trailing spaces with the TRIM function. With J you can arrange
texts left, center or right. As an argument, after the lowercase letter l, c or r, you have to specify the area (in the
selected unit of measurement) over which the alignment should take place. [J:c50] centers the text over 50
mm (or inches, depending on the country setting). You can find an example of the use of the alignment in the list
4.4 on page 33. There a text in the code lines 22 to 25 is aligned right.
If a calculation has several steps, you need several lines in JScript, because you cannot nest special functions.
Usually you use invisible text lines and assign field names ending with a consecutive number, e.g. “ZS1” for the
first intermediate step. cabLabel S3 uses letters.
The problem with these intermediate steps in JScript is that (unless otherwise defined) each result is output
as a floating point number with two decimal places. The contents behind the field names are always strings in
JScript, since they are derived from text.
But even with a simple rule of three, this can lead to problems. Let us assume we want to buy screws. Last
time we bought 750 screws and paid 7,49 € for them. But today we need the double amount of 1500 screws.
Now one could assume that we, with a rule of three calculation, also have to pay the double price, so exactly
14.98 €. If we look at the result of the calculation within the JScript label, a very special offer seems to work
(listing 5.8).
1 J
2 S l1; 0, 0, 68, 71, 100
3 H 100, 0
4 O R
5 T 10, 10, 0, 5, 8;Schraubenkauf
6 T 10, 20, 0, 3, 4;Stückzahl zuletzt:
7 T:AnzahlZG; 10, 20, 0, 3, 8;[J:r80][?:Zuletzt gekauft (Stück),750]
8 T 10, 30, 0, 3, 4;Dafür ausgegeben (EUR):
9 T:GPZG; 10, 30, 0, 3, 8;[J:r80][?:Dafür bezahlt (EUR),7.49]
10 G 10, 35, 0;L: 80, 1
11 T 10, 45, 0, 3, 4;Neue Anzahl:
12 T:AnzahlNEU; 10, 45, 0, 3, 8;[J:r80][?:Anzahl jetzt (Stück),1500]
13 T 10, 55, 0, 3, 4;Neuer Gesamtpreis (EUR):
14
15 ; now we calculate a rule of three in JScript
16 T:Einzelpreis; 0, 0, 0, 3, 3;[I][/:GPZG,AnzahlZG]
17 T:GPNEU; 0, 0, 0, 3, 3;[I][*:Einzelpreis,AnzahlNEU]
18
19 ; print the result
20 T 10, 55, 0, 3, 8;[J:r80][GPNEU]
21 A 1
Listing 5.8: Caution with multi-step calculation and disregarding the intermediate result formatting � Rundungsfehler.lbl
The special function U needs a number as argument and returns the corresponding Unicode character. Thus
[U:8364] returns a Euro currency symbol. You can also specify the hexadecimal value, then a dollar sign has
to be put in front. So [U:$20AC] also results in the Euro currency symbol.
A list of all official Unicode characters can be found here:
http://www.unicode.org/charts/
But you should check if very exotic Unicode characters are defined in the used font. Not all fonts return a unicorn
face for the character [U:$1F984].
Fonts with many UNICODE characters can also slow down the processing of a label if they are sent to the printer
together with the print job. For example, the “Arial Standard” font file is only 756 KB in size, while the “Arial Unicode
MS Standard” font requires 22.1 MB of disk space, almost thirty times as much.
Large TrueType font files should be kept on the printer and should only be included in the job using the M l
fnt;. . . and F command.
62 5 Special functions
With the parameter S of the O command, the single label buffer option can be enabled. Normally, the printer
pre-calculates as many labels as possible in advance for faster printing (no delay between printing single
labels).
However, if a special function is part of a dynamic label, the calculation is only performed at the beginning of the
process, and is then applied to all subsequent labels (if sufficient buffer memory is available).
You can see the effect in the following JScript code (listing 5.9), which uses BASIC to insert a delay of two seconds
between the simulated pressing of the dispense button. Everything that is printed in the BASIC code with the
command PRINT is sent to the JScript interpreter as a JScript line, so it is treated as if we had sent the code to
the printer from outside. The command POKE("io.xin") simulates the keystroke on the demand key in
dispense mode.
1 <ABC>
2 PRINT "m m"
3 PRINT "J"
4 PRINT "S l1; 0, 0, 68, 71, 100"
5 PRINT "H 150, 0"
6 REM option J = request labels by keystroke (force "print on demand" mode)
7 PRINT "O J"
8 PRINT "T 10, 40, 0, 5, 10;[TIME]"
9 PRINT "A"
10 FOR i = 1 TO 3
11 PAUSE 2
12 POKE("io.xin"), "START"
13 NEXT
14 END
15 </ABC>
Listing 5.9: Keystrokes made with BASIC � SingleBufferBASICDemo.lbl
If you are confused about the BASIC lines, here is the pure JScript code (listing 5.10). Start it and press the trigger
yourself several times with a pause of about two seconds.
5 Special functions 63
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, 0
5 O J
6 T 10, 40, 0, 5, 10;[TIME]
7 A
Listing 5.10: One label with demand button on the display � SingleBufferDemo.lbl
Send the code to the printer again. What changes? If you see no difference, the option “single buffer
mode” may set on in the printer’s menu. Turn it off to and try again if both printouts didn’t differ.
64 6 Using the different memories
If you want to remember values between the individual print jobs, e.g. the counter value of the last label printed,
you have the choice between different storage locations. You can create a file and write the values into it. Or you
can use one of the predefined memories.
Creating a file and constantly writing to this file has a major technical disadvantage. Flash memories, such as
an SD card, a USB memory stick or the internal IFFS have the technical characteristic of abrasion during write
operations. While it is possible to read from a flash medium almost as often as desired, the writing processes are
limited.
For this reason the cab printers have a user memory in the RAM of the battery backed up real time clock. It is
not affected by abrasion, it can be written as often as you like. However, the memory is only 32 bytes large and
global, i.e. shared by all JScript files (labels).
If global availability is no problem, [WUSER] and [RUSER] can be used to write to and read from the memory (see
listing 6.1).
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 T:XVAL; 10, 10, 0, 3, 3;[RUSER][I]
5 T:SERNO; 10, 10, 0, 3, 3;[+:XVAL,1][D:0,0][I][WUSER]
6 T 10, 20, 0, 3, 8;Serial Number: [SERNO]
7 A 4
Listing 6.1: Write values into the user memory and read them out again � WUSER-RUSER.lbl
Instead of using [WUSER] in the 32 bytes user memory, you can also write to the information memory. This is
done with [WINF]. The big difference to [WUSER] is that there is no [RINF] function. The Info memory can only be
read out using the escape function Esc i.
The special feature is that the actual writing process in the 128 bytes of volatile memory (RAM) only takes place
after the label has been completely printed and (if working in the dispense mode) dispensed. If, for example,
each label is provided with an unique serial number, this number can be written to the info memory. A PLC can
then read the serial number with the appropriate escape command and ensure that the label was printed and (if
provided) also dispensed.
If you want to use a file as storage location, you can name the file yourself. This has the advantage that different
JScript label jobs do not have to share a common memory. For example, different layouts for different product
labels could each remember their own counter without affecting each other.
6 Using the different memories 65
If a file is to be used, by the “E TMP;. . . ” command (capital letter E), the file name (without file extension) must be
defined first. After that, you can write and read with [WTMP] and [RTMP].
Writing to a file cannot be done in IFFS, a USB memory stick, SD card or WebDAV drive must be used. The
command always refers to the default memory. If the IFFS is selected as default memory, an error message is
displayed.
With a TMP file, the contents are completely overwritten with each write operation. So the file always contains
only the last written content, which is limited to a length of 128 bytes.
The example shown for user memory can also be implemented with a file as storage location (listing 6.2).
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 E TMP;KillMyFlash
5 T:XVAL; 10, 10, 0, 3, 3;[RTMP][I]
6 T:SERNO; 10, 10, 0, 3, 3;[+:XVAL,1][D:0,0][I][WTMP]
7 T 10, 20, 0, 3, 8;Serial Number: [SERNO]
8 A 4
Listing 6.2: Saving a value to a TMP file � WTMP-RTMP.lbl
New here is line number 4, where the file name to be used is defined (KillMyFlash.TMP in the subdirectory /misc). As
already mentioned in the name you should consider writing to a flash memory not too often.
A LOG file can be handled in the same way as a TMP file. But there is only one [WLOG] special function and no
[RLOG]. So you can only write to the file. But for this the write operations limited to 128 bytes are appended, the
file content is kept and the new content is added as a new line.
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 E LOG;INFO
5 T:VAL; 5, 6, 0, 3, 3;[SER:0001][I]
6 T:PRINT; 5, 15, 0, 3, 3;Label [VAL] printed on [DATE] at [TIME].[WLOG]
7 A 3
Listing 6.3: Logging into a file � Logging.lbl
66 6 Using the different memories
Create a JScript file that assigns an unique number to each runner starting with number 1. The runners
enter their names in a dialog on the printer (a SQUIX with USB keyboard). You will receive a 100 mm wide
and 68 mm high label with your name and starter number.
For the event manager the printer should create a file on a USB stick with the following content in CSV
format: “start number”, “first name”, “name”, “street”, “house number”, “postcode”, “residence”, “date of
entry” and “time of entry”. The CSV file already exists at the start of the event and consists of the first line
with the field names. The JScript file should therefore only append the respective data record.
The runners may decide during the input whether the first and last name should be printed completely
on the label next to the start number or whether the last name should be abbreviated with the first letter.
After input, printout and data storage, the input process starts again.
Exercise 6.2 The cherry on top for the JScript expert � S. 146
Complete the previous exercise so that the font size for the name on the name tag is automatically set so
that the name appears completely on the label.
Hint: Look in the programming guide for the special command [LEN:field name] and work with
conditional visibility.
Save the print job under the name “DEFAULT.LBL” so that it starts automatically when the printer is
switched on. Design the start number assignment so that accidentally switching off and restarting the
printer does not confuse the start numbers.
7 The most common Escape commands 67
In this manual only the most important escape commands will be described. For a complete list please refer to
the Programming Guide.
Escape commands provide an alternative approach to communicating with the printer. The main difference to the
“normal” JScript is that it is not line-oriented, and escape commands are processed directly.
They are usable on all interfaces where JScript is received. However, they never reach the JScript interpreter,
the software in the printer that processes JScript lines. Instead, they are filtered out by the respective in-
terfaces and processed directly. If an escape command returns an answer, it comes directly from the same
interface.
It is possible to merge escape commands into the JScript code. But this is not absolutely necessary. Escape
commands can also be used alone on an interface without sending additional JScript code. For example, a PLC
can query the status via an interface such as RS232 with the printer using escape commands, while the print
data is sent as JScript code over the network from a PC.
Pressing the pause button on the printer can also be done via one of the data interfaces. To do this, send
the character string Esc p1 to a JScript interface to set the printer to pause mode and Esc p0 to end the
pause.
This means the character strings consisting of the special character Esc , i.e. the ASCII character no. 27, the
lower case letter p and the number 1 or 0 (hexadecimal 1B 70 3016 or 1B 70 3116 ).
If a printer is set to the Pause state, it still finishes the current label to be printed and then interrupts the
current job. This ensures that no label is printed incompletely. The Esc t command described below, on
the other hand, immediately interrupts all printing activity, even if this means that a label is not completely
printed.
Via one of the interfaces you can send the sequence Esc t (ASCII values 27 and the lower case letter “t”, or
hexadecimal 1B 7416 ). The printer will then reset as if the Cancel key had been pressed for at least three sec-
onds15 .
If this does not help yet, you can switch off the printer and restart (reboot). For this purpose send Esc ! Esc ! or
hexadecimal 1B 21 1B 2116 .
15
Pressing Cancel for three seconds will result in the A+ printer to a cancel with erasing all pending jobs. You can cause the same reaction
on the EOS, SQUIX or Mach 4S by pressing the red symbol with the rejecting hand.
68 7 The most common Escape commands
With Esc s the status of the printer can be queried. Historically, Esc s is the older command and the response
is exactly 9 characters. These have the following meaning:
1. The first letter indicates whether the printer is ready to receive (response is Y) or not (response is N).
2. The second letter is an error code. A “-” (minus character) indicates that there is no error. The detailed
error list can be found in the programming manual and in the appendix on page 138.
3. The numbers in position three to eight in the answer indicate the number of labels still to be printed.
4. The last character is again a letter which indicates whether the JScript interpreter is currently active (Y = yes,
N = no).
Later in the evolution of the script language JScript, the Esc z command was added. It returns twelve letters as
response, which can be either Y (for yes) or N (for no). They indicate:
1. Printer is in pause mode
2. A job is loaded
3. Printer not able to receive more data
4. Label is moving
5. Pre-warning of foils (hardware-dependent)
6. Pre-warning of labels (hardware dependent)
7. Label in dispensing position
8. Label on vacuum plate (hardware dependent)
9. Applicator ready (hardware dependent)
10. External pause signal active (hardware dependent)
11. External Start signal active (hardware dependent)
12. Print head cleaning recommended (cleaning interval reached)
To be able to provide further information in the future, the answer closes with a carriage return character
(hexadecimal 0D16 ).
For a printer with applicator, the answer after switching on is normally:
NNNNNNNNYNNN<CR >
To exchange data between a PLC and the printer, and at the same time check whether the label has been dis-
pensed, there is the information memory. It is 128 characters in size and volatile (part of the RAM).
This memory is filled with the special function [WINF], which writes the contents of the line in which the
function is used to the INF memory.
However, this is only done after the label has been completely finished. Completely output means that for a
label in dispensing mode, the value is only written to the INF memory when it has actually been picked up under
the photocell of the dispensing sensor.
The selected value for the INF memory may also be marked as a non-printable element by additionally adding
the special function [I] to the same line of code.
The option “S” in line 5 is important: If the printer is not working in Single Buffer mode, all labels would
have the same timestamp. If the printing process was started by the night shift, but only four labels were
7 The most common Escape commands 69
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, -2
5 O R, S
6 T:ETINUM; 5, 6, 0, 3, 3;[SER:00001][I][WINF]
7 T 5, 15, 0, 3, 3;Label [ETINUM] printed on [DATE] at [TIME].
8 A 12
Listing 7.1: JScript writes the invisible text from line 6 to the INF memory � WINF-ESCi.lbl
printed, the morning shift would find the date and time from the previous day on the 8 labels still to be
printed.
[DATE] and [TIME] from the example are reserved function names and print the current date and time in
the format typical for the country setting. However, because JScript is case-sensitive, [Date] and [Time] are
references to the field names Date and Time (if defined as such).
The command Esc i thus returns the character strings in the example as an answer one after the other:
00001<CR >
00002<CR >
00003<CR >
00004<CR >
...
00012<CR >
But only after the corresponding label has been printed completely.
If a printout is not to be made immediately for all desired copies, but for one copy at a time by activating a
start contact, the command Esc g can also be used instead of the contact at the I/O interface (to be sent in
hexadecimal form as two bytes 1B 6716 , without terminating line end character).
The command Esc g corresponds to exactly one single triggering of the START contact at the I/O interface.
Thus, a printer can be controlled exclusively via a TCP/IP connection without having to use the I/O interface
too.
But also a remote control of an EOS2 or EOS5 printer, which both do not have an I/O interface (in contrast to the
SQUIX), will react to the Esc g command.
The possibilities to control a cab printer via TCP/IP connection (and without direct wiring of the I/O interface)
are even more versatile. To control the I/O interface on the TCP/IP network there is the command Esc xin. The
command must be followed by the name of the signal/connection, finished with a semicolon. An end of line is
not necessary.
The commands are interpreted as triggers. It is therefore not possible to set the printer to pause state. For this
purpose, the separate commands Esc p1 and Esc p0 must be used.
70 7 The most common Escape commands
Since these are escape commands, they can be sent, for example, by a PLC to port 9100 of the printer, while the
print data itself is sent to the printer via a PC or data server.
The commands are as follows:
The I/O interface can not only be triggered by an escape command, it is also possible to read the digital outputs
of the printer. To do this, send the command Esc xout to the printer. Because it is an escape command, no line
end is required.
The printer responds with a sequence of the letters N for No or Y for Yes. The letters are terminated by a carriage
return character (decimal 13, hexadecimal 0D16 ). They stand in order for:
7.8 Outlook: Printer control in the industry 4.0 age with OPC UA
Today’s machine communication is network-based, devices communicate with each other via TCP/IP based
services and protocols. JScript and the escape commands are still designed for direct communication with-
out complex protocols. In the past two decades, in which JScript exists, a lot has changed, especially in the
last few years. The current cab printers (except Mach1 and Mach2) are using the OPC UA protocol. It is pos-
sible to replace all escape queries with the advantages of a modern protocol. Therefore OPC UA provides
a mature security concept which allows to send commands encrypted only from authorized devices to the
printers.
16
The STOP signal interrupts each operation immediately and puts the printer into an error state (an EOS or SQUIX display shows External
Error). A print command sent in the error state will not be executed and the printer will remain quiet. In contrast to pressing an
emergency stop button, the error can be acknowledged and the printer can be used again by pressing Esc xin RSTERR;.
7 The most common Escape commands 71
If you want to know more about OPC UA, please have a look at the cab web page. There you will also find special
instructions how to integrate a cab printer into your production process control or IT infrastructure using the
OPC UA protocol.
72 8 Access to databases
8 Access to databases
The access to databases can be done from a cab printer via JScript and SQL interface. The printer connects to a
Windows service, the cab Database Connector. The connection is made via the database language SQL, in a
language range reduced to this application.
For JScript itself the actual database remains invisible. The printer always speaks only with the Database
Connector. Whether this interacts with a MySQL database server or a simple Excel file is not visible to the
printer.
Besides accessing a database via the cab Database Connector the printer can also access a local file (stored on
the printer) and act as database server itself. This is possible for the A, A+ and Hermes+ devices with a dBASE file
and for all newer printers based on the SQUIX with a SQLite file besides dBASE.
This requires either a suitable dBASE or SQLite file in the subdirectory misc/, or a Windows PC that can be reached
from the printer via an IP address and has access to the database. If the cab Database Connector is used, one
service for any number of printers is sufficient.
The database is accessed from the cab Database Connector via the ODBC or OLEDB17 interface. Therefore any
database can be used which has a suitable ODBC or OLEDB interface. The cab Database Connector in turn uses
a port to accept TCP connections to talk to the printers (usually port 1001).
We need to know the IP address of the machine running cab Database Connector. Then we need the port on
which the service listens and receives the SQL requests. In JScript we then use the following command line to
connect to the database (routed through the service).
E SQL;192.168.10.34:1001
From now on, the printer sends all database queries to the IP address 192.168.10.34 on port 1001 (of course you
will have to enter your address values here if you want to try the examples). There the cab Database Connector
should be installed and running. How to install the cab Database Connector can be read in the programming
manual (Chapter 7: cab Database Connector).
The software cab Database Connector and also the programming manual can be downloaded from the cab
website.
https://www.cab.de/en/programming
In addition to a connection to the Database Connector, a standalone solution can also be implemented. For
this purpose a database file compatible with SQLite 3 has to be created and copied into the directory misc/. The
printer then works with this SQLite file (possible since firmware 5.25).
We only have to tell the printer the file using the E command:
E SQLITE;filename
17
OLEDB is no longer maintained by Microsoft and should not be used anymore. Windows, ODBC and OLEDB are registered trademarks
of Microsoft Corporation.
8 Access to databases 73
If you omit the file extension, .sqlite3 is assumed. However, .db or .db3 are also possible, in which case the
extension must also be specified.
The example 12.2 Print vouchers on page 93 shows the use of a SQLite file stored locally on the printer.
Engaging the database connection (to a server or a local file) with the E command must always be done
after the J command, otherwise an error message will appear on the printer. �
For the query to a database there is the special function [SQL:…]. If it is used in a text or barcode content, the
response of the database is used as return value.
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 200
5 E SQL;192.168.10.34:1001
6 T:ARTNR; 10, 5, 0, 3, 5;[?:Article number?,5560432,1,R,D]
7 T 10, 15, 0, 3, 5;[SQL:SELECT PRODNAME FROM TA WHERE ARTICLE='{ARTNR}']
8 A 1
Listing 8.1: Get a string from a database � DBSearch.lbl
Within the special function, curly brackets can be used to insert the content of another JScript element (text
or barcode), so to speak a reference within an SQL call. In this example, the user is first asked for an article
number (line 6). Then this input is used in the following line. The cab Database Connector then receives this
request:
SELECT PRODNAME FROM TA WHERE ARTICLE='5560432'
Assuming that the user has accepted the default by simply confirming.
The response is a single string, regardless of whether the database server returns one or more responses. If the
response consists of multiple elements (strings), they are arranged one after the other and separated with a GS
ASCII character (Group Separator, decimal 29, hexadecimal 1D16 ).
The special function [SPLIT:name,pos] is available for processing in JScript. It can be used to refer to a content
of a single JScript line and pos is used to specify the position within the content defined by the GS character
separated string response from the database.
The position is counted from 1. If the referenced content contains no GS character, so if it consists of only one
element, then [SPLIT:name,1] returns the same result as [name].
A more extensive example shows listing 8.2.
74 8 Access to databases
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 100, 0
5 O R
6
7 ; definition of the IP and port address where the cab service is installed
8 E SQL;192.168.10.34:1001
9
10 ; user entry via touchscreen
11 T:INPUT; 0, 0, 0, 3, 3;[?:Artikelnr.:, , , L7, R, D][I]
12
13 ; Database Connector query (SQL Statement)
14 ; (query the database about all fields of the table 'article'
15 ; where 'artnr' was equal to the JScript variable 'INPUT')
16 T:RESULT; 0, 0, 0, 3, 3;[SQL:SELECT * FROM article WHERE artnr='{INPUT}'][I]
17
18 ; split the result from the database into
19 ; multiple text elements onto the label
20 T:RES1; 30, 5, 0, 5, pt11;[SPLIT:RESULT, 1][I]
21 T:RES2; 30, 10, 0, 5, pt11;[SPLIT:RESULT, 2]
22 T:RES3; 30, 15, 0, 5, pt11;[SPLIT:RESULT, 3]
23 T:RES4; 30, 20, 0, 5, pt11;[SPLIT:RESULT, 4]
24 T:RES5; 30, 25, 0, 5, pt11;[SPLIT:RESULT, 5]
25 B 12, 30, 0, 2OF5INTERLEAVED, 25, 1, 15;[RES2]
26
Since the database language SQL does not only know queries, the special function [SQL:…] can also be
used to write back to a database. The previous example shows this in line 37, where with the INSERT INTO
command three values can be inserted into a table. The line itself is implemented in JScript as invisible
text.
Besides the SQL special function, there is also the SQLLOG special function. It is only executed when the respective
label has been completely processed (printed and if necessary dispensed). The procedure works in analogy to
the WINF write command into the info memory. In the previous example (listing 8.2), line 37 could also look like
this to create the database entry only at the time of printing.
The cab printers allow via options (additional hardware mounted in front of the printer) different operation
modes like cutting, dispensing or printing and rewinding. For these options there are capital letters in JScript to
configure the respective option.
The commands to use (hardware) options must follow the command S (label size), otherwise an error
� message will appear on the printer.
To dispense a label you need two things. There must be a dispensing edge, combined either with a dispensing
photoelectric sensor, an I/O interface or a label applicator. In addition, a label must be pushed forward after
printing so that it can be removed by the user (or label applicator).
The dispensing mode is set with the command P in JScript. The command can be assigned an optional parameter,
the dispensing offset, i.e. the distance in millimeters or inches by which the label is moved beyond the dispensing
position. Positive and negative values are possible. If the values are positive, the label strip is transported further
out of the printer. The default value 0.0 mm positions the rear edge of the label on the dispensing edge. Typical
for the dispensing offset would be half the label distance (half the length of the gap).
P 1.5
In this example the dispensing distance is set to 1.5 mm and the dispensing mode is activated. After reaching
the dispensing position, the labels are pushed forward by +1.5 mm. Afterwards the printing of the next label is
waited until the removal of the label is confirmed.
When dispensing, the label is only moved forward in combination with a dispensing light barrier. Without such a
light barrier there is a similar option, the tear-off mode. This mode is activated by the T parameter of the option
command (Tear-Off Mode).
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, 0
5 O R, T2.5
6 T 12, 25, 0, 3, 6;Hallo Welt
7 A 1
Listing 9.1: With the T option, the printer switches to tear-off mode � TearOff.lbl
The fifth line (O R,T2.5) activates the tear-off mode in addition to the 180° rotation.
The specification of how far beyond the tear-off position must be shifted can be defined directly after the letter
“T” as an option argument. It is added to the parameter defined directly in the printer. Therefore, the value 0
should always be aimed for in the printer and only a slightly different value should be set in the printer menu to
compensate for differences between several printers. If both values are set to 0.0 mm, the position is approached
in such a way that the original accessory ( toothed tear-off edge) matching the respective printer is positioned at
the rear edge of the label.
9 More than just printing 77
The transport to the tear-off edge always takes place after the last label. When further labels are printed again,
a retraction is first triggered and the front edge of the next label is positioned under the printing bar again.
Then all new labels to be printed are printed without interruption and moved forward to the tear-off posi-
tion.
If a label has been dispensed, the beginning of the next label is no longer under the print head, but has already
passed it. To print the next label completely, the printer must retract the label. To do this, the counterpressure
roller is turned backwards until the start of the next label is under the print head.
However, this does not necessarily have to be done in this way. The printer can also start printing the next
label and print exactly until the dispensing position is reached. If the previous label is removed, the interrupted
label is printed to the end. This usually results in a hair-thin white (unprinted) cross line on the label due to
slippage.
If this is to be prevented, set the Back Transport parameter in the printer menu from optimized to always. In
JScript, the option command parameter D can be used.
O R, D
This line would also force a permanent retraction (including a 180° rotation). If you want to force an optimized
retraction instead, use the P parameter in the Options command.
Note that firmware 5.35 (published October, 27th 2020) comes with a new method of optimised printing to
eliminate the hair-thin white cross line. So instead of turning off the optimisation, updating the firmware may be
a better solution for you.
9.4 Ribbonsaver
If you have a printer with automatic saving, you can enable or disable the use of this option. To do this,
the additional argument R1 or R0 is appended to the H command. The argument R1 (“ribbon saver on”)
enables the use of automatic saving. The following line, however, would disable the automatic saver (if in-
stalled):
H 150, 0, R0
Where the first value sets the print speed to 150 mm/s, the second value adds a heat of 0 to the printer’s internal
value and the R0 disables the saving function, if the function is not forced in the printer menu. In the settings in
the printer you have the possibility to choose between “JScript” and “on”. If you have chosen “on”, a parameter
R0 cannot prevent the automatic saving activity. The printer setting has (exceptionally) priority over the JScript
code here.
You can also use a cutter to cut off a label. The command is C followed by a letter that specifies the cut type or a
number. The following commands are possible:
78 9 More than just printing
The position of the cut at the end of the label and an additional cut position can be selected as optional
parameters. Only positive values are allowed for the further cutting position.
The additional value parameters to get an offset of the cut cannot be mixed. Therefore, you cannot mix an offset
perforation with a cut through.
Probably the most common application is perforating on a shrink tube with final cutting at the end of the
job.
m m
J
; here are the elements like label size, options, texts, barcodes, etc.
...
C p
C e
A 5
Listing 9.2: Using the cutting command in a label made for shrink tubes. You will get a perforation cut between the single labels and a
fully cut through after the last label.
The example in listing 9.2 would create five markings (labels) on the heat shrink tube and then cut the tube. The
markings are separated from each other by a perforation.
The use of a perforation knife allows both perforating and cutting, but is limited in the maximum cut
� width depending on the material to be cut. Talk to us in advance if you want to perforate very large
materials.
An applicator can be attached to an A, A+ , SQUIX, Hermes A, Hermes+ or HERMES Q. The printer offers additional
parameters in the settings menu when an applicator is detected.18
18
Printer and applicator communicate via the Sub-D connector on the front of the printer. The printer is able to recognize that an
applicator is attached, but it cannot recognize which one it is.
9 More than just printing 79
Parameters can be passed to the applicator with the JScript print data. This is done with the option command O
Ax=y.
With the O command, several options can be spread over several command lines, or all options can be defined
on a single command line and separated by a comma.
In the printer settings, the mode can be selected between Print and Apply (default value) and Apply and
Print.
Normally a label is printed and applied directly if the A command was given. If an applicator is connected to e.g.
the Hermes A or Hermes+ , the digital input START must be triggered to start printing (apply +24 V between pin 13
and pin 25 at the I/O interface).
In Apply and Print mode, however, the applicator is “hold” in the waiting position and applies the held la-
bel while triggering the START signal. After the label is applied, a new label is automatically printed and
brought into the waiting position. This procedure allows a faster response to the signal from a production
process.
However, after loading a job, no label is yet in the waiting position, so the START signal does not trigger any
action. It is mandatory to send the FSTLBL signal to the printer first (connect +24 V between pin 1 and pin 25 at
the I/O interface).
The I/O interface can not only be wired directly with 24 V voltage, it is also possible to control it via TCP/IP networks.
Send as START signal the escape command Esc g (hexadecimal 1B 6716 ). In Apply and Print mode, you must send
the command Esc xin FSTLBL; once (hexadecimal 1B 78 69 6E 20 46 53 54 4C 42 4C 3B16 ).
80 10 Diagnostic options
10 Diagnostic options
The SQUIX offers several ways to log the data stream sent to the printer. On the one hand there is the possibility
to print the received data directly in plain text. This possibility exists since a very long time, old devices from the
A-series already master this.
This method is called Monitor Mode. It reaches its limits when interaction with the printer is required. In Monitor
Mode, the printer does not process the incoming data stream, but only produces a printout. The width can be
set in 5 mm steps from 50 mm to the maximum print width. The printer prints line by line and ignores the label
detection. As with all diagnostic functions that do not take the label dimensions into account during printing,
you can also turn the material around in monitor mode and print on the back of the carrier strip if no suitable
continuous material is available.
A new feature of the SQUIX series is the possibility to write the data to a file, which can later be loaded from the
printer via FTP or FTPS (FTP with TLS) connection or you can have the printer write directly to an SD card or USB
memory.
Monitor mode can be turned on at the printer in the Diagnostics menu. If it is active, this is indicated in the printer
display (Figure 10.1). Press the Cancel key to exit the monitor mode.
Figure 10.2: A SQUIX printer allows to record all incoming data into a file direcly on an USB storage device
The file name is displayed to indicate that recording is in progress. Pressing the button again will stop the
recording (with a query if you really want to stop).
While recording, the status bar on the main screen shows a circle with a dot flashing in the middle (similar to an
audio or video recorder).
The recorded file contains the pure input data stream without any additions (like timestamps).
A missing line end after an A command can be quickly exposed both with the monitor mode and via data stream
recording.
With the following command you can force the printer to create an internal bitmap of the label, but inhibit to
print it.
A [PREVIEW]
To show the bitmap of the last printed label (or forced preview), use this link in your browser:
https://192.168.10.1/cgi-bin/bitmap
If a user name and password are requested, use admin as the user name and the website password specified in
the Security menu. The initial factory default for the password is admin. Use the IP address of your printer as the IP
address. Starting with the SQUIX model series, you have the choice to force incoming connections via HTTP (unen-
crypted) or HTTPS (encrypted). Older printers can only communicate unencrypted.
82 11 Barcodes in global trade
In global trade, a number of barcode types have quickly established themselves which clearly classify goods. For
example, the EAN-13 code, the European Article Number. It consists of 13 digits, 12 of which identify the article
and the last digit acts as a check digit.
In addition to this code, there are similar codes like the ISBN for books and magazines. There is also a check
digit, the value that can be uniquely calculated from the previous digits.
Barcodes in general are a symbolic representation of content (numbers, character strings, etc.), which can be
captured particularly well by machine. E.g. with bar code readers based on a laser beam for one-dimensional
codes or sufficiently high-resolution cameras for two-dimensional codes.
When reading by machine, errors are to be ruled out as far as possible. Two methods are used for this purpose.
On the one hand, the correctness of data can be checked using check digits. Depending on the method used to
calculate these check digits, errors can be detected almost 100 %. However, the error detection can only confirm
a read data set. If the calculated and read check digits do not match, the actual content cannot be restored. One
can only discard the reading that was recognized as incorrect.
Therefore, there is not only the error detection but also the error correction. Because the correction data is
already integrated during the compilation without knowing whether the reader has to restore the data later
or not, this procedure is also called FEC, which means forward error correction. This means that more data is
displayed in the barcode than actually needs to be transported. Later you can read the data, perform a check,
and if the check is successful, you can process the data directly as checked values.
If the data cannot be verified as correct, an error correction procedure offers the possibility to restore the original
content of the data. Depending on the method, this is possible to a considerable extent, but requires increased
computing power.
There are some data that already have a built-in authenticity check. For example, a check digit is built into the
GTIN, the Global Trade Item Number. The complete GTIN number contains an additional digit that does not
contribute to the content and could actually be omitted. However, it provides confirmation that this sequence of
digits follows a certain rule and can therefore be considered correct.
The GTIN-13 has 12 payload digits followed by a check digit. The first 12 digits clearly identify a product. For exam-
ple, at a supermarket checkout, the price and product name can be determined with the help of a database after
the checkout system has read the GTIN from a printed barcode by a laser scanner.
You could simply add up the sum of the single digits and calculate the difference to the next multiple of 10 (as a
result, we only want to get a single digit, so the code standardized by GS1 uses this difference). The result would
then be the check digit.
So if you had to form the GTIN for the sequence of digits 123456789012, you would do the calculation:
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 = 48
50 – 48 = 2
11 Barcodes in global trade 83
The check digit would thus be 2 and the total GTIN would be 1234567890122.
Why so complicated? Why not just use the last digit of the sum of all useful digits as check digit? The answer lies
hidden in practical application. If we calculate the check digit as the difference to the next multiple of 10, then
the sum of all digits including the check digit is always a multiple of 10. This makes it much easier for the scanner
at the supermarket checkout to check whether the reading is valid. How much work we put into creating the
label is not important, the process at the checkout must be fast.
In our example, the scanner calculates like this:
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 + 2 = 50
50 = 5 · 10 + 0 7→ good read
If you now take any digit and replace it by another digit, e.g. the fifth digit by a 7, the reading result 1234767890122
would not be conform to the rules any more. Because the sum of all digits now results in 52.
But it is a little more complicated. If the barcode cannot be read by the scanner, a human would have to
read the GTIN from a plain text imprint and enter it on a keyboard. This can lead to an interchanging of two
neighboured digits, which happens more often with a manual input than typing a wrong digit. However, the
GTIN 1235467890122 would be valid according to the rule we have set up.
Therefore, starting from the back (with the check digit), each digit is multiplied alternately by 1 and by 3
before the sum is formed. This sum must be a multiple of 10.
The GTIN check digit for the useful digits 123456789012 is actually calculated in this way:
1 + 3 + 5 + 7 + 9 + 1 = 26
2 + 4 + 6 + 8 + 0 + 2 = 22
26 + 3 · 22 = 26 + 66 = 92
100 – 92 = 8
A final check will result in this (we multiply each digit alternatively with 1 and 3, starting from the last digit):
The actual GTIN is 1234567890128. 1235467890128 would no longer conform to the rules.
There are other check digits within the data defined by the GS1 organization. For example, certain GTINs
contain a weight specification in addition to the identification of the goods. This allows you to offer goods
in bulk and to charge them by weight at the supermarket checkout. The procedures for these additional
check digits are much more complex and are defined in the GS1 organization’s manual GS1 General Specifica-
tions.
84 11 Barcodes in global trade
Figure 11.1: Both, the printer and the cabLabel S3 software are calculating the check digit. If the digit the user entered is wrong, the
software will replace it automatically by the correct digit.
11.1.2 Error correction in QR and Datamatrix codes with the Reed-Solomon method
The two mathematicians Irving Stoy Reed and Gustave Solomon from the MIT Lincoln Laboratory, a research
facility of the United States Department of Defense, developed a data structure in the 1960s that allows data to
be reliably identified as faulty and even clearly reproduced again in the event of the loss of individual parts of the
data or corruption (e.g. the mixing up of digits).
The Reed-Solomon code is used by the Datamatrix in the form ECC200 and allows to correct up to 25 % of
destroyed or unreadable parts. ECC200 means error correction code and describes the procedure and the amount
of redundant information in the code. There exist a couple of different levels of error correction in Datamatrix.
But today’s Datamatrix always uses the ECC200 correction code. This does not have to be specified in the JScript,
the older procedures ECC00 to ECC140 are not supported.
The situation is different with the QR Code. The company Denso Wave, which invented the code in 1994 and
released it for public use, defines different levels of redundancy. In JScript, for example, you have the possibility
to append the options +ELx to the type identifier QR-Code, where the x indicates the level of redundancy (Error
Correction Level).
In the 4.7 listing on page 38 the error correction level was not specified. The printer has chosen level 1 by itself.
You can recognize this by the fact that both bits are set in the format definition. This way the code takes up the least
space. If a higher level is to be printed, the corresponding barcode option must be used.
11 Barcodes in global trade 85
Figure 11.2: Basic structure of a QR code with error level and mask pattern. Besides the three large search patterns, which are connected
to the two lines for timing, and the other smaller one, the code also contains the format information in addition to the user
data and the correction parameters (source: Wikipedia).
The GS1 is a global organization that defines a special data structure and associated barcodes. The data itself is
divided into so-called Application Identifier, also called AI. These AI are basically numbers that have the same
meaning worldwide. The following table 11.2 lists some of these AI.
86 11 Barcodes in global trade
All AI can be found on the Website of the GS1. The format describes the required digits or characters. N2 means
that you need exactly two digits. X..20 refers to a string of letters and/or numbers, which may have a maximum
length of 20 characters. With N2+X..20 as defined for the serial number, for example, you can include up to 20
letters or digits in this information. The data set then consists of up to 23 characters. If a data record is flexible in
length (and is not the last data record in a listing), it must be followed by a special character (usually an FNC1). A
FNC1 special character is always followed by an AI.
Barcodes like the GS1-128 consist of several AI, which are listed one after the other in the barcode. If a human-
readable plain text line is added to a code, the AI is placed in round brackets to increase readability. How-
ever, the code itself does not contain brackets. It consists only of the completely formed sequence of AI
and their respective contents, in case of a flexible length it ends with a special character before a following
AI.
If a GS1 barcode is defined in JScript, the data is also specified with the brackets, even if it is not contained in the
actual code. See 11.1 for an example of a GS1-style shipping label.
There are AI, which have a decimal number as content, e.g. the AI 310x. The meaning of this AI is to indicate
the net weight in the unit kilogram. The AI is formed in the form N4+N6, i.e. 4 digits are used for the AI itself
and then always 6 digits for the value. The last digit of the AI always indicates the number of decimal
digits.
11 Barcodes in global trade 87
If you want to display five kilograms net weight in a GS1 barcode, you can use the following line in JScript.
B 10, 30, 0, GS1-128, 20, 0.33;(3100)000005
Here the last digit of the AI is 0, so the coded value has no decimal digits. If you want to specify the value in
grams, you could use the following line. Then 5 kg = 5000 g.
Grams and kilograms are frequently used, but all specifications of the number of decimal digits up to the value
of 5 are still acceptable. In our example, it would therefore also be possible to form the AI including data as
follows:
Figure 11.4: In cabLabel S3 Pro you get assistance by a software tool. In this dialog window you will have to enter the number of digits of
some AIs in a seperate field.
11 Barcodes in global trade 89
1 m m
2 J
3 S l1; 0, 0, 150, 153, 100
4 H 150, 0
5
6 ; create the variable fields
7 T:GTIN; 0, 0, 0, 3, 3;04012345333336[I]
8 T:SSCC; 0, 0, 0, 3, 3;376170137518461130[I]
9 T:PDATE; 0, 0, 0, 3, 3;[YY][MONTH02][DAY02][I]
10 T:Charge; 0, 0, 0, 3, 3;123456[I]
11
12 ; draw a rectangle and some lines onto the label
13 G 2, 2, 0;R:96, 146, 0.5, 0.5
14 G 2, 22, 0;L:96, 0.5
15 G 2, 42, 0;L:96, 0.5
16 G 2, 62, 0;L:96, 0.5
17 G 2, 82, 0;L:96, 0.5
18
19 ; sender address
20 T 4, 5, 0, 5, 2;Absender
21 T 4, 8, 0, 3, 3;cab Produkttechnik GMBH & Co KG
22 T 4, 12, 0, 3, 3;Wilhelm-Schickard-Str. 14
23 T 4, 16, 0, 3, 3;76131 Karlsruhe
24 T 4, 20, 0, 3, 3;GERMANY
25
26 ; receiver address
27 T 54, 5, 0, 5, 2;Empfänger
28 T:ToLine1; 54, 8, 0, 3, 3;Musterfirma AG
29 T:ToLine2; 54, 12, 0, 3, 3;Industriestraße 128b
30 T:ToLine3; 54, 16, 0, 3, 3;1234 Schöndorf am Weier
31 T:ToLine4; 54, 20, 0, 3, 3;AUSTRIA
32
33 ; NVE plain text
34 T 4, 28, 0, 5, 5;SSCC
35 T 4, 38, 0, 3, 8;[SSCC]
36
37 ; GTIN plain text
38 T 4, 48, 0, 5, 5;GTIN
39 T 4, 58, 0, 3, 8;[GTIN]
40
41 ; production date and batch no. as plain text
42 T 4, 68, 0, 5, 5;Produktionsdatum
43 T 4, 78, 0, 3, 8;[PDATE,5,2].[PDATE,3,2].20[PDATE,1,2]
44 T 54, 68, 0, 5, 5;Charge
45 T 54, 78, 0, 3, 8;[Charge]
46
47 ; barcode for the AI 01, 10 and 11
48 ; To avoid the need for an additional FNC1, the AI10 is placed at the end.
49 B 10, 88, 0, GS1-128, 26, 0.3;(01)[GTIN](11)[PDATE](10)[Charge]
50
51 ; barcode for the SSCC
52 B 10, 120, 0, GS1-128, 26, 0.5;(00)[SSCC]
53
54 A [PREVIEW]
Listing 11.1: A GS1 conform shipping label � GS1Versandetikett.lbl
90 11 Barcodes in global trade
The GS1 usually does not use a new development, but uses already existing barcode types. These barcode
types are filled with data according to precisely defined rules in order to distinguish a GS1 barcode from its
original form. In most of the used codes you simply start with the special character FNC1 and let the sequence
of AI numbers and AI contents follow. If an AI has a variable length, a special character FNC1 is inserted at the
end of the user data to indicate that the AI’s data ends here and a new AI begins after the special character.
This method can be used to convert Datamatrix, QR Codes and Code-128 barcodes to GS1 compliant data
carriers.
However, the method is not a legal standard, but a non-proprietary regulation of the non-profit organization GS1.
It would not be punishable by law, but it would be unwise to use a FNC1 special character in the same way when
using a Datamatrix, QR Code or Code-128 barcode, because it can be assumed that all scanners in the world will
master the GS1 rules and identify the code as a GS1 code.
However, there are also barcode types that differ from this basic structure. So you can form the barcode types
EAN8 and EAN13. They always represent the GTIN or the shorter GTIN8. This is a separate barcode that does not
contain the special character FNC1 or the AI identifier (01) for the GTIN.
12 Best practice examples 91
In this chapter some more complex examples will be explained, as they are more common in practice. Even
if you are not familiar with the concrete task of the respective examples, it is still worth to take a closer look
into the code, because it shows the systematic procedure for individual solutions with the cab printer language
JScript.
The examples are simplified and focus on the detail to be demonstrated. The label dimensions of 68 x 100 mm
correspond to the “training label” as it is inserted on the training printers at the cab training center in Karlsruhe/Ger-
many. In practice there would be more elements like eg. logos on the labels.
12.1 Single digit month, shift identification and daily counter reset
In this example we will create a single barcode containing a searial number. The serial number is constructed
as:
1. Year of production (two digits)
2. a one digit month code (where October to December are uppercase letters O, N and D)
3. day of month (two digits)
4. a single uppercase letter as a shift code (F, S or N)
5. a five digit number starting with 00001 each new day
Listing 12.1 on page 92 will show the example.
It gets interesting from line 9 on. A special function [MONTH1] is simulated, which generates a one-digit month
code. First the string “123456789OND” is printed invisibly as AlleMonate. Then the month is determined with the
special function [MONTH] and saved as the content of AktuellerMonat.19 The value of the current month is now
used as index to the previously defined string to generate the one-character code.
The shift code looks a bit more complex. Let’s assume that the early shift starts at 6:00, the late shift takes over
at 14:00 and the night shift works from 22:00 until the next early shift starts. The shift abbreviations are defined in
line 15 (F, S and N).
Then the current time is determined in line 16. Since we use the options S and J (single buffer and demand button,
see line 7), the calculation only takes place when the trigger is pressed (symbol on the printer display or external
button). Three conditions now check if the current time is greater than the start time of the shifts. There is no
[>=:…] special function, so we check if the time is greater than one minute before start.
Each check returns 1 (numeric one) or 0 (numeric zero), depending on whether the condition is true or false.
Line 20 adds all checks and adds 1 more. We have to do this because we cannot use 0 as index, but all three
conditions could be false (e.g. at 3:47 in the morning).
19
Saving to a variable is equivalent to invisible printing with a field name as reference. A “variable command” does not exist in JScript,
instead, T:variable name;0,0,0,3,3;variable content[I] can be used to simulate assigning a value to a variable.
92 12 Best practice examples
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 150, 0
5
6 ; options: print on demand, single buffer, 180° rotation
7 O J, S, R
8
9 ; single digit month
10 T:AlleMonate; 0, 0, 0, 3, 3;123456789OND[I]
11 T:AktuellerMonat; 0, 0, 0, 3, 3;[MONTH][I]
12 T:MONTH1; 0, 0, 0, 3, 3;[AlleMonate,AktuellerMonat,1][I]
13
14 ; shift code (F from 6:00, S from 14:00, N from 22:00)
15 T:SchichtKuerzel; 0, 0, 0, 3, 3;NFSN[I]
16 T:AktuelleZeit; 0, 0, 0, 3, 3;[H24][MIN][I]
17 T:SC1; 0, 0, 0, 3, 3;[>:AktuelleZeit,559][I]
18 T:SC2; 0, 0, 0, 3, 3;[>:AktuelleZeit,1359][I]
19 T:SC3; 0, 0, 0, 3, 3;[>:AktuelleZeit,2159][I]
20 T:SC; 0, 0, 0, 3, 3;[+:SC1,SC2,SC3,1][I]
21 T:Schichtcode; 0, 0, 0, 3, 3;[SchichtKuerzel,SC,1][I]
22
23 ; serial number with storage in user memory and reset at the beginning of the day
24 T:Nutzerspeicher; 0, 0, 0, 3, 3;[RUSER][I]
25 T:AlteSN; 0, 0, 0, 3, 3;[Nutzerspeicher,6][I]
26 T:AlterTag; 0, 0, 0, 3, 3;[Nutzerspeicher,1,5][I]
27 T:NeuerTag; 0, 0, 0, 3, 3;[YY][DOFY][I]
28 T:Ruecksetzung; 0, 0, 0, 3, 3;[=:NeuerTag,AlterTag][I]
29 T:NeueSN; 0, 0, 0, 3, 3;[*:AlteSN,Ruecksetzung][D:5,0][C:0][I]
30 T:Seriennummer; 0, 0, 0, 3, 3;[+:NeueSN,1][D:5,0][C:0][I]
31 T:NeuerNutzerspeicher; 0, 0, 0, 3, 3;[YY][DOFY][Seriennummer][WUSER][I]
32
33 ; barcode centred on the label
34 B 0, 15, 0, CODE128, 20, 0.5;[YY][MONTH1][DAY02][Schichtcode] [Seriennummer][J:c100]
35
36 ; endless printing (on demand, see line no. 7)
37 A
Listing 12.1: With some extra work, a complex serial number can be generated, which is reset daily � Seriennummer.lbl
12 Best practice examples 93
If the time is eg. exactly 14:00:11 (2 p.m. plus 11 seconds), then the calculation in line 16 to 21 will result in:
Vouchers from 10 € to 500 € should be printed. The operator can enter the desired amount at the printer. Only
multiples of 10 € are allowed. A voucher is printed with a barcode consisting of a sixteen-digit random chain of
94 12 Best practice examples
letters. This information is written into a database. In order to be able to use the code later in the online store,
the content is also given in plain text, divided into four-digit segments.
Here the Advanced BASIC Compiler is used to generate the random sequence of capital letters. In JScript a check
is performed. If the desired amount is not a multiple of 10 € or if the amount is smaller than 10 € or higher than
500 €, only a “INVALID!” is printed on the label instead of the voucher.
In the lines 1 to 14 a BASIC program is included. If the label is loaded from memory or sent to the printer, the JScript
interpreter passes lines 2 to 13 to the Advanced BASIC compiler and continues from line 16.
The BASIC compiler translates the program and executes it directly. It runs in a continuous loop (REPEAT – UNTIL
lines 4 to 6). Line 3 specifies that characters can be sent directly to JScript. The actual magic of the program
is done with the commands JGET$ and JPUT. In line 5, the data stream is permanently queried from JScript.
You get an empty string if nothing is (yet) available. If the a$ assigned string differs from the empty string, it
can escape the UNTIL loop in line 6. Another loop is used to generate a random string and send it to JScript.
Afterwards the BASIC program is terminated in line 13.
Figure 12.2: 125€ are not allowed, because it’s undividable by 10 (see line 47 and 48 in listing 12.3).
12 Best practice examples 95
From line 16 on, the actual JScript code follows, which uses the BASIC program that is now running in the
background.
In line 27, the user is asked for a desired amount. The user can enter a maximum of three digits.
In line 28 the desired amount is sent to abc (our BASIC program). The answer is used via the identifier Zufall later
in line 54 and line 55.
If you read the BASIC code carefully you will notice that the sent value is not used at all. Only line 6 is used to
check if something was sent at all, otherwise the program will continue to wait in a continuous loop. However,
the special command [ABC:. . .] requires a field name as argument, and Wunschbetrag in line 28 is the only field
name defined in JScript so far (see also section 13.13.2 on page 126).
Line 55 uses the cutting a section of a string special command via the two parameters start position and
length. This procedure was already used in the previous example. New is the indexing using SPLIT in lines 37
and 42. SPLIT expects an identifier and an index as parameters. The record to which the identifier points should
be separated with the special character Group Separator, accessible via [U:GS]. On the newer printers based on
the SQUIX board, other separators can also be used, but the Group Separator is compatible with all printers and
is also used by the Database Connector.
Exciting are the checks, which are completely implemented in JScript here. They are single checks, which must
result in a 1 if everything is ok. If we multiply the results of the checks, a wrong result (value 0) is enough to make
the whole multiplication become 0.
Line 45 only accepts values starting from 10 (only three-digit integers are to be expected from the query). Line 46
limits up to and including 500 and lines 47 and 48 only allow multiples of 10.
In the layout part the elements become conditionally (un)visible, depending on whether the line ends with
[I:CHECK] or [I:!CHECK]. With [I:CHECK] the line becomes invisible if all conditions are fulfilled together. [I:!CHECK]
reverses the logic, the element is hidden if one of the conditions is not fulfilled.
In any case the input is written to the database together with the random number and a date/time stamp. So
you can see the wrong input in the database. The database entry is only made when the voucher has also been
printed.
96 12 Best practice examples
16 J
17 S l1; 0, 0, 68, 71, 100
18 H 150, 0
19
20 ; options: single buffer, 180° rotation, prohibit a reprint
21 O S, R, U
22
23 ; database connection to the file misc/Gutscheine.sqlite3
24 E SQLITE;Gutscheine
25
26 ; user query and random calculation of the character string
27 T:Wunschbetrag; 0, 0, 0, 3, 3;[?:Wunschbetrag eingeben,,,D,M111][I]
28 T:Zufall; 0, 0, 0, 3, 3;[ABC:Wunschbetrag][I]
29
30 ; create text string for plain text display of price
31 T:Hunderter; 0, 0, 0, 3, 3;[U:GS]einhundert[U:GS]zweihundert[U:GS]dreihundert[U:GS]…
vierhundert[U:GS]fünfhundert[I]
32 T:Zehner; 0, 0, 0, 3, 3;[U:GS]zehn[U:GS]zwanzig[U:GS]dreißig[U:GS]vierzig[U:GS]fü…
nfzig[U:GS]sechzig[U:GS]siebzig[U:GS]achtzig[U:GS]neunzig[I]
33
34 ; calculations
35 T:HUND1; 0, 0, 0, 3, 3;[/:Wunschbetrag,100][I]
36 T:HUND2; 0, 0, 0, 3, 3;[+:HUND1,1][I]
37 T:HTEXT; 0, 0, 0, 3, 3;[SPLIT:Hunderter,HUND2][I]
38
39 T:ZEHN1; 0, 0, 0, 3, 3;[%:Wunschbetrag,100][I]
40 T:ZEHN2; 0, 0, 0, 3, 3;[/:ZEHN1,10][I]
41 T:ZEHN3; 0, 0, 0, 3, 3;[+:ZEHN2,1][I]
42 T:ZTEXT; 0, 0, 0, 3, 3;[SPLIT:Zehner,ZEHN3][I]
43
44 ; checks
45 T:CHK1; 0, 0, 0, 3, 3;[>:Wunschbetrag,9][I]
46 T:CHK2; 0, 0, 0, 3, 3;[<:Wunschbetrag,501][I]
47 T:CHK3; 0, 0, 0, 3, 3;[%:Wunschbetrag,10][I]
48 T:CHK4; 0, 0, 0, 3, 3;[=:CHK3,0][I]
49 T:CHECK; 0, 0, 0, 3, 3;[*:CHK1,CHK2,CHK4][I]
50
51 T 20, 60, 35, 3, 15, b;UNGÜLTIG![I:CHECK]
52
53 ; layout
54 B 0, 5, 0, code128, 20, 0.4;[Zufall][J:c100][I:!CHECK]
55 T 0, 30, 0, 3, 6;[Zufall,1,4] [Zufall,5,4] [Zufall,9,4] [Zufall,13,4][J:c100][I:!…
CHECK]
56 T 0, 50, 0, 3, 12, b;[Wunschbetrag] [U:$20AC][J:c100][I:!CHECK]
57 T 0, 58, 0, 3, 4;In Worten [HTEXT][ZTEXT] Euro[J:c100][I:!CHECK]
58
59 ; filling the database
60 T:DAT; 0, 0, 0, 3, 3;[DATE][I]
61 T:TIM; 0, 0, 0, 3, 3;[TIME][I]
62 T 0, 0, 0, 5, pt10;[SQLLOG:INSERT INTO Gutscheine VALUES ('{DAT}','{TIM}','{Zufall…
}','{Wunschbetrag}')][I]
63
64 A 1
Listing 12.3: A voucher with plain text and barcode on it logged into a database � Coupon.lbl
12 Best practice examples 97
If you want to write the incorrect entries into a separate table, you can change the code. The example would
then end as in listing 12.4 (replaces the part from line 59 on). � Gutscheine.sqlite3
59 ; filling the database
60 T:DAT; 0, 0, 0, 3, 3;[DATE][I]
61 T:TIM; 0, 0, 0, 3, 3;[TIME][I]
62
63 T:CHECKIDX; 0, 0, 0, 3, 3;[+:CHECK,1][I]
64 T:Tabellen; 0, 0, 0, 3, 3;Fehleingaben[U:GS]Gutscheine[I]
65 T:wohindamit; 0, 0, 0, 3, 3;[SPLIT:Tabellen,CHECKIDX][I]
66
67 T 0, 0, 0, 5, pt10;[SQLLOG:INSERT INTO {wohindamit} VALUES ('{DAT}','{TIM}','{Zufall…
}','{Wunschbetrag}')][I]
68
69 A 1
Listing 12.4: Log incorrect entries in a separate table � FehlerGesondertLoggen.lbl
As a more complex example of programming with ABC, the import of a CSV file shall demonstrate it. The following
program (listing 12.5), stored as CSVPrinter.lbl in the labels directory of the printer’s default memory, will read a
CSV file, ignore the first line and then pass the twenty-first to twenty-fifth record as CSV using the JScript Replace
command and print the desired number of labels (here one label at a time).
1 <ABC>
2 REM Set parameters as a block of variables
3 CSV_Datei$ = "regional-averages-tm-year.csv"
4 Titelzeile = TRUE
5 Trenner$ = "|;,"
6 Layout$ = "CSV-Layout"
7 Anzahl = 1
8 von = 21
9 bis = 25
10
11 REM ------8<-----------------------------------------
12
13 REM load the layout
14 PRINT "M l LBL;" + Layout$
15
The program can be used universally. Only the first part with the parameters must be adapted. If you want to
print all records, you have to select 1 and 999999 (a number higher than the number of expected records) for von
and bis. All characters in the character string Trenner$ are exchanged by the character [GS] (Group Separator, for
the JScript special function [SPLIT:CSV,Index]).
The data of this example is provided by the German Weather Service and can be downloaded here:
https://opendata.dwd.de/climate_environment/CDC/regional_averages_DE/annual/
air_temperature_mean/
From there, load the CSV file “regional_averages_tm_year.txt” and change the file extension to “.csv” if you want
to reproduce the example.
Note that here all three characters from the Trenner$ parameter are replaced by a Group Separator. A CSV file
should therefore be read appropriately, in this case better that way:
5 Trenner$ = ";"
The layout was stored in the file CSV-Layout.lbl. It could look like this (listing 12.6).
12 Best practice examples 99
Figure 12.3: Annual average temperatures are read from a CSV file with climate data (source: Deutscher Wetterdienst).
� regional-averages-tm-year.csv
1 m m
2 J
3 S l1; 0, 0, 68, 71, 100
4 H 100, 0
5
6 ; get Data from csv file
7 T:CSV; 0, 0, 0, 3, 3;nix[I]
8
9 T 10, 15, 0, 5, 6;Jahresmitteltemperatur [SPLIT:CSV,1]
10 G 5, 17, 0;L: 90, 0.1
11
12 T 10, 25, 0, 3, 5;Niedersachsen
13 T 10, 30, 0, 3, 5;Thüringen
14 T 10, 35, 0, 3, 5;Baden-Württemberg
15 T 10, 40, 0, 3, 5;Bayern
16 T 10, 45, 0, 3, 5;Deutschland
17
18 T 70, 25, 0, 3, 5;[SPLIT:CSV,9]°C
19 T 70, 30, 0, 3, 5;[SPLIT:CSV,18]°C
20 T 70, 35, 0, 3, 5;[SPLIT:CSV,5]°C
21 T 70, 40, 0, 3, 5;[SPLIT:CSV,6]°C
22 T 70, 45, 0, 3, 5;[SPLIT:CSV,19]°C
Listing 12.6: In the layout the identifier CSV can be used to process the file from the source line by line. The SPLIT command leads to the
individual values. � CSV-Layout.lbl
100 13 Advanced BASIC Compiler
In addition to the JScript code, BASIC code can also be embedded. This code must be embedded between
the two lines <ABC> and </ABC>. The JScript interpreter then passes the abc code block as a whole to the
abc compiler. This will translate the code and run the generated program. The generated abc program
starts independently of the JScript interpreter as its own task. Execution start and speed are out of sync with
JScript.
You can only pass a single such code block. If a new code block is passed to the abc compiler while the old
BASIC program is still running, the newly passed code is initially only buffered. Only when an abc program is
terminated can new code be compiled from the buffer and brought to execution.
The BASIC language is not explained here. Ask your favorite search engine for BASIC tutorials and books, there
are plenty of them.
The abc BASIC used in cab printers is derived from Yabasic. A (admittedly not very beginner-friendly) guide to
Yabasic can be found on the net:
http://www.yabasic.de/yabasic.htm
If BASIC is used, you should not integrate JScript into the same label file, but embed the JScript code in the
BASIC program via the PRINT command. This is because it causes synchronization problems when pure JScript
code with an abc block is placed in a single file. The abc code usually takes a little longer to be compiled and
then executed. However, the timing cannot be predicted with certainty. If the JScript portion is sent from BASIC
via the PRINT command, it is clearly determined in the time sequence of the abc BASIC program when it is
executed.
Not only JScript allows to insert comment lines, also in abc BASIC you can make the program code readable
by comments for later maintenance. abc goes even further, allowing a line of other code to be commented
on by two slashes until the end of the line. Mixing command and comment in one line is not possible in
JScript.
If you want to insert a pure comment line use the REM command. The listing 13.1 shows the use of both comment
forms.
13 Advanced BASIC Compiler 101
The way from abc to JScript is quite simple. Just use the command PRINT and “print” into JScript.
From within the BASIC program, you can send a string to the JScript interpreter as a command line using the
PRINT command. The string is given without line end characters, the PRINT command automatically appends
the line end.
It should always be remembered that the timing of the processing of an embedded BASIC code is unpredictable
because the abc compiler and the JScript interpreter run independently of each other as separate processes in
the printer. The X2 motherboards still contained cab’s own monolithic architecture without multitasking. The
only process running was a continuous loop.
However, this disadvantage of the older systems (Linux was first introduced with the X3 motherboard) offered
predictability in the sequence of processing JScript and Advanced BASIC. This can lead to the fact that solutions
programmed for older systems can lead to problems on X4 mainboards today if JScript and BASIC are not
properly separated.
If a semicolon is appended to the PRINT command, the automatically appended <CR> Character omitted. Do
not forget to end the line with a PRINT command without a semicolon, otherwise you will get a non-executable
JScript code. An example shows the listing 13.5.
The IF statement can be used in abc to attach a command block to a condition. The condition must be followed by
the keyword THEN. The ELSE part is optional and is executed if the condition results in FALSE. The keyword ENDIF,
with which the construct must be terminated, is mandatory. ELSIF blocks can be inserted in between. Any number
of them is allowed. The listing 13.2 shows examples of conditional statements.
A condition is a logical expression enclosed in round brackets. The following symbols are available (table 13.1).
They have different values for determining the order. Comparison operators are evaluated before the logical op-
erators (similar to the “dot-before-dash rule” in calculations). Mathematical calculation operators are processed
before the comparison operators.
There is also a short form of the IF instruction. If you write the condition and the conditional command together
with the IF in only one line of code, you can do without THEN and ENDIF.
Several conditional statements are used in the listing 13.2. It should also be noted that abc BASIC makes a short
circuit for logical calculations. That is, if an AND statement results FALSE in the first argument, or an OR statement
results TRUE in the first argument, then all the following arguments are no longer evaluated. This behavior can
be seen in the listing 13.1
1 <ABC>
2 PRINT "J"
3 PRINT "S 0, 0, 68, 71, 100"
4 PRINT "H 100, 0"
5 PRINT "O R"
6
7 REM If the first element of an AND condition is false,
8 REM the second element won't be evaluated (logical shortcut).
9 PRINT "T 5, 30, 0, 3, 4;[J:c90]FALSE AND FALSE: ";
10 IF (falsch("with") AND falsch("out")) THEN
11 PRINT "** Oh no! **"; // This should never become visible ...
12 ENDIF
13 PRINT " short circuit"
14
15 REM The same happens to OR conditions,
16 REM if the first part is true.
17 PRINT "T 5, 40, 0, 3, 4;[J:c90]TRUE OR TRUE: ";
18 IF (richtig("with") OR richtig("out")) THEN
19 PRINT " short circuit"
20 ENDIF
21
22 PRINT "A 1"
23
30 SUB richtig(text$)
31 PRINT text$; // print the given text towards JScript
32 RETURN TRUE // and return TRUE for the logic evaluation
33 END SUB
34 </ABC>
Listing 13.1: abc is using logical shortcuts � LogicShortcut.lbl
You can also jump within a program. The GOTO command jumps to the position with a matching LABEL com-
mand, while the GOSUB command remembers the current position in the program and jumps back there when
the program hits the RETURN command. Both can be seen in the abc program in listing 13.2.
13 Advanced BASIC Compiler 103
1 <ABC>
2 OPEN #1, "/DEV/RAWIP", "r"
3 OPEN #2, "/DEV/RAWIP", "w"
4
5 DO
6 LINE INPUT #1 Eingabe$
7 IF (Eingabe$ = "exit") BREAK
8 GOSUB Antworte
9 LOOP
10
11 GOTO goodbye
12
13 LABEL Antworte
14 IF (Eingabe$ = "time") THEN
15 PRINT #2 TIME$
16 RETURN
17 ELSIF (Eingabe$ = "date") THEN
18 PRINT #2 DATE$
19 RETURN
20 ELSIF (Eingabe$ = "random") THEN
21 PRINT #2 STR$(RAN(100))
22 RETURN
23 ELSE
24 PRINT #2 "syntax error: ", Eingabe$
25 RETURN
26 ENDIF
27
28 LABEL goodbye
29 PRINT #2 "goodbye"
30 CLOSE #1
31 CLOSE #2
32 END
33 </ABC>
Listing 13.2: Conditional instructions and jumps. If you want to test the program, you need to start a Telnet session on port 9100 of the
printer. � IF-THEN.lbl
13.6 Loops
In BASIC there are various forms to repeat a code specifically. Implemented in the printer is a FOR/NEXT, DO/LOOP,
WHILE/WEND und REPEAT/UNTIL loop construction.
This example will print four labels with a serial number (listing 13.3)
You can exchange the example by this abc program (listing 13.4).
104 13 Advanced BASIC Compiler
1 m m
2 J
3 S l1;0,0,68,71,100
4 H 150,0
5 O R
6 T 40,40,0,5,20;[SER:1]
7 A 4
Listing 13.3: A label containing a serial number � JScript-SER.lbl
1 <ABC>
2 PRINT "m m"
3 FOR i = 1 TO 4 STEP 1
4 PRINT "J"
5 PRINT "S l1; 0, 0, 68, 71, 100"
6 PRINT "H 150, 0"
7 PRINT "O R"
8 PRINT "T 40, 40, 0, 5, 20;" + STR$(i)
9 PRINT "A 1"
10 NEXT
11 </ABC>
Listing 13.4: abc creates a serial number with a loop � abc-SER.lbl
A FOR loop must be completed with the NEXT command. The loop variable is first assigned to the start value. The
code between FOR and NEXT is repeated until the variable reaches the final value. The STEP command is optional
and specifies the increment. If you omit STEP, abc counts up with 1. Negative values count down. If the end value
is exceeded, the loop content will no longer be executed, see also the listing 13.5.
1 <ABC>
2 PRINT "m m"
3 PRINT "J"
4 PRINT "S l1; 0, 0, 68, 71, 100"
5 PRINT "H 150, 0"
6 PRINT "O R"
7
13.6.2 DO . . . LOOP
In a DO/LOOP loop the code is repeated endlessly within the loop. You can, however, break out of the loop with the
BREAK command. abc will continue with the code after the LOOP command in a BREAK command.
A continuous loop without end shows listing 13.6 (by pressing the red Cancel key on the display or pressing
Cancel on the Navigator Pad for at least three seconds on older printers, an abc program can be terminated at
any time).
1 <ABC>
2 OPEN #1,"/DEV/RS232","w"
3 OPEN #2,"/DEV/RAWIP","r"
4
5 DO
6 x = PEEK(#2)
7 IF (x <> -1) POKE #1,x
8 LOOP
9 </ABC>
Listing 13.6: Redirect the IP interface to the RS232 interface � IP-Umleiten.lbl
After the WHILE command a condition must be specified. This is similar to the IF command, except that the condi-
tion is directly followed by the loop block, without another command word like THEN or DO. When the loop block
is finished, the WEND command is used to inform the compiler of the end of the loop.
With a WHILE loop, it is also possible that the loop block is not executed at all if the condition already re-
sults in FALSE during the first check. As long as the condition results in TRUE the loop is executed repeatedly.
An example is reading files line by line. If a file has no content, then nothing is processed, as seen in list-
ing 13.7.
If a loop is to be run through at least once, the REPEAT UNTIL loop can be used to check the condition only after
a loop has been run through. However, the loop is executed again if the condition results in FALSE. Such a loop
can also be found in the listing 13.7. The two commands MOUSEX and MOUSEY return the numeric value -1 if the
display is not touched or the respective position if the display is touched.
Both the WHILE and the REPEAT loop can be replaced with a suitably designed DO loop if the IF (condition) BREAK
command is used in it to exit from the repetition.
13 Advanced BASIC Compiler 107
1 <ABC>
2 REM This program has to be started from
3 REM the printer's default storage memory!
4 OPEN #1,"/card/labels/WHILE.lbl","r"
5 OPEN WINDOW 272, 480
6 y = 0
7 POKE "lcd", 1
8
9 WHILE (NOT EOF(#1))
10 LINE INPUT #1 Zeile$
11 TEXT 0,y,Zeile$
12 y = y + 12
13 WEND
14
15 TEXT 65, 460, "*** PLEASE TOUCH ME! ***"
16
17 REPEAT
18 PAUSE 0.1
19 UNTIL (MOUSEX > -1)
20
21 POKE "lcd", 0
22 CLOSE WINDOW
23 </ABC>
Listing 13.7: A file reads itself and shows up on the display of a SQUIX or EOS printer. The command EOF(#1) indicates whether the end
of the file has been reached. � WHILE.lbl
When BASIC was invented, Structured Programming with encapsulated routines had not yet been thought of.
At that time BASIC was invented as a pure imperative programming language. Later, various dialects of the
language introduced structured programming through concepts such as encapsulated subroutines. This also
applies to abc. Also when programming cab printers you can define functions and call them in the program
using the function name followed by arguments in round brackets. A function can, but does not have to return a
value. The return from a function is done by the RETURN command, as with the GOSUB command. You can let
RETURN be followed by another value. This is then used as the function return value.
Note, however, that each variable is also defined globally within a subroutine. If you want to encapsulate a
variable in a function, you have to declare it once with the prefixed keyword LOCAL before using it. A variable
declared this way within a subroutine is not available outside the subroutine. If the subroutine is terminated, all
local variables are removed from the RAM again. If you want to keep a variable value over several calls, you must
use the STATIC keyword. Variables declared with STATIC are automatically also local variables, i.e. they are not
accessible outside the subroutine.
How locally declared variables leave the global variables untouched can be seen in the listing 13.8. If you use
subroutines, always make sure to declare all variables with LOCAL or STATIC. BASIC (and therefore abc) does not
pay attention to this detail. Otherwise you will get an error like in listing 13.9.
108 13 Advanced BASIC Compiler
1 <ABC>
2 REM global variables
3 a = 1
4 b = 2
5 c = 3
6
7 Test(a, b)
8
9 REM all variables inside the subroutine are local
10 SUB Test(b, c)
11 LOCAL a
12 a = 30
13 b = 40
14 c = 50
15 END SUB
16
17 PRINT "J"
18 PRINT "S l1; 0, 0, 68, 71, 100"
19 PRINT "H 100, 0"
20 PRINT "O R"
21 PRINT "T 10, 65, 0, 3, 20;", a, b, c
22 PRINT "A 1"
23 </ABC>
Listing 13.8: Variables that have been declared with LOCAL or passed as arguments are local in a subroutine, the output on the label is
“1 2 3”. � LOCAL.lbl
Figure 13.2: The listing 13.9 should originally produce ten rows with the numbers from 1 to 10. But four rows are missing, because the
global variable “i” is changed in the subroutine.
13 Advanced BASIC Compiler 109
1 <ABC>
2 PRINT "J"
3 PRINT "S l1; 0, 0, 68, 71, 100"
4 PRINT "H 100, 0"
5 PRINT "O R"
6
7 REM The first five rows are counted upwards by the global variable "y"
8 FOR y = 1 TO 5
9 Zahlenreihe(y, 10)
10 NEXT
11
12 REM division line on the label
13 PRINT "G 5, 31, 0;L:80,0.5"
14
15 REM "i" is used globally for the last five rows (underneath the division line)
16 FOR i = 1 TO 5
17 Zahlenreihe(i, 30)
18 NEXT
19
20 PRINT "A 1"
21
22 SUB Zahlenreihe(a, b)
23 FOR i = 1 TO 10 // ATTENTION: The variable "i" is still used globally!
24 PRINT "T " + STR$(5 * i) + "," + STR$(4 * a + b) + ",0,3,3;" + STR$(i)
25 NEXT
26 END SUB
27 </ABC>
Listing 13.9: Also a counter variable in a FOR/NEXT loop is global within a subroutine. For the exercise change the code so that ten rows
are printed. � Kapselung.lbl
The listing 13.10 is based on a lecture about bad programming style and the resulting program errors caused by
it. Here the subroutines access global variables and the names of the passed variables do not match the names
in the SUB( . . . ) definition. Who has to deal with such a code has after few minutes only spaghetti in the brain.
The listing 13.11 solves the same task in a more understandable way, even if the subroutine also accesses the
global array.
110 13 Advanced BASIC Compiler
1 <ABC>
2 REM global variables
3 DATA 45, 23, 34, 12
4 READ vinegar, oil, salt, pepper
5
1 <ABC>
2 REM global variables
3 DATA 45, 23, 34, 12
4 DIM Values(4) // four values stored into one global array
5 FOR i = 1 TO 4
6 READ Values(i)
7 NEXT
8
9 REM use a pointer to an array to manipulate a global array
10 SUB sortiere(a(),x,y)
11 LOCAL puffer // this variable exists only during a function call
12 IF (a(x) > a(y)) THEN // swap the two numbers in the related array
13 puffer = a(x)
14 a(x) = a(y)
15 a(y) = puffer
16 ENDIF
17 END SUB
18
19 REM Network Sort over four values
20 sortiere(Values(),1,3)
21 sortiere(Values(),2,4)
22 sortiere(Values(),1,2)
23 sortiere(Values(),3,4)
24 sortiere(Values(),2,3)
25
26 REM The JScript code is equal to the label "Salad.lbl"
27 PRINT "J"
28 PRINT "S l1; 0, 0, 68, 71, 100"
29 PRINT "H 100, 0"
30 PRINT "O R"
31 PRINT "T 10, 35, 0, 3, 10;";
32 FOR i = 1 TO 4
33 PRINT Values(i);
34 NEXT
35 PRINT // Don't forget the line ending character, or JScript will fail!
36 PRINT "A 1"
37 </ABC>
Listing 13.11: Does the same as listing 13.10 � NetworkSort.lbl
If one of the arguments passed to a function is an array where the round bracket remains empty, a pointer to
that array is passed to the function. The function then edits the global array under the name used locally in the
function definition. You can use this oddity to create more than one return value. For an example of an abc array
pointer, see listing 13.11.
In abc BASIC, a variable can represent a number or a string. Numbers have a simple variable name that must
begin with a letter and can only consist of letters and numbers. A distinction is made between upper case and
lower case. Here in this guide, variable names are always lower case and commands are capitalized. But you
112 13 Advanced BASIC Compiler
can also use abc commands in lower case. If a variable contains a string, a dollar sign must be appended to the
variable name.
You can also place multiple contents numbered in one variable. Such an entity is called array. The array must be
announced in size before first being used with the DIM command (declaration).
Here is an example (listing 13.12). The TOKEN command breaks down a string into multiple elements and writes
it to an array.
1 <ABC>
2 zahl = 42
3 antwort$ = "We have the solution for every challenge."
4 DIM a$(10)
5 anzahl = TOKEN(antwort$, a$(), " ")
6 IF (a$(4) = "solution") END
7 ERROR "Oh no, that went wrong!"
8 </ABC>
Listing 13.12: A meaningless BASIC program. If the abc symbol disappears from the display of the printer, the program has been
successfully executed. Change line 6 to get the error message from line 7 presented. � BASIC-Variablen.lbl
The SPLIT command requires a string to be split as the first argument. Then a pointer to an array must follow
(array name with dollar signs and empty brackets) that allows the SPLIT command to edit the array. The last
argument is expected to be a string with the separator characters.
The SPLIT command copies character by character from the string to the first element of the array. If it reads a
delimiter, it will not be transferred, but it will be switched to the next array element. At the end of the procedure,
you have one array element more than the string contains separator characters. The return value of the SPLIT
command is the number of elements generated in the array. If the array was previously too small with the DIM
command, the SPLIT command corrects the array size to fit it.
The TOKEN command works like the SPLIT command, but with the difference that no empty strings are created as
elements of the array. So you can’t say that TOKEN creates exactly one more element in the array than delimiters
exist. For clarity, see listing 13.13.
You can cut out a part of a string from it. For this purpose there are the commands LEFT$(string$, number),
RIGHT$(string$, number) and MID$(string$, position, number). If you omit the last parameter in the MID$ com-
mand, the string is returned or replaced from the position (second parameter) to the end.
The special thing about this is that you can also reassign parts of a string by using the function on the left side of
an assignment operation. The listing 13.14 shows how to use the MID$ function for a reassignment of a part of a
string. But be careful, the reassignment only works for replacements of equal length!
13 Advanced BASIC Compiler 113
Figure 13.3: With SPLIT you get one element more than separators are present in the string. TOKEN, on the other hand, doesn’t create
empty elements (listing 13.13).
Figure 13.4: With the software Packet Sender we send a line to the RAW-IP interface and receive an accordingly manipulated line as
response (listing 13.14).
114 13 Advanced BASIC Compiler
1 <ABC>
2 PRINT "J"
3 PRINT "S l1; 0, 0, 68, 71, 100"
4
5 DIM t$(1)
6 t = TOKEN("good boy", t$(), "o")
7 PRINT "T 10, 25, 0, 3, 5;TOKEN: ";
8 FOR i = 1 TO t
9 PRINT "|" + t$(i) + "| ";
10 NEXT
11 PRINT " = ", t, " Teile"
12
13 DIM s$(1)
14 s = SPLIT("good boy", s$(), "o")
15 PRINT "T 10, 50, 0, 3, 5;SPLIT: ";
16 FOR i = 1 TO s
17 PRINT "|" + s$(i) + "| ";
18 NEXT
19 PRINT " = ", s, " Teile"
20
Searches for the occurrence of a search pattern in a string and returns the position of the first occurrence. If you
do not want to search from left to right, you can use the RINSTR command. If the pattern is not found, the result
is 0 (numeric zero). If the string starts with the search pattern, the answer is 1.
The TRIM$(a$) command removes all spaces at the beginning and end of the a$ string. If you only want to remove
spaces at the beginning, you have to use the LTRIM$() command, for removing spaces at the end you can use the
RTRIM$() command. In the listing 13.16 this is used to make the constructed “LOAD” command more robust. So
you can use any number of spaces between “LOAD” and the file name.
There are more commands to process strings. For example, you can use LEN(a$) to get the length of the string
a$. With VAL(number$) you can convert the string number$ into a numeric value. The reverse is possible with
STR$(number). With UPPER(a$) you get a string of uppercase letters, with LOWER(a$) lowercase letters are
generated.
13 Advanced BASIC Compiler 115
1 <ABC>
2 OPEN #1, "/DEV/RAWIP", "r"
3 OPEN #2, "/DEV/RAWIP", "w"
4
5 REPEAT
6 LINE INPUT #1 Text$
7
8 REM we replace animal products with healthier alternatives (fruit salad)
9 pos = INSTR(Text$, "Schnitzel")
10 WHILE (pos > 0)
11 MID$(Text$, pos, 9) = "Obstsalat"
12 pos = INSTR(Text$, "Schnitzel")
13 WEND
14
15 PRINT #2 Text$
16 UNTIL (Text$ = "ende")
17 </ABC>
Listing 13.14: Send a line to the RAW-IP interface and look at the answer � BesserVegan.lbl
In abc you can use the command OPEN to read or write from the following interfaces:
• /dev/rs232:baud,handshake
• /dev/usb
• /dev/rawip
• /dev/lpr
• /dev/panel
• /dev/keyboard
• /dev/jscript
• /card/filename.ext
• /iffs/name.ext
• mailto:address
We are looking at an example which is often sent to a cab printer for diagnostic purposes (you already know it as
the 13.6 listing on page 106). It reads all incoming characters from /dev/rawip and sends them to /dev/rs232. So
you can listen to the IP interface on the RS232 interface. If you swap the two interfaces, you can also use a cab
printer to listen to an RS232 connection in the same way. If you mix the two, you can use the printer to access an
RS232 interface via port 9100 (listing 13.15).
116 13 Advanced BASIC Compiler
1 <ABC>
2 REM from IP interface to RS232
3 OPEN #1,"/DEV/RAWIP","r"
4 OPEN #2,"/DEV/RS232","w"
5
6 REM and vice versa
7 OPEN #3,"/DEV/RS232","r"
8 OPEN #4,"/DEV/RAWIP","w"
9
10 DO
11 // IP --> RS232
12 x = PEEK(#1)
13 IF (x <> -1) POKE #2,x
14 // RS232 --> IP
15 x = PEEK(#3)
16 IF (x <> -1) POKE #4,x
17 LOOP
18 </ABC>
Listing 13.15: Using a cab printer as a bridge between RS232 and ethernet. Probably clever, if you want to access a RS232
connected machine for diagnostics at a factory hall, where your modern laptop no longer have an interface to RS232.
� IP-RS232-Bridge.lbl
Sometimes a printer has to be integrated into an existing system that uses a completely different syntax than
JScript and whose rebuilding is not possible or only possible with great effort. Here we want to think of an
alternative dialect as an example. There are only four rules:
1. Each command has it’s own line of code.
2. If the line starts with LOAD, a filename has to follow.
3. Filling fields (variables) by using the equation sign.
4. If a line starts with PRINT, the number of labels has to follow.
We will open the RAW IP interface and listen to the incoming data. If we can convert the incoming code, we send
it as JScript code with abc’s PRINT command.
13 Advanced BASIC Compiler 117
1 <ABC>
2 OPEN #1, "/dev/rawip", "r"
3
4 DO
5 LINE INPUT #1 Zeile$
6
7 REM load layout
8 IF (UPPER$(LEFT$(Zeile$, 5)) = "LOAD ") THEN
9 PRINT "M l LBL;" + TRIM$(MID$(Zeile$, 6))
10 ENDIF
11
12 REM replace field values
13 pos = INSTR(Zeile$, "=")
14 IF (pos > 0) THEN
15 PRINT "R " + LEFT$(Zeile$, pos-1) + ";" + MID$(Zeile$, pos+1)
16 ENDIF
17
18 REM print the right among of labels
19 IF (UPPER$(LEFT$(Zeile$, 6)) = "PRINT ") THEN
20 PRINT "A " + MID$(Zeile$, 7)
21 ENDIF
22 LOOP
23 </ABC>
Listing 13.16: Parsing an unknown stream of data using BASIC logic. � Parser.lbl
1 LOAD LayoutVorlage
2 PARTNO=5977008
3 PROD=SQUIX 4/600MP
4 RESOL=600 dpi
5 SERNR=164162038304
6 PRINT 1
Listing 13.17: Thanks to the parser we can send this code directly to the printer. � Alternativsyntax.lbl
The printer display can also be used by abc. For this purpose, a suitable part of the RAM must first be reserved,
which is done with the command OPEN WINDOW. The arguments of the command are the number of pixels in X
and Y direction. With a SQUIX we control a 272 x 480 pixel display.
After that the bitmap can be edited in memory until we delete it from RAM with CLOSE WINDOW. The command
POKE “lcd” switches between the display of the standard controls and the abc bitmap, 1 is for the bitmap, with 0
the controls are displayed again.
You can only write into the bitmap. After creation it is completely filled in white. With the command POKE “bcolor”
a background color can be defined. But only as an index from 0 (always black) to 255 (always white). Which color
is hidden behind the index can be defined with the POKE “color#num”, where for num a number from 1 to 254 is
allowed.
The listing 13.18 shows the commands for graphical output with abc.
118 13 Advanced BASIC Compiler
The command TEXT can be used to output a text at the coordinates X, Y. In contrast to JScript, the upper left
corner is used here, not the baseline. With the FONT command you can select a font, e.g. “Swiss” or “Swiss
Bold”, followed by the height in display pixels. If a TrueType font is to be used, it must be located in the printer’s
RAM. Since there is no font load command, we leave this task to JScript, as shown in the example of the 13.18
listing.
1 <ABC>
2 REM Let JScript load the font Indie Flower into RAM
3 PRINT "M l FNT;IndieFlower-Regular"
4
5 REM Assign a part of the RAM for a bitmap of the printer screen
6 OPEN WINDOW 272, 480
7
8 REM background color set to black
9 POKE "bcolor", 1
10
As another example, the listing 13.19 will show a parser that uses values from the already known CSV file from
the practical example on page 99 (section 12.3).
These are annual mean temperatures from 1881 to today, published by the German Weather Service (the file
“regional_averages_tm_year.txt” must be placed in the /misc sub directory of the printer and the file extension
must be changed to .csv):
13 Advanced BASIC Compiler 119
https://opendata.dwd.de/climate_environment/CDC/regional_averages_DE/annual/
air_temperature_mean/
The abc program uses the possibility to show a bitmap not only as a display on the printer’s screen, but also to
transfer it to a JScript graphic in the RAM via the WINDOW TRANSFER command. JScript can then easily transfer
the bitmap into a label using the I command (Image). However, you should note that within the abc bitmap, the
coordinate system starts in the upper left corner and positive X values point to the right and positive Y values
point to the bottom.
You could use PEEK(“resolution”) to determine the printer resolution and create the usable pixels or a conversion
factor for millimeters yourself. Here, however, it is only about a temperature trend without any scale. The focus
is on the possibility to create a graphic in abc and use it in JScript.
On the other hand the example shows how to create a selection list in abc and display it in JScript. You get a value
back using the JGET$/JPUT combination. Since you use the special function SELECT, you have to finish the label
with A [PREVIEW] without printing it, otherwise the selection will not be displayed.
After that you have to rebuild the label. In the first label, which is not to be printed, the size was intentionally
chosen small to show that an S command is required, but the exact dimensions are irrelevant if you only need
the result of a screen dialog.
1 <ABC>
2 OPEN #1, "regional-averages-tm-year.csv", "r"
3
4 REM The first line contains only remarks and is skipped
5 LINE INPUT #1 Zeile$
6
7 REM We create a fictitious label to fetch a value from JScript
8 DIM Bundesland$(1)
9 LINE INPUT #1 Zeile$
10 Anzahl = SPLIT(Zeile$, Bundesland$(), ";")
11
37 DIM Werte$(1)
38 NEW CURVE
39 DO
40 LINE INPUT #1 Zeile$
41 Anzahl = SPLIT(Zeile$, Werte$(), ";")
42 IF (Anzahl < Auswahl) BREAK
43 REM The coordinate origin is at the top left
44 x = (VAL(Werte$(1)) - 1880) * 5
45 y = 600 - VAL(TRIM$(Werte$(Auswahl))) * 50
46 LINE TO x, y
47 LOOP
48
49 REM Store it directly into RAM as a JScript image
50 WINDOW TRANSFER TO "Temperaturen"
51 CLOSE WINDOW
52
53 REM Finally print the actual label
54 PRINT "J"
55 PRINT "S l1; 0, 0, 68, 71, 100"
56 PRINT "H 50, 0"
57 PRINT "O S"
58 PRINT "T 5, 10, 0, 3, 5;" + Bundesland$(Auswahl)
59
60 PRINT "I 5, 15, 0;Temperaturen"
61 PRINT "A 1"
62
63 CLOSE #1
64 </ABC>
Listing 13.19: This selection dialog can only be performed on the newer printers with an X4 motherboard. It has only become possible
with the touch display and its user interface. � Temperaturverlauf.lbl
It is relatively easy to draw a rectangle. To do this, use the RECT command, followed by the coordinates of two
opposite corners of the rectangle.
RECT x1, y1, x2, y2
As a result, a rectangle is drawn. You can’t influence the pen width, it’s always one pixel wide. The rectangle can
be filled out. Preceding the FILL command fills it with the foreground color, CLEAR fills it with the background
color.
If a line is to be drawn instead of a rectangle, it must be initiated with the NEW CURVE command. The individual
points of the line strokes are then defined with LINE TO x, y Unlike Yabasic, however, abc BASIC does not have a
CLOSE CURVE command. You must return to the first point by yourself, and you cannot fill the resulting surface.
The CIRCLE and TRIANGLE commands are also not available.
The use of the RECT and LINE TO commands shows listing 13.20.
13 Advanced BASIC Compiler 121
Figure 13.5: The listing 13.20 creates five buildings on the display and waits for a touch input.
122 13 Advanced BASIC Compiler
1 <ABC>
2 OPEN WINDOW 272, 480
3 POKE "bcolor", 0 // 0 = black, 255 = white
4 CLEAR WINDOW
5 POKE "lcd", 1
6
7 FOR wdh = 1 TO 5
8 REM By default all colors are grayscaled
9 POKE "fcolor", 100 + RAN(155)
10 Hausbau(RAN(200), RAN(380))
11 NEXT
12
13 POKE "fcolor", 200
14 FONT "Swiss721,25"
15 TEXT 10, 440, "Touch display to quit!"
16 REPEAT PAUSE 0.02 UNTIL (MOUSEX>-1)
17 POKE "lcd", 0
18 CLOSE WINDOW
19 END
20
If you have a graphic in PNG format that has transparency information (an alpha channel), an X4 printer (SQUIX
or newer) can process this transparency. We will look at this in an example. The listing 13.21 loads two graphics
into the abc window (lines 4 and 5). Actually row 5 would overwrite the graphic from row 4, but the file has a
transparency, so both will mix in the display.
The rest of the program is relatively simple, it opens the RAW-IP interface for reading, and everything sent to
this interface is output to the display instead of being processed by the JScript interpreter. So it’s a kind of
monitor mode without labels to print on. If the text reaches the bottom of the display, the display is erased
again and reassembled from the two graphics. The incoming text is displayed line by line starting from the top
again.
13 Advanced BASIC Compiler 123
Figure 13.6: The stethoscope merges with the background using transparency (listing 13.21)
� SQUIX-background.png � Stethoskop.png
Interesting about listing 13.21 is also line 8. The POKE command causes the abc window to appear on the display,
36 pixels down. This keeps the upper toolbar visible (see figure 13.6). Besides the vertical offset lcdy there is also
lcdx available for a horizontal offset.
124 13 Advanced BASIC Compiler
1 <ABC>
2 REM abc window with transparent background logo
3 OPEN WINDOW 272,444
4 WINDOW READ FROM "SQUIX-background"
5 WINDOW READ FROM "Stethoskop"
6 FONT "Monospace,16"
7 POKE "fcolor", 255
8 POKE "lcdy", 36
9 POKE "lcd", 1
10
11 REM listen to input stream
12 OPEN #1, "/dev/rawip", "r"
13
14 position = 20
15 DO
16 LINE INPUT #1 Zeile$
17 REPEAT
18 position = position + 14
19 IF (position > 430) THEN
20 position = 34
21 CLEAR WINDOW
22 WINDOW READ FROM "SQUIX-background"
23 WINDOW READ FROM "Stethoskop"
24 ENDIF
25 TEXT 2, position, LEFT$(Zeile$, 27)
26 Zeile$ = MID$(Zeile$, 28)
27 UNTIL (Zeile$ = "")
28 IF (MOUSEX > -1) BREAK
29 LOOP
30 </ABC>
Listing 13.21: The inputs to the RAW-IP interface are written line by line to the display. The logo from line 5 is transparent so that it
merges with the graphic below. � RAWIP2Display.lbl
A cab printer with a X4 motherboard (SQUIX series or newer) has not only a color display for a graphical user
interface, but also a resistive touch sensor. This makes it possible to detect keystrokes on the display. In abc
BASIC the touch sensor is represented in the two commands MOUSEX and MOUSEY. If the screen is not touched,
both have the value -1. If pressure is applied to the display, the two commands return the respective coordinates
of the pressure point.
Try it, the listing 13.22 creates a polyline from the pressure points by using the two commands MOUSEX and
MOUSEY. Do you manage to draw a house of Santa Claus? Compared to a capacitive touch screen, a resistive
sensor can also be controlled with a glove. Multiple finger gestures like on a smartphone are not necessary on
the display of a printer, so it is not a big deal that a resistive sensor can’t handle it.
The request of the mouse position is sent internally via bus to the display driver. In order not to flood the driver
unnecessarily, the request should only be sent again after a pause of 20 ms or longer.
13 Advanced BASIC Compiler 125
1 <ABC>
2 REM Open graphical display and show message
3 OPEN WINDOW 272, 480
4 POKE "fcolor", 0 // black
5 FILL RECT 0, 440, 272, 480
6 TEXT 5, 5, "Draw the Nikolaus puzzle by touching the screen!"
7 POKE "fcolor", 255 // white
8 FONT "Monospace,20"
9 TEXT 110, 450, "QUIT"
10
11 REM set up drawing color and switch to abc screen
12 POKE "color#1", DEC("0000FF") // blue
13 POKE "fcolor", 1
14 POKE "lcd", 1
15
Important with examples like a parser is that abc in a DO … LOOP continuous loop has to work. An abc symbol is
shown in the printer display during this time. The execution can be terminated by pressing the Cancel icon (or
button on older printers).
So far, we have only ever learned about the interaction between JScript and abc in one direction. From abc,
which should work as far as possible without inparallel processing JScript code, JScript lines are sent to the
interpreter with the command PRINT.
But there is another way to interact. Values can be passed to an abc program working in the background and the
return value is transferred to the JScript interpreter with the special function [ABC:]
126 13 Advanced BASIC Compiler
Now one could assume that the first parameter is a function name, followed by the arguments to be passed to
the function. The value returned by the BASIC command RETURN is then included in the contents of the JScript
line as the result of the special function.
This could look like listing 13.23.
1 <ABC>
2 SUB Umklammern$(Text$)
3 RETURN "<" + Text$ + ">"
4 END SUB
5 </ABC>
6 J
7 S e;0,0,30,32,100
8 H 100,0,T
9 O S
10 T:text;10,10,0,3,5;[SER:1]
11 ; Nice, but this dream will never become true!
12 T 10,20,0,3,5;[ABC:Umklammern$,text]
13 A 5
Listing 13.23: Calling a BASIC sub routine directly from JScript isn’t allowed
Unfortunately, it doesn’t work that way because we have a thinking error in this example. abc is a BASIC
compiler, not an interpreter. It is not possible for the JScript interpreter to jump into the abc code and execute a
subroutine.
So we have to create an abc program ourselves that is constantly looking in the background that data is submitted
by the JScript interpreter. In concrete terms, this is done as in a listing 13.24.
1 <ABC>
2 POKE "bypass", 1
3 DO
4 REPEAT
5 a$ = JGET$
6 UNTIL (a$ <> "")
7 JPUT "<" + a$ + ">"
8 LOOP
9 </ABC>
10
11 J
12 S e;0,0,30,32,1000
13 H 100,0,T
14 O S
15 T:text;10,10,0,3,5;[SER:1]
16 T 10,20,0,3,5;[ABC:text]
17 A 5
Listing 13.24: Interact with JGET$ and JPUT � JGET-JPUT-Zusammenspiel.lbl
13 Advanced BASIC Compiler 127
There is a function JGET$, which reads the input buffer, which is filled by the JScript special function [ABC:]. After
passing the parameter to the buffer, the JScript interpreter stops until a return value is received via the abc function
JPUT. Then the JScript interpreter continues its work and uses this return value.
The only parameter allowed for the special function [ABC:] is a field identifier. In this example text.
The use of this special function is also only allowed once. It is not possible to calculate several values or even to
use different calculation functions.
Error handling in abc BASIC is only possible in a very simplified way. There is the command ERROR to abort
the program with an error message. The abort corresponds to a complete reset, which also clears the JScript
buffer. After the ERROR command a character string must follow, that is shown in the printer display. The printer
automatically adds the line number from which the command was called.
Please note that the abc BASIC compiler only receives and numbers the lines after a <ABC> and before the
closing </ABC> from the JScript interpreter. In the example from listing 13.25, line 8 is mentioned at the printer.
It is the eighth line received by the abc BASIC compiler, but line 9 in the JScript code. The resulting message on
the printer touchscreen is shown in figure 13.7.
Figure 13.7: The abc command ERROR forces an error message onto the display
128 13 Advanced BASIC Compiler
1 <ABC>
2 POKE "bypass",1
3 DO
4 REPEAT
5 a$ = JGET$
6 UNTIL (a$ <> "")
7 a = VAL(a$)
8 IF (a = 0) THEN
9 ERROR "Division durch Null!"
10 ENDIF
11 b$ = STR$(1/a)
12 JPUT b$
13 LOOP
14 </ABC>
15
16 J
17 S l1; 0, 0, 68, 71, 100
18 H 100, 0, T
19 O R, S
20 T:Zahl; 10, 10, 0, 3, 5;[SER:5,-1][I]
21 T 10, 20, 0, 3, 5;1 / [Zahl] = [ABC:Zahl]
22 A 10
Listing 13.25: Forcing the printer to stop and display an error message � ERROR.lbl
14 Appendix 129
14 Appendix
The appendix lists some useful tables, sorted by topic. Use the appendix to this guide to look up and support
your thoughts. This is not a complete collection. For a complete listing, please refer to the programming
manual.
You can find the manual on the cab website:
https://cab.de/en/programming
The following tables show the JScript commands of a typical label. Optional parameters are printed in italics
and can be omitted.
The two commands J and A have been omitted. A can also have [PREVIEW] instead of a concrete number as
a parameter, in which case the label is not printed but internally processed as a bitmap. In addition, since
firmware 5.20 you can also give the A command a field name in square brackets as a parameter, then the number
is taken from this “variable”.
The tables are taken from the programming manual, some of them are shortened. In the title line of the tables,
the syntax of the programming manual is used. Optional parameters, which can also be omitted, are enclosed in
curly brackets. You must not use the curly brackets in JScript code, they only indicate what you may omit. If the
brackets include several parameters, they can only be used together or not at all.
For better readability, spaces were used in the syntax representation, which should not be used in the JScript
code. A closing semicolon must not be followed by a space, because immediately after the last semicolon in a
JScript command line follows the content of the text, barcode or the name of a file. If there is a space between
the semicolon and the file name, the file will not be found. Spaces before text move the text by the spaces and
barcodes are corrupted in their content.
130 14 Appendix
20
No return transport is not completely correct, within the print order “is printed” if the next label is already known.
132 14 Appendix
You can find an example in the section 4.3.5 Barcodes on page 37. Please refer to the programming manual for
the exact syntax. There you will find the information on all codes on over 100 pages, which would go far beyond
the scope of these instructions.
The autoload option simplifies the use of a graphic. Normally, the graphic would first have to be loaded into the
RAM so that it can then be positioned using the I command. With this original syntax, the parameters mx and my
are optional.
M l IMG;Logo
I 10,10,0;Logo
Circles (as well as lines or rectangles) can contain other options. For a complete overview, it is worth taking
a look at the programming manual. In the section 4.3.8 Graphical elements (circles, lines and rectangles) on
page 43 you will find an example for the creative use of circles and ellipses including one Shading as an additional
option.
14 Appendix 135
Example:
T 20,50,0,3,4;Mindestens haltbar bis: [MONTH02:0,6]/[YYYY:0,6]
Generates a text with a date in the format “02/2021”, calculated with an offset of 6 months in the font Swiss 721 Reg-
ular with 4 mm font size. The value 02/2021 would have been e.g. calculated on 08/20/2020.
A positive date or time offset always points to the future. Negative values are possible to calculate in the
past.
136 14 Appendix
The following are some examples of queries in standalone mode. The queries are to be written as special
functions in the content of a text or barcode line.
Prompts for the Artikelnr: and sets the value 7733214 for the next 3 labels to be printed. After that, the input is
cleared, which only appears the first time it is called:
[?:Artikelnr:,7733214,3,D]
Prompts for the Artikelnr: with the preset value of Schraube. The maximum length of the input here is 8
characters:
[?:Artikelnr:,Schraube,,L8]
Asks for the number with the preset value 7733214 and masks the input for purely numeric values:
[?:Nummer,7733214,,M1111111]
Prompts for ArtNr? and allows 3 digits and 4 capital letters during input:
[?:ArtNr?,,1,M1114444]
Prompts for Article? with no preset value, input limited to 7 characters and repeat query if database entry is not
found:
[?:Artikel?,,1,M1111111,R,D]
Prompts for Article? with preset value 22003 and masks the input for 5 digits without spaces:
138 14 Appendix
[?:Artikel?,22003,,,L5,M!11111]
When the label is finished, displays the prompt again until the print job is terminated by Cancel.
If you send Esc s to the printer, you get a 9 character status back. The second character is the error code. The error
code should always be a “-” (minus character), that indicates we have no error at all.
The exercises in this manual are used in the JScript training putting what you have learned into practice. We
have not printed all exercises from the training in this manual and have not published a solution for all exercises.
If you have any questions about individual exercises or sections of this manual, please contact our training or
support team by e-mail or phone. You can find the contact details on our website.
https://www.cab.de/en/information/contact/
Now apparently 6 labels are printed. But this is not quite correct. If you specify a label height to the printer
with the label size command, no attention is paid to gaps during this distance. So the printer passes the
gap by the label height that is 20 mm too long and only then starts to search for the next label. You can
easily try this. Add the following line before the line “A 3” (even if the contents may not mean anything to
you):
T 5, 5, 0, 3, 3;Hello World!
You can now see that in fact every second label is skipped without being printed. There are three labels,
but the height was given wrong.
1 m m
2 J
3 ; The training labels are 100 mm wide and 68 mm high
4 S l1; 0, 0, 68, 71, 100
5 ; Because of the rotation, the base point must be 7 mm from the edge
6 T 7, 65, 29, 3, 19, n;Fritz Fischer
7 A 1
Listing 15.1: Texts can also be printed crossways � Quername.lbl
15 Solutions to some exercises 141
6 J
7 S l1; 0, 0, 30, 33, 100
8
9 ; assign font no. 13
10 F 13;Indie Flower
11
7 ; query dialog
8 T:Gesamt;0,0,0,3,3;[?:Anzahl Packstücke?,20][I]
9 T:JeKarton;0,0,0,3,3;[?:Stücke je Karton?,5][I]
10
11 ; define counter
12 T:KartonNr;0,0,0,3,3;[SER:00000,1,2][I]
13
14 ; do the calculation
15 T:Hilfsvariable;0,0,0,3,3;[*:KartonNr,JeKarton][D:1,0][I]
16 T:VON;0,0,0,3,3;[+:Hilfsvariable,1][D:1,0][I]
17 T:BIS;0,0,0,3,3;[+:Hilfsvariable,JeKarton][D:1,0][I]
18
To calculate with integers, the special function [D:1,0] was added after each calculation, which
formats the result with at least one digit before but no decimal place. The solution thus found always
works if the number of units per box is an integer divisor of the total number, i.e., the last box can be filled
completely. With the code, test packing 17 pieces at 4 pieces per box. Better would be (the first 13 lines
are identical):
We can start here and provide line 16 with more decimal places accordingly.
16 T:Einzelpreis; 0, 0, 0, 3, 3;[I][/:GPZG,AnzahlZG][D:1,8]
15 Solutions to some exercises 145
It becomes more complicated with the automatic font size adjustment. Here (within the scope of this
manual) only a single distinction between two sizes is to be made in order not to make the process too
complex. The first 18 lines are identical to the previous solution.
19 ; logic for shortening the name (string comparison)
20 T:Kürzen;0,0,0,3,3;[==:Anonym,ja][I]
21 T:Namensliste;0,0,0,3,3;[Vorname] [Name][U:GS][Vorname] [Name,1,1].[I]
22 T:Namenswahl;0,0,0,3,3;[+:Kürzen,1][I]
23
24 ; generate start number
25 T:AlteNummer;0,0,0,3,3;[RUSER][I]
26 T:Startnummer;0,0,0,3,3;[+:1,AlteNummer][D:1,0][WUSER][I]
27
28 ; write data into log file
29 T 0,0,0,3,3;[Startnummer],[Vorname],[Name],[Straße],[HNR],[PLZ],[Ort],[DATE],[TIME…
][WLOG][I]
30
31 ; is there enough space for font height 10 (max. 22 characters)?
32 T:VollerName;0,0,0,3,3;[SPLIT:Namensliste,Namenswahl][I]
33 T:Zeichenlänge;0,0,0,3,3;[LEN:VollerName][I]
34 T:ZuLang;0,0,0,3,3;[>:Zeichenlänge,22][I]
35
36 ; print the label (compress names to 85% or 50% character width)
37 T 0,20,0,3,10,q85;[VollerName][J:c100][I:ZuLang]
38 T 0,20,0,3,8,q50;[VollerName][J:c100][I:!ZuLang]
39 T 0,55,0,5,40;[Startnummer][J:c100]
40
41 ; repeat in an infinite loop, reloading this JScript file
42 A 1
43 M r
Listing 15.9: Extended version of the donation run label � SpendenlaufPRO.lbl
The decisive factor is that only one conditional visibility can be used per text element. Therefore, both
decisions (last name shortened and string length) must be combined to one decision about the font
height. For this purpose, a list is generated which contains both the full name and the anonymized name.
The evaluation of the user input (field name “Anonym”) is then used to access the first or second element
of the list.
147