Version | : Candle 0.13 |
Published date | : Jun 13, 2013 |
<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 = !1997-07-14 17:00:00z!
dtend = !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": {And in Candle Object Notation:
"id": "file", "value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
<?cmk1.0?>Candle Object Notation is much cleaner than JSON:
menu #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 {You can see that Candle version has a much clearer nesting structure than the Lua version.
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"
}
}
<!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 #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}
}
}
}
}
#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 {
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} }
}
@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 object notation
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/'
}
}
{...}
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.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?>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} }
}
}
}