diff --git a/client/tpk/navbar/navbar.jsx b/client/tpk/navbar/navbar.jsx index 53dac98..b780998 100644 --- a/client/tpk/navbar/navbar.jsx +++ b/client/tpk/navbar/navbar.jsx @@ -9,7 +9,7 @@ var Navbar = React.createClass({ -
Total.Party.Knolling
+
Total Party Knolling
v0.0.0
diff --git a/gulpfile.js b/gulpfile.js index fc99fbe..711bff8 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -30,7 +30,7 @@ var gulp = vitreumTasks(gulp, { "codemirror", "codemirror/mode/gfm/gfm.js", 'codemirror/mode/javascript/javascript.js', - + 'codemirror/mode/jsx/jsx.js', "moment", "superagent", diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 305e5cc..12596ce 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -10,6 +10,7 @@ if(typeof navigator !== 'undefined'){ //Language Modes require('codemirror/mode/gfm/gfm.js'); //Github flavoured markdown require('codemirror/mode/javascript/javascript.js'); + require('codemirror/mode/jsx/jsx.js'); } diff --git a/shared/naturalcrit/jsx-parser.js b/shared/naturalcrit/jsx-parser.js new file mode 100644 index 0000000..69cc11a --- /dev/null +++ b/shared/naturalcrit/jsx-parser.js @@ -0,0 +1,228 @@ +var WHITESPACE = /(\s|\t|\n|\r)/g; +var NUMBERS = /[0-9]/; +var LETTERS = /[a-zA-Z_]/; + +var tokenizer = function(input){ + var tokens = []; + var current = 0; + var inTag = false; + + while(current < input.length){ + var char = input[current]; + + var getToken = function(regex){ + var value = ''; + while(regex.test(char) && current < input.length){ + value += char; + char = input[++current]; + } + return value; + } + + if(inTag){ + if(char == '>'){ + inTag = false; + tokens.push({ + type : 'closeTag' + }) + } + else if(char == '/' && input[current+1] == '>'){ + inTag = false; + tokens.push({ + type : 'endTag' + }) + current++; + } + else if(char == '='){ + tokens.push({ + type : 'equals' + }); + } + else if(WHITESPACE.test(char)){ + + } + else if(NUMBERS.test(char)){ + tokens.push({ + type : 'number', + value : getToken(NUMBERS)*1 + }); + current--; + } + else if(LETTERS.test(char)){ + var word = getToken(LETTERS); + if(word == 'true' || word == 'false'){ + tokens.push({ + type : 'boolean', + value : word == 'true' + }); + }else{ + tokens.push({ + type : 'word', + value : word + }); + } + current--; + } + else if(char == "'"){ + char = input[++current] + tokens.push({ + type : 'text', + value : getToken(/[^\']/) + }); + } + else if(char == '"'){ + char = input[++current] + tokens.push({ + type : 'text', + value : getToken(/[^\"]/) + }); + } + } + //Not tokenizing a tag definition + else{ + //End tag + if(char == '<' && input[current+1] == '/'){ + char = input[++current] + char = input[++current] + tokens.push({ + type : 'endTag', + value : getToken(LETTERS) + }) + } + else if(char == '<'){ + inTag = true; + char = input[++current]; + tokens.push({ + type : 'openTag', + value : getToken(LETTERS) + }) + current--; + } + else{ + //Handle slush text + var value = ''; + while(char != '<' && current < input.length){ + value += char; + char = input[++current]; + } + value = value.trim() + if(value){ + tokens.push({ + type : 'text', + value : value + }); + } + current--; + } + } + current++; + } + return tokens; +} + +var parser = function(tokens){ + var nodes = []; + var current = 0; + var token = tokens[current]; + + var parseProps = function(){ + var props = {}; + var key = null; + var last = null; + + while(current < tokens.length && token.type != 'endTag' && token.type != 'closeTag'){ + if(last && token.type == 'word'){ + props[last] = true; + last = token.value; + }else if(!key && token.type == 'word'){ + last = token.value; + }else if(last && token.type == 'equals'){ + key = last; + last = null; + }else if(key && (token.type == 'number' || token.type == 'text' || token.type == 'boolean')){ + props[key] = token.value; + key = null; + last = null; + }else{ + throw "Invalid property value: " + key + '=' + token.value; + } + token = tokens[++current]; + } + if(last) props[last] = true; + + return props; + } + + var genNode = function(tagType){ + token = tokens[++current]; + var node = { + tag : tagType, + props : parseProps(), + children : getChildren(tagType) + } + return node + } + + var getChildren = function(tagType){ + var children = []; + while(current < tokens.length){ + if(token.type == 'endTag'){ + if(token.value && token.value != tagType){ + throw "Invalid closing tag: " + token.value + ". Expected closing tag of type: " + tagType + }else{ + break; + } + } + if(token.type == 'openTag'){ + children.push(genNode(token.value)); + }else if(token.type == 'text'){ + children.push(token.value); + } + token = tokens[++current]; + } + return children; + } + return getChildren(); +} + +module.exports = function(input){ + return parser(tokenizer(input)); +} + + + + + + + +/* + +SOME TEST, remove later + + + + +var test1 = ` +
+ + Hey there! + so fucking cool + + let's go party + +
+` + +var test2 = "
Hey there!
" + + +var tokens = tokenizer(test1); + +console.log(test1, '\n---\n', tokens, '---\n', JSON.stringify(parser(tokens), null, ' ')); + + +*/ + + + +