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 |
this is a link sample
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. h@44: The system location for «.yml2» and «.ysl2» files is always searched afterwards. 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@74: p > If there are the files part1.yml2, part2.yml2 and part3.yml2, part3.yml2 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@74: p > If there is a file mask or a filename in a pointer you can include indirectly: vb@74: vb@74: Code || vb@74: declare files = "*.yml2" vb@74: include from *files vb@74: || vb@74: 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: }