Candle Markup Examples

Version : Candle 0.13
Published date : Jun 13, 2013

Introduction

A good example is the best sermon.   - by Benjamin Franklin

So I'll let the examples speak for themselves.

The 1st group of examples show how Candle compares against some general markup and configuration formats:
Example 1: A Simple Note
Example 2: An iCanlendar Record
Example 3: XML vs. JSON vs. Candle Object Notation
Example 4: A Configuration File in Lua
Example 5: An HTML5 SVG Example

The 2nd group of examples show how Candle takes up the change of DSLs:
Example 6: An MathML Example
Example 7: An Example in POV-Ray SDL
Example 8: An Example in RDF Turtle Notation

Example 1: A Simple Note

For this simple XML (a typical usecase of XML that you see everyday):
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

In equivalent Candle Object Notation:

note {
to = "Tove"
from = "Jani"
heading { "Reminder" }
"Don't forget me this weekend!"
}

In Candle, it is less verbose and far easier to read. There's no whitespace-ambiguity. The data structure is also better with to and from changed to attributes followed by the heading element and body content.

Example 2: An iCanlendar Record

For this XML:
<?xml version="1.1"?>
<iCalendar xmlns="urn:ietf:params:xml:ns:xcal">
<vcalendar>
<version>2.0</version>
<prodid>-//hacksw/handcal//NONSGML v1.0//EN</prodid>
<vevent>
<dtstart>19970714T170000Z</dtstart>
<dtend>19970715T035959Z</dtend>
<summary xml:lang="en_US">Bastille Day Party</summary>
</vevent>
</vcalendar>
</iCalendar>
In Candle object notation:
<?cmk1.0?>
namespace '
urn:ietf:params:xml:ns:xcal', xml='http://www.w3.org/XML/1998/namespace';
iCalendar {
vcalendar {
version = "2.0"
prodid = "-//hacksw/handcal//NONSGML v1.0//EN"
vevent{
dtstart = !1997-07-14 17:00:00z!
dtend = !1997-07-15 03:59:59z!
summary
{ xml:lang="en_US" "Bastille Day Party" }
}
}
}
Again, you can see that Candle's object notation is less verbose and more readable. dtstart and dtend are written using the predefined datetime syntax instead of just as string.

Example 3: XML vs. JSON vs. Candle Object Notation

Here's an example from JSON.org. In XML syntax:
<menu id="file" value="File">
<popup>
<menuitem value="New" onclick="CreateNewDoc()" />
<menuitem value="Open" onclick="OpenDoc()" />
<menuitem value="Close" onclick="CloseDoc()" />
</popup>
</menu>
And in JSON:
{"menu": {
"id": "file", "value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
And in Candle Object Notation:
<?cmk1.0?>
menu #file {
value="File"
popup {
menuitem { value="New" onclick="CreateNewDoc()" }
menuitem { value="Open" onclick="OpenDoc()" }
menuitem { value="Close" onclick="CloseDoc()" }
}
}
Candle Object Notation is much cleaner than JSON:

Example 4: A Configuration File in Lua

Here's a configuration file in Lua, which is used to build Candle using Premake:
solution "CandleOnLinux"
  configurations { "Debug", "Release" }  --first config 'debug' is the default config
  defines { "_LINUX=1" }
  flags { "ExtraWarnings", "NativeWChar" }
  buildoptions { "-fshort-wchar" }  -- sets the size of wchar as 2-byte
project "Candle"
  language "C++"
  kind    "ConsoleApp"   
  location ("_Build")
  links { "Native", "Core", "Markup", "Script", "Gui", "Scene", "Engine" }
  libdirs { "../../../" }
  files  { "*.h", "*.cpp" }
  targetdir "../../../"
configuration { "Debug" } defines { "_DEBUG", "DEBUG" } flags { "Symbols" }
  linkoptions { "-v" }
configuration { "Release" } defines { "NDEBUG" } flags { "Optimize" }
In Candle object notation:
solution { 
name = "CandleOnLinux"
  configurations = ("Debug", "Release")  <!--first config 'debug' is the default config -->
  defines = "_LINUX=1"
  flags = ("ExtraWarnings", "NativeWChar")
  buildoptions = "-fshort-wchar"  <!-- sets the size of wchar as 2-byte -->
  project {
name = "Candle"
    language = "C++"
    kind    = ConsoleApp
    location = "_Build"
    links = ("Native", "Core", "Markup", "Script", "Gui", "Scene", "Engine")
   libdirs = "../../../"
    files  = ("*.h", "*.cpp")
    targetdir = "../../../"
  }
  configuration {
name = "Debug"
  defines = ("_DEBUG", "DEBUG") flags = "Symbols" linkoptions = "-v"
  }
  configuration {
name = "Release"
  defines = "NDEBUG" flags = "Optimize"
  }
}
You can see that Candle version has a much clearer nesting structure than the Lua version.

Example 5: An HTML5 SVG Example

For this HTML5 SVG example:
<!DOCTYPE html>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 150">
<defs>
<radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:rgb(200,200,200); stop-opacity:0"/>
<stop offset="100%" style="stop-color:rgb(0,0,255); stop-opacity:1"/>
</radialGradient>
</defs>
<ellipse cx="100" cy="50" rx="100" ry="50" style="fill:url(#gradient)" />
<path d="M150 0 L75 200 L225 200 Z" />
<g transform="translate(90,30) rotate(-30) scale(.9)">
<text x="0" y="+30" font-size="18px" font-weight="bold"
text-anchor="middle">Button</text>
</g>
</svg>
In Candle Markup:
<?cmk1.0?>
namespace s='http://www.w3.org/2000/svg';
s:svg { viewBox=(0,0,300,150)
s:defs {
s:radialGradient #gradient { cx=50% cy=50% r=50% fx=50% fy=50%
s:stop { offset=0% style={stop-color=rgb{200,200,200} stop-opacity=0} }
s:stop { offset=100% style={stop-color=rgb{0,0,255} stop-opacity=1} }
}
}
s:ellipse { cx=100 cy=50 rx=100 ry=50 style={fill='#gradient'} }
s:path { d=(M,150,0,L,75,200,L,225,200,Z) }
s:g { transform={translate=(90,30) rotate=-30 scale=.9}
s:text { x=0 y=30 font-size=18px font-weight=bold text-anchor=middle
 "Button"
}
}
}
All SVG attributes in Candle are typed literal values instead of strings. And SVG style, transform and path d attributes that require domain-specific syntax in HTML are naturally expressed using complex attribute content in Candle.

