| Version | : Candle 0.11 |
| Published date | : Mar 5, 2012 |
A
good example is the best sermon.
by Benjamin Franklin<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.
<?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:
Again, you can see that Candle's object notation is less verbose and more readable.<?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 = 't:1997-07-14 17:00:00z'
dtend = 't:1997-07-15 03:59:59z'
summary{xml:lang="en_US""Bastille Day Party"}
}
}
}
dtstart
and dtend
are written using the predefined datetime syntax instead of just as
string.<menu id="file" value="File">And in JSON:
<popup>
<menuitem value="New" onclick="CreateNewDoc()" />
<menuitem value="Open" onclick="OpenDoc()" />
<menuitem value="Close" onclick="CloseDoc()" />
</popup>
</menu>
{"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?>Candle Object Notation is much cleaner than JSON:
menu {
id=file value="File"
popup {
menuitem { value="New" onclick="CreateNewDoc()" }
menuitem { value="Open" onclick="OpenDoc()" }
menuitem { value="Close" onclick="CloseDoc()" }
}
}
solution "CandleOnLinux"In Candle object notation:
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" }
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.<!DOCTYPE html>In Candle Markup:
<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>
<?cmk1.0?>All SVG attributes in Candle are typed literal values instead of strings. And SVG
namespace s='http://www.w3.org/2000/svg';
s:svg { viewBox=(0,0,300,150)
s:defs {
s:radialGradient { id=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"
}
}
}
style,
transform
and path d
attributes that require domain-specific syntax in HTML are naturally
expressed using complex attribute content in Candle.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:
{...}
for bracketed expression; func{...}
for function call; 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">−</mo>
<mi>b</mi>
<mo>±</mo>
<msqrt>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
<mo>−</mo>
<mn>4</mn>
<mo>⁢</mo>
<mi>a</mi>
<mo>⁢</mo>
<mi>c</mi>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mo>⁢</mo>
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</math>
<?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" "−" }
mi {n:b}
mo { "±" }
msqrt {
msup {
mi {n:b}
mn {2}
}
mo { "−" }
mn {4}
mo { "⁢" }
mi {n:a}
mo { "⁢" }
mi {n:c}
}
}
mrow {
mn {2}
mo { "⁢" }
mi {n:a}
}
}
}
}
digraph g {In Candle object notation:
node [shape=plaintext]
A1 -- B1
A2 -- B2
A3 -- B3
A1 -> A2 [label=f]
A2 -> A3 [label=g]
B2 -> B3 [label="g'"]
B1 -> B3 [label="(g o f)'" tailport=s headport=s]
{ rank=same; A1 A2 A3 }
{ rank=same; B1 B2 B3 }
}
<?cmk1.0?>You can see, the Candle Markup version, although being a general format, looks almost the same as the original DOT version. Even the signature syntaxes,
digraph {
node { shape=plaintext }
A1 __ B1
A2 __ B2
A3 __ B3
A1 _. A2 {label="f"}
A2 _. A3 {label="g"}
B2 _. B3 {label="g'"}
B1 _. B3 {label="(g o f)'" tailport=s headport=s}
option { rank=same A1 A2 A3 }
option { rank=same B1 B2 B3 }
}
--
for undirected edge and ->
for directed edge, can be mimicked closely. The advantage is
of
course you can now use advanced processing
capabilities in Candle, like schema, query and transformation, to work
with
these graphs.#version 3.6;In Candle object notation:
//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> }
<?cmk1.0?>The challenging part is to express the formulas used in the attribute values. Here I used an encoding scheme similar to MathML example.
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) }
#declare the_angle = 0;In Candle Object Notation:
#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
declare { the_angle = 0 }You can see that even scripting statements can be represented in Candle Markup reasonably well.
while {
_{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} }
}
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .In Candle Object Notation:
@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/>
].
<?cmk1.0?>In this conversion exercise, you can see that anonymous object
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/';
'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/'
}
}
{...}
is used to group RDF predicates and objects. And Turtle's type
annotation
is represented by an object with a name that is the same as the type
name.x
"=" +{ "-"b "+-" sqrt{b sup 2 "-" 4 a c}} over _{2 a}
might be very readable but can be hard to process with flat lists of
nodes. A more structured representation could be:<?cmk1.0?>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.
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} }
}
}
}