The best way to view a feature map is on the Start Screen in Tag. There is an interactive graph view and links to all the described apps. Download Tag now to see how it works.
Some of the feature map content related to open standards used by Tag is included below. A list of all feature maps can be found here.
A lot of what Tag does is based on open standards. This means the knowledge that you automate using these standards can be used in other software. It also means that the symbols Tag uses for all these instructions are durable and unlikely to change over time, and that online communities exist to help you use them.
Data standards are used to define how data fields are structured, how data instructions can be reused and available data sources.
Expression standards address features such as paths, math and functions.
Rich text standards define word processing content, format and conversion.
Graphics standards describe how to build graphics logically using common shapes, clever paint, coordinate paths and more.
Logic standards address powerful features like creating content and data, templates, variables and processing rules.
Finally, pipeline standards define pipelines using document ports, steps and behavior rules.
Data can be imported from CSV files.
When importing data from CSV files, the content is organized using columns and rows. These are handled differently according to where you import the file.
Forms in the Scribe app let you import from several sources including CSV. Since the goal of importing into a form involves populating 1 set of form controls, you typically only want 1 row from the CSV. In this case, the values in columns of that row can be used to fill in form controls.
Pipelines in the Automate app can also import CSV, however sometimes you want all rows and not just 1. For example, you could generate a letter or email for each row in a CSV.
You can import CSV into a pipeline using the tag:csv extension step, which is unique to Tag. It converts the CSV into XML that contains all columns and rows, which can then be processed in many ways.
Note that when converting CSV to XML, the column headers are used as element name suggestions. This is described further in CSV schemas.
CSV files can be used to define data fields.
CSV files are very common in organizations. They are great for importing and exporting data from one system to another.
Data setup files (which use RNG) can be created from CSV files. Each column in the CSV is used to define 1 data field using the column header as a suggested name.
The name may be modified slightly to remove spaces and ensure that it starts with a letter or "_". For example, "my label" will become "my_label" and "2nd label" will become "_2nd_label".
A wizard is used to guide this process. One page is used to enter a namespace for the data setup file, which is simply a URI that uniquely identifies the defined data.
Data fields are described by element definitions.
There are several properties of interest when it comes to data fields. Are they optional or required, is there a human-friendly label, or does it share any properties with other fields?
The RNG standard describes a data field as an element, where that element can have a name (mandatory) and various properties (optional).
Some properties are simple strings, including label and comment. Other properties use child declarations to describe something more complex, like referencing a predefined field or defining a value list. The Tag data setup editor hides all these details, and makes defining properties on an element easy.
Element definitions can also describe compound, or hierarchical, data structures. For example, a contact element may have two parts: name and email. The nested structures can be several layers deep if needed, and are displayed using the data setup editor's tree view.
Data can be imported from JSON files.
JSON is an important file format often used by web APIs. It is similar to XML due to its hierarchical structure, which starts with a single root and builds a tree.
It is different from XML because JSON has no concept of attributes. It also includes the built-in concepts of arrays and maps, which may provide some convenience when processing these files.
Tag emphasizes the similarities between JSON and XML, and makes it easy to convert back and forth. A common use case is to download JSON from a web API, convert it to XML, and then process it further using logic or pipelines (which both can do much more with XML).
There are two ways to convert JSON to XML. The default way is defined by XPath and results in XML that reflects the formal json-to-xml mapping defined by XPath. The resulting XML belongs to the http://www.w3.org/2005/xpath-functions namespace and has XML names like string, boolean, map and array.
Tag offers an alternative that uses the popular Jackson software library. This alternative creates XML that has no namespace and uses XML names that match JSON map keys. This approach creates a more intuitive XML structure, however it has some limitations and may not be able to convert all JSON structures.
Converting from XML to JSON is more straightforward. If the XML uses the xpath-functions namespace it is converted using that mechanism, otherwise it is converted using Jackson.
Fields can have lists of pre-defined values.
When defining data fields, sometimes there is a list of valid values (e.g., days of the week). These can be added to an element definition, and will become part of the element's validation rules.
In the data setup editor, there is a way to enter a list of allowed values. Using the Form control pick list, select the "Dropdown list" option. This displays a list where you can add, reorder and remove allowed values for the field.
If a list of values is detected when a form is generated, a pick list (drop down list) is displayed to the user.
Note that value lists are part of the RNG open standard, however the Form control setting is not. That setting is only a hint for the Tag user interface and will be ignored by other software. Value lists created by other software are handled normally in Tag.
Predefined elements let you share element definitions.
Sometimes you have a data field definition that closely resembles another. For example, you may store a list of location names for your company that identify office locations with different teams. Furthermore, you may want multiple data fields that store locations (e.g., sales office, service office).
Predefined fields can be defined on one place, and reused by multiple fields with different names. This lets you define the list of locations in only one place, and reuse it as many times as you want.
Continuing the previous example, a predefined element called "location" could define the list of allowed location names. Predefined fields are accessed using the "Show fields" button at the top of the data setup editor.
Back in the data tree (which stores all named fields), you could create salesLocation and serviceLocation fields. In each of these, you would select the "Use predefined field" toggle switch and then select "location" in the provided pick list.
Tag offers several ways to reuse data definitions. The RNG standard supports the concept of predefined fields, which save time (only enter information once) and increase quality (prevent duplicate but not identical definitions, which can happen as things change over time).
Predefined fields in Tag provide a way to share identical data field definitions between multiple named data fields.
It is also possible to reuse field definitions that are embedded in CSV files. This amounts to creating and naming fields to match CSV columns as closely as possible.
Reusing field definitions from XSD schema files is also possible. This makes it possible to import data field information from other systems that support the XML Schema open standard.
Rules are used to describe data fields.
Data fields are used to understand data when generating content. The RNG standard provides several ways to describe data fields.
The foundation of data definitions is an element. An element definition must have a name, which is the minimum amount of information to define a data field. It can also have several optional properties.
One of the most important properties is the datatype. This tells the computer if a field stores a number, or date, or true/false.
Value lists are used when there is a list of allowed values for a field. Once defined, these lists display nicely in Tag forms as pick lists.
Data can be mapped to the schema.org vocabulary.
{pending}
Tag supports importing data from several data sources.
CSV files can be used to import rows and columns of data. In some cases you can import a single row, while in others you can import all rows and columns and process like a grid of values.
Importing from a SQL database is similar to CSV, in that the data is organized into rows and columns. A no-code query builder is provided to help you build SQL queries.
Importing from SPARQL endpoints is handled similarly to SQL and CSV.
JSON files are an increasingly important file format, used for downloading data from web APIs and other systems. Tag has several unique features aimed at making JSON easy and flexible to work with.
Data can be imported from SPARQL endpoints.
When importing data from SPARQL endpoints, the content is organized using columns and rows. These are handled differently according to where you import the file, as explained in csv import.
Column names are extracted from the SPARQL query used to call the database. Each variable in the query becomes a column, while each row in the query results becomes a row. Cells that are not explicitly filled are left empty.
Tag has an early-stage prototype of a no-code editor for SPARQL queries. Contact technical support to find out more.
Data can be imported from SQL databases.
When importing data from SQL databases, the content is organized using columns and rows. These are handled differently according to where you import the file, as explained in csv import.
Column names are extracted from the SQL query used to call the database. Each variable in the query becomes a column, while each row in the query results becomes a row. Cells that are not explicitly filled are left empty.
Tag includes a simple no-code query panel for exploring SQL databases. This can be used to create a query, or you can paste a query created using another tool.
Note that when converting SQL to XML, the column names are used as element name suggestions. This usually works fine, however column names that start with digits (0-9) will result in an XML element name starting with "_".
Datatypes describe what characters are allowed.
When defining data fields, at the very lowest-level, the computer needs to know exactly which characters are allowed. This is true for simple (atomic) and complex (hierarchical) elements.
Open standards define a long list of valid datatypes, many of which are used for scientific purposes. For most organizations, a subset of common datatypes is enough.
Tag supports these atomic datatypes:
Datatypes are entered in the data setup editor using the "Form control" pick list.
The Scribe app also supports some statistics-related datatypes, which are not part of any open standard:
Statistics datatypes are enabled using the "File settings" dialog in the data setup editor.
Data standards are used to define data used during content generation. There are three relevant standards.
XML Schema Datatypes is by far the most widely used. It defines all accepted datatypes like xs:string, xs:integer, xs:dateTime, etc. It is used by the following open standards and many more. Tag supports a core set of these datatypes in many parts of the system.
XML Schema Structures (XSD) works at a higher level than datatypes. It defines rules for optional vs. required fields, complex fields, and much more. Tag supports conversion from this standard to/from RNG (see below), but does not consider it a core standard.
Relax NG (RNG) is similar to XML Schema Structures, but much simpler. It is considerably more intuitive for humans, and maps more cleanly to a concise user interface. Tag uses RNG as a core standard within the data setup editor.
XSD files can be used to define data fields.
XSD (XML Schema) files are used by many software programs. They are similar to RNG (which Tag uses), but can be considerably more complex.
RNG data setup files can be created from XSD files. A conversion is attempted which will preserve element names and properties to be best extent possible. In some cases the XSD schema may be too complex to automatically convert, and some properties or structure may be lost.
Store a list of items.
Arrays are used to store an ordered list of items. Each item can be a simple value (e.g., string, number), an XML node, or a child expression.
They are created by putting square brackets around a comma-separated list of items.
[1, 2, 5, 7] - creates an array with four members: 1, 2, 5, and 7
Expressions can do a lookup by position on arrays. The array is followed by "?" and the desired position. Extending the example shown above looks like this.
[1, 2, 5, 7]?4 - returns 7
More information on arrays can be found in the XPath standard.
Expressions can process collections of items.
Sequences make it easy to work with flat lists of items. They are heavily used in expressions.
Arrays are similar to sequences in that they store an ordered list of items, however they also can be nested and support lookup by position.
Maps work like a dictionary, where a set of unique keys are used to store values. They can be nested and support lookup by key.
Expressions can make comparisons between values.
The XPath standard includes support for comparisons that work on numerical values and XML nodes.
More information on these operators can be found in the XPath standard.
Functions do work on input to produce output.
XPath includes a list of more than 190 predefined functions that handle a wide range of jobs.
Each function has a name, accepts zero or more arguments (parameters), and returns a result. They can be used anywhere within an expression.
Click on the arrow icon in this topic to view a dialog that describes all available functions.
Store a set of key/value pairs.
Maps are used to store a dictionary of keys and values. Keys can be any kind of item (most often strings), but must be unique within the map. Values can also be any kind of item.
They are created by putting "map{}" around a comma-separated list of key/value pairs. The key/value pairs use a ":" to separate them.
map{"north" : "Canada", "south" : "Chile"} - creates a map
with two key/value pairs: "north"="Canada" and "south"="Chile"
Expressions can do a lookup by key on maps. The map is followed by "?" and the desired key. Extending the example shown above looks like this.
map{"north" : "Canada", "south" : "Chile"}?"south" - returns "Chile"
More information on maps can be found in the XPath standard.
Expressions can contain mathematical capabilities.
The XPath standard supports a wide range of mathematical functions.
Operators include the well known (+, -, *, div), and the not so well known (idiv, mod).
Some comparisons work on numbers (=, <, <=, >, >=), and some work on nodes (is, <<, >>).
It also defines some advanced trigonometric and exponential functions like pi(), exp(), sin() and cos().
Note that expressions can use brackets to group operators and comparisons. Brackets can be nested, and are generally resolved according to standard order of operations in math.
PEMDAS: Parentheses, Exponents, Multiplication,
and Division (left to right), Addition and Subtraction
(left to right)
every $var in {sequence} satisfies {condition}
The every expression provides a true/false answer.
Each item in {sequence} is processed and assigned to a variable (e.g., $var). The {condition} expression is computed for each item. Returns true if {condition} resolves to true for all of the items.
e.g., every $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4 = false
You can insert an every expression in the advanced panel of the expression editor using the "Logic" menu.
More details are in the XPath standard.
for $var in {sequence} return {result}
The for expression provides a looping mechanism.
Each item in {sequence} is processed and assigned to a variable (e.g., $var). The {result} expression is computed for each item and added to the result sequence.
e.g., for $i in (10, 20) return ($i + 1) = (11, 21)
Multiple sequences can be processed, where each sequence has its own unique variable.
e.g., for $i in (10, 20), $j in (1, 2) return ($i + $j)
= (11, 12, 21, 22)
You can insert a for expression in the advanced panel of the expression editor using the "Logic" menu.
More details are in the XPath standard.
if {condition} then {result1} else {result2}
The if expression decides between two outcomes.
If {condition} evaluates to true execute {result1}, otherwise execute {result2}.
e.g., if ($part/@discounted) then $part/wholesale else $part/retail
You can insert an if expression in the advanced panel of the expression editor using the "Logic" menu.
More details are in the XPath standard.
let $var := {something} return {result}
The let expression allows a variable to be bound to a value. It can handle sequences and multiple variables.
e.g., let $x := 5, $y := 10 return $x + $y = 15
You can insert a let expression in the advanced panel of the expression editor using the "Logic" menu.
More details are in the XPath standard.
Expressions can have multiple parts working together.
There is a small set of specialized expressions that involve multiple keywords working together.
The for expression provides a looping mechanism that returns a sequence.
The let expression provides a way to work with variables.
The if expression decides between two outcomes.
The some expression returns true if a condition resolves to true for any item in a sequence.
The every expression returns true if a condition resolves to true for all items in a sequence.
some $var in {sequence} satisfies {condition}
The some expression provides a true/false answer.
Each item in {sequence} is processed and assigned to a variable (e.g., $var). The {condition} expression is computed for each item. Returns true if {condition} resolves to true for any of the items.
e.g., some $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4 = true
You can insert a some expression in the advanced panel of the expression editor using the "Logic" menu.
More details are in the XPath standard.
Expressions can use standard math operators.
The XPath standard includes support for several mathematical operators, including detailed rules for handling special datatypes like xs:date and xs:time.
Note that "div" is used for divide instead of "/" to avoid confusion with the path operator (/).
More information on these operators can be found in the XPath functions standard.
Paths are used to locate nodes within XML trees.
Paths start at a context item and contain one or more steps.
Each step moves the expression's focus in a direction identified by the axis.
Filters can be used on each step to narrow the list of results being processed.
Variables can function as placeholders in an XML tree, and can serve as the first step in a path.
More information on paths can be found in the XPath standard.
Directions for traversing XML trees.
All expressions start at a fixed location in an XML tree called the context node. From there you can traverse (move) in several directions which are individually called an axis.
Below is a list of all axes. The default axis is child.
e.g., descendant::toy[@color = "red"]
The string "//" is a shorthand for descendant-or-self, while "@" is a shorthand for attribute.
More information on axes can be found in the XPath standard.
The starting point for an expression
The context item is either a node in the XML tree, or an atomic value (e.g., string, number). It designates the starting position of an expression, which can then be moved (navigated) away from.
The direction in which evaluation moves is called an axis.
Within an expression, the context item is referenced by a period (.).
More information on the context item can be found in the XPath standard.
Narrow a list of results
Filters provide an extremely flexible way to reduce a list of results according to some criteria. They are specified using square brackets and are also called predicates.
e.g., $products[price > 100]
e.g., $products[@price > 100]
e.g., $products[price > 100][color='red']
The preceding examples show how filters might work on a list of product information. The first one checks the value of a child element "price". The second one checks the value of an attribute "price". The third one does a secondary check of a child element "color".
More information on filters can be found in the XPath standard.
The building blocks on paths
Paths are used to locate one or more nodes in an XML tree. They contain one or more steps, separated by the path operator (/), each of which advance the navigation one step (part) at a time.
Each step generates a sequence of items and then optionally reduces the sequence by zero or more filters. Steps pass their results to the next step. The result of a path is the result of the last step in the path.
Steps may specify an axis to establish a direction to move. If no axis is provided the child axis is used.
Steps usually select a node based on name, however other node tests using wildcards or node type can also be used.
e.g., chapter[@num = '5']/title
e.g., chapter[@num = '5']/@author
Both of the above examples select a chapter element based on its "num" attribute. The first one then selects its "title" child element, while the second one selects its "author" attribute.
More information on steps can be found in the XPath standard.
Use a name to identify a node, sequence or value.
A variable is simply a name that points at something. The value of a variable can be anything that an expression returns.
The XPath expression language allows you to reference a variable using the "$" character, however it does not let you define one (except in the narrow scope defined by the let expression).
Variables are usually defined using the host language (a language which is built upon XPath), such as XSLT (logic) and XProc (pipelines).
e.g., $total - refers to a variable named "total"
e.g., $product/name - refers to the "name" child element of
an element stored in a variable named "product"
More information on variables can be found in the XPath standard.
Store zero or more items as a single object.
Sequences are treated like single items but can store zero or more ordered items. Many kinds of expressions return sequences.
They are similar to arrays, but cannot be nested and do not support lookup by position.
They are created by putting brackets around a comma-separated list of items. Nested sequences are flattened before any kind of processing occurs.
(1, 2, 5, 7) - creates a sequence with four members: 1, 2, 5, and 7
(1, (2, 5), (), 7) - creates a sequence with four members: 1, 2, 5, and 7
A range expression can be used to create a sequence of consecutive integers.
(10, 1 to 4) - returns a sequence of 10, 1, 2, 3, 4
10 to 10 - returns a sequence of 10
15 to 10 - returns an empty sequence
More information on sequences can be found in the XPath standard.
Trigonometric and exponential functions.
The XPath standard includes support for trigonometric and exponential functions. These are provided primarily for geometrical computation, which can be applied when generating SVG graphics.
These work just like normal functions, however they all use the math: prefix in their names.
More detail can be found in the XPath functions standard.
ExprType content.
Expression standards are used to define the precise syntax used by all expressions in Tag (e.g., in pipelines, content generation, form setup and more). There are two key standards.
XML Path Language (XPath) is a very widely used standard. It is used as a foundation for many other standards that work with data and logic.
XPath contains instructions for selecting data (paths), filtering, conversion, collections, conditions, looping, functions and more. Tag supports all of XPath 3.1, although there are still some limitations in the no-code expression editor.
XPath and XQuery Functions and Operators is an extension to XPath. It defines all standard XPath functions in great detail. This is where you find functions like round(), substring-after(), year-from-date(), format-date(), current-date() and many more. Tag supports all XPath 3.1 functions.
Content is defined using formatting objects, which use properties to specify text layout details.
The most important formatting object is block, which usually displays like a paragraph. Blocks can also be nested to provide structure for more complex documents.
Within block (paragraph) content, style can be applied to substrings of text (e.g., making a term italic). This is done using inline instructions.
Images can be inserted as inline content and flow within paragraphs like characters.
Ordered and unordered lists are supported, as are tables which contain columns, rows and cells.
Page headers and footers can be defined to display on printed pages. An optional first page header and/or footer is also supported.
Rich text can be converted into several file formats.
The default format for rich text is XSL-FO, which is a language of formatting objects. It is a well structured standard that lends itself well to content generation.
The core formatting objects are similar to other widely used formats: *.docx for word processing files, and *.html for website content. Tag allows you to convert a subset of formatting objects between these important open standards.
The Tag no-code editor for rich text supports blocks (paragraphs), inline text (bold/italic runs), images, lists and tables. In particular, it allows you combine these formatting instructions with logic to generate content.
After content is generated (in XSL-FO) it can be converted to DOCX or HTML. This can be done in the editor (Scribe and Automate apps), or using custom pipeline steps (Automate app only).
The scope of conversion matches the formatting objects in the editor. That is to say, only a subset of the DOCX and HTML standards is supported which corresponds to what you can type in Tag.
Generate word processor (*.docx) files.
The default format of the Tag no-code editor is XSL-FO. This is what gets created during content generation. The end result can be converted to *.docx files which can be edited in your favorite word processor.
When generating content in the Tag editor, you can select the DOCX format when saving the result.
In pipelines, the tag:docx step converts XSL-FO from any source to DOCX. The result is passed to the next step, which is usually p:store which will save it to a file.
Note that DOCX is not a true XML format that can be processed further by pipelines. In fact, *.docx files are zip files which contain multiple valid XML files - you can rename the file to *.zip and unzip normally to see what's inside.
Generate web content (*.html) files.
The default format of the Tag no-code editor is XSL-FO. This is what gets created during content generation. The end result can be converted to *.html files which can be viewed in a web browser, and/or edited in a text editor (e.g., Notepad++) or an HTML editor (e.g., BlueGriffon).
Note that the XHTML format is very similar to HTML, but is designed as pure XML (which HTML is not due to historical reasons). Most projects will want HTML which web browsers like to read, however since XHTML is based on XML it can be processed further using logic.
When generating content in the Tag editor, you can select the HTML or XHTML formats when saving the result (coming soon).
In pipelines, the tag:html step converts XSL-FO from any source to HTML or XHTML. The result is passed to the next step, which can save it to a file or process it further. Many pipeline steps accept XML or HTML, however p:archive, p:xslt and some custom Tag steps only accept XML.
Paragraphs and groups of paragraphs.
The fo:block instruction implements paragraphs. It can contain a mix of text (strings of characters) and nested elements. Nested elements are called inline text.
Blocks can be nested to create hierarchical structures. For example, when publishing a textbook it is convenient to create blocks for chapters, which contain blocks for sections, which contain a block for the title. Each block can update inherited properties, and this approach can make expressions more intuitive if you want to run queries on the book (e.g., to find snippets).
Text layout revolves around blocks. Block content is filled into the available viewing space, using line breaks as needed. Embedded objects like images are flowed in between text fragments as the user types.
Properties for font, color, margins and alignment are supported. All of these are inherited except margins, which means you can apply them at higher levels (e.g., making the font bold at the table level, will cause all text in all blocks in the table to use a bold font).
If blocks are turned into list items they continue to be blocks, however they now reside within fo:list-block, fo:list-item and fo:list-item-body ancestors.
Content for page headers and footers.
The XSL-FO standard can handle complex publishing requirements. This may include detailed instructions for page layout that uses conditional and/or repeating sections.
Tag is focused more on everyday word processing documents, that contain a page header and footer but nothing more complex.
When you create a new XSL-FO document in Tag a page structure is created to support this. It uses an 8.5 x 11 inches page size, allows for one header and one footer for most of the document, and an optional first page header and first page footer.
Tag can open documents with other page layouts, but may not be able to support the editing of headers and footers. If the default page layout is used, a toolbar button is provided to edit header/footer content.
There is no restriction on what content is used within headers and footers. Using a table can be very helpful to align text fragments to both the left and right edges of the page.
Embed external images within text.
The fo:external-graphic instruction creates inline content that resides (and flows) within blocks. It displays a single external graphic (image) file.
Supported image formats include PNG, JPEG and SVG.
The content-width and content-height properties establish the rectangular display area. If this is different from the image's native size, the image is scaled to fit.
If the scaling property is set to "uniform" (the default value), the scaling process will preserve the image's aspect ratio.
Applying style to substrings of text.
The fo:inline instruction lives within blocks. It wraps one or more characters and nested elements. Their main purpose is to affect style (e.g., make one word bold).
Inline instructions can be nested to an arbitrary level. Each one updates inherited properties when text is laid out, in the same way that blocks do.
Each inline instruction can only have one parent, which means a valid hierarchy is always preserved. This is different from some other rich text formats that use runs of text that may overlap. Having a reliable hierarchy can be extremely helpful when using expressions on the document tree.
Lists of ordered and unordered items.
The fo:list-block instruction creates block level content. This means that any line items it contains have access to the full width of the text layout area (subject to margins).
List blocks contain one or more fo:list-item instructions. List items are responsible for the bullet or number prefix area (which is not editable), as well as all content in the list item.
The bullet or number prefix area can technically be quite complex, to meet the requirements of high-end publishing jobs. Tag keeps things simple and has two pre-defined options: a bullet for unordered lists and a number for ordered lists. This is controlled using tools on the toolbar.
All content in a list item is stored in the fo:list-item-body instruction. This is a container for blocks and other block-level content. The tag editor automatically stores content that you type here, so this instruction can generally be ignored when editing.
Tables of rows and columns.
The fo:table instruction creates a table which is block level content (full page width). It contains a fixed hierarchy of instructions to define all the rows, columns and cells.
The first set of instructions are zero or more fo:table-columns. These are important to define column width, which can be specified using fixed or relative lengths.
The fo:table-body instruction contains all the fo:table-row instructions. Even though other structures are possible, Tag always uses rows to contain cells to match the behavior of most word processors.
Rows contain fo:table-cell instructions which is where most of the content is.
Table level properties include table width and inherited properties picked up by the cells.
Row level properties include row height and inherited properties picked up by the cells.
Cell level properties include font, color and alignment. Borders and shading can also be applied at this level.
Format commands make rich text look good.
Common format commands include color, font, alignment and page breaks.
Block margins refer to spacing on all 4 sides of blocks.
Borders and backgrounds can be defined using a list of properties that includes several convenient shorthands.
Format commands can also be applied at a higher conceptual level using inherited properties.
Apply borders and background shading.
There are 20 properties that can be used to define borders, giving you lots of control over them. The border-top-color, border-top-width and border-top-style (dotted, dashed, solid, groove and inset) properties define the top border. Similar ones exist for the right, bottom and left borders.
The border-top property is a shorthand that can combine all 3 settings (e.g., "1pt solid black"). There are similar shorthands for the right, bottom and left borders. There is also a border property which is a shorthand for all 4 sides.
The border-color, border-width and border-style properties are shorthands for all 4 sides.
Background shading is defined by several properties that specify color, image, position, repeat and attachment. The background property is a shorthand for several of the above (e.g., no-repeat center/80% url("lizard.png")).
The Tag editor lets you update borders and background shading for table cells. Updating these for blocks is not yet possible in the editor, but can be done using markup.
More information on borders can be found in this CSS tutorial.
More information on backgrounds can be found in this CSS tutorial.
Format commands found on the editor's toolbar.
These commands are familiar to most people from many programs including word processors, email editors, etc. Tag has tools in the editor for them as well, but also lets you use these commands with logic (e.g., when generating rich text).
The color property controls text color and is sometimes used for other marks (e.g., horizontal rule).
There are several font properties that control font family, size, bold and italic settings.
The text-align property defines how text in blocks (paragraphs) aligns to the edges (i.e., left, center, right and justify).
The break-before property will insert a page break before the text object it is attached to if its value is set to "page".
Format text logically using document structure.
There are two kinds of rich text properties: not-inherited and inherited.
Not-inherited properties only modify the content they are attached to. Margins are a good example.
Inherited properties modify the content they are attached to and all descendants. In the Tag editor, color, font and alignment are all inherited.
Using inherited properties can be very efficient. For example, placing a single "bold" command on a table will cause all paragraphs in the table to be bold. This can be helpful when generating content as you can apply format rules at a higher conceptual level.
The Tag editor provides hooks for inherited properties in several places. You can specify them at the inline, block, table, table row and table cell levels.
Allocate space above, below or beside text blocks.
Margins are a little like borders, in that you can change them for just one side, or several at once using a shorthand.
The margin-top, margin-right, margin-bottom and margin-left properties control margins on all 4 sides respectively.
The margin property is a shorthand that applies to multiple sides at once. For example,
"10px" updates all 4 sides
"10px 0" updates top/bottom | left/right
"10px 0 20px" updates top | left/right | bottom
"10px 0 20px 0.1in" updates top | right | bottom | left
More information on margins can be found in this CSS tutorial.
Rich text standards define formatted text used by word processors and web browsers. There are three standards that are supported in some way by Tag.
Extensible Stylesheet Language (XSL-FO) is a powerful standard capable of defining complex published works like textbooks and engineering manuals. Most notably, it has a well designed structure that lends itself well to content generation.
It defines formatting objects like blocks (paragraphs), lists, graphics, tables and more. It also defines formatting properties like margin-top, font-family and text-align. Tag supports a subset of XSL-FO that is comparable to what you find in a word processor.
Office Open XML (OpenXML) was created by Microsoft to store Word documents in an open XML format, and has since been implemented by several popular word processors including Mac Pages and Open Office. Tag lets you import and export OpenXML (*.docx files) by converting it to/from XSL-FO, which is more suitable for automated processing.
HTML5 is the central standard of the World Wide Web (the most visible part of the Internet). It is important to any organization that wants to communicate using a website.
Tag allows you generate HTML content using data, expressions and logic. This is useful when generating chunks of HTML (e.g., product information) that can be embedded in an existing website. Tag does not build or host entire websites.
The rich text editor in Tag currently only supports XSL-FO, however future versions will likely support native HTML5 editing of logic+content as well.
Use special effects to alter how graphics display.
Graphics objects can be translated (moved), scaled, rotated or skewed using transform effects.
Graphics objects can also be affected using filter effects, which create effects like blurring, changing color intensity and warping the image.
Animation can also be used on graphic objects to change the value of certain properties over time.
Change an attribute or property over time.
The svg:animate instruction lets you specify start and end values for any SVG attribute. When the animation is played, the value will be changed gradually over a specified duration.
The from and to properties contain the start and end values. The dur property specifies the duration (e.g., dur="5s").
Most graphic objects can be animated including shapes, text, images and groups.
Most properties can be animated including those that store angles, colors, numbers, paint (some limitations apply) and percentages.
The svg:animateMotion instruction causes a referenced element to move along a motion path.
The svg:animateTransform instruction animates transformation attributes, allowing animations to control translation, scaling, rotation and/or skewing.
More information on animate can be found in the SVG standard.
Using computation to transform graphics.
Filter effects involve taking one or more input images, performing operations on them, and producing one output image.
For example, a "flood" filter effect produces an output image that is completely filled with a given color. An "inversion" filter effect takes a single image input and adjusts each pixel to have the opposite color value.
The svg:filter instruction is used to define named filter effects. It uses x, y, width and height properties to establish an area that will be processed.
You can apply filter effects using the filter property (attribute) on a svg:g instruction.
There are pre-defined filter effects (primitives) that you can use as-is. These can also be combined to create a complex combination of effects.
The list of filter primitives includes svg:feBlend, svg:feConvolveMatrix, svg:feDiffuseLighting, svg:feDropShadow, svg:feGaussianBlur, svg:feTurbulence and more.
More information on filter effects can be found in the SVG standard and the related Filter Effects Module.
Translating, rotating and scaling.
You can create transformational effects using the transform property (attribute) on any SVG instruction. This property uses transform functions as explained below.
The translate() function moves an object by x and y coordinates (e.g., translate(50 50)).
The rotate() function specifies rotation by degrees about a given point (e.g., rotate(100, 10, 10) will rotate 100 degrees around the point 10@10). Note that the SVG rotate property on svg:text provides a shorthand way to achieve the same effect.
The scale() function changes the horizontal, vertical or both dimensions of an object (e.g., scale(4, 1) will only scale the horizontal dimension).
More information on transform property can be found in the SVG standard and the related CSS Transforms Module.
This topic groups together a few general purpose SVG features.
External images (PNG, JPEG or SVG) can be embedded within graphics.
Groups are used to logically organize graphic objects. They can be used to change style properties or apply special effects to several objects at once.
CSS rules can also be used to logically modify the style of graphic objects.
Treat several graphic objects as a single object.
The svg:g instruction is incredibly useful. It is used as a wrapper around one or more graphic objects to apply style or other special effects.
A group of elements, as well as individual objects, can be given a name using the id property. Named groups are needed for several purposes, such as animation and re-usable objects.
Groups created in the svg:defs section are re-usable and can be referenced later (perhaps many times) with the svg:use instruction.
Group elements can be nested to an arbitrary depth.
They provide a convenient way to specify inherited properties like fill and stroke, so that all child elements pick up the same values.
Transformations applied to a group are performed on all its child elements.
More information on groups can be found in the SVG standard.
Display an external image within a graphic.
The svg:image instruction lets you specify an image file to display within a rectangular area within a graphic. Supported image formats include PNG, JPEG and SVG.
The display area is defined by coordinates stored in the x and y properties, and extending to the width and height properties.
The preserveAspectRatio property determines how the image is scaled and positioned to fit into the display area.
By default, images will be clipped if they are larger than the display area. The overflow property can change this behavior.
More information on images can be found in the SVG standard.
Shapes can be filled or stroked using paint.
The SVG standard defines paint in several ways. Paint is applied to a shape using the fill property. Paint is applied to a shape's outline using the stroke property.
The most obvious kind of paint is a single color. Colors can be defined according to CSS rules (see link below) using keywords (e.g., "green", "blue"), hex notation (e.g., "#00ff00"), RGB values (e.g., "rgb(0,255,0)"), or RGBA values (e.g., "rgba(0,255,0,0.5)"). Using RGBA values allows you to change the color's opacity.
Linear or radial gradients are used to create smooth color transitions.
Patterns use a pre-defined graphic object and replicate (tile) it at fixed intervals to cover a larger area.
Smooth color transitions.
Gradients allow you to define a smooth, mathematical transition between two colors. They can be computed using linear or radial geometry.
The svg:linearGradient instruction changes colors in a top-to-bottom or left-to-right way. It uses x1, y1, x2 and y2 properties to define gradient vectors. Gradient vectors provide starting and ending points onto which gradient stops are mapped.
The svg:radialGradient instruction changes colors in a center-outward way. It uses cx, cy, r, fx, fy and fr properties to define circles onto which gradient stops are mapped.
The svg:stop instruction is used to define gradient stops for both linear and radial gradients.
More information on gradients can be found in the SVG standard.
Replicate graphic objects to paint larger areas.
Patterns allow you to paint larger areas by replicating (tiling) smaller graphic objects at fixed intervals.
The svg:pattern instruction is used to define smaller graphic objects that are used as patterns. It uses x, y, width and height properties to establish an area that will be copied many times.
The contents of svg:pattern can be any drawable SVG instruction including shapes, images and text.
When a pattern is used as paint, the area described by svg:pattern will be copied as many times as necessary to fill a shape or its outline (stroke).
More information on patterns can be found in the SVG standard.
Graphics can use paths to draw custom shapes.
The SVG standard describes paths using the analogy of drawing on paper: "The current point can be thought of as the location of the pen. The position of the pen can be changed, and the outline of a shape (open or closed) can be traced by dragging the pen in either straight lines or curves."
Paths can also be used for clipping paths, to describe animation, or position text.
Custom shapes are created using the path instruction. Custom shapes can use paint to set the fill (inner color) and stroke-* (border) properties. They can also use the effects properties.
The path instruction uses commands like moveto, lineto, arc, curveto and closepath.
Draw an elliptical arc.
The arc command draws an elliptical arc from the current point to specified x/y coordinates. The rx and ry values are radii that describe the curve. The x-axis-rotation (in degrees), large-arc-flag (0 or 1) and sweep-flag (0 or 1) values describe the arc sweep.
e.g., A 25,25 -30 0,1 50,-25
e.g., a 25,25 -30 0,1 50,-25
The A (uppercase) command indicates that absolute coordinates will follow. The a (lowercase) command indicates that relative coordinates will follow.
The order of values in this command is "rx ry x-axis-rotation large-arc-flag sweep-flag x y".
More information on arcs can be found in the SVG standard.
End a path to create a closed shape.
The closepath command ends the current path, or subpath, by connecting it back to its initial point. It accepts no parameters.
If a path does not have closepath command, it is considered an open subpath. Some instructions like painting will not work on open paths.
e.g., Z
e.g., z
The Z (uppercase) and z (lowercase) commands have an identical effect.
More information on closepath can be found in the SVG standard.
Draw cubic or quadratic Bézier curves.
The curveto command can draw cubic Bézier curves.
e.g., C 100,100 250,100 250,200
e.g., c 100,100 250,100 250,200
The C (uppercase) command indicates that absolute coordinates will follow. The c (lowercase) command indicates that relative coordinates will follow.
There are also convenience commands which draw a cubic curve from the current point (S and s).
The curveto command can also draw quadratic Bézier curves.
e.g., Q 400,50 600,300
e.g., q 400,50 600,300
The Q (uppercase) command indicates that absolute coordinates will follow. The q (lowercase) command indicates that relative coordinates will follow.
There are also convenience commands which draw a quadratic curve from the current point (T and t).
More information on curveto can be found in the SVG standard.
Draw a line from current point to new point.
The lineto command draws straight lines. The line always starts at the current point, and extends to the new point defined with x/y coordinates.
e.g., L 100 100
e.g., l 100 100
The L (uppercase) command indicates that absolute coordinates will follow. The l (lowercase) command indicates that relative coordinates will follow.
There are convenience commands provided for horizontal lines (H and h) and vertical lines (V and v), which only accept a single x or y coordinate.
More information on lineto can be found in the SVG standard.
Move the pen to a new initial point.
The moveto command creates the effect of lifting the pen and moving it to a new location. The new location (initial point and current point) is specified using x/y coordinates.
Paths must begin with a moveto command. Subsequent moveto commands represent the start of a new subpath.
e.g., M 100 100
e.g., m 100 100
The M (uppercase) command indicates that absolute coordinates will follow. The m (lowercase) command indicates that relative coordinates will follow.
More information on moveto can be found in the SVG standard.
Draw custom shape outlines.
The svg:path instruction draws a custom shape using commands (data) in the d property. A path is made up of segments and each command (other than moveto or closepath), defines one path segment.
Path data contains moveto, lineto, curveto, arc and closepath commands.
For example, a triangle is created using the following path data: "M 100 100 L 300 100 L 200 300 z".
More information on paths can be found in the SVG standard.
Graphics can contain mathematical shapes.
The SVG standard defines a core set of shapes using the coordinate system. Each coordinate is either a length (measured from top-left) or a percentage. Units can be provided for a coordinate (e.g., em, cm, mm, in, pt, pc, px, %), and if no units are provided px (pixels) is used.
Supported shapes include circle, rectangle, ellipse, line, polyline and polygon.
All shapes can use paint to set the fill (inner color) and stroke-* (border) properties. They can also use the effects properties.
Draw a circle based on a center point and a radius.
The svg:circle instruction draws a circle in the image centered on coordinates stored in the cx and cy properties.
The r attribute defines the radius which must be a positive value.
More information on circles can be found in the SVG standard.
Draw an ellipse based on a center point and two radii.
The svg:ellipse instruction draws an ellipse in the image centered on coordinates stored in the cx and cy properties.
The rx and ry properties define define the x- and y-axis radii of the ellipse. Both values must be positive.
More information on ellipses can be found in the SVG standard.
Draw a line from one point to another.
The svg:line instruction draws a line in the image from the point defined by the x1 and y1 properties to the point defined by the x2 and y2 properties.
More information on lines can be found in the SVG standard.
Draw a closed shape using line segments.
The svg:polygon instruction draws a polygon in the image using coordinates stored in the points attribute. The coordinates must be listed in pairs as follows (e.g., 350,75 379,161 469,161 397,215 423,301).
Drawing is done by creating lines between each point. The last point is automatically closed (i.e., a line is drawn from it to the first point).
More information on polygons can be found in the SVG standard.
Draw an open shape using line segments.
The svg:polyline instruction draws a polyline in the image using coordinates stored in the points attribute. The coordinates must be listed in pairs as follows (e.g., 350,75 379,161 469,161 397,215 423,301).
Drawing is done by creating lines between each point. The last point is not automatically closed which makes this an open shape.
More information on polylines can be found in the SVG standard.
Draw a rectangle using a point, width and height.
The svg:rect instruction draws a rectangle in the graphic starting from coordinates stored in the x and y properties, and extending to the width and height properties.
The rx and ry properties define rounded rectangles. If present, they define the x- and y-axis radii of elliptical arcs used to round off the corners of the rectangle. Both values must be positive.
More information on rectangles can be found in the SVG standard.
Apply CSS rules to graphic objects.
While you can use SVG properties on each graphic object to define details like font or color, CSS rules offer a way to apply style using logic. In this way, you could change the color of every circle using one command instead of updating each circle manually.
You can even update graphic objects more selectively (e.g., only update circles that are in a group). There are many other possibilities - CSS rules are powerful and expressive.
There are two ways to apply CSS rules to SVG graphics. The svg:style instruction lets you embed CSS rules in an inline stylesheet. This is useful if you have one graphic and one set of CSS rules.
An alternative is to use the html:link instruction (which is unusual because it uses the HTML namespace and not the SVG namespace), or an @import rule in an inline stylesheet that points to an external *.css file. In both cases the result is the same, and you can share one set of CSS rules between multiple graphics.
More information on style can be found in the SVG standard and in some of the many web pages discussing CSS.
Embed text within graphics.
The svg:text instruction draws a string of characters starting from coordinates stored in the x and y properties. Once drawn, chunks of text behave just like shapes and can be painted, clipped, masked or transformed in the same way.
Properties are available to specify font. Text decorations (e.g., underlining, over-lining) are also supported.
Authors can use a horizontal or vertical orientation of text, and left-to-right or bidirectional text is also possible.
The dx and dy properties shift text position, while the rotate property specifies desired rotation (in degrees).
If an inline-size property is provided, text will be auto-wrapped to fit within that size.
More advanced effects can be achieved using text in shape and text on path. Text spans are used to alter style for substrings of a text chunk.
More information on text can be found in the SVG standard.
Use a shape to define text wrapping area.
The shape-inside property of a text instruction allows you to make text flow within a shape.
The shape used to contain wrapped text can be a circle, rectangle, ellipse or polygon. A special syntax is used to define the shape, for example "circle(120px at 150px 150px)".
The shape-subtract property is used to "carve out" areas within the shape that should not contain text.
The shape-inside property can contain a list of shapes. Each shape defines an independent content area. Text is first laid out in the first shape. If it overflows that first shape, the overflow text is laid out in the next shape until all text is laid out or no more shapes exist.
More information on text in shape can be found in the SVG standard.
Layout text along a path or shape.
The svg:textPath instruction allows you to make text flow along a path, or along the outline of a shape.
The textPath instruction must be placed within a svg:text instruction. Path data can be provided using the path property, or by referencing a pre-defined path object.
Characters can be aligned with no stretching/warping, or stretched using the method property.
Properties are also available to define a start offset, spacing between characters, and the side of the path that text should be placed on.
More information on text on path can be found in the SVG standard.
Define text style for sections of a text block.
The svg:tspan instruction wraps a substring of characters within a text string. It is used to change style or apply other effects at a more granular level.
The tspan instruction has an identical set of properties to the text instruction.
More information on text spans can be found in the SVG standard.
There is only one open standard that directly addresses graphics, however it works closely with the HTML standard used in websites.
Scalable Vector Graphics (SVG) considers graphics from a logical perspective. It lets you use instructions to create shapes, text, paths, paint and special effects.
SVG documents (*.svg) are considered images when embedded in HTML, working exactly the same as PNG or JPEG files. The only difference is you can open SVG files in a text editor and see exactly what is being drawn in the image.
It can be used to create simple logical graphics that combine shapes, text and paths to create logos, icons, branding images and even posters. Since SVG is scalable, it can provide consistently high quality results even at very large sizes.
SVG can also store scenes created by free-hand (as an artist draws on paper). A great (free) program that does this well is Inkscape. Although you can view free-hand SVG files in a text editor, they can contain very dense mathematical paths that are difficult for humans to read. That being said, you can still use IDs and expressions to gain some level of programmatic control of these images.
SVG is widely supported on the web. There are many free sites that contain samples, and many web services that offer SVG as an option when downloading. It is also widely used in software that is not a web browser (like Tag).
Control how pipeline steps run.
Pipelines are made of steps. They process documents by allowing them to flow between steps.
Container steps provide a way to organize steps, and apply high-level conditional and looping logic to the flow of documents.
Atomic steps define options which let you pass in values when running them. Option values directly impact how steps run.
Variables are used to define temporary values, give them a name, and reuse them multiple times within pipeline expressions.
Define high-level pipeline logic.
Pipelines are made of steps. There are two kinds of step: atomic and container. Atomic steps do all the real work, processing documents and creating output.
Container steps organize and control how atomic steps run, using higher-level logical concepts.
The p:if container step acts as a guard for its child steps, and only lets them run if a test expression resolves to true.
The p:choose step is similar except it defines multiple outcomes, each one guarded by its own test expression. Both of these steps define conditional logic.
The p:for-each step supports looping (repetition). It accepts a sequence of documents, and runs its child steps once for each input document.
The p:group step provides a convenient way to organize related child steps. The p:viewport step produces multiple "views" of a single input document. Finally, the p:try step defines an error handling mechanism.
More information on container steps can be found in the XProc standard.
Pass documents between steps.
As a pipeline runs, documents are passed between steps. There are many ways for this to occur, and the process in general is referred to as flow.
The most important, and by far the most commonly used, flow is between primary ports. This is the default flow that occurs with no additional instructions required.
There are primary input and output ports. A primary output ports (if one exists) automatically passes its document(s) to the next step's primary input port (if one exists). This kind of flow only occurs between sibling steps.
Pipeline authors can change, or augment, the default flow using port bindings. Flow is also affected by Container steps, which define higher-level conditional and looping logic.
There are two notable ways to stop the default flow. The p:sink step accepts one or more documents on its primary input port and does not have an output port. Anything that flows into it, disappears.
Similarly, the p:empty binding allows you to delete the current contents of a port (if any).
Use settings to control how steps run.
The p:option instruction defines a named setting for a step. It can be a true/false flag, a string, or anything else that an expression can understand.
Some options are optional and have a default value (specified using the select attribute). Others are mandatory and require that you provide a value when you call that step (using a p:with-option instruction).
The as attribute defines the datatype of an option. The values attribute can be used to list acceptable values.
An option's current value can be accessed in expressions. They behave exactly like variables and are referenced using the "$" character (e.g., $optionA).
The p:with-option instruction is important, and lets you set an option's value when running a step. It works much the same as p:option, but with 3 more attributes. The href and pipe attributes are shorthands for port bindings. The collection attribute lets you treat the input document sequence as the default collection within an XPath expression.
More information on p:option can be found in the XProc standard.
Define and use temporary named values.
The p:variable instruction creates a temporary value and gives it a name. That value can then be reused and accessed within expressions multiple times.
Variables can store any kind of value (e.g., string, number, true/false, XML node, map, array, etc.). They can also store port bindings, which allows them to load documents just like a port does.
A variable's current value can be accessed in expressions using the "$" character (e.g., $varB). Variable and option names are managed in a single pool, meaning you can use them interchangeably within expressions.
If a variable or option uses a name that is already in use, its value will take precedence while that instruction is in force (in scope). This is called "shadowing" and simply means lower-level values can override high-level ones.
More information on p:variable can be found in the XProc standard.
Ports enable documents to flow between steps.
Pipeline steps do work on documents. They have a clearly defined model of how documents get passed in, and how the results of their work get passed out.
Input ports are part of a step's definition. They are addressable by name and have other properties (e.g., can it store 1 document or many, what document format is expected). Logic within a step can read input ports by name, to do whatever work is required.
Output ports are very similar, although they store the result of a step's work. They have names and similar properties.
You can store document(s) in ports using bindings. These include loading from URI, piping from another step and in-memory inline content.
There is also an p:empty binding, which guarantees that a port remains empty. This can be useful in conditional logic, to signal that an outcome did not succeed (e.g., a report on an output port will only exist if the step succeeds).
Read from temporary in-memory documents.
The p:inline instruction provides a way to define a document within the instruction itself, without any need to save it in a file or elsewhere.
This technique works for any text-based document type, including the most important XML, HTML, JSON and text formats. It is an invaluable feature for pipeline authors.
The content-type attribute determines how an inline document is interpreted (default is XML). In some cases, the encoding attribute may also be specified (e.g., base64).
More information on p:inline can be found in the XProc standard.
Pass documents into steps.
Input ports provide a named or unnamed "hook" upon which you can provide a document to a step.
Container steps generally use unnamed input ports. Input documents are provided using a p:with-input instruction that does not use a name.
Atomic steps use named input ports defined by an p:input instruction. Most have a "source" input port, occasionally accompanied by a secondary input port (e.g., query, stylesheet, replacement). Some atomic steps do not have an input port (e.g., p:load which reads a document from a URI).
If at least 1 input port exists, a step must have 1 designated primary input port (using the p:primary attribute). This is a special input port, which automatically receives document(s) from the previous step's primary output port (if one exists).
Input ports can load static documents (the same for every run) using an p:href attribute, or dynamic documents (can be different for each run) using p:with-input instructions. There are many ways to bind documents to input ports.
Some input ports accept a single document while others accept a sequence of documents. This is controlled using the p:sequence attribute (default is no sequence).
More information on p:input can be found in the XProc standard.
Read documents from files.
The p:document instruction reads 1 document from the href attribute URI.
Using the URI, it can read local files using the file:// protocol. It can also read remote files using the http:// protocol.
If the URI is relative, it will be resolved against the base URI. By default, that is the folder containing the pipeline, however this can be changed using the xml:base instruction.
The content-type attribute determines how the document is interpreted. If not provided, the system will infer the content type (from file name, or peeking inside), or retrieve it from HTTP response headers.
More information on p:document can be found in the XProc standard.
Provide access to step output.
The p:output instruction provides a named "hook" upon which the output from steps is written.
Container steps generally use output ports defined by their last child step. There are some special rules related to the p:choose step, that ensure all possible outcomes have a consistent primary output port (see below).
Most atomic steps have a "result" output port, occasionally accompanied by a secondary output port (e.g., report, differences, not-matched). The p:sink step does not have an output port, and therefore (intentionally) blocks the normal flow of documents from progressing to the next step.
If at least 1 output port exists, a step must have 1 designated primary output port (using the p:primary attribute). This is a special output port, which automatically passes document(s) to the next step's primary input port (if one exists).
Some output ports accept a single document while others accept a sequence of documents. This is controlled using the p:sequence attribute (default is no sequence).
More information on p:output can be found in the XProc standard.
Documents can be "piped" between steps.
The p:pipe instruction connects an input port to a port on another step.
Ports are identified using the port attribute and the step attribute. A shorthand way to refer to a port is "portName@stepName" (e.g., as used in the pipe attribute of the p:with-input instruction).
Port names are declared when a step is defined. All steps have at least 1 input or output port.
Step names may be specified when a step is added to a pipeline, or the default step name is used. Default names are based on the step position in the pipeline (e.g., "!1.2" refers to the second child of the root step, where the root step is always p:declare-step).
Default names are not stable, because if you insert another step somewhere before a given step, its default name will change. Therefore, it is safer to explicitly name any step that you reference with p:pipe.
More information on p:pipe can be found in the XProc standard.
Click on the arrow icon (hover your mouse over the "steps" topic in the feature graph) to review a list of all steps available in the pipeline editor (the step dialog).
Steps are organized into a tree that can filter based on an "advanced" flag. This is the same tree used to add steps in the pipeline editor, although the list of steps shown will vary in the editor depending upon which pipeline engine is selected.
If the Tag pipeline engine is selected, some XProc steps that are not yet implemented directly are hidden, and the Tag extension steps are shown. If an external engine (e.g., Morgana) is selected, all XProc steps will be shown and the Tag extension steps are hidden.
Documentation in the step dialog addresses input ports, output ports and options that are declared for that step. Links to online documentation are also provided, where in some cases there is more detail.
There is an important distinction between Container steps and atomic steps. The former has child steps and is responsible for conditional logic and pipeline flow. The later does real work, and never has child steps. The step dialog includes both.
There is only one open standard that directly addresses pipelines, however it works closely with the same expression standards used to support no-code logic.
XML Pipeline Language (XProc) defines pipelines of reusable steps that do useful work. It lets you automate and combine many tasks, including some that utilize other open standards.
Steps are usually arranged in a list, where steps receive something from the previous step, and pass something else on to the next step. Different steps specialize in handling different tasks, and the scope of pre-defined steps available to you is substantial.
Most tasks process XML data/content. This provides a hierarchical view of your files, allowing you to find, insert, delete or copy specific chunks of content with ease.
Some tasks also process JSON (from web APIs) or text files, or some combination of several formats. Tag makes it easy to swap between XML and JSON, which means they can often be treated as alternative views of the same hierarchy of data/content (i.e., you can do a lot of cool stuff with JSON).
XProc supports extension steps, which provide capabilities outside the scope of XProc. Tag includes several of these that support reading SQL databases, calling web APIs, converting between common file formats, and more.
Logic is used to create content.
The ultimate goal of generating content is to create files that contain useful content. Content is defined as whatever the host language (e.g., rich text, graphics) is representing.
Content can be static (never change) or dynamic (change according to data values). These can be freely mixed as you generate new content.
Sometimes you need to copy content and want to paste it in several places. The copy instructions let you do this, and even let you customize exactly what is being pasted based on data.
The output instruction provides additional control over how a file is saved. For many projects it can be ignored.
Generate static or dynamic content.
There are two main ways to generate content that belongs to a host language (e.g., rich text, graphics). They are static (literal) content that never changes, and dynamic (logic based) content. Both are created within templates.
Literal content is created simply by adding host language instructions to the template. If you add a circle at location 100@100, it will be generated exactly that way every time you run the template.
Dynamic content uses logic and can change each time you run. The xsl:element, xsl:attribute and xsl:text instructions let you create content according to logic and data. For example, the circle created above could change its location using xsl:attribute according to data values (e.g., sales, customer satisfaction).
Using xsl:element you can even change what is created. For example, based on data values you could insert an image into rich text, or a table that contains much more detail. Elements are the main instructions, while attributes customize how they run.
Adding dynamic text means you can compute phrases, such as taking a list of strings and writing them as a comma-separated phrase ending with a final 'and' (e.g., "Tuesday, Thursday and Friday"). You can also decide between words or phrases, such as "We exceeded sales targets" where 'exceeded' is chosen from a list of allowed values.
The xsl:sequence instruction creates sequences of items. A common use of this is creating a list of items (strings, numbers, XML fragments, or other), and reading/processing them in a xsl:for-each instruction.
More detail on creating new content can be found in the XSLT standard.
Copy content from one location to another.
The xsl:copy instruction copies content retrieved by the select attribute expression. If no expression is provided, the context item is copied.
The precise nature of the copy depends upon what item is selected to copy. If that item is an atomic value (e.g., string, number, true/false), just that value is copied.
Similarly, if a simple XML node is selected (e.g., text, attribute) just that node is copied.
When the selected node is an element or document, a shallow copy (same kind and name, but no children or attributes) is made at first. The contents of the new node is constructed from child instructions of the xsl:copy instruction, and the select attribute expression if one exists.
Additional attributes can be used to control how namespaces are handled, to apply named attribute sets, or to run validation on the final constructed node.
The xsl:copy-of instruction is similar, yet simpler. It inserts a deep copy of the selected node and does not contain any child instructions. See the link below for more information.
These instructions can only be entered in Tag using the Automate app and the tree editor (or raw markup).
More detail on xsl:copy can be found in the XSLT standard.
More detail on xsl:copy-of can be found in the XSLT standard.
Control how result documents are saved.
The xsl:output instruction can be ignored in many situations when using Tag. The Tag editor often knows enough about the host language to set default output settings for you.
However, in other situations you may need more control. The output instruction has many attributes that let you control all aspects of how a document is saved.
There are attributes that control indent, media-type and encoding. Others deal with versions, separators, namespace prefixes and more.
See the link below for more information.
This instruction can only be entered in Tag using the Automate app and the tree editor (or raw markup).
More detail on xsl:output can be found in the XSLT standard.
Pass in named values when calling logic.
Parameters (referred to as pass-in values in Tag) provide a way to pass data in to a template, or to all templates (global parameters). They are referenced in expressions exactly like variables using the "$" character.
Parameters are defined as part of a template. A name is assigned and an optional default value may be provided. They can also be marked as required.
Tag doesn't yet let you define global parameters, although it will process them properly if they exist. This means you can define them using raw markup.
The names of parameters will shadow variable names and vice versa. Template level parameters will similarly shadow global parameters, and parameters defined in higher-level (calling) templates.
More detail on parameters can be found in the XSLT standard.
Useful logic requires some processing.
One of the most commonly used logic instructions is if/then. It serves as a guard for its child instructions, only letting them run when conditions are right.
Slightly more complex is choose/when. It stores guards for several possible outcomes, choosing zero or one at generation time according to logic.
Looping is handled by identifying a sequence of items, and running all child instructions once for each item.
Items of all types can be sorted, utilizing multiple sort keys and detailed sorting instructions.
Numbering is also supported, in a way that respects hierarchical document structure (e.g., "chapter 5 / section 2 / title" could correspond to number "5.2.1").
Conditional logic using choose/when rules.
The xsl:choose instruction defines several possible outcomes and uses expressions to choose between them.
It may only contain xsl:when and xsl:otherwise instructions. Each when has a test attribute which contains an expression that must resolve to a true/false value.
When the choose instruction runs, it queries each of the stored whens in order and selects the first one that has a test expression that resolves to true. If none do, the contents of the otherwise instruction is used if one exists.
More detail on xsl:choose can be found in the XSLT standard.
XsltForEach content.
The xsl:for-each instruction processes each item in a sequence of items. It does so by executing its child instructions once for each item.
When an item is processed, it is designated as the context item. This allows expressions to refer to the current item explicitly. Expressions can also access the context position (position of the item in its sequence) and context size (total number of items in the sequence).
The items can be sorted before processing begins.
Repetition is also supported by the xsl:iterate instruction. It is more suitable for calculating running totals (e.g., where values computed for one item are available to subsequent items).
The xsl:for-each instruction is supported by the Tag no-code editor, while the xsl:iterate instruction is not (it can be added using the tree view or by using raw XSLT markup.
More detail on xsl:for-each can be found in the XSLT standard.
More detail on xsl:iterate can be found in the XSLT standard.
Conditional logic using if/then rules.
The xsl:if instruction serves as a guard for its child instructions.
The test attribute contains an expression that must resolve to a true/false value. The child instructions of an xsl:if will only be processed in the test expression resolves to true.
More detail on xsl:if can be found in the XSLT standard.
Create a formatted number.
The xsl:number instruction accepts a number one of two ways. The most common is evaluating the value attribute expression. It can also be calculating based on the position of a selected node within the XML tree using the select, level, count and from attributes.
It processes the number by determining a place marker, which is a position within a hierarchic numbering scheme (e.g., "1.12.2" or "3(c)ii"). It also formats the place marker to insert it into final text.
The start-at attribute is used to restart numbering of a list of items. It can handle hierarchical positions within the final document.
The format attribute is used to describe how the number should appear in text. The default value is "1". A more interesting example is for the sequence of numbers 5, 13, 7 and the format token "A-001(i)", the output will be the string "E-013(vii)".
The xsl:number instruction is not yet available in the Tag no-code editor. It can be added using the tree view or by using raw XSLT markup.
More detail on xsl:number can be found in the XSLT standard.
Sort a sequence of items.
The xsl:sort instruction defines rules for sorting. Several can be used together to define multiple sort keys.
A sequence of xsl:sort instructions is called a sort key specification. The first instruction is the primary sort key, followed by the secondary key, and so on.
A sort key specification may occur immediately within xsl:apply-templates, xsl:for-each, xsl:perform-sort, or xsl:for-each-group instructions. They must always be placed before any other child instructions.
Sort key instructions define how sort key values are calculated, and how they are compared. The value is determined by either the select attribute expression, or its child instructions. If neither is present the default select expression "." will use the current item value as-is.
The sorting process is informed by the order ("ascending" or "descending"), collation and case-order attributes.
The xsl:sort instruction is not yet available in the Tag no-code editor. It can be added using the tree view or by using raw XSLT markup.
More detail on xsl:sort can be found in the XSLT standard.
Templates combine content, data and logic.
The xsl:template instruction defines a reusable template which can contain many things. Templates can contain content and/or logic instructions, in almost any combination.
Content is defined by the host language, which is the vocabulary you want to generate (e.g., rich text, graphics). Logic instructions are defined by the XSLT language.
Templates can be called by name, if one is provided in the name attribute.
They can also be applied by XML node type, if a match attribute pattern is provided.
Templates are a fundamental unit of reuse when generating content. The same template can be invoked many times while generating a result document.
They can also be shared between multiple generated documents, by importing templates from another file.
More detail on xsl:template can be found in the XSLT standard.
Calling a template inserts its content.
Templates can be named using the name attribute. The xsl:call-template instruction calls a named template and optionally passes in information.
When a call-template instruction is run, it is replaced by whatever is created by the called template. A template may create content, more instructions, or nothing at all.
If a named template defines one or more named parameters, you can pass-in values for the parameters when you call the template. This is done using the xsl:with-param instruction.
Parameters may be optional and define default values, or they may be required (and must be provided before the generation logic can run).
In rich text documents, call-template instructions display as logic bubbles, which freely float within formatted text (like small images). When generating graphics, call-template instructions are created in an XML tree view (or using raw XSLT markup).
More detail on xsl:call-template can be found in the XSLT standard.
Templates can be shared between generated documents.
Templates are stored in *.xsl files. One of their more useful features is the ability to import them.
When generating multiple documents that contain similar content, or process similar data, the need to reuse logic occurs often. This is supported using the xsl:import instruction.
For example, there may be 2 generated rich text documents that include some common client data. If the client data includes a gender field, it makes sense to create a "he-she" template that knows about the client data and inserts "he" or "she" as required. Since both documents have the same need for this template, you can define 1 copy of it and import it into both documents.
The xsl:include instruction works in a similar way. The difference is that, when importing, template rules and other declarations in the importing module take precedence over template rules and declarations in the imported module.
More detail on xsl:import can be found in the XSLT standard.
More detail on xsl:include can be found in the XSLT standard.
Templates can be matched to content by type.
An alternative to naming templates is using match patterns. These are defined using the match attribute.
Match attributes store XSLT selection patterns, which is a concise syntax to select XML nodes within an input document.
For example, if an input (source) document contained a <name> element, the selection pattern "name" will detect the presence of this element and apply a template that has that pattern or something similar.
The matching process is started using the xsl:apply-templates instruction, which takes an input sequence of items and selects a template to run for each one based on match patterns.
When using match patterns, it may also be necessary to establish priorities between templates. This is done using the priority attribute on templates which stores a number.
Note that Tag's no-code rich text template editor supports match patterns in the Automate app. The Scribe app only supports named templates.
More detail on selection patterns can be found in the XSLT standard.
More detail on xsl:apply-templates can be found in the XSLT standard.
Use named references to other items
Variables provide a way to assign a name to any kind of item. They can be used anywhere in expressions using the "$" character.
Logic instructions can be used to create variables. They are usually defined as a name combined with a binding expression. Whenever the variable is referenced, the result of the binding expression is substituted.
Variables can also define inline values, instead of providing a binding expression. In this case, the content of the variable instruction (which can be logic and/or content) is substituted whenever the variable is referenced.
The names of variables do not have to be unique. If a new declaration of variable is encountered using a name that is already in use, the new value will take precedence and is said to "shadow" the existing declaration's value.
More detail on variables can be found in the XSLT standard.
Logic standards define the central rules behind content and data generation. There is one important standard in this area, which works closely with the other data and expression standards.
XSL Transformations (XSLT) is a powerful technology that unlocks many of the tools used by software programmers. Making logic instructions like these easy to use for non-technical people, is one of the central goals of the no-code philosophy embraced by Tag.
XSLT provides a way to define chunks of reusable logic+content (templates), and share them in a modular way.
It also integrates expressions, using them to handle conditional (if-then) processing, repetition, sorting, numbering and more. Tag has rich support for expressions (i.e., no-code expression editor), and leverages that when editing XSLT instructions.
You can create XSLT instructions within formatted text and have them seamlessly flow with other content as you type.
You can also create XSLT instructions using the XML tree editor, which is important when generating content that is not formatted text (e.g., HTML or vector graphics).