In ZML, paragraphs are delimited (~separated) by empty lines. There is no limit as to how many characters each paragraph contains. They can be as short as a single word. As long as there is an empty line before a piece of text, then that piece is called a paragraph, and can use ZML's paragraph formatting. If there are no empty lines in your text, then the whole text is treated as a single paragraph!

Empty lines are created by pressing Enter twice. If you press it once, then you create line breaks. There is no point in pressing Enter more than twice, as ZML automatically deletes excessive lines. Whitespace between paragraphs is controlled by the skin and not by the user.

ZML recognizes the following paragraph types:

  1. Plain
  2. Rules
  3. Headings
  4. Lists
  5. Clips

It is very important to understand that these types have to do with their syntax in plain text, and not with how they are rendered and appear in your browser. The purpose of ZML is to convert plain text to rich HTML text. How HTML is presented is the job of the skin in use.

Last but not least, ZML uses a powerful construct, called a paragraph shebang, which allows you to not only control and/or choose a different rendering for your paragraphs but to also generate them dynamically, such as a table of contents.

Plain paragraphs

Plain paragraphs are - as the name implies - paragraphs with no special structure and format other than the usual one found in written language: an extra vertical whitespace that separates them from each other and makes reading easier. An example of a plain paragraph is the one you are reading right now!

ZML breaks text into paragraphs (on empty line boundaries) and looks for a special syntax. If none is found, the paragraph is output as plain (wrapped with a <p> tag).

Plain paragraphs are - as the name implies - paragraphs with no special structure and ...

ZML breaks text into paragraphs (on empty line boundaries) and looks for ...


If a paragraph consists solely of repeating (2 or more) equal signs, hyphens or tildes (= - ~), then that paragraph is output as a horizontal rule construct, the appearance of which is controlled by the active skin.


You can use any of these characters but only a single one of them should be repeated. No spaces or other symbols are allowed in a rule paragraph.

... the appearance of which is controlled by the active skin.


You can use any of these characters ...


If a paragraph consists of 2 lines, where the first one is text and the second one is a repetition (2 or more) of either equal signs or hyphens (= -), then that paragraph is interpreted as a heading. If it is equal signs, then the heading is marked as <h2>, otherwise an <h3> is output.


If a paragraph consists of **2 lines**, ...


A list is a paragraph with at least 2 items. A list item is an arbitrary piece of text preceded by a predefined symbol followed by a single space. In other words, each item is prefixed by a two character sequence: symbol+space.

There are 4 types of list supported, each one designated with a separate symbol, as following:

 NameUsed for
-hyphen / minusUnordered lists
+cross / plusOrdered lists
*asterisk / timesDefinition lists

The following rules and conditions apply to lists and their items:

  1. Each item must start on a new line (not paragraph). This means that you must press a single Enter between items.
  2. Each item must start with the same symbol used in the list's first item. You cannot have mixed-type list items!
  3. You may use line breaks in items, as long as you start each line (not item) with 2 spaces.
  4. Lists can be nested. A child list follows exactly the same rules and conditions as the parent list, except from the fact that it is indented with 2 spaces. A child list can be of a different type that its parent list.

Unordered list

A list is unordered when its items are not numbered. A bullet is commonly used for prefixing its items. Use an unordered list for listing items whose order has no semantics.

Example of an an unordered list:

  • item 1
  • item 2
  • item 3
Example of an unordered list:

- item 1
- item 2
- item 3

Ordered list

A list is ordered when its items are numbered. Use an ordered list for listings items whose order is significant (like procedural steps, to do items, etc).

Example of an ordered list:

  1. item 1
  2. item 2
  3. item 3
Example of an an unordered list:

+ item 1
+ item 2
+ item 3

Definition list

This is a list of terms and their definitions. Due to its nature, there must be at least one line break per item so that this list is qualified as a definition one. You can have more line breaks, if you like. Each one of them will translate into a separate definition.

Example of a definition list:

term 1
definition 1
term 2
definition 2
term 3
definition 3
Example of a definition list:

* term 1
  definition 1
* term 2
  definition 2
* term 3
  definition 3


This is a list in which items are presented as a grid of rows and columns. Each item represents a row. Each line in an item represents a column. So, similarly to a definition list, there must be at least one line break per item so that this list is qualified as a table.

Example of a table:

Example of a table:

# R1C1
# R2C1
# R3C1


This is one of the most powerful and unique ZML features! The clip tag allows you to inject dynamic content, generated by zoglair's content building plugins, called clips. Since a clip can output anything, from a single phrase to a whole portal (!), you realize that using this feature there is absolutely no limit to what you can “write”!

To inject a clip into your text, enter the following:


The “[path?query]” part is optional and depends on the clip in use. You cannot insert a clip inline - it has to be on its own paragraph.

The problem with this tag is, of course, to find out all the available clips and their syntax. There are clips that come with zoglair as default, clips you can install as Addons and clips you can create yourself via the Hook mechanism. For this purpose, zoglair supports the following convenient url:


The above url will show you (among other) all available clips on your domain, except those created via the “zClipCustom::html” hook. As a convenience, the help button on your toolbar, shows you the same URL.

Paragraph Shebangs

If the first line of a paragraph starts with a shebang sequence (“#!”), then this line is considered to be a list of attributes in standard (X)HTML format:

#! name1="value1" ... nameN="valueN"

You may enter any number of name="value" space-delimited pairs.

Shebang attributes fall into 2 categories:

  1. System attributes
  2. Standard (X)HTML attributes

ZML parser first looks for, extracts and processes all system attributes found in a paragraph shebang. If any are left, they are copied (verbatim) to the paragraph's opening tag, whatever that is. The most common (standard) attributes that you would want to use, are the “class” and “style” ones.

Example of class and style attributes:

I am a special paragraph!

Example of class and attribute:

#! class="faded" style="letter-spacing:1em;"
I am a special paragraph!

There are a lot of predefined classes to use, plus you can create you own via the “zSkinBase::render_unit_css” Hook. Unfortunately, a CSS reference is beyond the scope of this guide.

System attributes

Zoglair comes with 2 system attributes registered under the following names:

  1. sevel, and
  2. @

The first one (sevel) allows you to type a paragraph that will be either visible to guests only (if sevel=0) or to users having at least the specified sevel (if sevel>0)!

To make a paragraph in your text appear to guests only :

#! sevel="0"
Dear visitor, why don't you register?

To make a paragraph in your text appear to staff only :

#! sevel="4"
This needs to be fixed, somehow...

The second one (@) is a special attribute because it creates paragraphs dynamically. So, this attribute does not really apply to the following paragraph's text because it is a paragraph on its own. In fact, using this attribute means the shebang line is the only line in the paragraph. You may still use other attributes, like class, to be applied to the generated paragraph.

What this symbol does is to execute a function, in the local scope of the active parser instance, with specified arguments. And this exactly is where it differs from a clip paragraph, as discussed above. Clips are “aliens”, autonomous entities, which have no knowledge of the running text. @ functions are “friends”, trusted with ultimate knowledge. Zoglair comes with an @ function registered as “toc” that stands for “table of contents”.

Dynamic table of contents

You can have a dynamic table of contents (ToC), generated for you automatically, by using the following paragraph shebang:

#! @="toc [anchors|(C|c)hildren|(C|c)hapions] [-|+|#|*] [<img>] [more]

As you can see, the “@” system attribute is used for executing function “toc”. This function takes up to 4 optional arguments:

  1. The ToC's content type
    (if left empty, anchors will be used)
  2. The ToC's list type
    (if left empty, - will be used)
  3. The ToC's image type or dimension
    (if left empty, no images will be used)
  4. A phrase name to be appended at the end of each topic's excerpt (useful for adding a “more” button or link phrase)
    (if left empty, nothing will be appended)

1st argument: content type

There are three content types; anchors, children and chapions:

A list of all headings included in your text. Something like a pagemap.
An example of this ToC can be found in Installation Procedure.
A list of the current page node's children, along with a small excerpt.
An example of this ToC can be found in all chapters of this guide, like Getting Started.
A 2-level list of the current page node's children and descendants.
An example of this ToC can be found in User Guide.

Both children and chapions may be typed with either a lower or upper case “C”. There is difference between them: an uppercase “C” will make the top links bold. You can use this extra tag to further modify their appearance via CSS.

2nd argument: list type

All ToCs are structured as list paragraphs. This argument controls the list type (unordered, ordered, definition or table) according to the relative section above.

3rd argument: images

In children ToCs there is an additional option of using images. For example, the ToC in Documentation is generated with the following shebang:

#! @="toc Children - medx0" class="grid col2 toc"

This argument can have the following possible formats:

1. (ico|sml|med|big|ful|d+)x(ico|sml|med|big|d+|[0-9.]+)
This is output as
{{<uploadId> |<img>}}
so, every item gets an image with the given dimensions.
2. (icon\d\d)[0-9a-fA-F]{2}
This is output as
so, every item gets the specified icon in front.
3. [1a-zA-Z]
This is output as
<em class="sn rounded">%i</em>
where %i is incremented, so, every item is auto-numbered.

4th argument: more

Only applicable to the children type of ToC, it gives you the ability to add an additional (to the title) custom link, at the end of the excerpt. This must be the name of a phrase, created by you, accepting a single parameter (the ToC's node). For example, this site uses a phrase named “var.more”, with the following content:

[[%1%|>>^Read more...|~var more rounded]]

« Blocks Inline »
(C) Nick B. Cassos - All Rights Reserved
powered by zoglair
page generated in 60ms (11 queries, 9ms)