Skip to content

Commit 4364777

Browse files
Create .EBNF.mkdn
1 parent c9f487c commit 4364777

1 file changed

Lines changed: 262 additions & 0 deletions

File tree

Docs/.EBNF.mkdn

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
Temple expression documentation
2+
===============================
3+
4+
Temple uses S-expressions to represent the parsed template code. The S-expressions
5+
are passed from filter to filter until the generator. The generator transforms
6+
the S-expression to a ruby code string. See the {file:README.md README} for an introduction.
7+
8+
In this document we documented all the expressions which are used by Temple. There is also
9+
a formal grammar which can validate expressions.
10+
11+
The Core Abstraction
12+
--------------------
13+
14+
The core abstraction is what every template evetually should be compiled
15+
to. Currently it consists of six types:
16+
multi, static, dynamic, code, newline and capture.
17+
18+
When compiling, there's two different strings we'll have to think about.
19+
First we have the generated code. This is what your engine (from Temple's
20+
point of view) spits out. If you construct this carefully enough, you can
21+
make exceptions report correct line numbers, which is very convenient.
22+
23+
Then there's the result. This is what your engine (from the user's point
24+
of view) spits out. It's what happens if you evaluate the generated code.
25+
26+
### [:multi, *sexp]
27+
28+
Multi is what glues everything together. It's simply a sexp which combines
29+
several others sexps:
30+
31+
[:multi,
32+
[:static, "Hello "],
33+
[:dynamic, "@world"]]
34+
35+
### [:static, string]
36+
37+
Static indicates that the given string should be appended to the result.
38+
39+
Example:
40+
41+
[:static, "Hello World"]
42+
is the same as:
43+
_buf << "Hello World"
44+
45+
[:static, "Hello \n World"]
46+
is the same as
47+
_buf << "Hello\nWorld"
48+
49+
### [:dynamic, ruby]
50+
51+
Dynamic indicates that the given Ruby code should be evaluated and then
52+
appended to the result.
53+
54+
The Ruby code must be a complete expression in the sense that you can pass
55+
it to eval() and it would not raise SyntaxError.
56+
57+
Example:
58+
59+
[:dynamic, 'Math::PI * r**2']
60+
61+
### [:code, ruby]
62+
63+
Code indicates that the given Ruby code should be evaluated, and may
64+
change the control flow. Any \n causes a newline in the generated code.
65+
66+
Example:
67+
68+
[:code, 'area = Math::PI * r**2']
69+
70+
### [:newline]
71+
72+
Newline causes a newline in the generated code, but not in the result.
73+
74+
### [:capture, variable_name, sexp]
75+
76+
Evaluates the Sexp using the rules above, but instead of appending to the
77+
result, it sets the content to the variable given.
78+
79+
Example:
80+
81+
[:multi,
82+
[:static, "Some content"],
83+
[:capture, "foo", [:static, "More content"]],
84+
[:dynamic, "foo.downcase"]]
85+
is the same as:
86+
_buf << "Some content"
87+
foo = "More content"
88+
_buf << foo.downcase
89+
90+
Control flow abstraction
91+
------------------------
92+
93+
Control flow abstractions can be used to write common ruby control flow constructs.
94+
These expressions are compiled to [:code, ruby] by Temple::Filters::ControlFlow
95+
96+
### [:if, condition, if-sexp, optional-else-sexp]
97+
98+
Example:
99+
100+
[:if,
101+
"1+1 == 2",
102+
[:static, "Yes"],
103+
[:static, "No"]]
104+
is the same as:
105+
if 1+1 == 2
106+
_buf << "Yes"
107+
else
108+
_buf << "No"
109+
end
110+
111+
### [:block, ruby, sexp]
112+
113+
Example:
114+
115+
[:block,
116+
'10.times do',
117+
[:static, 'Hello']]
118+
is the same as:
119+
10.times do
120+
_buf << 'Hello'
121+
end
122+
123+
### [:case, argument, [condition, sexp], [condition, sexp], ...]
124+
125+
Example:
126+
127+
[:case,
128+
'value',
129+
["1", "value is 1"],
130+
["2", "value is 2"],
131+
[:else, "don't know"]]
132+
is the same as:
133+
case value
134+
when 1
135+
_buf << "value is 1"
136+
when 2
137+
_buf << "value is 2"
138+
else
139+
_buf << "don't know"
140+
end
141+
142+
### [:cond, [condition, sexp], [condition, sexp], ...]
143+
144+
[:cond,
145+
["a", "a is true"],
146+
["b", "b is true"],
147+
[:else, "a and b are false"]]
148+
is the same as:
149+
case
150+
when a
151+
_buf << "a is true"
152+
when b
153+
_buf << "b is true"
154+
else
155+
_buf << "a and b are false"
156+
end
157+
158+
Escape abstraction
159+
------------------
160+
161+
The Escape abstraction is processed by Temple::Filters::Escapable.
162+
163+
### [:escape, bool, sexp]
164+
165+
The boolean flag switches escaping on or off for the content sexp. Dynamic and static
166+
expressions are manipulated.
167+
168+
Example:
169+
170+
[:escape, true,
171+
[:multi,
172+
[:dynamic, "code"],
173+
[:static, "<"],
174+
[:escape, false, [:static, ">"]]]]
175+
is transformed to
176+
[:multi,
177+
[:dynamic, 'escape_html(code)'],
178+
[:static, '&lt;'],
179+
[:static, '>']]
180+
181+
HTML abstraction
182+
----------------
183+
184+
The HTML abstraction is processed by the html filters (Temple::HTML::Fast and Temple::HTML::Pretty).
185+
186+
### [:html, :doctype, string]
187+
188+
Example:
189+
[:html, :doctype, '5']
190+
generates
191+
<!DOCTYPE html>
192+
193+
Supported doctypes:
194+
195+
<table>
196+
<tr><td><b>Name</b></td><td><b>Generated doctype</b></td></tr>
197+
<tr><td>1.1</td><td>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;</td></tr>
198+
<tr><td>html, 5</td><td>&lt;!DOCTYPE html></td></tr>
199+
<tr><td>strict</td><td>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;</td></tr>
200+
<tr><td>frameset</td><td>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"&gt;</td></tr>
201+
<tr><td>mobile</td><td>&lt;!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd"&gt;</td></tr>
202+
<tr><td>basic</td><td>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"&gt;</td></tr>
203+
<tr><td>transitional</td><td>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;</td></tr>
204+
</table>
205+
206+
### [:html, :comment, sexp]
207+
208+
Example:
209+
[:html, :comment, [:static, 'comment']]
210+
generates:
211+
<!--comment-->
212+
213+
### [:html, :condcomment, condition, sexp]
214+
215+
Example:
216+
[:html, :condcomment, 'IE', [:static, 'comment']]
217+
generates:
218+
<!--[if IE]>comment<![endif]-->
219+
220+
### [:html, :tag, identifier, attributes, optional-sexp]
221+
222+
HTML tag abstraction. Identifier can be a String or a Symbol. If the optional content Sexp is omitted
223+
the tag is closed (e.g. `<br/>` `<img/>`). The tag is also closed if the content Sexp is empty
224+
(consists only of :multi and :newline expressions) and the tag is registered as auto-closing.
225+
226+
Example:
227+
[:html, :tag, 'img', [:html, :attrs, [:html, :attr, 'src', 'image.png']]]
228+
[:html, :tag, 'p', [:multi], [:static, 'Content']]
229+
generates:
230+
231+
<img src="image.png"/>
232+
<p>Content</p>
233+
234+
### [:html, :attrs, attributes]
235+
236+
List of html attributes [:html, :attr, identifier, sexp]
237+
238+
### [:html, :attr, identifier, sexp]
239+
240+
HTML attribute abstraction. Identifier can be a String or a Symbol.
241+
242+
### [:html, :js, code]
243+
244+
HTML javascript abstraction which wraps the js code in a HTML comment or CDATA depending on document format.
245+
246+
Formal grammar
247+
--------------
248+
249+
Validate expressions with Temple::Grammar.match? and Temple::Grammar.validate!
250+
251+
Temple::Grammar.match? [:multi, [:static, 'Valid Temple Expression']]
252+
Temple::Grammar.validate! [:multi, 'Invalid Temple Expression']
253+
254+
The formal grammar is given in a Ruby DSL similar to EBNF and should be easy to understand if you know EBNF. Repeated tokens
255+
are given by appending ?, * or + as in regular expressions.
256+
257+
* ? means zero or one occurence
258+
* \* means zero or more occurences
259+
* \+ means one or more occurences
260+
261+
<!-- Find a better way to include the grammar -->
262+
<script src="http://gist-it.appspot.com/github/judofyr/temple/raw/master/lib/temple/grammar.rb"></script>

0 commit comments

Comments
 (0)