mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
CoffeeScript 0.2.5 is on the books
This commit is contained in:
parent
ed8a54995d
commit
e77e520607
17 changed files with 237 additions and 70 deletions
|
@ -1,7 +1,7 @@
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = 'coffee-script'
|
s.name = 'coffee-script'
|
||||||
s.version = '0.2.4' # Keep version in sync with coffee-script.rb
|
s.version = '0.2.5' # Keep version in sync with coffee-script.rb
|
||||||
s.date = '2010-1-12'
|
s.date = '2010-1-13'
|
||||||
|
|
||||||
s.homepage = "http://jashkenas.github.com/coffee-script/"
|
s.homepage = "http://jashkenas.github.com/coffee-script/"
|
||||||
s.summary = "The CoffeeScript Compiler"
|
s.summary = "The CoffeeScript Compiler"
|
||||||
|
|
6
documentation/coffee/long_arrow.coffee
Normal file
6
documentation/coffee/long_arrow.coffee
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Account: customer, cart =>
|
||||||
|
this.customer: customer
|
||||||
|
this.cart: cart
|
||||||
|
|
||||||
|
$('.shopping_cart').bind('click') event ==>
|
||||||
|
this.customer.purchase(this.cart)
|
|
@ -1,9 +1,10 @@
|
||||||
switch day
|
switch day
|
||||||
when "Tuesday" then eat_breakfast()
|
when "Mon" then go_to_work()
|
||||||
when "Wednesday" then go_to_the_park()
|
when "Tue" then go_to_the_park()
|
||||||
when "Saturday"
|
when "Thu" then go_ice_fishing()
|
||||||
|
when "Fri", "Sat"
|
||||||
if day is bingo_day
|
if day is bingo_day
|
||||||
go_to_bingo()
|
go_to_bingo()
|
||||||
go_dancing()
|
go_dancing()
|
||||||
when "Sunday" then go_to_church()
|
when "Sun" then go_to_church()
|
||||||
else go_to_work()
|
else go_to_work()
|
|
@ -1,5 +1,8 @@
|
||||||
while demand > supply
|
if this.studying_economics
|
||||||
sell()
|
while supply > demand then buy()
|
||||||
restock()
|
while supply < demand then sell()
|
||||||
|
|
||||||
while supply > demand then buy()
|
num: 6
|
||||||
|
lyrics: while num -= 1
|
||||||
|
num + " little monkeys, jumping on the bed.
|
||||||
|
One fell out and bumped his head."
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Latest Version:</b>
|
<b>Latest Version:</b>
|
||||||
<a href="http://gemcutter.org/gems/coffee-script">0.2.4</a>
|
<a href="http://gemcutter.org/gems/coffee-script">0.2.5</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Table of Contents</h2>
|
<h2>Table of Contents</h2>
|
||||||
|
@ -76,6 +76,7 @@
|
||||||
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
|
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
|
||||||
<a href="#blocks">Blocks</a><br />
|
<a href="#blocks">Blocks</a><br />
|
||||||
<a href="#pattern_matching">Pattern Matching</a><br />
|
<a href="#pattern_matching">Pattern Matching</a><br />
|
||||||
|
<a href="#long_arrow">Function Binding</a><br />
|
||||||
<a href="#embedded">Embedded JavaScript</a><br />
|
<a href="#embedded">Embedded JavaScript</a><br />
|
||||||
<a href="#switch">Switch/When/Else</a><br />
|
<a href="#switch">Switch/When/Else</a><br />
|
||||||
<a href="#try">Try/Catch/Finally</a><br />
|
<a href="#try">Try/Catch/Finally</a><br />
|
||||||
|
@ -387,9 +388,12 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
|
||||||
|
|
||||||
<p id="while">
|
<p id="while">
|
||||||
<b class="header">While Loops</b>
|
<b class="header">While Loops</b>
|
||||||
The only low-level loop that CoffeeScript provides is the while loop.
|
The only low-level loop that CoffeeScript provides is the <b>while</b> loop. The
|
||||||
|
main difference from JavaScript is that the <b>while</b> loop can be used
|
||||||
|
as an expression, returning an array containing the result of each iteration
|
||||||
|
through the loop.
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('while') %>
|
<%= code_for('while', 'lyrics.join("\n")') %>
|
||||||
<p>
|
<p>
|
||||||
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
|
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
|
||||||
can be mimicked by variations on <b>while</b>, but the hope is that you
|
can be mimicked by variations on <b>while</b>, but the hope is that you
|
||||||
|
@ -528,6 +532,17 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('object_extraction', 'poet + " — " + street') %>
|
<%= code_for('object_extraction', 'poet + " — " + street') %>
|
||||||
|
|
||||||
|
<p id="long_arrow">
|
||||||
|
<b class="header">Function binding</b>
|
||||||
|
The long arrow <tt>==></tt> can be used to both define a function, and to bind
|
||||||
|
it to the current value of <tt>this</tt>, right on the spot. This is helpful
|
||||||
|
when using callback-based libraries like Prototype or jQuery, for creating
|
||||||
|
iterator functions to pass to <tt>each</tt>, or event-handler functions
|
||||||
|
to use with <tt>bind</tt>. Functions created with the long arrow are able to access
|
||||||
|
properties of the <tt>this</tt> where they're defined.
|
||||||
|
</p>
|
||||||
|
<%= code_for('long_arrow') %>
|
||||||
|
|
||||||
<p id="embedded">
|
<p id="embedded">
|
||||||
<b class="header">Embedded JavaScript</b>
|
<b class="header">Embedded JavaScript</b>
|
||||||
Hopefully, you'll never need to use it, but if you ever need to intersperse
|
Hopefully, you'll never need to use it, but if you ever need to intersperse
|
||||||
|
@ -546,6 +561,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
|
||||||
in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
|
in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
|
||||||
<tt>when</tt> clauses, <tt>else</tt> the default case.
|
<tt>when</tt> clauses, <tt>else</tt> the default case.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
As in Ruby, <b>switch</b> statements in CoffeeScript can take multiple
|
||||||
|
values for each <b>when</b> clause. If any of the values match, the clause
|
||||||
|
runs.
|
||||||
|
</p>
|
||||||
<%= code_for('switch') %>
|
<%= code_for('switch') %>
|
||||||
|
|
||||||
<p id="try">
|
<p id="try">
|
||||||
|
@ -625,6 +645,15 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
|
||||||
|
|
||||||
<h2 id="change_log">Change Log</h2>
|
<h2 id="change_log">Change Log</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b class="header" style="margin-top: 20px;">0.2.5</b>
|
||||||
|
The conditions in switch statements can now take multiple values at once —
|
||||||
|
If any of them are true, the case will run. Added the long arrow <tt>==></tt>,
|
||||||
|
which defines and immediately binds a function to <tt>this</tt>. While loops can
|
||||||
|
now be used as expressions, in the same way that comprehensions can. Splats
|
||||||
|
can be used within pattern matches to soak up the rest of an array.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b class="header" style="margin-top: 20px;">0.2.4</b>
|
<b class="header" style="margin-top: 20px;">0.2.4</b>
|
||||||
Added ECMAScript Harmony style destructuring assignment, for dealing with
|
Added ECMAScript Harmony style destructuring assignment, for dealing with
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// Eat lunch.
|
// Eat lunch.
|
||||||
lunch = (function() {
|
lunch = (function() {
|
||||||
__a = []; __b = ['toast', 'cheese', 'wine'];
|
__a = []; __b = ['toast', 'cheese', 'wine'];
|
||||||
for (__c=0; __c<__b.length; __c++) {
|
for (__c = 0; __c < __b.length; __c++) {
|
||||||
food = __b[__c];
|
food = __b[__c];
|
||||||
__a.push(eat(food));
|
__a.push(eat(food));
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
})();
|
})();
|
||||||
// Naive collision detection.
|
// Naive collision detection.
|
||||||
__d = asteroids;
|
__d = asteroids;
|
||||||
for (__e=0; __e<__d.length; __e++) {
|
for (__e = 0; __e < __d.length; __e++) {
|
||||||
roid = __d[__e];
|
roid = __d[__e];
|
||||||
__f = asteroids;
|
__f = asteroids;
|
||||||
for (__g=0; __g<__f.length; __g++) {
|
for (__g = 0; __g < __f.length; __g++) {
|
||||||
roid2 = __f[__g];
|
roid2 = __f[__g];
|
||||||
if (roid !== roid2) {
|
if (roid !== roid2) {
|
||||||
if (roid.overlaps(roid2)) {
|
if (roid.overlaps(roid2)) {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
(function(){
|
(function(){
|
||||||
var __a, __b, globals, name;
|
var __a, __b, globals, name;
|
||||||
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
// The first ten global properties.
|
// The first ten global properties.
|
||||||
globals = ((function() {
|
globals = ((function() {
|
||||||
__a = []; __b = window;
|
__a = []; __b = window;
|
||||||
for (name in __b) {
|
for (name in __b) {
|
||||||
if (__b.hasOwnProperty(name)) {
|
if (__hasProp.call(__b, name)) {
|
||||||
__a.push(name);
|
__a.push(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
documentation/js/long_arrow.js
Normal file
20
documentation/js/long_arrow.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
(function(){
|
||||||
|
var Account;
|
||||||
|
Account = function Account(customer, cart) {
|
||||||
|
var __a, __b;
|
||||||
|
var __this = this;
|
||||||
|
this.customer = customer;
|
||||||
|
this.cart = cart;
|
||||||
|
__a = $('.shopping_cart').bind('click', (function() {
|
||||||
|
__b = function(event) {
|
||||||
|
var __c;
|
||||||
|
__c = this.customer.purchase(this.cart);
|
||||||
|
return Account === this.constructor ? this : __c;
|
||||||
|
};
|
||||||
|
return (function() {
|
||||||
|
return __b.apply(__this, arguments);
|
||||||
|
});
|
||||||
|
})());
|
||||||
|
return Account === this.constructor ? this : __a;
|
||||||
|
};
|
||||||
|
})();
|
|
@ -1,5 +1,6 @@
|
||||||
(function(){
|
(function(){
|
||||||
var __a, __b, age, ages, child, years_old;
|
var __a, __b, age, ages, child, years_old;
|
||||||
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
years_old = {
|
years_old = {
|
||||||
max: 10,
|
max: 10,
|
||||||
ida: 9,
|
ida: 9,
|
||||||
|
@ -9,7 +10,7 @@
|
||||||
__a = []; __b = years_old;
|
__a = []; __b = years_old;
|
||||||
for (child in __b) {
|
for (child in __b) {
|
||||||
age = __b[child];
|
age = __b[child];
|
||||||
if (__b.hasOwnProperty(child)) {
|
if (__hasProp.call(__b, child)) {
|
||||||
__a.push(child + " is " + age);
|
__a.push(child + " is " + age);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
// Array comprehensions:
|
// Array comprehensions:
|
||||||
cubed_list = (function() {
|
cubed_list = (function() {
|
||||||
__a = []; __b = list;
|
__a = []; __b = list;
|
||||||
for (__c=0; __c<__b.length; __c++) {
|
for (__c = 0; __c < __b.length; __c++) {
|
||||||
num = __b[__c];
|
num = __b[__c];
|
||||||
__a.push(math.cube(num));
|
__a.push(math.cube(num));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
(function(){
|
(function(){
|
||||||
if (day === "Tuesday") {
|
if (day === "Mon") {
|
||||||
eat_breakfast();
|
go_to_work();
|
||||||
} else if (day === "Wednesday") {
|
} else if (day === "Tue") {
|
||||||
go_to_the_park();
|
go_to_the_park();
|
||||||
} else if (day === "Saturday") {
|
} else if (day === "Thu") {
|
||||||
|
go_ice_fishing();
|
||||||
|
} else if (day === "Fri" || day === "Sat") {
|
||||||
if (day === bingo_day) {
|
if (day === bingo_day) {
|
||||||
go_to_bingo();
|
go_to_bingo();
|
||||||
go_dancing();
|
go_dancing();
|
||||||
}
|
}
|
||||||
} else if (day === "Sunday") {
|
} else if (day === "Sun") {
|
||||||
go_to_church();
|
go_to_church();
|
||||||
} else {
|
} else {
|
||||||
go_to_work();
|
go_to_work();
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
(function(){
|
(function(){
|
||||||
while (demand > supply) {
|
var __a, lyrics, num;
|
||||||
sell();
|
if (this.studying_economics) {
|
||||||
restock();
|
while (supply > demand) {
|
||||||
}
|
buy();
|
||||||
while (supply > demand) {
|
}
|
||||||
buy();
|
while (supply < demand) {
|
||||||
|
sell();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
num = 6;
|
||||||
|
lyrics = (function() {
|
||||||
|
__a = [];
|
||||||
|
while (num -= 1) {
|
||||||
|
__a.push(num + " little monkeys, jumping on the bed. \
|
||||||
|
One fell out and bumped his head.");
|
||||||
|
}
|
||||||
|
return __a;
|
||||||
|
})();
|
||||||
})();
|
})();
|
152
index.html
152
index.html
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Latest Version:</b>
|
<b>Latest Version:</b>
|
||||||
<a href="http://gemcutter.org/gems/coffee-script">0.2.4</a>
|
<a href="http://gemcutter.org/gems/coffee-script">0.2.5</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Table of Contents</h2>
|
<h2>Table of Contents</h2>
|
||||||
|
@ -62,6 +62,7 @@
|
||||||
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
|
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
|
||||||
<a href="#blocks">Blocks</a><br />
|
<a href="#blocks">Blocks</a><br />
|
||||||
<a href="#pattern_matching">Pattern Matching</a><br />
|
<a href="#pattern_matching">Pattern Matching</a><br />
|
||||||
|
<a href="#long_arrow">Function Binding</a><br />
|
||||||
<a href="#embedded">Embedded JavaScript</a><br />
|
<a href="#embedded">Embedded JavaScript</a><br />
|
||||||
<a href="#switch">Switch/When/Else</a><br />
|
<a href="#switch">Switch/When/Else</a><br />
|
||||||
<a href="#try">Try/Catch/Finally</a><br />
|
<a href="#try">Try/Catch/Finally</a><br />
|
||||||
|
@ -139,7 +140,7 @@ race <span class="Keyword">=</span> <span class="Storage">function</span> <span
|
||||||
<span class="Comment"><span class="Comment">//</span> Array comprehensions:</span>
|
<span class="Comment"><span class="Comment">//</span> Array comprehensions:</span>
|
||||||
cubed_list <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
cubed_list <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> list;
|
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> list;
|
||||||
<span class="Keyword">for</span> (__c<span class="Keyword">=</span><span class="Number">0</span>; __c<span class="Keyword"><</span>__b.<span class="LibraryConstant">length</span>; __c<span class="Keyword">++</span>) {
|
<span class="Keyword">for</span> (__c <span class="Keyword">=</span> <span class="Number">0</span>; __c <span class="Keyword"><</span> __b.<span class="LibraryConstant">length</span>; __c<span class="Keyword">++</span>) {
|
||||||
num <span class="Keyword">=</span> __b[__c];
|
num <span class="Keyword">=</span> __b[__c];
|
||||||
__a.<span class="LibraryFunction">push</span>(math.cube(num));
|
__a.<span class="LibraryFunction">push</span>(math.cube(num));
|
||||||
}
|
}
|
||||||
|
@ -180,7 +181,7 @@ if ((typeof elvis !== "undefined" && elvis !== null)) {
|
||||||
// Array comprehensions:
|
// Array comprehensions:
|
||||||
cubed_list = (function() {
|
cubed_list = (function() {
|
||||||
__a = []; __b = list;
|
__a = []; __b = list;
|
||||||
for (__c=0; __c<__b.length; __c++) {
|
for (__c = 0; __c < __b.length; __c++) {
|
||||||
num = __b[__c];
|
num = __b[__c];
|
||||||
__a.push(math.cube(num));
|
__a.push(math.cube(num));
|
||||||
}
|
}
|
||||||
|
@ -667,21 +668,56 @@ backwards("stairway", "to", "heaven");
|
||||||
|
|
||||||
<p id="while">
|
<p id="while">
|
||||||
<b class="header">While Loops</b>
|
<b class="header">While Loops</b>
|
||||||
The only low-level loop that CoffeeScript provides is the while loop.
|
The only low-level loop that CoffeeScript provides is the <b>while</b> loop. The
|
||||||
|
main difference from JavaScript is that the <b>while</b> loop can be used
|
||||||
|
as an expression, returning an array containing the result of each iteration
|
||||||
|
through the loop.
|
||||||
</p>
|
</p>
|
||||||
<div class='code'><pre class="idle"><span class="Keyword">while</span> demand <span class="Keyword">></span> supply
|
<div class='code'><pre class="idle"><span class="Keyword">if</span> <span class="Variable">this</span>.studying_economics
|
||||||
sell()
|
<span class="Keyword">while</span> supply <span class="Keyword">></span> demand <span class="Keyword">then</span> buy()
|
||||||
restock()
|
<span class="Keyword">while</span> supply <span class="Keyword"><</span> demand <span class="Keyword">then</span> sell()
|
||||||
|
|
||||||
<span class="Keyword">while</span> supply <span class="Keyword">></span> demand <span class="Keyword">then</span> buy()
|
<span class="FunctionName">num</span><span class="Keyword">:</span> <span class="Number">6</span>
|
||||||
</pre><pre class="idle"><span class="Keyword">while</span> (demand <span class="Keyword">></span> supply) {
|
<span class="FunctionName">lyrics</span><span class="Keyword">:</span> <span class="Keyword">while</span> num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>
|
||||||
sell();
|
num <span class="Keyword">+</span> <span class="String"><span class="String">"</span> little monkeys, jumping on the bed.</span>
|
||||||
restock();
|
<span class="String"> One fell out and bumped his head.<span class="String">"</span></span>
|
||||||
|
</pre><pre class="idle"><span class="Storage">var</span> __a, lyrics, num;
|
||||||
|
<span class="Keyword">if</span> (<span class="Variable">this</span>.studying_economics) {
|
||||||
|
<span class="Keyword">while</span> (supply <span class="Keyword">></span> demand) {
|
||||||
|
buy();
|
||||||
|
}
|
||||||
|
<span class="Keyword">while</span> (supply <span class="Keyword"><</span> demand) {
|
||||||
|
sell();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<span class="Keyword">while</span> (supply <span class="Keyword">></span> demand) {
|
num <span class="Keyword">=</span> <span class="Number">6</span>;
|
||||||
buy();
|
lyrics <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
|
__a <span class="Keyword">=</span> [];
|
||||||
|
<span class="Keyword">while</span> (num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>) {
|
||||||
|
__a.<span class="LibraryFunction">push</span>(num <span class="Keyword">+</span> <span class="String"><span class="String">"</span> little monkeys, jumping on the bed. \</span>
|
||||||
|
<span class="String">One fell out and bumped his head.<span class="String">"</span></span>);
|
||||||
|
}
|
||||||
|
<span class="Keyword">return</span> __a;
|
||||||
|
})();
|
||||||
|
</pre><button onclick='javascript: var __a, lyrics, num;
|
||||||
|
if (this.studying_economics) {
|
||||||
|
while (supply > demand) {
|
||||||
|
buy();
|
||||||
|
}
|
||||||
|
while (supply < demand) {
|
||||||
|
sell();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><br class='clear' /></div>
|
num = 6;
|
||||||
|
lyrics = (function() {
|
||||||
|
__a = [];
|
||||||
|
while (num -= 1) {
|
||||||
|
__a.push(num + " little monkeys, jumping on the bed. \
|
||||||
|
One fell out and bumped his head.");
|
||||||
|
}
|
||||||
|
return __a;
|
||||||
|
})();
|
||||||
|
;alert(lyrics.join("\n"));'>run: lyrics.join("\n")</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
|
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
|
||||||
can be mimicked by variations on <b>while</b>, but the hope is that you
|
can be mimicked by variations on <b>while</b>, but the hope is that you
|
||||||
|
@ -709,7 +745,7 @@ backwards("stairway", "to", "heaven");
|
||||||
<span class="Comment"><span class="Comment">//</span> Eat lunch.</span>
|
<span class="Comment"><span class="Comment">//</span> Eat lunch.</span>
|
||||||
lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
|
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
|
||||||
<span class="Keyword">for</span> (__c<span class="Keyword">=</span><span class="Number">0</span>; __c<span class="Keyword"><</span>__b.<span class="LibraryConstant">length</span>; __c<span class="Keyword">++</span>) {
|
<span class="Keyword">for</span> (__c <span class="Keyword">=</span> <span class="Number">0</span>; __c <span class="Keyword"><</span> __b.<span class="LibraryConstant">length</span>; __c<span class="Keyword">++</span>) {
|
||||||
food <span class="Keyword">=</span> __b[__c];
|
food <span class="Keyword">=</span> __b[__c];
|
||||||
__a.<span class="LibraryFunction">push</span>(eat(food));
|
__a.<span class="LibraryFunction">push</span>(eat(food));
|
||||||
}
|
}
|
||||||
|
@ -717,10 +753,10 @@ lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
})();
|
})();
|
||||||
<span class="Comment"><span class="Comment">//</span> Naive collision detection.</span>
|
<span class="Comment"><span class="Comment">//</span> Naive collision detection.</span>
|
||||||
__d <span class="Keyword">=</span> asteroids;
|
__d <span class="Keyword">=</span> asteroids;
|
||||||
<span class="Keyword">for</span> (__e<span class="Keyword">=</span><span class="Number">0</span>; __e<span class="Keyword"><</span>__d.<span class="LibraryConstant">length</span>; __e<span class="Keyword">++</span>) {
|
<span class="Keyword">for</span> (__e <span class="Keyword">=</span> <span class="Number">0</span>; __e <span class="Keyword"><</span> __d.<span class="LibraryConstant">length</span>; __e<span class="Keyword">++</span>) {
|
||||||
roid <span class="Keyword">=</span> __d[__e];
|
roid <span class="Keyword">=</span> __d[__e];
|
||||||
__f <span class="Keyword">=</span> asteroids;
|
__f <span class="Keyword">=</span> asteroids;
|
||||||
<span class="Keyword">for</span> (__g<span class="Keyword">=</span><span class="Number">0</span>; __g<span class="Keyword"><</span>__f.<span class="LibraryConstant">length</span>; __g<span class="Keyword">++</span>) {
|
<span class="Keyword">for</span> (__g <span class="Keyword">=</span> <span class="Number">0</span>; __g <span class="Keyword"><</span> __f.<span class="LibraryConstant">length</span>; __g<span class="Keyword">++</span>) {
|
||||||
roid2 <span class="Keyword">=</span> __f[__g];
|
roid2 <span class="Keyword">=</span> __f[__g];
|
||||||
<span class="Keyword">if</span> (roid <span class="Keyword">!</span><span class="Keyword">==</span> roid2) {
|
<span class="Keyword">if</span> (roid <span class="Keyword">!</span><span class="Keyword">==</span> roid2) {
|
||||||
<span class="Keyword">if</span> (roid.overlaps(roid2)) {
|
<span class="Keyword">if</span> (roid.overlaps(roid2)) {
|
||||||
|
@ -791,6 +827,7 @@ egg_delivery = function egg_delivery() {
|
||||||
<span class="FunctionName">ages</span><span class="Keyword">:</span> <span class="Keyword">for</span> child, age <span class="Keyword">of</span> years_old
|
<span class="FunctionName">ages</span><span class="Keyword">:</span> <span class="Keyword">for</span> child, age <span class="Keyword">of</span> years_old
|
||||||
child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age
|
child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age
|
||||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, age, ages, child, years_old;
|
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, age, ages, child, years_old;
|
||||||
|
<span class="Storage">var</span> __hasProp <span class="Keyword">=</span> <span class="LibraryClassType">Object</span>.<span class="LibraryConstant">prototype</span>.hasOwnProperty;
|
||||||
years_old <span class="Keyword">=</span> {
|
years_old <span class="Keyword">=</span> {
|
||||||
max: <span class="Number">10</span>,
|
max: <span class="Number">10</span>,
|
||||||
ida: <span class="Number">9</span>,
|
ida: <span class="Number">9</span>,
|
||||||
|
@ -800,13 +837,14 @@ ages <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> years_old;
|
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> years_old;
|
||||||
<span class="Keyword">for</span> (child <span class="Keyword">in</span> __b) {
|
<span class="Keyword">for</span> (child <span class="Keyword">in</span> __b) {
|
||||||
age <span class="Keyword">=</span> __b[child];
|
age <span class="Keyword">=</span> __b[child];
|
||||||
<span class="Keyword">if</span> (__b.hasOwnProperty(child)) {
|
<span class="Keyword">if</span> (__hasProp.<span class="LibraryFunction">call</span>(__b, child)) {
|
||||||
__a.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age);
|
__a.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> __a;
|
<span class="Keyword">return</span> __a;
|
||||||
})();
|
})();
|
||||||
</pre><button onclick='javascript: var __a, __b, age, ages, child, years_old;
|
</pre><button onclick='javascript: var __a, __b, age, ages, child, years_old;
|
||||||
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
years_old = {
|
years_old = {
|
||||||
max: 10,
|
max: 10,
|
||||||
ida: 9,
|
ida: 9,
|
||||||
|
@ -816,7 +854,7 @@ ages = (function() {
|
||||||
__a = []; __b = years_old;
|
__a = []; __b = years_old;
|
||||||
for (child in __b) {
|
for (child in __b) {
|
||||||
age = __b[child];
|
age = __b[child];
|
||||||
if (__b.hasOwnProperty(child)) {
|
if (__hasProp.call(__b, child)) {
|
||||||
__a.push(child + " is " + age);
|
__a.push(child + " is " + age);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -931,22 +969,24 @@ six = (one = 1) + (two = 2) + (three = 3);
|
||||||
|
|
||||||
<span class="FunctionName">globals</span><span class="Keyword">:</span> (name <span class="Keyword">for</span> name <span class="Keyword">of</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
|
<span class="FunctionName">globals</span><span class="Keyword">:</span> (name <span class="Keyword">for</span> name <span class="Keyword">of</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
|
||||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, globals, name;
|
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, globals, name;
|
||||||
|
<span class="Storage">var</span> __hasProp <span class="Keyword">=</span> <span class="LibraryClassType">Object</span>.<span class="LibraryConstant">prototype</span>.hasOwnProperty;
|
||||||
<span class="Comment"><span class="Comment">//</span> The first ten global properties.</span>
|
<span class="Comment"><span class="Comment">//</span> The first ten global properties.</span>
|
||||||
globals <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
|
globals <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
|
||||||
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> <span class="LibraryClassType">window</span>;
|
__a <span class="Keyword">=</span> []; __b <span class="Keyword">=</span> <span class="LibraryClassType">window</span>;
|
||||||
<span class="Keyword">for</span> (name <span class="Keyword">in</span> __b) {
|
<span class="Keyword">for</span> (name <span class="Keyword">in</span> __b) {
|
||||||
<span class="Keyword">if</span> (__b.hasOwnProperty(name)) {
|
<span class="Keyword">if</span> (__hasProp.<span class="LibraryFunction">call</span>(__b, name)) {
|
||||||
__a.<span class="LibraryFunction">push</span>(name);
|
__a.<span class="LibraryFunction">push</span>(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> __a;
|
<span class="Keyword">return</span> __a;
|
||||||
})()).<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
|
})()).<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
|
||||||
</pre><button onclick='javascript: var __a, __b, globals, name;
|
</pre><button onclick='javascript: var __a, __b, globals, name;
|
||||||
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
// The first ten global properties.
|
// The first ten global properties.
|
||||||
globals = ((function() {
|
globals = ((function() {
|
||||||
__a = []; __b = window;
|
__a = []; __b = window;
|
||||||
for (name in __b) {
|
for (name in __b) {
|
||||||
if (__b.hasOwnProperty(name)) {
|
if (__hasProp.call(__b, name)) {
|
||||||
__a.push(name);
|
__a.push(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1230,6 +1270,41 @@ street = __c[0];
|
||||||
city = __c[1];
|
city = __c[1];
|
||||||
;alert(poet + " — " + street);'>run: poet + " — " + street</button><br class='clear' /></div>
|
;alert(poet + " — " + street);'>run: poet + " — " + street</button><br class='clear' /></div>
|
||||||
|
|
||||||
|
<p id="long_arrow">
|
||||||
|
<b class="header">Function binding</b>
|
||||||
|
The long arrow <tt>==></tt> can be used to both define a function, and to bind
|
||||||
|
it to the current value of <tt>this</tt>, right on the spot. This is helpful
|
||||||
|
when using callback-based libraries like Prototype or jQuery, for creating
|
||||||
|
iterator functions to pass to <tt>each</tt>, or event-handler functions
|
||||||
|
to use with <tt>bind</tt>. Functions created with the long arrow are able to access
|
||||||
|
properties of the <tt>this</tt> where they're defined.
|
||||||
|
</p>
|
||||||
|
<div class='code'><pre class="idle"><span class="FunctionName">Account</span><span class="Keyword">:</span> <span class="FunctionArgument">customer, cart</span> <span class="Storage">=></span>
|
||||||
|
<span class="FunctionName">this.customer</span><span class="Keyword">:</span> customer
|
||||||
|
<span class="FunctionName">this.cart</span><span class="Keyword">:</span> cart
|
||||||
|
|
||||||
|
$(<span class="String"><span class="String">'</span>.shopping_cart<span class="String">'</span></span>).bind(<span class="String"><span class="String">'</span>click<span class="String">'</span></span>) <span class="FunctionName">event</span> <span class="Keyword">=</span><span class="Storage">=></span>
|
||||||
|
<span class="Variable">this</span>.customer.purchase(<span class="Variable">this</span>.cart)
|
||||||
|
</pre><pre class="idle"><span class="Storage">var</span> Account;
|
||||||
|
Account <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Account</span>(<span class="FunctionArgument">customer, cart</span>) {
|
||||||
|
<span class="Storage">var</span> __a, __b;
|
||||||
|
<span class="Storage">var</span> __this <span class="Keyword">=</span> <span class="Variable">this</span>;
|
||||||
|
<span class="Variable">this</span>.customer <span class="Keyword">=</span> customer;
|
||||||
|
<span class="Variable">this</span>.cart <span class="Keyword">=</span> cart;
|
||||||
|
__a <span class="Keyword">=</span> <span class="Keyword">$</span>(<span class="String"><span class="String">'</span>.shopping_cart<span class="String">'</span></span>).bind(<span class="String"><span class="String">'</span>click<span class="String">'</span></span>, (<span class="Storage">function</span>() {
|
||||||
|
<span class="FunctionName">__b</span> = <span class="Storage">function</span>(<span class="FunctionArgument">event</span>) {
|
||||||
|
<span class="Storage">var</span> __c;
|
||||||
|
__c <span class="Keyword">=</span> <span class="Variable">this</span>.customer.purchase(<span class="Variable">this</span>.cart);
|
||||||
|
<span class="Keyword">return</span> Account <span class="Keyword">===</span> <span class="Variable">this</span>.<span class="LibraryConstant">constructor</span> ? <span class="Variable">this</span> : __c;
|
||||||
|
};
|
||||||
|
<span class="Keyword">return</span> (<span class="Storage">function</span>() {
|
||||||
|
<span class="Keyword">return</span> __b.<span class="LibraryFunction">apply</span>(__this, arguments);
|
||||||
|
});
|
||||||
|
})());
|
||||||
|
<span class="Keyword">return</span> Account <span class="Keyword">===</span> <span class="Variable">this</span>.<span class="LibraryConstant">constructor</span> ? <span class="Variable">this</span> : __a;
|
||||||
|
};
|
||||||
|
</pre><br class='clear' /></div>
|
||||||
|
|
||||||
<p id="embedded">
|
<p id="embedded">
|
||||||
<b class="header">Embedded JavaScript</b>
|
<b class="header">Embedded JavaScript</b>
|
||||||
Hopefully, you'll never need to use it, but if you ever need to intersperse
|
Hopefully, you'll never need to use it, but if you ever need to intersperse
|
||||||
|
@ -1261,25 +1336,33 @@ return [document.title, "Hello JavaScript"].join(": ");
|
||||||
in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
|
in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
|
||||||
<tt>when</tt> clauses, <tt>else</tt> the default case.
|
<tt>when</tt> clauses, <tt>else</tt> the default case.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
As in Ruby, <b>switch</b> statements in CoffeeScript can take multiple
|
||||||
|
values for each <b>when</b> clause. If any of the values match, the clause
|
||||||
|
runs.
|
||||||
|
</p>
|
||||||
<div class='code'><pre class="idle"><span class="Keyword">switch</span> day
|
<div class='code'><pre class="idle"><span class="Keyword">switch</span> day
|
||||||
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Tuesday<span class="String">"</span></span> <span class="Keyword">then</span> eat_breakfast()
|
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Mon<span class="String">"</span></span> <span class="Keyword">then</span> go_to_work()
|
||||||
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Wednesday<span class="String">"</span></span> <span class="Keyword">then</span> go_to_the_park()
|
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Tue<span class="String">"</span></span> <span class="Keyword">then</span> go_to_the_park()
|
||||||
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Saturday<span class="String">"</span></span>
|
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Thu<span class="String">"</span></span> <span class="Keyword">then</span> go_ice_fishing()
|
||||||
|
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Fri<span class="String">"</span></span>, <span class="String"><span class="String">"</span>Sat<span class="String">"</span></span>
|
||||||
<span class="Keyword">if</span> day <span class="Keyword">is</span> bingo_day
|
<span class="Keyword">if</span> day <span class="Keyword">is</span> bingo_day
|
||||||
go_to_bingo()
|
go_to_bingo()
|
||||||
go_dancing()
|
go_dancing()
|
||||||
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Sunday<span class="String">"</span></span> <span class="Keyword">then</span> go_to_church()
|
<span class="Keyword">when</span> <span class="String"><span class="String">"</span>Sun<span class="String">"</span></span> <span class="Keyword">then</span> go_to_church()
|
||||||
<span class="Keyword">else</span> go_to_work()
|
<span class="Keyword">else</span> go_to_work()
|
||||||
</pre><pre class="idle"><span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Tuesday<span class="String">"</span></span>) {
|
</pre><pre class="idle"><span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Mon<span class="String">"</span></span>) {
|
||||||
eat_breakfast();
|
go_to_work();
|
||||||
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Wednesday<span class="String">"</span></span>) {
|
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Tue<span class="String">"</span></span>) {
|
||||||
go_to_the_park();
|
go_to_the_park();
|
||||||
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Saturday<span class="String">"</span></span>) {
|
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Thu<span class="String">"</span></span>) {
|
||||||
|
go_ice_fishing();
|
||||||
|
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Fri<span class="String">"</span></span> <span class="Keyword">||</span> day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Sat<span class="String">"</span></span>) {
|
||||||
<span class="Keyword">if</span> (day <span class="Keyword">===</span> bingo_day) {
|
<span class="Keyword">if</span> (day <span class="Keyword">===</span> bingo_day) {
|
||||||
go_to_bingo();
|
go_to_bingo();
|
||||||
go_dancing();
|
go_dancing();
|
||||||
}
|
}
|
||||||
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Sunday<span class="String">"</span></span>) {
|
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">"</span>Sun<span class="String">"</span></span>) {
|
||||||
go_to_church();
|
go_to_church();
|
||||||
} <span class="Keyword">else</span> {
|
} <span class="Keyword">else</span> {
|
||||||
go_to_work();
|
go_to_work();
|
||||||
|
@ -1407,6 +1490,15 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">&q
|
||||||
|
|
||||||
<h2 id="change_log">Change Log</h2>
|
<h2 id="change_log">Change Log</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b class="header" style="margin-top: 20px;">0.2.5</b>
|
||||||
|
The conditions in switch statements can now take multiple values at once —
|
||||||
|
If any of them are true, the case will run. Added the long arrow <tt>==></tt>,
|
||||||
|
which defines and immediately binds a function to <tt>this</tt>. While loops can
|
||||||
|
now be used as expressions, in the same way that comprehensions can. Splats
|
||||||
|
can be used within pattern matches to soak up the rest of an array.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b class="header" style="margin-top: 20px;">0.2.4</b>
|
<b class="header" style="margin-top: 20px;">0.2.4</b>
|
||||||
Added ECMAScript Harmony style destructuring assignment, for dealing with
|
Added ECMAScript Harmony style destructuring assignment, for dealing with
|
||||||
|
|
|
@ -10,7 +10,7 @@ require "coffee_script/parse_error"
|
||||||
# Namespace for all CoffeeScript internal classes.
|
# Namespace for all CoffeeScript internal classes.
|
||||||
module CoffeeScript
|
module CoffeeScript
|
||||||
|
|
||||||
VERSION = '0.2.4' # Keep in sync with the gemspec.
|
VERSION = '0.2.5' # Keep in sync with the gemspec.
|
||||||
|
|
||||||
# Compile a script (String or IO) to JavaScript.
|
# Compile a script (String or IO) to JavaScript.
|
||||||
def self.compile(script, options={})
|
def self.compile(script, options={})
|
||||||
|
|
|
@ -34,11 +34,12 @@ module CoffeeScript
|
||||||
ASSIGNMENT = /\A(:|=)\Z/
|
ASSIGNMENT = /\A(:|=)\Z/
|
||||||
|
|
||||||
# Token cleaning regexes.
|
# Token cleaning regexes.
|
||||||
JS_CLEANER = /(\A`|`\Z)/
|
JS_CLEANER = /(\A`|`\Z)/
|
||||||
MULTILINER = /\n/
|
MULTILINER = /\n/
|
||||||
|
STRING_NEWLINES = /\n\s*/
|
||||||
COMMENT_CLEANER = /(^\s*#|\n\s*$)/
|
COMMENT_CLEANER = /(^\s*#|\n\s*$)/
|
||||||
NO_NEWLINE = /\A([+\*&|\/\-%=<>:!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)\Z/
|
NO_NEWLINE = /\A([+\*&|\/\-%=<>:!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)\Z/
|
||||||
HEREDOC_INDENT = /^\s+/
|
HEREDOC_INDENT = /^\s+/
|
||||||
|
|
||||||
# Tokens which a regular expression will never immediately follow, but which
|
# Tokens which a regular expression will never immediately follow, but which
|
||||||
# a division operator might.
|
# a division operator might.
|
||||||
|
@ -106,7 +107,7 @@ module CoffeeScript
|
||||||
# Matches strings, including multi-line strings.
|
# Matches strings, including multi-line strings.
|
||||||
def string_token
|
def string_token
|
||||||
return false unless string = @chunk[STRING, 1]
|
return false unless string = @chunk[STRING, 1]
|
||||||
escaped = string.gsub(MULTILINER, " \\\n")
|
escaped = string.gsub(STRING_NEWLINES, " \\\n")
|
||||||
token(:STRING, escaped)
|
token(:STRING, escaped)
|
||||||
@line += string.count("\n")
|
@line += string.count("\n")
|
||||||
@i += string.length
|
@i += string.length
|
||||||
|
|
|
@ -750,7 +750,7 @@ module CoffeeScript
|
||||||
else
|
else
|
||||||
index_var = nil
|
index_var = nil
|
||||||
source_part = "#{svar} = #{source.compile(o)};\n#{idt}"
|
source_part = "#{svar} = #{source.compile(o)};\n#{idt}"
|
||||||
for_part = @object ? "#{ivar} in #{svar}" : "#{ivar}=0; #{ivar}<#{svar}.length; #{ivar}++"
|
for_part = @object ? "#{ivar} in #{svar}" : "#{ivar} = 0; #{ivar} < #{svar}.length; #{ivar}++"
|
||||||
var_part = @name ? "#{body_dent}#{@name} = #{svar}[#{ivar}];\n" : ''
|
var_part = @name ? "#{body_dent}#{@name} = #{svar}[#{ivar}];\n" : ''
|
||||||
end
|
end
|
||||||
body = @body
|
body = @body
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
"description": "Unfancy JavaScript",
|
"description": "Unfancy JavaScript",
|
||||||
"keywords": ["javascript", "language"],
|
"keywords": ["javascript", "language"],
|
||||||
"author": "Jeremy Ashkenas",
|
"author": "Jeremy Ashkenas",
|
||||||
"version": "0.2.4"
|
"version": "0.2.5"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue