vb@0: include homepage.en.yhtml2
vb@0:
vb@0: page "The Features" {
vb@0: h2 id=text > Text
vb@0:
vb@0: p >>
vb@0: To output text nodes (¬http://www.w3.org/TR/2008/REC-xml-20081126/#syntax character data¬),
vb@0: write literals. There are integer literals, floating point literals and text literals.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: Literals are written
vb@0: ¬http://docs.python.org/reference/lexical_analysis.html#id7 like in Python¬,
vb@0: that means, text literals are in single or double quotes, or multiline
vb@0: in triple double quotes:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: "text" 'also text' """some more text"""
vb@0: 42 "an integer and" 42.23 "a floating point literal"
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Literals are being output by the ¬#textfunction text function¬.
vb@0: >>
vb@0:
vb@0: h2 id=functioncalls > Function Calls
vb@0:
vb@0: p >>
vb@0: The main idea of YML scripts is calling functions which then generate
vb@0: XML tags (¬http://www.w3.org/TR/2008/REC-xml-20081126/#syntax Markup¬).
vb@0: Functions are generating single tags, lists or trees of tags.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: To call a function, write the name of the function, followed by a comma separated list
vb@0: of function parameters (C like syntax) or just «attribute=value» pairs. Unlike C, you don't
vb@0: need to insert the parameter list into parentheses. A simple function call can be terminated
vb@0: by a semicolon «;» or by a period «.»
vb@0: >>
vb@0:
vb@0: p >>
vb@0: It does not matter, if you're calling your function using parentheses or brackets or without.
vb@0: So these statements are equal:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: foo "hello, world";
vb@0: foo "hello, world".
vb@0: foo("hello, world");
vb@0: foo["hello, world"];
vb@0: ||
vb@0:
vb@0: h3 id=subtree > Subtrees
vb@0:
vb@0: p >>
vb@0: If you omit the tailing semicolon, you're creating a Subtree; YML Subtrees can also be
vb@0: opened and closed with braces:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: foo {
vb@0: bar {
vb@0: something;
vb@0: }
vb@0: }
vb@0: ||
vb@0:
vb@0: p > If a Subtree only consists of one single subelement, then you may omit the braces:
vb@0:
vb@0: Code ||
vb@0: foo
vb@0: bar;
vb@0: ||
vb@0:
vb@0: h3 id=named > Named Parameters
vb@0:
vb@0: p >>
vb@0: To generate ¬http://www.w3.org/TR/2008/REC-xml-20081126/#attdecls attributes¬ by calling
vb@0: a function, you can use Named Parameters.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: For that case, assign literals or symbols to attribute names like the following.
vb@0: The name of the parameter then will be used as the name of the generated attribute.
vb@0: An example:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: div id=sample {
vb@0: "this is a " a href="#sample" "link sample"
vb@0: }
vb@0: ||
vb@0:
vb@0: p > This generates:
vb@0:
vb@0: Code |
vb@0:
vb@0: h3 > Unnamed Parameters
vb@0:
vb@0: p >>
vb@0: Unnamed Parameters prepare values for predefined attributes. The following example is
vb@0: equivalent to the sample above:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl a(href);
vb@0: decl div(id);
vb@0:
vb@0: div "sample" {
vb@0: "this is a " a "#sample" "link sample"
vb@0: }
vb@0: ||
vb@0:
vb@0: p > If no predefined attribute can be allocated, the value of the parameter is added to the body.
vb@0:
vb@0: h3 > Calling with &
vb@0:
vb@0: p >>
vb@0: Especially if you have a ¬#defaultbody default body¬ for your function, calling with
vb@0: a leading «&» can be sensible: then the tag itself is omitted and only the body is being output:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl something { tag1; tag2; };
vb@0:
vb@0: list {
vb@0: &something;
vb@0: }
vb@0: ||
vb@0:
vb@0: p > results in:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: p >>
vb@0: This has the same result as ¬#alias aliasing¬ «something» to «-».
vb@0: >>
vb@0:
vb@0: h3 id=funclist > Function Lists
vb@0:
vb@0: p >>
vb@0: Function Lists are a feature of YML to simulate a more C like syntax. Let's have some
vb@0: examples. You can have a list of functions whereever you can have a function. Function
vb@0: Lists are comma separated:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: x i, j, k
vb@0: ||
vb@0:
vb@0: p > compiles to:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: h3 id=paramlists > Parameter Lists
vb@0:
vb@0: p >>
vb@0: A sample together with ¬#descending Descending Attributes¬:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl Interface @name;
vb@0: decl attr @type @name;
vb@0: decl func @type @name;
vb@0:
vb@0: Interface Icecream {
vb@0: attr color flavour;
vb@0: attr long number;
vb@0: func int getPrice();
vb@0: func void addFlavour(in color flavour, in long number);
vb@0: }
vb@0: ||
vb@0:
vb@0: p > compiles to:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Note the «parm» tags – they're generated by default, if you write a Parameter List
vb@0: behind a Function Call. That differs from calling the function with parameters –
vb@0: ¬#functioncalls calling¬ means using ¬#text text¬ values.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: The «parm» tags are emitted, because the «_parm» function is called each time
vb@0: such a parameter will be emitted.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: If you want to have the «_parm» function doing other things, just ¬#decl declare¬
vb@0: it in another way.
vb@0: >>
vb@0:
vb@0: h3 id=generics > Generic Declarations
vb@0:
vb@0: p >>
vb@0: Using Generic Declarations is just like using ¬#paramlists Parameter Lists¬ – use angle brackets
vb@0: instead of parentheses. For Generic Declarations, the «_generic» function is called each
vb@0: time such a Generic Declaration will be emitted, generating «generic» tags as the default:
vb@0: >>
vb@0:
vb@0: Code | max(x, y)
vb@0:
vb@0: p > compiles to:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: h3 id=contentfc > The «content» function
vb@0:
vb@0: p >>
vb@0: The «content;» Function Call has a special meaning (only in a ¬#defaultbody default body¬):
vb@0: it does not generate a tag, but instead
vb@0: the tags of a supplied body in a call will be inserted at each place where the «content;»
vb@0: function call is existing in the ¬#defaultbody default body¬.
vb@0: >>
vb@0:
vb@0: h3 id=textfunction > The «text» function
vb@0:
vb@0: p >>
vb@0: There is a special YML function named «text». Usually, it's just ¬#alias aliased¬ to «-» (and
vb@0: therefore outputting nothing). The «text» function is called each time a text literal will be
vb@0: output.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: If you ¬#decl declare¬ the «text» function, you can overload that behaviour. For example,
vb@0: ¬yslt YSLT¬ is declaring «text» like this:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl text alias xsl:text;
vb@0:
vb@0: "test"
vb@0: ||
vb@0:
vb@0: p > generates:
vb@0:
vb@0: Code | test
vb@0:
vb@0: p >>
vb@0: The «text» function is not called, if you give text as a value for an attribute:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl text alias xsl:text;
vb@0:
vb@0: a "test"
vb@0: ||
vb@0:
vb@0: p > generates:
vb@0:
vb@0: Code | test
vb@0:
vb@0: p >>
vb@0: But it is called using the quoting operators:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl text alias xsl:text;
vb@0:
vb@0: a > test
vb@0: ||
vb@0:
vb@0: p > generates:
vb@0:
vb@0: Code | test
vb@0:
vb@0: h3 id=declfunction > The «decl», «define» and «operator» functions
vb@0:
vb@0: p >>
vb@0: The «decl», «define» and «operator» functions are not defined, so they cannot be used
vb@0: accidentally by having a syntax error i.e. in a «decl» statement. If you want to use such
vb@0: a function, i.e. «decl()», you have to ¬#decl declare it explicitely¬:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl decl;
vb@0: decl();
vb@0: ||
vb@0:
vb@0: p > will result in:
vb@0:
vb@0: Code |
vb@0:
vb@0: h2 id=decl > Declaring Functions: decl
vb@0:
vb@0: p >>
vb@0: As default, each Function Call generates one XML tag, which has the same name. To be exact,
vb@0: the XML tag has dashes in it's name where the YML function has underscores.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: To define, how tags and attributes look like, which are created by a Function Call, you
vb@0: can use the «decl» statement.
vb@0: >>
vb@0:
vb@0: h3 > Trivial Declarations
vb@0:
vb@0: p > In a trivial declaration, you're just declaring the Function Name and so the XML tag name:
vb@0:
vb@0: Code | decl html, head, title, body, p, a;
vb@0:
vb@0: p > As seen in the example, multiple declarations can be done in a comma separated list.
vb@0:
vb@0: p >>
vb@0: Because trivial declarations are done automatically, if you're using a function for the
vb@0: first time, you usually don't need to declare this way.
vb@0: >>
vb@0:
vb@0: h3 > Specifying Unnamed Parameters
vb@0:
vb@0: p >>
vb@0: To specifiy Unnamed Parameters, give the parameter list comma separated in parentheses
vb@0: or provide one or more brackets with parameter lists in them:
vb@0: >>
vb@0:
vb@0: Code | decl a(href), img[src];
vb@0:
vb@0: p >>
vb@0: If you're using the corresponding functions a() and img() together with an unnamed parameter
vb@0: in a call, then these attributes are used for applying the values, respectively:
vb@0: >>
vb@0:
vb@0: Code | a "http://www.ccc.de" "The Club Homepage" img "logo.png";
vb@0:
vb@0: p > These Function Calls generate:
vb@0:
vb@0: Code | The Club Homepage
vb@0:
vb@0: h3 id=defaultattr > Giving Default Values for parameters
vb@0:
vb@0: p >>
vb@0: To give default values for generating XML attributes, assign a literal to each named parameter
vb@0: in the declaration parentheses or brackets. Two examples, which do the same:
vb@0: >>
vb@0:
vb@0: Code
vb@0: ||
vb@0: decl img(src, alt="picture");
vb@0: decl img[src][alt="picture"];
vb@0: ||
vb@0:
vb@0: h3 id=alias > Aliasing: using different YML functions for the same XML tag for different tasks
vb@0:
vb@0: p >>
vb@0: Sometimes tags are used in different ways to do different things. For this case, you can
vb@0: use aliasing. Aliasing means, the YML function name and the XML tag name differ. For example:
vb@0: >>
vb@0:
vb@0: Code | decl a(href), target(name) alias a;
vb@0:
vb@0: p > Both defined YML functions then generate «» tags – but the Unnamed Parameter differs.
vb@0:
vb@0: p >>
vb@0: The alias name «-» has a special meaning: it omits the tag in the output. That is especially
vb@0: sensible if you have a ¬#defaultbody default body¬. Then an alias to «-» has the same meaning
vb@0: as starting the function call with the «&» character: only the body is emitted.
vb@0: >>
vb@0:
vb@0: h3 id=descending > Specifying Descending Attributes
vb@0:
vb@0: p >>
vb@0: Maybe you want to write something like this:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: Module ERP {
vb@0: Interface Customer {
vb@0: // ...
vb@0: }
vb@0: }
vb@0: ||
vb@0:
vb@0: p > Without any extras, this compiles to:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: p >>
vb@0: For this case, it would be practical, if «ERP» would not be interpreted as extra tag
vb@0: but as value for an attribute «name». This you can achive with Descending Attributes:
vb@0: >>
vb@0:
vb@0: Code | decl Module @name, Interface @name;
vb@0:
vb@0: p > With this declaration, the code sample above is compiling to:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Descending attributes can also be used this way:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl module +name;
vb@0: decl element +name;
vb@0:
vb@0: module Some {
vb@0: element {
vb@0: one;
vb@0: two;
vb@0: three;
vb@0: }
vb@0: element {
vb@0: four; five; six
vb@0: }
vb@0: }
vb@0: ||
vb@0:
vb@0: p >>
vb@0: The above generates:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: h3 id=descending_pointer > Specifying Descending Pointers
vb@0:
vb@0: p >>
vb@0: Like with descending attributes, you can use descending ¬#pointer pointers¬. Instead of preceding the
vb@0: name of an attribute with a «+» sign (like with ¬#descending descending attributes¬), precede it with an asterisk «*».
vb@0: >>
vb@0:
vb@0: p >>
vb@0: Like with ¬#pointer pointers¬ in general, it's a good idea to combine that with a ¬#defaultbody default body¬:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl f *p { some tags with *p };
vb@0:
vb@0: f value;
vb@0: ||
vb@0:
vb@0: p >>
vb@0: This generates:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: value
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: h3 id=defaultbody > Supplying a Default Body
vb@0:
vb@0: p >>
vb@0: Additionally, you can supply a Default Body for each tag. For that case, add a YML function
vb@0: block in braces to your declaration:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl pageContent alias body {
vb@0: a name=top;
vb@0: include heading.en.yhtml2;
vb@0: div id=entries
vb@0: content;
vb@0: };
vb@0: ||
vb@0:
vb@0: p > The sample above is used for generating this homepage, for example.
vb@0:
vb@0: p > See the ¬#contentfc content function¬.
vb@0:
vb@0: h3 id=inheritance > Inheritance
vb@0:
vb@0: p >>
vb@0: Declarations can ¬http://en.wikipedia.org/wiki/Inheritance_(computer_science) inherit¬
vb@0: information from previous declarations. For that case, there is the
vb@0: possibility to use an «is» clause to give a function name to inherit from.
vb@0: >>
vb@0:
vb@0: p > The following is an example from the YSLT specification:
vb@0:
vb@0: Code ||
vb@0: decl stylesheet(version="1.0", xmlns:xsl="http://www.w3.org/1999/XSL/Transform");
vb@0:
vb@0: decl estylesheet is stylesheet (
vb@0: xmlns:exsl='http://exslt.org/common',
vb@0: xmlns:math='http://exslt.org/math',
vb@0: xmlns:func='http://exslt.org/functions',
vb@0: xmlns:str='http://exslt.org/strings',
vb@0: xmlns:dyn='http://exslt.org/dynamic',
vb@0: xmlns:set='http://exslt.org/sets',
vb@0: extension-element-prefixes='exsl func str dyn set math'
vb@0: );
vb@0:
vb@0: decl textstylesheet is estylesheet {
vb@0: output "text";
vb@0: const "space", !"'" + " " * 200 + "'"!;
vb@0: param "autoindent", 4;
vb@0: content;
vb@0: }, tstylesheet is textstylesheet;
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Here «estylesheet» inherits the tag name and the Default Values from «stylesheet»,
vb@0: while «textstylesheet» inherits all from «estylesheet» again. «estylesheet» then adds
vb@0: a Default Body, and «tstylesheet» does exactly the same as «textstylesheet».
vb@0: >>
vb@0:
vb@0: p > All of these YML functions output «stylesheet» XML tags, but with different defaults.
vb@0:
vb@0: h3 id=shapes > Shapes
vb@0:
vb@0: p >>
vb@0: Shapes are comparable to ¬#inheritance inheritance¬. Declaring a shape inherits
vb@0: every property beside the name.
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl coords(x=0, y=0);
vb@0: decl point (name);
vb@0:
vb@0: point "origin";
vb@0: ||
vb@0:
vb@0: p > compiles to:
vb@0:
vb@0: Code |
vb@0:
vb@0: p >>
vb@0: It's possible to have more than one shape, too. Multiple shapes
vb@0: are patching each other in the sequence they're listed:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl coords(x=0, y=0);
vb@0: decl named +name;
vb@0: decl point ;
vb@0:
vb@0: point origin;
vb@0: ||
vb@0:
vb@0: p > compiles to:
vb@0:
vb@0: Code |
vb@0:
vb@0: h3 > Namespaces
vb@0:
vb@0: p >>
vb@0: ¬http://www.w3.org/TR/xml-names/ XML namespaces¬ can be used just by providing an
vb@0: «alias» clause. Additionally, they can be used by an «in» clause; these two lines
vb@0: are equivalent:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl apply(select) alias xsl:apply-templates;
vb@0: in xsl decl apply(select) alias apply-templates;
vb@0: ||
vb@0:
vb@0: p > «in» clauses also can be used with a block of declarations in braces:
vb@0:
vb@0: Code ||
vb@0: in xsl {
vb@0: decl template(match);
vb@0: decl apply(select) alias apply-templates;
vb@0:
vb@0: decl function(name) alias template;
vb@0: decl call(name) alias call-template;
vb@0: }
vb@0: ||
vb@0:
vb@0: h3 id=pointer > Pointers
vb@0:
vb@0: p >>
vb@0: In some situations, it is good to have information in a Function Call, which then
vb@0: changes the way XML tags are generated. For this case, there are Pointers.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: The name should not mislead you; I took it because I chose the «*» symbol to declare them,
vb@0: and that is the meaning of this symbol in the programming language C. The concept behind
vb@0: is very easy.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: For example, it could be a good idea to generate a small HTML document containing some
vb@0: content. For this case, the title of the page is a good case for using pointers:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl page(*title) alias html {
vb@0: head {
vb@0: title *title;
vb@0: }
vb@0: body {
vb@0: h1 *title;
vb@0: content;
vb@0: }
vb@0: };
vb@0: ||
vb@0:
vb@0: p >>
vb@0: In the example above, calling «page('My Page') { p 'hello, world'; }» will result in
vb@0: this XML output:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0: My Page
vb@0:
vb@0:
vb@0:
My Page
vb@0:
hello, world
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Pointers can be referenced in any place in the Default Body of a «decl» statement, also for
vb@0: generating extra tags. Then the value for a Pointer will be the tag name.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: Additionally, you can insert the value of a pointer as text by calling it with two leading
vb@0: asterisks, i.e. if the pointer is defined as «*x», you can insert its value as text using: «**x».
vb@0: >>
vb@0:
vb@0: h4 id=pwt > Pointers without tags
vb@0:
vb@0: p >>
vb@0: To give a literal a name, you can define pointers to literals.
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: define *answer = 42;
vb@0: something *answer;
vb@0: ||
vb@0:
vb@0: p > will compile to:
vb@0:
vb@0: Code | 42
vb@0:
vb@0: p >>
vb@0: The «define» keyword as well as the asterisk «*» can be omitted. So this is
vb@0: equivalent to the statements above:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: answer = 42;
vb@0: something *answer;
vb@0: ||
vb@0:
vb@0: h4 > The pointer *_debug_trace
vb@0:
vb@0: p >>
vb@0: If you're calling ¬toolchain#processor yml2proc¬ with ¬toolchain#debug --debug¬, then this pointer is filled
vb@0: with tracing info text, otherwise it's an empty string.
vb@0: >>
vb@0:
vb@0: h3 id=macros, "Macros";
vb@0:
vb@0: p >>
vb@0: Macros are a way to generate values for attributes with variable content. Macros can be set
vb@0: like any other parameters; they're used for a text search & replace in the values of attributes
vb@0: when attributes are generated.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: Parameters, which represent macros, are determined with a preceding «%» sign. They're
vb@0: accounted for before any other parameter is accounted for in a function call, even if
vb@0: they were defined after other parameters.
vb@0: >>
vb@0:
vb@0: p > An example:
vb@0:
vb@0: Code ||
vb@0: decl foo(%macro, myAttr="something %macro for testing");
vb@0:
vb@0: testing
vb@0: foo "nice";
vb@0: ||
vb@0:
vb@0: p > This generates:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: h3 id=nullfunction > The Null Function
vb@0:
vb@0: p >>
vb@0: The function with the name «_» (underscore) is called Null Function. If you define this
vb@0: function, then you're switching off the default behaviour, that trivial declares are done
vb@0: automatically.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: Instead, unknown functions now call the Null Function. This can be very sensible together
vb@0: with ¬#descending Descending Attributes¬:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: decl _ +type +name alias func;
vb@0: decl interface +name;
vb@0:
vb@0: interface Testcase {
vb@0: void f(in string input);
vb@0: long getOptions();
vb@0: }
vb@0: ||
vb@0:
vb@0: p > compiles to:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0:
vb@0: ||
vb@0:
vb@0: h2 id=quoting > Quoting Operators
vb@0:
vb@0: p > Five different quoting operators implement different functionality:
vb@0:
vb@0: h3 id=quote > Quote >
vb@0:
vb@0: p > The «>» operator quotes into text nodes, doing XML escaping of text. An example:
vb@0:
vb@0: Code | > this text will be put into a text node and these angle brackets <> will be quoted
vb@0:
vb@0: p > Additionally, it can be used to implement an indention system, see ¬yslt YSLT¬ below.
vb@0:
vb@0: p >>
vb@0: Then an integer literal can be the first part of the operator; it gives the indention
vb@0: level. For example:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: 0> this text is indented to the actual level and then output,
vb@0: > followed by this text.\\n
vb@0:
vb@0: 1> this text is indented one indention level\\n
vb@0: 2> two levels\\n
vb@0: 1> one level again\\n
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Quote text is being output by the ¬#textfunction «text» function¬.
vb@0: >>
vb@0:
vb@0: h3 id=blockquote > Block Quote >>
vb@0:
vb@0: p {
vb@0: > To include more lines of text into a single quoted area, use double «>>». The lines
vb@0: > are concatenated together then. An example:
vb@0: }
vb@0:
vb@0: Code ||
vb@0: p >>
vb@0: This generates a text paragraph for HTML. All this text, which you can find in
vb@0: these lines, is being concatenated together to one single text node, and then put
vb@0: into the body of the
...
tag.
vb@0: >>
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Block quote text is being output by the ¬#textfunction «text» function¬.
vb@0: >>
vb@0:
vb@0: h3 > Line Quote |
vb@0:
vb@0: p > The «|» operator does the same as the «>» operator, adding a newline character to the text node.
vb@0:
vb@0: p > Additionally, it can be used to implement an indention system, see ¬yslt YSLT¬ below.
vb@0:
vb@0: p > Then it's used together with additional «>» symbols showing the grade of indention:
vb@0:
vb@0: Code ||
vb@0: | not indented
vb@0: |> single indent
vb@0: |>> double indent
vb@0: (...)
vb@0: ||
vb@0:
vb@0: p >>
vb@0: Line quote text is being output by the ¬#textfunction «text» function¬.
vb@0: >>
vb@0:
vb@0: h3 > Block Line Quote ||
vb@0:
vb@0: p >>
vb@0: The «||» operator opens and closes a block of lines, which then are handled like if each of
vb@0: them would be preceeded with a Line Operator «|».
vb@0: >>
vb@0:
vb@0: p > Sample:
vb@0:
vb@0: Code {
vb@0: | ||
vb@0: ||
vb@0: this is code being quoted through
vb@0: this is the second line
vb@0: ||
vb@0: | ||
vb@0: }
vb@0:
vb@0: p > is equivalent to:
vb@0:
vb@0: Code {
vb@0: ||
vb@0: | this is code being quoted through
vb@0: | this is the second line
vb@0: ||
vb@0: }
vb@0:
vb@0: p >>
vb@0: Block line quote text is being output by the ¬#textfunction «text» function¬.
vb@0: >>
vb@0:
vb@0: h3 > Inserting Commands
vb@0:
vb@0: p >>
vb@0: Just like with a ¬http://en.wikipedia.org/wiki/Shell_(computing)#Unix_shells Unix shell¬,
vb@0: you can insert statements into text by using backticks:
vb@0: >>
vb@0:
vb@0: Code ] | Click `a href="http://fdik.org/yml/" "this link"`, please!
vb@0:
vb@0: p {
vb@0: >>
vb@0: Being in a Block Line Quote «||», you additionally can use the Line Command operator
vb@0: (two backquotes,
vb@0: >>
vb@0: ] ``).
vb@0: }
vb@0:
vb@0: p > This is very interesting to have in YSLT, for example:
vb@0:
vb@0: Code {
vb@0: | ||
vb@0: | some code
vb@0: ] ``
vb@0: > apply "myTemplate";\n
vb@0: | some other code
vb@0: | ||
vb@0: }
vb@0:
vb@0: h3 id=userop > User defined in-text Operators
vb@0:
vb@0: p > You can define short cuts for inserting commands into text by defining operators.
vb@0:
vb@0: p >>
vb@0: Therefore, you need a ¬http://en.wikipedia.org/wiki/Regular_expression regular expression¬
vb@0: for matching text and YML text for replacing with. Here an example, how this is used by YSLT:
vb@0: >>
vb@0:
vb@0: Code ] define operator "«(.*?)»" as value "%1";
vb@0:
vb@0: p > The RegEx have ¬http://docs.python.org/library/re.html Python syntax¬.
vb@0:
vb@0: p >>
vb@0: In this example all matches to the RegEx will be replaced by the YML text in the «as» clause.
vb@0: The text of the first group in the RegEx will replace the «%1» in the resulting YML text. You
vb@0: can do that for more than one group – just use «%2» for the second group, «%3» for the third
vb@0: one and so on.
vb@0: >>
vb@0:
vb@0: p > The «define» keyword can be omitted.
vb@0:
vb@0: h3 id=quotethrough > Quote Through ]
vb@0:
vb@0: p >>
vb@0: The ¬http://en.wikipedia.org/wiki/Apple_II_series Apple ][¬ prompt operator just quotes
vb@0: through directly into XML what it gets.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: If the first character of a command is a «<», then quote through is applied
vb@0: automatically.
vb@0: >>
vb@0:
vb@0: p > This is the preferred way to output XML tags directly in YML:
vb@0:
vb@0: Code ||
vb@0:
vb@0:
vb@0: ]
vb@0: ||
vb@0:
vb@0: h2 id=including > Including YML files
vb@0:
vb@0: p >>
vb@0: You can include a second YML script file into an existing YML script file
vb@0: at any place using one of the following:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: include something.yml2
vb@0: include "something else.yml2"
vb@0: include 'anything addionally.yml2'
vb@0: ||
vb@0:
vb@0: a name="ymlpath";
vb@0: p >>
vb@0: If you're not starting the filename with '.' or '/' as in the example above, then
vb@0: if the «YML_PATH» environment variable is set to a colon separated list of directories,
vb@0: these directories are being searched for the given filename. Otherwise, the local
vb@0: directory is searched.
vb@0: >>
vb@0:
vb@0: p >>
vb@0: Filename ¬http://en.wikipedia.org/wiki/Glob_(programming) globbing¬ using «*» and «?»
vb@0: placeholders is supported to include more than one file at a time:
vb@0: >>
vb@0:
vb@0: Code | include part*.yml2
vb@0:
vb@0: p >>
vb@0: Filename globbing also can be used reverted; that means, the files are included in reverse
vb@0: order:
vb@0: >>
vb@0:
vb@0: Code | include reverse part*.yml2
vb@0:
vb@0: p > If there are the files part1.yml, part2.yml and part3.yml, part3.yml is included first now.
vb@0:
vb@0: p > To include plain text as text nodes, you can use:
vb@0:
vb@0: Code | include text some.txt
vb@0:
vb@0: p > To include ready made XML, use:
vb@0:
vb@0: Code | include xml some.xml
vb@0:
vb@0: h2 id=python > Escaping into Python – the Escape Operator !
vb@0:
vb@0: p > You can insert a Python command at any place by using the «!» operator:
vb@0:
vb@0: Code | !class X(str): pass
vb@0:
vb@0: h3 > Python script Operator !!
vb@0:
vb@0: p > You can use the double «!!» to include more than one line of Python code:
vb@0:
vb@0: Code ||
vb@0: !!
vb@0: def fak(n):
vb@0: if n == 0:
vb@0: return 1
vb@0: else:
vb@0: return n * fak(n - 1)
vb@0:
vb@0: def getName(id):
vb@0: return SQL("select name from customers where id='"+str(id)+"';")[0]
vb@0: !!
vb@0: ||
vb@0:
vb@0: h3 > Python generated parameters in Function Calls
vb@0:
vb@0: p >>
vb@0: You may use Python expressions to generate names and/or values in Function Calls.
vb@0: To do so, embed the Python expression in «! ... !»:
vb@0: >>
vb@0:
vb@0: Code ||
vb@0: f x=!fak(5)!;
vb@0: customer name=!getName(42)!;
vb@0: tag !getNextAttributeName()!=42;
vb@0: ||
vb@0:
vb@0: h3 > Python generated Function Calls
vb@0:
vb@0: p >>
vb@0: You can generate text with a Python expression, which represents an YML Function Call.
vb@0: The resulting YML function is then executed. Also here, embed the Python expression
vb@0: in «! ... !»:
vb@0: >>
vb@0:
vb@0: Code | !getTagName() + " " + getAttrib() + "='" + getValue() + "'"!
vb@0:
vb@0: h3 > Using Pointers as values in Python function calls
vb@0:
vb@0: p >>
vb@0: Sometimes it is useful to call a generating Python function using information of a
vb@0: YML Function Call. For that case, there is the «python» statement in YML. You can
vb@0: call there a single Python function using YML Pointers as parameters.
vb@0: >>
vb@0:
vb@0: p > This is used in the YSLT specification, for example:
vb@0:
vb@0: Code ||
vb@0: decl apply(select, *indent=1) alias apply-templates {
vb@0: python withIndent(*indent);
vb@0: content;
vb@0: };
vb@0: ||
vb@0:
vb@0: h2 id=comments > Comments //, /* */
vb@0:
vb@0: p > Comments are written like in Java or C++:
vb@0:
vb@0: Code ||
vb@0: // this is a comment
vb@0: something() { // this is a comment after a tag
vb@0: /* this is some comment, too */
vb@0: ||
vb@0:
vb@0: p > After Quoting Operators, comments are not possible. Instead, they're quoted through:
vb@0:
vb@0: Code ||
vb@0: // the following line you'll find in the output document
vb@0: > this text is being output // and this too
vb@0: ||
vb@0:
vb@0: div id=bottom {
vb@0: > ¬programming << Using YML 2¬
vb@0: > ¬#top ^Top^¬
vb@0: > ¬yslt >> show me YSLT¬
vb@0: > ¬features.en.yhtml2 (source)¬
vb@0: }
vb@0: }