SlideShare a Scribd company logo
Arbortext Command Language
(ACL) Basics
Clay Helberg
The MathWorks
Arbortext Command Language (ACL)
• ACL is a scripting language embedded in Arbortext
Editor
• Provides ways to:
– Control the software
– Make dialogs work
– Navigate and manipulate documents
– Interface with other software components (e.g.
Publishing Engine, Dynamic Link Manager, Content
Manager, etc.)
– Interact with user
Arbortext Command Language (ACL)
• Basic syntax
• Variables and arrays
• Defining and using functions
• Working with files and documents
• Modifying the content of documents
• Using callbacks and hooks to handle events
• Integrating ACL scripts into your application
Basic Syntax
• ACL is sort of Perl-ish, sort of C-ish
– Like Perl, without the “line noise”
– Like C, without the pointer arithmetic and memory
management
• Statements are the fundamental steps in a
program
– Two types of statements: commands and functions
ACL Commands
• Commands use syntax like this:
commandname argument argument …
• Commands don’t return a value
• BUT May store information in system variables
about error status, etc.
• Example:
print composed current
ACL Functions
• Functions use syntax like this:
functionname ( argument, argument, …)
• Functions often, but not always, return a value
– Result of calculation or transformation
– Status of operation (success/failure)
• Example:
if (doc_name(doc)==“foo.xml”) …
ACL Functions
• Gotcha: Return value vs. updated parameter
– Example:
Global $windows[]
$return = window_list($windows);
– $return is number indicating status (number of
windows), not the list itself
– The actual list (array) of windows is stored in $windows
ACL Comments
• Comments start with a hash #
• Everything after the hash is ignored
# This function is really cool
function reallyCoolFunction(input) {
# do some really cool stuff here
}
• You can stick a comment at the end of a line after
some “real” code
if (oid_type($oid) == 4) { # type 4 -> equation
ACL Blocks
• A block is a section of a program that is a
cohesive unit
• Delimited with curly braces { }
• Examples:
– Function definitions
– The branches of if/else statements
– The guts of while and for loops
ACL Flow Control
• The usual flow control structures are supported
– for loops
for (i=1; i < count($arr); i++) {
doc_close($arr[i]);
}
– while loops
find “Leno”
while ($status == 0) {
delete_mark;
insert_string “O’Brien”
find “Leno”
}
More ACL Flow Control
– if/else branches
if ($size == “legal”) {
set stylesheet=“legal.style”
}
else {
set stylesheet=“letter.style”
}
Still more flow control
– switch trees:
$resp = response(“Save Changes?”,”Yes”,”No”,”Cancel”);
switch ($resp) {
case 1:
doc_save(current_doc());
break;
case 2:
set modified=off;
doc_close(current_doc());
break;
case 3:
# do nothing
}
ACL Packages
• Analogous to Java or Perl packages
• Similar to namespaces in XML
package log;
global $errlog = “C:tempapterr.txt”;
function error(msg) {
local $fid = open($log::errlog,a);
put($fid, “*** ERROR: $msgn”);
flush($fid);
close($fid);
}
Using Packages
• Use require to import a package’s code
• Use package::functionname to call a function in
another package
package custom;
require log;
function load_doc(docname) {
local $docid = doc_open(docname);
if ($docid == -1) {
log::error(“Couldn’t open $docname”);
}
}
ACL Variables
• Variables in ACL are dynamically typed
– Automatically assumes the required type for the value
• Name is sometimes preceded with a $ like Perl
(optional)
– But arrays are NOT preceded with an @
• You can define scope with local and global
keywords
– Default is local scope
– Local variables are only accessible in the block in which
they are declared (e.g. inside a function)
– Global variables are accessible anywhere
Assigning Values to Variables
• Assign values using the assignment operator =
– $mydoc = “C:tempmydocsmydoc.xml”;
• You can use expressions in assignment
– $mydoc = current_doc();
– $mypath = dirname(doc_path(current_doc()));
Assigning Values to Variables
• You can also use shortcut assignment operators
– $linecount += 1;
– $product *= get_multiplier();
• Use . (dot) operator for string concatenation
– $msg = “Do you want to close “ . doc_name() . “?”;
ACL Variable Evaluation
• Variables are evaluated
– Variable references inside double quotes are evaluated
• $docname = “foo.xml”;
• $msg = “Close $docname?”
# returns “Close foo.xml?”
– References inside single quotes are not
• $msg = ‘Close $docname?’
# returns “Close $docname?”
Deferred Evaluation of Variables
• Gotcha: In commands, you may need to defer
evaluation
– Ex: (wrong way – prints first doc repeatedly)
for ($i in $doclist) {
print composed $doclist[$i];
}
• Use execute or eval commands to defer
– Ex: (right way – prints each document once)
for ($i in $doclist) {
execute(“print composed $doclist[$i]”);
}
ACL Arrays
• ACL supports two kinds of arrays
– Normal arrays, indexed by number
$array[1] = “foo”
– Associative arrays, indexed by key
$array[“foo”] = “bar”
• Gotcha: ACL arrays are indexed from one, not
zero
Declaring ACL Arrays
• Both types have the same declaration syntax:
– [local | global] $arrayname[];
• Most arrays resize dynamically as necessary
– Unless declared using global and a fixed size
• global $myarray[10];
• Use square brackets [] to access array elements
– $msg = “the first element is $myarray[1]”;
– $msg = “owner of $docname is $owners[$docname]”;
Using ACL Arrays
• You can iterate over items in an array using
for (… in …) construction
– for ($i in $myarray) {
if ($myarray[$i]==doc_name()) {
response(doc_name() . “ is in array”);
break;
}
}
• This works for both types of arrays
• Gotcha: Loop index is the array index, not the
array value for that index
ACL Built-in Functions
• ACL has a wide variety of built-in functions
User-Defined Functions in ACL
• You can define your own functions
– function functionname(param1, param2) {
# do some stuff here
return result of operation;
}
• Example:
– function doc_dir(doc) {
local $docname = doc_name(doc);
return dirname($docname);
}
Forward Declarations
• In an ACL file, you often have multiple function
definitions
• A function can’t use another function if it hasn’t
been defined yet
Why You Need Forward Declarations
• This will fail:
function launch_browser(filename) {
local $url = file_to_url(filename);
system(“start $url”);
}
function file_to_url(filename) {
gsub(filename,””,”/”);
return("http://". filename);
}
• We try to use file_to_url() before it is defined
How to Write a Forward Declaration
• Forward declaration is an empty function definition
at the top of the file
• Lets other functions know that you're going to
define the function later
Forward Declaration Example
• This will work because of the forward declaration:
function file_to_url() {}; # forward decl
function launch_browser(filename) {
local $url = file_to_url(filename);
system(“start $url”);
}
function file_to_url(filename) {
gsub(filename,””,”/”);
return("http://". filename);
}
A Brief Tour of Built-In Functions
• Arbortext provides a ton of built-in functions for
various purposes
• We'll look at some of the most useful categories
– document and file handling
– document content manipulation
– user interaction
• For more information see the online help
– ACL reference in online help is very complete
– If you don't know what it's called, try search
– If you still can't find it, try Adepters email!
Working with Files and Documents
• current_doc() - gets a handle (ID number) for the
currently active document
• doc_open() - loads a document
– flags determine whether it's opened as XML or ASCII,
whether context checking happens, etc.
• doc_name() - filename of the document
• doc_path() - fully-qualified pathname of the doc
• doc_incomplete() - tells whether doc is valid
• doc_save() - saves the document
• edit_new_window() - opens document in a new
edit window
Working with Generic Files
• open() - open an arbitrary file for reading and/or
writing (e.g. for logging messages or importing
text content into a document)
• read() - read from a file
• getline() - read from a file one line at a time
• put() - write content to a file
• close() - close a file
General File System Info
• glob() - fills an array with names of files that
match the globbing expression (e.g. "*.xml")
• file_directory() - tells whether specified filename is
really a directory
• file_size() - size of the file
• file_newer() - determines if one file is newer than
another
• username() - user name string (from OS)
• system() - execute an arbitrary system command
• file_selector() - starts a standard file selection
dialog, returning the user's choice
Modifying Document Contents
• The OID is your friend (Object ID)
– Unique ID for each element in the document
– Can be used to find, access, change, or delete markup
• oid_root() - the root element of the doc
• oid_name() - the name of the specified element
• oid_caret() - the element containing the caret
• oid_attr() - gets the value of the specified
attribute on the specified element
• oid_content() - returns the content of the element
as a markup string
Moving Around with OIDs
• oid_first() - OID of first element in the doc
• oid_next() - OID of next element
• oid_prev() - OID of previous element
• oid_last() - OID of last element
• oid_parent() - OID of parent element
• oid_child() - OID of nth child element (or null OID
if no such child exists)
• goto_oid() - moves the caret to an element
• oid_xpath_nodeset() - nodes that match an XPath
expression (OIDs in an array)
Making Changes with OIDs
• oid_select() - selects the element
• oid_modify_attr() - changes an attribute value
• oid_delete_attr() - removes an attribute
• oid_delete - removes the element
• change_tag command - changes the element at
the caret (use with goto_oid())
• insert_tag() - inserts a new element at the caret
(use with goto_oid())
• insert() - inserts a markup string at the caret
OID example
• Return the title of the nearest enclosing element
based on caret location
function oid_title(oid=oid_caret()) {
# if this oid has a title, use that
oid_find_children(oid,$titles,"title");
if (count($titles) > 0) {
return oid_content($titles[1]);
}
# otherwise walk up the tree till we find one
oid = oid_parent(oid);
while (oid_valid(oid)) {
oid_find_children(oid,$titles,"title");
if (count($titles) > 0) {
return oid_content($titles[1]);
}
oid = oid_parent(oid);
}
}
Lots More Fun
• There are specific functions for navigating and
changing special elements
– Tables
– Graphics
– Equations
– Entities and entity references
– Document objects from repositories
– Change tracking markup
• Too much to cover here--see the online help!
Getting User Input
• There are several ways to get user input in ACL
– response()
– list_response()
– readvar command
– file_selector()
– XUI dialogs
The response() Function
• Simple message with buttons for response
$answer = response(“Continue?”,”Yes”,”No”);
returns 1 returns 2
Multiple Response Buttons
• You can have as many buttons as you like
$ans = response(“Error! What do you want to do?”, 
“&Abort”, 
“&Retry”, 
“&Fail”, 
“Pull out &hair”, 
“&Defenestrate computer”, 
“&Move to MN and open a bait shop”);
The list_response() Function
• Similar to response(), but uses an array to
generate a listbox
get_printers($options);
$ans = list_response($options,"Print",
"Select a printer");
response("You selected $ans");
The readvar Command
• Lets user type a line of text
readvar -title "Notifications" 
-prompt "Enter emails to notify:" 
-value "epic-admin@mycompany.com" 
notify;
global $emails[];
split($notify,$emails,',;');
response("You want to notify:n" . 
join($emails,"n"));
The file_selector() Function
• Use file_selector() to invoke the standard file
chooser for your OS
$fname = file_selector(doc_dir(),"xml",
"XML files|*.xml|All files|*.*",
"Select file to open");
response("You selected $fname");
Using XUI dialogs
• See Jason & Asli's slides (Tues 1:15, "Using XUI to
Manage Cross-References")
• Also dialog item callbacks are handy for this (a
few slides from now)
Using Callbacks and Hooks
• Use your own functions to handle events
– document callbacks
– window callbacks
– session callbacks
– dialog item callbacks
• Callbacks vs. Hooks
– Hooks are global, callbacks can have limited scope
Using Callbacks
• Use *_add_callback() to add a callback to the
desired item
– window_add_callback(0,"create","setupinfo");
• Use *_remove_callback() to remove a callback
– window_remove_callback(0,"create","setupinfo");
Document Callbacks
• Document callbacks can trigger actions when:
– User copies, cuts, pastes, deletes, inserts, or modifies
content
– The document is saved or closed
– A table operation is done
– The document is printed
– Various other things (see online help)
Document Callback Example
• Auto-fill an attribute value when element is
inserted
– uses insert_tag_after callback
function remark_add_user(doc,tag,oid,op) {
if ((op == 1) && (tag == "remark")) {
modify_attr("role",username());
}
}
doc_add_callback(current_doc(),'insert_tag_after',
'remark_add_user');
Window Callbacks
• Window callbacks can trigger actions when:
– A window is created or destroyed
– A window gains or loses focus
– The caret moves
• Some window callbacks use
window_add_callback(), others use
window_set()
Window Callback Example
• Reports window information when window is
created
function showinfo(win) {
response("Window ID=" . win . ", doc ID=" .
window_doc(win));
}
window_add_callback(0,"create","showinfo");
Session Callbacks
• Session callbacks can trigger actions when:
– drag and drop operations happen
– the session ends (quit Arbortext)
Session callback example
• Lets user control handling of dropped files using
SHIFT and CTRL keys
function drop_handler(path,num,count,flags) {
local $ext = tolower(substr($path,length($path)-3));
if ($ext == "xml") {
if ($flags & 0x0001) { # SHIFT-drag
# insert content inline
execute("read " . $path);
}
else if ($flags & 0x0002) { # CTRL-drag
# insert Xinclude reference
$xi = "<xi:include href='" . $path . "'/>";
insert($xi);
}
else {
execute("edit -newwindow " . path);
}
}
}
session_add_callback("drop_file",drop_handler);
Dialog Item Callbacks
• Used to attach behaviors to dialog items
– Button clicked
– Listbox selection changed
– Checkbox checked or unchecked
– etc.
Dialog Item Callback Example
• Debug message for button
function buttoncb(win,dlgitem,event) {
response("You clicked " . 
dlgitem_get($win,$dlgitem,"label"));
}
dlgitem_add_callback($win,"MyButton",buttoncb);
Timer Callbacks
• Use a timer callback to make something happen
after a specific delay, or repeatedly
Timer Callback Example
• Add autosave every 5 minutes
function autosave(doc) {
doc_save(doc);
}
timer_add_callback(30000,'autosave',current_doc());
Hooks
• Some overlap with callbacks, but hooks can
respond to some things callbacks can’t
– Change tracking events
– Formatting stages (print composition)
– Import/Export
– Preference changes
Hook Example
• Return concurrent Print Composer License to
server immediately after printing
function returnlicense() {
if (license("PrintPublishing")!=0) {
license_release("PrintPublishing");
}
}
add_hook(printcompletehook,returnlicense);
Integrating ACL Code with Applications
• ACL code generally goes in the custom directory
– put in $EPICcustom...
OR
– set APTCUSTOM environment variable to the location
• e.g. shared configuration on a server
Where to Put ACL Scripts
• Where you put it determines when it runs
– custominit: runs once when Arbortext starts
– ~/.pubrc (UNIX) or file pointed at by %APTRC% (Windows):
User-specific startup script, runs once at startup
– customeditinit: runs each time you open a document for
editing
– customdoctypes{yourdoctype}{yourdoctype}.acl: runs
once when the doctype is referenced during a session
– customdoctypes{yourdoctype}instance.acl: runs each
time a document of that type is opened
– {document_directory}/{docname}.acl: document-specific,
runs when you open {document_dir}/{docname}.xml
Where to Put Non-startup ACL Scripts
• For scripts that don’t need to run at startup, put
them in customscripts to make them available
– use source {filename} to run from command line or
another script
– use require {packagename} to load scripts in a package
file from another context
• Gotcha: avoid circular references:
foo.acl:
package foo;
require bar;
bar.acl:
package bar;
require foo;
Customizing Arbortext Features
• Much of Arbortext’s functionality is implemented
as ACL scripts
• By customizing those scripts you can customize
how Arbortext works
– Make modified copies of the scripts in custom/scripts.
These will override the default scripts.
– DON’T MODIFY ORIGINAL SCRIPTS IN $EPIC/packages
or other install subdirectories
• You might want the originals back someday
• You might break something else and have to revert
• Your changes will get blown away next time you
upgrade
Using alias Command to Customize
• You can use the alias command to change
Arbortext’s definition of certain commands
alias FilePrint { customPrint(); }
Using ACL with Other Custom Code
• You can use ACL to interact with other custom
code
– Java
– JavaScript
– VBscript & COM objects
ACL and Java
• Access static methods using java_static()
• Create instances with java_constructor()
• Execute instance methods with java_instance()
• Exchange array data with java_array_to_acl()
and java_array_from_acl()
Accessing Java Fields
• No way to access java fields (properties) directly,
but you can use reflection
function getJavaField(object,fldname) {
class = java_instance(object,"getClass");
field = java_instance($class,"getField",fldname);
value = java_instance($field,"get",object);
valuestr = java_instance($value,"toString");
java_delete($class);
java_delete($field);
java_delete($value);
return valuestr;
}
ACL and JavaScript
• Use js_source() function to execute a JavaScript
file
• The source command can also run JavaScript files
• Use javascript() function to execute a string of
JavaScript code and return the value to ACL
# make array of day names
split("S,M,T,W,Th,F,S", $daynames, ",");
# use javascript to get today’s day of week
$dow = javascript("d = new Date(); d.getDay();") + 1;
# +1 because JS is zero-indexed but ACL is one-indexed
response("Today is $daynames[$dow]");
ACL and VBScript/COM
• Use source command to execute a VBS file
• com_*() functions provide access to COM objects
# start Excel
$excel = com_attach("Excel.Application");
$ex_wbs = com_prop_get($excel,"Workbooks");
# open our data file
$result = com_call($ex_wbs,"Open","C:tempdata.xls");
# get value of cell A5
$mywb = com_prop_get($excel,"ActiveWorkbook");
$mysheet = com_prop_get($mywb,"Worksheets",1);
$mycell = com_prop_get($mysheet,"Cells",5,1);
$value = com_prop_get($mycell,"value");
# clean up objects with com_release()...
Running ACL Code From the Command Line
• You can run Arbortext in “batch” mode by giving it
code on the command line
• Use the –c parameter to give it a string of ACL
• Use the –b parameter to suppress windows (batch
mode)
epic –b –c “print composed; quit” foo.xml
Q & A
• Ask now (raise your hand)
• OR Ask later:
– Clay Helberg
The Mathworks
– clay.helberg@mathworks.com
Helberg acl-final

More Related Content

What's hot

Unit 4 plsql
Unit 4  plsqlUnit 4  plsql
Unit 4 plsql
DrkhanchanaR
 
Java
Java Java
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
Deniz Oguz
 
Collections
CollectionsCollections
Scala, Play 2.0 & Cloud Foundry
Scala, Play 2.0 & Cloud FoundryScala, Play 2.0 & Cloud Foundry
Scala, Play 2.0 & Cloud Foundry
Pray Desai
 
Rapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on RailsRapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on Rails
Simobo
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - Introduction
Łukasz Biały
 
Let's start with Java- Basic Concepts
Let's start with Java- Basic ConceptsLet's start with Java- Basic Concepts
Let's start with Java- Basic Concepts
Aashish Jain
 
Code generating beans in Java
Code generating beans in JavaCode generating beans in Java
Code generating beans in Java
Stephen Colebourne
 
Java 103 intro to java data structures
Java 103   intro to java data structuresJava 103   intro to java data structures
Java 103 intro to java data structures
agorolabs
 
Intermediate JavaScript
Intermediate JavaScriptIntermediate JavaScript
Intermediate JavaScript
☆ Milan Adamovsky ☆
 
Java SE 8
Java SE 8Java SE 8
Java SE 8
Simon Ritter
 
PHP- Introduction to Object Oriented PHP
PHP-  Introduction to Object Oriented PHPPHP-  Introduction to Object Oriented PHP
PHP- Introduction to Object Oriented PHP
Vibrant Technologies & Computers
 
Database programming
Database programmingDatabase programming
Scala basic
Scala basicScala basic
Scala basic
Nguyen Tuan
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
LivePerson
 
Java 201 Intro to Test Driven Development in Java
Java 201   Intro to Test Driven Development in JavaJava 201   Intro to Test Driven Development in Java
Java 201 Intro to Test Driven Development in Java
agorolabs
 
Clojure - An Introduction for Java Programmers
Clojure - An Introduction for Java ProgrammersClojure - An Introduction for Java Programmers
Clojure - An Introduction for Java Programmers
elliando dias
 
PHP - Introduction to Object Oriented Programming with PHP
PHP -  Introduction to  Object Oriented Programming with PHPPHP -  Introduction to  Object Oriented Programming with PHP
PHP - Introduction to Object Oriented Programming with PHP
Vibrant Technologies & Computers
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern Java
Sina Madani
 

What's hot (20)

Unit 4 plsql
Unit 4  plsqlUnit 4  plsql
Unit 4 plsql
 
Java
Java Java
Java
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
Collections
CollectionsCollections
Collections
 
Scala, Play 2.0 & Cloud Foundry
Scala, Play 2.0 & Cloud FoundryScala, Play 2.0 & Cloud Foundry
Scala, Play 2.0 & Cloud Foundry
 
Rapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on RailsRapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on Rails
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - Introduction
 
Let's start with Java- Basic Concepts
Let's start with Java- Basic ConceptsLet's start with Java- Basic Concepts
Let's start with Java- Basic Concepts
 
Code generating beans in Java
Code generating beans in JavaCode generating beans in Java
Code generating beans in Java
 
Java 103 intro to java data structures
Java 103   intro to java data structuresJava 103   intro to java data structures
Java 103 intro to java data structures
 
Intermediate JavaScript
Intermediate JavaScriptIntermediate JavaScript
Intermediate JavaScript
 
Java SE 8
Java SE 8Java SE 8
Java SE 8
 
PHP- Introduction to Object Oriented PHP
PHP-  Introduction to Object Oriented PHPPHP-  Introduction to Object Oriented PHP
PHP- Introduction to Object Oriented PHP
 
Database programming
Database programmingDatabase programming
Database programming
 
Scala basic
Scala basicScala basic
Scala basic
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Java 201 Intro to Test Driven Development in Java
Java 201   Intro to Test Driven Development in JavaJava 201   Intro to Test Driven Development in Java
Java 201 Intro to Test Driven Development in Java
 
Clojure - An Introduction for Java Programmers
Clojure - An Introduction for Java ProgrammersClojure - An Introduction for Java Programmers
Clojure - An Introduction for Java Programmers
 
PHP - Introduction to Object Oriented Programming with PHP
PHP -  Introduction to  Object Oriented Programming with PHPPHP -  Introduction to  Object Oriented Programming with PHP
PHP - Introduction to Object Oriented Programming with PHP
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern Java
 

Similar to Helberg acl-final

Information Retrieval - Data Science Bootcamp
Information Retrieval - Data Science BootcampInformation Retrieval - Data Science Bootcamp
Information Retrieval - Data Science Bootcamp
Kais Hassan, PhD
 
Powershell Training
Powershell TrainingPowershell Training
Powershell Training
Fahad Noaman
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
Harry Potter
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
James Wong
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
Young Alista
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
Tony Nguyen
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
Hoang Nguyen
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
Fraboni Ec
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
Luis Goldster
 
1 xml fundamentals
1 xml fundamentals1 xml fundamentals
1 xml fundamentals
Dr.Saranya K.G
 
Modularity and Layered Data Model
Modularity and Layered Data ModelModularity and Layered Data Model
Modularity and Layered Data Model
Attila Jenei
 
Advanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojoAdvanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojo
Fu Cheng
 
XMl
XMlXMl
23xml
23xml23xml
23xml
Adil Jafri
 
ASP.Net Presentation Part2
ASP.Net Presentation Part2ASP.Net Presentation Part2
ASP.Net Presentation Part2
Neeraj Mathur
 
Xml
XmlXml
Xml
Anas Sa
 
Week3
Week3Week3
CodeIgniter & MVC
CodeIgniter & MVCCodeIgniter & MVC
CodeIgniter & MVC
Jamshid Hashimi
 
XML
XMLXML
FFW Gabrovo PMG - PHP OOP Part 3
FFW Gabrovo PMG - PHP OOP Part 3FFW Gabrovo PMG - PHP OOP Part 3
FFW Gabrovo PMG - PHP OOP Part 3
Toni Kolev
 

Similar to Helberg acl-final (20)

Information Retrieval - Data Science Bootcamp
Information Retrieval - Data Science BootcampInformation Retrieval - Data Science Bootcamp
Information Retrieval - Data Science Bootcamp
 
Powershell Training
Powershell TrainingPowershell Training
Powershell Training
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
Xml and webdata
Xml and webdataXml and webdata
Xml and webdata
 
1 xml fundamentals
1 xml fundamentals1 xml fundamentals
1 xml fundamentals
 
Modularity and Layered Data Model
Modularity and Layered Data ModelModularity and Layered Data Model
Modularity and Layered Data Model
 
Advanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojoAdvanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojo
 
XMl
XMlXMl
XMl
 
23xml
23xml23xml
23xml
 
ASP.Net Presentation Part2
ASP.Net Presentation Part2ASP.Net Presentation Part2
ASP.Net Presentation Part2
 
Xml
XmlXml
Xml
 
Week3
Week3Week3
Week3
 
CodeIgniter & MVC
CodeIgniter & MVCCodeIgniter & MVC
CodeIgniter & MVC
 
XML
XMLXML
XML
 
FFW Gabrovo PMG - PHP OOP Part 3
FFW Gabrovo PMG - PHP OOP Part 3FFW Gabrovo PMG - PHP OOP Part 3
FFW Gabrovo PMG - PHP OOP Part 3
 

Helberg acl-final

  • 1. Arbortext Command Language (ACL) Basics Clay Helberg The MathWorks
  • 2. Arbortext Command Language (ACL) • ACL is a scripting language embedded in Arbortext Editor • Provides ways to: – Control the software – Make dialogs work – Navigate and manipulate documents – Interface with other software components (e.g. Publishing Engine, Dynamic Link Manager, Content Manager, etc.) – Interact with user
  • 3. Arbortext Command Language (ACL) • Basic syntax • Variables and arrays • Defining and using functions • Working with files and documents • Modifying the content of documents • Using callbacks and hooks to handle events • Integrating ACL scripts into your application
  • 4. Basic Syntax • ACL is sort of Perl-ish, sort of C-ish – Like Perl, without the “line noise” – Like C, without the pointer arithmetic and memory management • Statements are the fundamental steps in a program – Two types of statements: commands and functions
  • 5. ACL Commands • Commands use syntax like this: commandname argument argument … • Commands don’t return a value • BUT May store information in system variables about error status, etc. • Example: print composed current
  • 6. ACL Functions • Functions use syntax like this: functionname ( argument, argument, …) • Functions often, but not always, return a value – Result of calculation or transformation – Status of operation (success/failure) • Example: if (doc_name(doc)==“foo.xml”) …
  • 7. ACL Functions • Gotcha: Return value vs. updated parameter – Example: Global $windows[] $return = window_list($windows); – $return is number indicating status (number of windows), not the list itself – The actual list (array) of windows is stored in $windows
  • 8. ACL Comments • Comments start with a hash # • Everything after the hash is ignored # This function is really cool function reallyCoolFunction(input) { # do some really cool stuff here } • You can stick a comment at the end of a line after some “real” code if (oid_type($oid) == 4) { # type 4 -> equation
  • 9. ACL Blocks • A block is a section of a program that is a cohesive unit • Delimited with curly braces { } • Examples: – Function definitions – The branches of if/else statements – The guts of while and for loops
  • 10. ACL Flow Control • The usual flow control structures are supported – for loops for (i=1; i < count($arr); i++) { doc_close($arr[i]); } – while loops find “Leno” while ($status == 0) { delete_mark; insert_string “O’Brien” find “Leno” }
  • 11. More ACL Flow Control – if/else branches if ($size == “legal”) { set stylesheet=“legal.style” } else { set stylesheet=“letter.style” }
  • 12. Still more flow control – switch trees: $resp = response(“Save Changes?”,”Yes”,”No”,”Cancel”); switch ($resp) { case 1: doc_save(current_doc()); break; case 2: set modified=off; doc_close(current_doc()); break; case 3: # do nothing }
  • 13. ACL Packages • Analogous to Java or Perl packages • Similar to namespaces in XML package log; global $errlog = “C:tempapterr.txt”; function error(msg) { local $fid = open($log::errlog,a); put($fid, “*** ERROR: $msgn”); flush($fid); close($fid); }
  • 14. Using Packages • Use require to import a package’s code • Use package::functionname to call a function in another package package custom; require log; function load_doc(docname) { local $docid = doc_open(docname); if ($docid == -1) { log::error(“Couldn’t open $docname”); } }
  • 15. ACL Variables • Variables in ACL are dynamically typed – Automatically assumes the required type for the value • Name is sometimes preceded with a $ like Perl (optional) – But arrays are NOT preceded with an @ • You can define scope with local and global keywords – Default is local scope – Local variables are only accessible in the block in which they are declared (e.g. inside a function) – Global variables are accessible anywhere
  • 16. Assigning Values to Variables • Assign values using the assignment operator = – $mydoc = “C:tempmydocsmydoc.xml”; • You can use expressions in assignment – $mydoc = current_doc(); – $mypath = dirname(doc_path(current_doc()));
  • 17. Assigning Values to Variables • You can also use shortcut assignment operators – $linecount += 1; – $product *= get_multiplier(); • Use . (dot) operator for string concatenation – $msg = “Do you want to close “ . doc_name() . “?”;
  • 18. ACL Variable Evaluation • Variables are evaluated – Variable references inside double quotes are evaluated • $docname = “foo.xml”; • $msg = “Close $docname?” # returns “Close foo.xml?” – References inside single quotes are not • $msg = ‘Close $docname?’ # returns “Close $docname?”
  • 19. Deferred Evaluation of Variables • Gotcha: In commands, you may need to defer evaluation – Ex: (wrong way – prints first doc repeatedly) for ($i in $doclist) { print composed $doclist[$i]; } • Use execute or eval commands to defer – Ex: (right way – prints each document once) for ($i in $doclist) { execute(“print composed $doclist[$i]”); }
  • 20. ACL Arrays • ACL supports two kinds of arrays – Normal arrays, indexed by number $array[1] = “foo” – Associative arrays, indexed by key $array[“foo”] = “bar” • Gotcha: ACL arrays are indexed from one, not zero
  • 21. Declaring ACL Arrays • Both types have the same declaration syntax: – [local | global] $arrayname[]; • Most arrays resize dynamically as necessary – Unless declared using global and a fixed size • global $myarray[10]; • Use square brackets [] to access array elements – $msg = “the first element is $myarray[1]”; – $msg = “owner of $docname is $owners[$docname]”;
  • 22. Using ACL Arrays • You can iterate over items in an array using for (… in …) construction – for ($i in $myarray) { if ($myarray[$i]==doc_name()) { response(doc_name() . “ is in array”); break; } } • This works for both types of arrays • Gotcha: Loop index is the array index, not the array value for that index
  • 23. ACL Built-in Functions • ACL has a wide variety of built-in functions
  • 24. User-Defined Functions in ACL • You can define your own functions – function functionname(param1, param2) { # do some stuff here return result of operation; } • Example: – function doc_dir(doc) { local $docname = doc_name(doc); return dirname($docname); }
  • 25. Forward Declarations • In an ACL file, you often have multiple function definitions • A function can’t use another function if it hasn’t been defined yet
  • 26. Why You Need Forward Declarations • This will fail: function launch_browser(filename) { local $url = file_to_url(filename); system(“start $url”); } function file_to_url(filename) { gsub(filename,””,”/”); return("http://". filename); } • We try to use file_to_url() before it is defined
  • 27. How to Write a Forward Declaration • Forward declaration is an empty function definition at the top of the file • Lets other functions know that you're going to define the function later
  • 28. Forward Declaration Example • This will work because of the forward declaration: function file_to_url() {}; # forward decl function launch_browser(filename) { local $url = file_to_url(filename); system(“start $url”); } function file_to_url(filename) { gsub(filename,””,”/”); return("http://". filename); }
  • 29. A Brief Tour of Built-In Functions • Arbortext provides a ton of built-in functions for various purposes • We'll look at some of the most useful categories – document and file handling – document content manipulation – user interaction • For more information see the online help – ACL reference in online help is very complete – If you don't know what it's called, try search – If you still can't find it, try Adepters email!
  • 30. Working with Files and Documents • current_doc() - gets a handle (ID number) for the currently active document • doc_open() - loads a document – flags determine whether it's opened as XML or ASCII, whether context checking happens, etc. • doc_name() - filename of the document • doc_path() - fully-qualified pathname of the doc • doc_incomplete() - tells whether doc is valid • doc_save() - saves the document • edit_new_window() - opens document in a new edit window
  • 31. Working with Generic Files • open() - open an arbitrary file for reading and/or writing (e.g. for logging messages or importing text content into a document) • read() - read from a file • getline() - read from a file one line at a time • put() - write content to a file • close() - close a file
  • 32. General File System Info • glob() - fills an array with names of files that match the globbing expression (e.g. "*.xml") • file_directory() - tells whether specified filename is really a directory • file_size() - size of the file • file_newer() - determines if one file is newer than another • username() - user name string (from OS) • system() - execute an arbitrary system command • file_selector() - starts a standard file selection dialog, returning the user's choice
  • 33. Modifying Document Contents • The OID is your friend (Object ID) – Unique ID for each element in the document – Can be used to find, access, change, or delete markup • oid_root() - the root element of the doc • oid_name() - the name of the specified element • oid_caret() - the element containing the caret • oid_attr() - gets the value of the specified attribute on the specified element • oid_content() - returns the content of the element as a markup string
  • 34. Moving Around with OIDs • oid_first() - OID of first element in the doc • oid_next() - OID of next element • oid_prev() - OID of previous element • oid_last() - OID of last element • oid_parent() - OID of parent element • oid_child() - OID of nth child element (or null OID if no such child exists) • goto_oid() - moves the caret to an element • oid_xpath_nodeset() - nodes that match an XPath expression (OIDs in an array)
  • 35. Making Changes with OIDs • oid_select() - selects the element • oid_modify_attr() - changes an attribute value • oid_delete_attr() - removes an attribute • oid_delete - removes the element • change_tag command - changes the element at the caret (use with goto_oid()) • insert_tag() - inserts a new element at the caret (use with goto_oid()) • insert() - inserts a markup string at the caret
  • 36. OID example • Return the title of the nearest enclosing element based on caret location function oid_title(oid=oid_caret()) { # if this oid has a title, use that oid_find_children(oid,$titles,"title"); if (count($titles) > 0) { return oid_content($titles[1]); } # otherwise walk up the tree till we find one oid = oid_parent(oid); while (oid_valid(oid)) { oid_find_children(oid,$titles,"title"); if (count($titles) > 0) { return oid_content($titles[1]); } oid = oid_parent(oid); } }
  • 37. Lots More Fun • There are specific functions for navigating and changing special elements – Tables – Graphics – Equations – Entities and entity references – Document objects from repositories – Change tracking markup • Too much to cover here--see the online help!
  • 38. Getting User Input • There are several ways to get user input in ACL – response() – list_response() – readvar command – file_selector() – XUI dialogs
  • 39. The response() Function • Simple message with buttons for response $answer = response(“Continue?”,”Yes”,”No”); returns 1 returns 2
  • 40. Multiple Response Buttons • You can have as many buttons as you like $ans = response(“Error! What do you want to do?”, “&Abort”, “&Retry”, “&Fail”, “Pull out &hair”, “&Defenestrate computer”, “&Move to MN and open a bait shop”);
  • 41. The list_response() Function • Similar to response(), but uses an array to generate a listbox get_printers($options); $ans = list_response($options,"Print", "Select a printer"); response("You selected $ans");
  • 42. The readvar Command • Lets user type a line of text readvar -title "Notifications" -prompt "Enter emails to notify:" -value "epic-admin@mycompany.com" notify; global $emails[]; split($notify,$emails,',;'); response("You want to notify:n" . join($emails,"n"));
  • 43. The file_selector() Function • Use file_selector() to invoke the standard file chooser for your OS $fname = file_selector(doc_dir(),"xml", "XML files|*.xml|All files|*.*", "Select file to open"); response("You selected $fname");
  • 44. Using XUI dialogs • See Jason & Asli's slides (Tues 1:15, "Using XUI to Manage Cross-References") • Also dialog item callbacks are handy for this (a few slides from now)
  • 45. Using Callbacks and Hooks • Use your own functions to handle events – document callbacks – window callbacks – session callbacks – dialog item callbacks • Callbacks vs. Hooks – Hooks are global, callbacks can have limited scope
  • 46. Using Callbacks • Use *_add_callback() to add a callback to the desired item – window_add_callback(0,"create","setupinfo"); • Use *_remove_callback() to remove a callback – window_remove_callback(0,"create","setupinfo");
  • 47. Document Callbacks • Document callbacks can trigger actions when: – User copies, cuts, pastes, deletes, inserts, or modifies content – The document is saved or closed – A table operation is done – The document is printed – Various other things (see online help)
  • 48. Document Callback Example • Auto-fill an attribute value when element is inserted – uses insert_tag_after callback function remark_add_user(doc,tag,oid,op) { if ((op == 1) && (tag == "remark")) { modify_attr("role",username()); } } doc_add_callback(current_doc(),'insert_tag_after', 'remark_add_user');
  • 49. Window Callbacks • Window callbacks can trigger actions when: – A window is created or destroyed – A window gains or loses focus – The caret moves • Some window callbacks use window_add_callback(), others use window_set()
  • 50. Window Callback Example • Reports window information when window is created function showinfo(win) { response("Window ID=" . win . ", doc ID=" . window_doc(win)); } window_add_callback(0,"create","showinfo");
  • 51. Session Callbacks • Session callbacks can trigger actions when: – drag and drop operations happen – the session ends (quit Arbortext)
  • 52. Session callback example • Lets user control handling of dropped files using SHIFT and CTRL keys function drop_handler(path,num,count,flags) { local $ext = tolower(substr($path,length($path)-3)); if ($ext == "xml") { if ($flags & 0x0001) { # SHIFT-drag # insert content inline execute("read " . $path); } else if ($flags & 0x0002) { # CTRL-drag # insert Xinclude reference $xi = "<xi:include href='" . $path . "'/>"; insert($xi); } else { execute("edit -newwindow " . path); } } } session_add_callback("drop_file",drop_handler);
  • 53. Dialog Item Callbacks • Used to attach behaviors to dialog items – Button clicked – Listbox selection changed – Checkbox checked or unchecked – etc.
  • 54. Dialog Item Callback Example • Debug message for button function buttoncb(win,dlgitem,event) { response("You clicked " . dlgitem_get($win,$dlgitem,"label")); } dlgitem_add_callback($win,"MyButton",buttoncb);
  • 55. Timer Callbacks • Use a timer callback to make something happen after a specific delay, or repeatedly
  • 56. Timer Callback Example • Add autosave every 5 minutes function autosave(doc) { doc_save(doc); } timer_add_callback(30000,'autosave',current_doc());
  • 57. Hooks • Some overlap with callbacks, but hooks can respond to some things callbacks can’t – Change tracking events – Formatting stages (print composition) – Import/Export – Preference changes
  • 58. Hook Example • Return concurrent Print Composer License to server immediately after printing function returnlicense() { if (license("PrintPublishing")!=0) { license_release("PrintPublishing"); } } add_hook(printcompletehook,returnlicense);
  • 59. Integrating ACL Code with Applications • ACL code generally goes in the custom directory – put in $EPICcustom... OR – set APTCUSTOM environment variable to the location • e.g. shared configuration on a server
  • 60. Where to Put ACL Scripts • Where you put it determines when it runs – custominit: runs once when Arbortext starts – ~/.pubrc (UNIX) or file pointed at by %APTRC% (Windows): User-specific startup script, runs once at startup – customeditinit: runs each time you open a document for editing – customdoctypes{yourdoctype}{yourdoctype}.acl: runs once when the doctype is referenced during a session – customdoctypes{yourdoctype}instance.acl: runs each time a document of that type is opened – {document_directory}/{docname}.acl: document-specific, runs when you open {document_dir}/{docname}.xml
  • 61. Where to Put Non-startup ACL Scripts • For scripts that don’t need to run at startup, put them in customscripts to make them available – use source {filename} to run from command line or another script – use require {packagename} to load scripts in a package file from another context • Gotcha: avoid circular references: foo.acl: package foo; require bar; bar.acl: package bar; require foo;
  • 62. Customizing Arbortext Features • Much of Arbortext’s functionality is implemented as ACL scripts • By customizing those scripts you can customize how Arbortext works – Make modified copies of the scripts in custom/scripts. These will override the default scripts. – DON’T MODIFY ORIGINAL SCRIPTS IN $EPIC/packages or other install subdirectories • You might want the originals back someday • You might break something else and have to revert • Your changes will get blown away next time you upgrade
  • 63. Using alias Command to Customize • You can use the alias command to change Arbortext’s definition of certain commands alias FilePrint { customPrint(); }
  • 64. Using ACL with Other Custom Code • You can use ACL to interact with other custom code – Java – JavaScript – VBscript & COM objects
  • 65. ACL and Java • Access static methods using java_static() • Create instances with java_constructor() • Execute instance methods with java_instance() • Exchange array data with java_array_to_acl() and java_array_from_acl()
  • 66. Accessing Java Fields • No way to access java fields (properties) directly, but you can use reflection function getJavaField(object,fldname) { class = java_instance(object,"getClass"); field = java_instance($class,"getField",fldname); value = java_instance($field,"get",object); valuestr = java_instance($value,"toString"); java_delete($class); java_delete($field); java_delete($value); return valuestr; }
  • 67. ACL and JavaScript • Use js_source() function to execute a JavaScript file • The source command can also run JavaScript files • Use javascript() function to execute a string of JavaScript code and return the value to ACL # make array of day names split("S,M,T,W,Th,F,S", $daynames, ","); # use javascript to get today’s day of week $dow = javascript("d = new Date(); d.getDay();") + 1; # +1 because JS is zero-indexed but ACL is one-indexed response("Today is $daynames[$dow]");
  • 68. ACL and VBScript/COM • Use source command to execute a VBS file • com_*() functions provide access to COM objects # start Excel $excel = com_attach("Excel.Application"); $ex_wbs = com_prop_get($excel,"Workbooks"); # open our data file $result = com_call($ex_wbs,"Open","C:tempdata.xls"); # get value of cell A5 $mywb = com_prop_get($excel,"ActiveWorkbook"); $mysheet = com_prop_get($mywb,"Worksheets",1); $mycell = com_prop_get($mysheet,"Cells",5,1); $value = com_prop_get($mycell,"value"); # clean up objects with com_release()...
  • 69. Running ACL Code From the Command Line • You can run Arbortext in “batch” mode by giving it code on the command line • Use the –c parameter to give it a string of ACL • Use the –b parameter to suppress windows (batch mode) epic –b –c “print composed; quit” foo.xml
  • 70. Q & A • Ask now (raise your hand) • OR Ask later: – Clay Helberg The Mathworks – clay.helberg@mathworks.com