Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add comments, fix parser tree, change header for each file, include n…

…ew compiled files,

Fix on parser tree pushes in undefined elements; so now if there are {{
variables }} in block tags. I'll be displayed properly.
  • Loading branch information...
commit 2d2250ff65643111af6f4710d194161320e3d599 1 parent aa732a5
@fadrizul authored
View
19 compiled/compiler.js
@@ -1,11 +1,11 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/
-var Compile, Compiler, exports, helpers, pr, x;
+var Compile, Compiler, exports, helpers, x;
x = require("./regexes");
helpers = require("./helpers");
-pr = require("../dev/eyes");
Compiler = (function() {
function Compiler(node) {
this.node = node || {};
@@ -13,9 +13,8 @@ Compiler = (function() {
this.type = node.type;
}
Compiler.prototype.compile = function() {
- var blockName, blocks, errMsg, i, merge, p, parent, parentBlock, path, token, tokens, _i, _len, _len2;
+ var blockName, errMsg, i, merge, p, parent, parentBlock, path, token, tokens, _i, _len, _len2;
tokens = this.node.tokens;
- blocks = this.node.blocks;
parent = {};
merge = [];
if (this.type === x.TEMPLATE) {
@@ -40,7 +39,7 @@ Compiler = (function() {
if (parent) {
for (_i = 0, _len2 = parent.length; _i < _len2; _i++) {
p = parent[_i];
- if (typeof p !== "string") {
+ if (typeof p !== "string" && p.name === "block") {
parentBlock = p.args;
if (parentBlock.toString() === blockName.toString()) {
p[blockName] = token[parentBlock];
@@ -53,13 +52,13 @@ Compiler = (function() {
}
}
merge = merge.concat(tokens, parent);
- return this.out(merge);
}
+ return this.out(merge);
};
- Compiler.prototype.out = function(tok) {
+ Compiler.prototype.out = function(merge) {
var blockName, i, t, varOut, _len;
- for (i = 0, _len = tok.length; i < _len; i++) {
- t = tok[i];
+ for (i = 0, _len = merge.length; i < _len; i++) {
+ t = merge[i];
if (typeof t === "string" && t.name !== "block") {
this.html.push(t);
}
View
5 compiled/helpers.js
@@ -1,6 +1,7 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/
var isLiteral, isStringLiteral, isValidBlockName, isValidName, isValidShortName, x;
x = require("./regexes");
@@ -68,7 +69,7 @@ exports.escape = function(variable, context) {
}
chain = "";
props = variable.split(".");
- props.forEach(function(prop) {
+ rops.forEach(function(prop) {
return chain += (chain ? (isNaN(prop) ? "." + prop : "[" + prop + "]") : prop);
});
return chain.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
View
10 compiled/parser.js
@@ -1,10 +1,10 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/
-var Parser, exports, pr, x;
+var Parser, exports, x;
x = require("./regexes");
-pr = require("../dev/eyes");
Parser = (function() {
function Parser(str, tags) {
this.rawTokens = str ? str.trim().replace(x.Replace, "").split(x.Split) : {};
@@ -49,7 +49,7 @@ Parser = (function() {
name: varname,
filters: filters
};
- stack[index].push(token);
+ stack[0].push(token);
} else if (x.twigLogic.test(token)) {
parts = token.replace(x.LogDelimiter, "").split(" ");
tagname = parts.shift();
@@ -78,7 +78,7 @@ Parser = (function() {
index++;
continue;
}
- } else {
+ } else if (token !== "") {
if (typeof token !== "undefined") {
stack[0].push(token);
}
View
3  compiled/regexes.js
@@ -1,6 +1,7 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/exports.TEMPLATE = 0;
exports.LOGIC_TOKEN = 1;
exports.VAR_TOKEN = 2;
View
6 compiled/tags.js
@@ -1,11 +1,11 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/
-var Compiler, check, escape, helpers, pr;
+var Compiler, check, escape, helpers;
Compiler = require("./compiler");
helpers = require("./helpers");
-pr = require("../dev/eyes");
check = helpers.check;
escape = helpers.escape;
exports["extends"] = {};
View
6 compiled/twig.js
@@ -1,10 +1,10 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/
-var Compiler, Parser, compile, fileRenderer, fs, parse, pr, tags, widgets;
+var Compiler, Parser, compile, fileRenderer, fs, parse, tags, widgets;
fs = require("fs");
-pr = require("../dev/eyes");
Parser = require("./parser");
Compiler = require("./compiler");
tags = require("./tags");
View
6 compiled/widgets.js
@@ -1,9 +1,9 @@
/*
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
*/
-var pr, textWidgetGenerator;
-pr = require("../dev/eyes");
+var textWidgetGenerator;
textWidgetGenerator = function(tagname) {
return function() {
var i, output;
View
6 index.js
@@ -1,2 +1,8 @@
+/*
+ TwigJS
+ Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+ MIT Licensed
+*/
+
require('./support/coffee-script');
module.exports = require('./lib/twig');
View
67 lib/compiler.coffee
@@ -1,71 +1,104 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
# Module dependencies
x = require "./regexes"
helpers = require "./helpers"
-pr = require "../dev/eyes" # Debugging purposes
+# Compiler class
class Compiler
constructor: (node) ->
- @node = node or {}
- @html = []
- @type = node.type
+ @node = node or {} # Instantiate as local object
+ @html = [] # Create empty array to be pushed into later
+ @type = node.type # Get the token types
compile: ->
tokens = @node.tokens
- blocks = @node.blocks
- parent = {}
+ parent = {}
merge = []
+ # If token type is TEMPLATE start looping
if @type is x.TEMPLATE
+
for token, i in tokens
- if typeof token isnt "undefined"
+
+ # Make sure parser tree isn't passing undefined Tokens
+ if typeof token isnt "undefined"
+
+ # Get extends tags
if token.name is "extends"
+ # Sets up the path for the parent template
path = @node.options.root.replace(/['"]/g, "") + "/" + token.args[0].replace(/['"]/g, "")
+ # Throw error is extends tag is invalid
errMsg = "Only one string literal accepted of Extends."
throw new Error errMsg if token.args.length > 1
+ # Read parent files and return its content as token
parent = @node.fileRenderer(path, @node.options)
+
+ # Get block tags
else if token.name is "block"
+ # Get the block name
blockName = token.args
+ # Throw errors if invalid block name
throw new Error "Invalid syntax." if not helpers.isValidBlockName blockName
+ # Doesn't support nested blocks
throw new Error "Multiple block tag detected" if @type isnt x.TEMPLATE
+ # If parent isn't empty loop throught it,
+ # and matches the array inside with the token
if parent
for p in parent
- if typeof p isnt "string"
+ # Get only blocks inside parent
+ if typeof p isnt "string" and p.name is "block"
+ # Get parent's block name
parentBlock = p.args
+
+ # Make sure the two block matches and sets it into
+ # parent if it does
if parentBlock.toString() is blockName.toString()
p[blockName] = token[parentBlock]
+ # Remove the matched token
tokens.splice(i, 1)
+ # Merge the arrays parent and tokens
merge = merge.concat(tokens, parent)
-
- @out merge
-
- out: (tok) ->
- for t, i in tok
+
+ # Returns result of @out method
+ @out merge
+
+ out: (merge) ->
+ # Loop through the merged arrays and
+ # pushes the elements into a new stack
+ for t, i in merge
+ # If elemenet is normal string pushes it
if typeof t is "string" and t.name isnt "block"
@html.push t
-
+
+ # VARIABLE {{ }} type of the token
if t.type is x.VAR_TOKEN
+ # Get the value from "options" and pushes it
varOut = t.name
@html.push @node.options[varOut]
+ # LOGIC {% %} type of the token
else if t.type is x.LOGiC_TOKEN
-
+
+ # If extends tags isn't the first one, throw errors
throw new Error "Extends tag must be the first tag in the template" if @type isnt x.TEMPLATE
throw new Error "Nested blocks isn't supported yet." if @type isnt x.TEMPLATE
-
+
+ # Pushes the block into stack
if t.name is "block"
blockName = t.args
@html.push t[blockName.toString()]
+ # Join the elements and returns it
@html.join ""
# Expose
View
22 lib/helpers.coffee
@@ -1,6 +1,7 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
# Load regexes
@@ -8,10 +9,14 @@ x = require "./regexes"
isLiteral = (string) ->
literal = false
+
if x.NUMBER_LITERAL.test(string)
literal = true
+
else if (string[0] == string[string.length - 1]) and (string[0] == "'" or string[0] == "\"")
+
teststr = string.substr(1, string.length - 2).split("").reverse().join("")
+
throw new Error("Invalid string literal. Unescaped quote (" + string[0] + ") found.") if string[0] == "'" and x.UNESCAPED_QUOTE.test(teststr) or string[1] == "\"" and x.UNESCAPED_DQUOTE.test(teststr)
literal = true
literal
@@ -19,7 +24,9 @@ isLiteral = (string) ->
isStringLiteral = (string) ->
if (string[0] == string[string.length - 1]) and (string[0] == "'" or string[0] == "\"")
teststr = string.substr(1, string.length - 2).split("").reverse().join("")
+
throw new Error("Invalid string literal. Unescaped quote (" + string[0] + ") found.") if string[0] == "'" and x.UNESCAPED_QUOTE.test(teststr) or string[1] == "\"" and x.UNESCAPED_DQUOTE.test(teststr)
+
return true
false
@@ -35,10 +42,13 @@ isValidBlockName = (string) ->
exports.check = (variable, context) ->
variable = variable.replace(/^this/, "__this.__currentContext")
return "(true)" if isLiteral(variable)
- props = variable.split(".")
- chain = ""
+
+ props = variable.split(".")
+ chain = ""
output = []
+
props.unshift context if typeof context == "string" and context.length
+
props.forEach (prop) ->
chain += (if chain then (if isNaN(prop) then "." + prop else "[" + prop + "]") else prop)
output.push "typeof " + chain + " !== 'undefined'"
@@ -47,12 +57,16 @@ exports.check = (variable, context) ->
exports.escape = (variable, context) ->
variable = variable.replace(/^this/, "__this.__currentContext")
+
if isLiteral(variable)
variable = "(" + variable + ")"
+
else variable = context + "." + variable if typeof context == "string" and context.length
+
chain = ""
props = variable.split(".")
- props.forEach (prop) ->
+
+ rops.forEach (prop) ->
chain += (if chain then (if isNaN(prop) then "." + prop else "[" + prop + "]") else prop)
chain.replace(/\n/g, "\\n").replace /\r/g, "\\r"
View
12 lib/parser.coffee
@@ -1,13 +1,13 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
# Load regexes
x = require "./regexes"
-pr = require "../dev/eyes" # Debugging purposes
-# This class create the Token tree
+# This class create the Parser tree
class Parser
constructor: (str, tags) ->
@rawTokens = if str then str.trim().replace(x.Replace, "").split(x.Split) else {} # Rearranges str in to array
@@ -54,7 +54,7 @@ class Parser
filters : filters
# Pushes the new tree into stack
- stack[index].push(token)
+ stack[0].push token
# Get Logic delimiters {% %}
else if x.twigLogic.test(token)
@@ -93,8 +93,8 @@ class Parser
index++
continue
# If it's only string, pushes it into stack for compiling
- else
- if typeof token isnt "undefined"
+ else if token isnt ""
+ if typeof token isnt "undefined"
stack[0].push(token)
# return the new Parser tree
View
3  lib/regexes.coffee
@@ -1,6 +1,7 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
# Constants
View
4 lib/tags.coffee
@@ -1,12 +1,12 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
# Load dependencies
Compiler = require "./compiler"
helpers = require "./helpers"
-pr = require "../dev/eyes" # Debugging purposes
# Declare helpers
check = helpers.check
View
5 lib/twig.coffee
@@ -1,11 +1,11 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
# Module dependencies
fs = require "fs"
-pr = require "../dev/eyes" # Debugging purpose
# Load local lib
Parser = require "./parser"
@@ -67,4 +67,3 @@ exports.compile = compile = (str, options) ->
# Sends to http.ServerResponse for rendering
return new Function("locals", fn)
-
View
5 lib/widgets.coffee
@@ -1,10 +1,9 @@
###
TwigJS
-Author: Fadrizul H. <fadrizul[at]gmail.com>
+Copyright(c) 2011 Fadrizul Hasani <fadrizul@twigjs.org>
+MIT Licensed
###
-pr = require "../dev/eyes" # Debugging purposes
-
textWidgetGenerator = (tagname) ->
->
output = [ "<", tagname ]
Please sign in to comment.
Something went wrong with that request. Please try again.