Example 6: An MathML Example

Here's the example from the MathML Wikipedia page:

The well-known quadratic formula:

would be marked up using LaTeX syntax like this:

x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

in troff/eqn like this:

x={-b +- sqrt{b sup 2 - 4ac}} over 2a

in OpenOffice.org Math like this (all three are valid):

x={-b plusminus sqrt {b^2 - 4 ac}} over {2 a}
x={-b ± sqrt {b^2 - 4ac}} over 2a
x={-b +- sqrt {b^2 - 4ac}} over 2a

in ASCIIMathML like this:

x = (-b +- sqrt(b^2 - 4ac)) / (2a)

Firstly, I'll show you how Candle Markup can be stretched to match the above domain-specific formats:

x "=" {"-"b "+-" sqrt{b; sup; 2 "-" 4 a; c;}} over {2 a;}

As you can see, although Candle Markup is not specifically designed for such usage, it is really not too far from the domain-specific ones. Of course, some 'inventive' encoding scheme has to be used:

Actually, just by following these 3 simple rules, you can easily translate ASCII-like math formulas into Candle Markup. The advantage is of course you can now use advanced processing capabilities in Candle, like query and transformation, to work with these formulas.

The above equation represented in Presentation MathML as an expression tree made up from layout elements like mfrac or msqrt elements:

<math mode="display" xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mi>x</mi>
<mo>=</mo>
<mfrac>
<mrow>
<mo form="prefix">&#x2212;</mo>
<mi>b</mi>
<mo>&#x00B1;</mo>
<msqrt>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
<mo>&#x2212;</mo>
<mn>4</mn>
<mo>&#x2062;</mo>
<mi>a</mi>
<mo>&#x2062;</mo>
<mi>c</mi>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mo>&#x2062;</mo>
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</math>
In Candle object notation:
<?cmk1.0?>
namespace 'http://www.w3.org/1998/Math/MathML', n='';
math { n:mode=display
mrow {
mi {n:x}
mo {"="}
mfrac {
mrow {
mo { n:form="prefix" "&#x2212;" }
mi {n:b}
mo { "&#x00B1;" }
msqrt {
msup {
mi {n:b}
mn {2}
}
mo { "&#x2212;" }
mn {4}
mo { "&#x2062;" }
mi {n:a}
mo { "&#x2062;" }
mi {n:c}
}
}
mrow {
mn {2}
mo { "&#x2062;" }
mi {n:a}
}
}
}
}

Example 7: An Example in POV-Ray SDL

Here's again a domain-specific example in POV-Ray SDL:
#version 3.6;
//Includes a separate file defining a number of common colors
#include "colors.inc"
global_settings { assumed_gamma 1.0 }
background { color rgb <0.25, 0.25, 0.25> }
camera { location <0.0, 0.5, -4.0>
direction 1.5*z
right x*image_width/image_height
look_at <0.0, 0.0, 0.0> }
light_source { <0, 0, 0>
color rgb <1, 1, 1>
translate <-5, 5, -5> }
light_source { <0, 0, 0>
color rgb <0.25, 0.25, 0.25>
translate <6, -6, -6> }
box { <-0.5, -0.5, -0.5>,
<0.5, 0.5, 0.5>
texture { pigment { color Red }
finish { specular 0.6 }
normal { agate 0.25 scale 1/2 }
}
rotate <45,46,47> }
In Candle object notation:
<?cmk1.0?>
version { 3.6 }
<!-- Includes a separate file defining a number of common colors -->
include { "colors.inc" }
global_settings { assumed_gamma = 1.0 }
background { color = rgb {0.25 0.25 0.25} }
camera { location = (0.0, 0.5, -4.0)
direction = {1.5 "*" z;}
right = {x; "*" image_width; "/" image_height;}
look_at = (0.0, 0.0, 0.0) }
light_source { v = (0, 0, 0)
color = rgb {1 1 1}
translate = (-5, 5, -5) }
light_source { v = (0, 0, 0)
color = rgb {0.25 0.25 0.25}
translate = (6, -6, -6) }
box { v1 = (-0.5, -0.5, -0.5)
v2 = (0.5, 0.5, 0.5)
texture { pigment { color = Red }
finish { specular = 0.6 }
normal { agate = 0.25 scale = 0.5 }
}
rotate = (45,46,47) }
The challenging part is to express the formulas used in the attribute values. Here I used an encoding scheme similar to MathML example.

And an even more challenging example with variable declaration, assignment, comparison and the while loop construct:
#declare the_angle = 0;
#while (the_angle < 360)
box { <-0.5, -0.5, -0.5>
<0.5, 0.5, 0.5>
texture { pigment { color Red }
finish { specular 0.6 }
normal { agate 0.25 scale 1/2 } }
rotate the_angle }
#declare the_angle = the_angle + 45;
#end
In Candle Object Notation:
declare { the_angle = 0 }
while {
cond = {the_angle; "<" 360}

box { v1 = (-0.5, -0.5, -0.5)
v2 = (0.5, 0.5, 0.5)
texture { pigment { color = Red }
finish { specular = 0.6 }
normal { agate = 0.25 scale = 0.5 } }
rotate = the_angle }
declare { the_angle = {the_angle; "+" 45} }
}
You can see that even scripting statements can be represented in Candle Markup reasonably well.

Example 8: An Example in RDF Turtle Notation

Here's an example of RDF data expressed in the very terse Turtle notation:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix ex: <http://example.org/stuff/1.0/> .
<http://www.w3.org/TR/rdf-syntax-grammar>
dc:title "RDF/XML Syntax Specification (Revised)" ;
ex:editor [
ex:fullname "Dave Beckett"^^xsd:string;
ex:homePage <http://purl.org/net/dajobe/>
].
In Candle Object Notation:
<?cmk1.0?>
namespace rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
dc = 'http://purl.org/dc/elements/1.1/',
ex = 'http://example.org/stuff/1.0/';
ns:http:www.w3.org:TR:rdf-syntax-grammar {
dc:title = "RDF/XML Syntax Specification (Revised)"
ex:editor = {
ex:fullname = xsd:string { "Dave Beckett" }
ex:homePage = 'http://purl.org/net/dajobe/'
}
}
In this conversion exercise, you can see that object notation {...} is used to group RDF predicates. The subject URI is converted into Candle object name. And Turtle's type annotation is represented by an object with a name that is the same as the type name.

Summary

From the examples, you can see that Candle Markup has a very expressive syntax and flexible data model, with which you can easily invent your own pseudo DSLs to suit your application and still enjoy all the benefits of a general markup format. Just to reiterate the advantages of a general markup format over a domain-specific format:
And take note that the examples above are created to demonstrate the syntactic expressiveness and readability of Candle Markup, rather than to set good examples for application or domain modeling in Candle. When you invent a very terse representation, it might not have a very structured data model behind it. For example, the math formula like 
x "=" {"-"b "+-" sqrt{b; sup; 2 "-" 4 a; c;}} over {2 a;}
might be quite terse but can be hard to process as an almost flat list of nodes. A more structured representation could be:
<?cmk1.0?>
math {
in {
i{x}
divide {
plus-minus {
minus { i{b} }
root {
minus {
power { i{b} 2 }
times { 4 i{a} i{c} }
}
}
}
times { 2 i{a} }
}
}
}
No matter you prefer a terse format or a structured format, the power is now in your hand. Candle supports both equally well, and can easily transform one into the other.