Browse files

Cleaned up executable code and added parallel output file tree featur…

…e to command line tool.
  • Loading branch information...
1 parent 5ac3efc commit b6427acd5a70d3047a00dd5f5d9337787d422702 @vail130 committed Jan 16, 2013
View
20 README.md
@@ -3,7 +3,7 @@
## tl;dr
-WieldyMarkup is an HTML abstraction markup language, similar in many ways to [Haml](http://haml.info) and [Jade](http://jade-lang.com/). However, WieldyMarkup does not do any interpolation (currently), and is meant to be part of the build & deploy process, not the page serving process. It's probably best for writing static HTML pages and templates that use Underscore or Mustache templating languages, as well.
+WieldyMarkup is an HTML abstraction markup language, similar in many ways to [Jade](http://jade-lang.com/). However, WieldyMarkup does not do any interpolation (currently), and is meant to be part of the build & deploy process, not the page serving process. It's probably best for writing static HTML pages and templates that use Underscore or Mustache templating languages, as well.
## Installation
@@ -25,13 +25,25 @@ This will fail if any files do not have the `.wml` extension. Use `-f` or `--for
### In a Directory
-The directory should directly follow the `-d` argument. This will only compile direct children with `.wml` extension.
+The directory should directly follow the `-d` argument. This will compile direct children with `.wml` extension and create `.html` files in the same directory.
```shell
-./path/to/wieldymarkup -d /path/to/parent/directory
+./path/to/wieldymarkup -d example/
```
-Add `-r` to compile all `.wml` files, recursively.
+Use `-r` or `--recursive` to compile all `.wml` files, recursively.
+
+```shell
+./path/to/wieldymarkup -r -d example/
+```
+
+Add a second directory argument to compile all `.wml` files into `.html` files in a separate file tree.
+
+```shell
+./path/to/wieldymarkup -r -d example-wml/ example-html/
+```
+
+Use `-v` or `--verbose` for more messages in the console.
## Node Usage
View
239 bin/wieldymarkup
@@ -5,62 +5,152 @@ var _ = require('underscore');
var findit = require('findit');
var fs = require('fs');
-function compileFileFromPath(filepath, options) {
- if(typeof options !== 'object' || typeof options.hasOwnProperty === 'undefined') {
- options = {};
- }
- options.strict = options.hasOwnProperty('strict') ? !!options.strict : true;
- options.compress = options.hasOwnProperty('compress') ? !!options.compress : false;
+var Commander = function(args) {
- var filepathSections = filepath.split('/');
- var filenameSections = filepathSections[filepathSections.length - 1].split('.');
- var filename = filenameSections.slice(0, filenameSections.length - 1).join('.');
- var ext = filenameSections[filenameSections.length - 1];
- if(ext !== 'wml') {
- if(options.strict) {
- return console.log("Invalid extension for (" + filepath + "). Must be .wml.");
- } else {
- return;
+ var makeDirsForPath = function(path, verbose) {
+ var pathSections = path.split('/');
+ pathSections.pop();
+ if(pathSections[0] == '') {
+ pathSections.shift();
+ }
+ var tempPath, stats;
+ for(var i = 0; pathSections[i]; i++) {
+ tempPath = '/' + pathSections.slice(0, i+1).join('/');
+ if(!fs.existsSync(tempPath)) {
+ if(verbose) {
+ console.log("Creating directory " + tempPath);
+ }
+ fs.mkdirSync(tempPath);
+ }
}
}
- fs.readFile(filepath, 'utf8', function(err, data) {
- if (err) { return console.log(err); }
- var html = new Compiler(data, options.compress).output;
- var temp = filepath.split('/');
- temp.pop();
- newFilepath = temp.join('/') + '/' + filename + '.html';
- fs.writeFile(newFilepath, html);
- });
-}
-
-function compileFromCommandLine(args) {
- var compress = false;
- if(args.indexOf("-c") > -1 || args.indexOf("--compress") > -1) {
- compress = true
- args = _.reject(args, function(arg) {
- return ["-c", "--compress"].indexOf(arg) > -1;
+ var self = this;
+
+ this.init = function(args) {
+ this.args = args;
+
+ this.verbose = false;
+ if(this.args.indexOf("-v") > -1 || this.args.indexOf("--verbose") > -1) {
+ this.verbose = true;
+ this.args = _.reject(this.args, function(arg) {
+ return ["-v", "--verbose"].indexOf(arg) > -1;
+ });
+ }
+
+ this.compress = false;
+ if(this.args.indexOf("-c") > -1 || this.args.indexOf("--compress") > -1) {
+ this.compress = true;
+ if(this.verbose) {
+ console.log("Compression activated.");
+ }
+ this.args = _.reject(this.args, function(arg) {
+ return ["-c", "--compress"].indexOf(arg) > -1;
+ });
+ }
+
+ this.recursive = false;
+ if(this.args.indexOf("-r") > -1 || this.args.indexOf("--recursive") > -1) {
+ this.recursive = true;
+ if(this.verbose) {
+ console.log("Recursive activated.");
+ }
+ this.args = _.reject(this.args, function(arg) {
+ return ["-r", "--recursive"].indexOf(arg) > -1;
+ });
+ }
+
+ return (
+ this.args.indexOf("-d") > -1
+ ? this.processDirectory()
+ : this.processFile()
+ );
+ };
+
+ this.processFile = function() {
+ if(this.verbose) {
+ console.log("Processing as file.");
+ }
+
+ this.strict = true;
+ if(this.args.indexOf("-f") > -1 || this.args.indexOf("--force") > -1) {
+ this.strict = false;
+ if(this.verbose) {
+ console.log("Strict suppressed.");
+ }
+ this.args = _.reject(
+ this.args,
+ function(arg) {
+ ["-f", "--force"].indexOf(arg) > -1;
+ }
+ );
+ }
+
+ _.each(this.args, function (filepath) {
+ self.compileFromPath(filepath);
});
- }
+
+ return this;
+ };
- if(args.indexOf("-d") > -1) {
- var dIndex = args.indexOf("-d");
- if(args.length < dIndex + 1) {
- return console.log("The -d argument must be followed immediately by a directory path in which to compiler .wml files.");
+ this.processDirectory = function() {
+ if(this.verbose) {
+ console.log("Processing as directory.");
}
- var dirPath = args[dIndex + 1];
- var stats = fs.statSync(dirPath);
+ this.strict = false;
+ if(this.args.indexOf("-f") > -1 || this.args.indexOf("--force") > -1) {
+ this.args = _.reject(
+ this.args,
+ function(arg) {
+ ["-f", "--force"].indexOf(arg) > -1;
+ }
+ );
+ }
- if(!stats.isDirectory()) {
+ var dIndex = args.indexOf("-d");
+ if(this.args.length < dIndex + 1) {
+ return console.log("The -d argument must be followed immediately by a " +
+ "directory path in which to compiler .wml files.");
+ }
+
+ var dirPath = process.cwd().toString() + '/' + this.args[dIndex + 1];
+ if(typeof dirPath !== 'string') {
+ return console.log("Invalid directory path; it must be a string.");
+ }
+ if(dirPath[dirPath.length - 1] !== '/') {
+ dirPath += '/';
+ }
+ if(!fs.existsSync(dirPath)) {
+ return console.log("Invalid directory path following -d argument.");
+ }
+ if(!fs.statSync(dirPath).isDirectory()) {
return console.log("Invalid directory path following -d argument.");
}
+ if(this.verbose) {
+ console.log("Source directory detected.");
+ }
+
+ var newDirPath = dirPath;
+ if(this.args[dIndex + 2]) {
+ newDirPath = process.cwd().toString() + '/' + this.args[dIndex + 2];
+ if(typeof newDirPath !== 'string') {
+ return console.log("Invalid destination directory path; " +
+ "it must be a string.");
+ }
+ if(newDirPath[newDirPath.length - 1] !== '/') {
+ newDirPath += '/';
+ }
+ if(this.verbose) {
+ console.log("Destination directory detected.");
+ }
+ }
- if(args.indexOf("-r") > -1) {
+ if(this.recursive) {
findit(dirPath).on('file', function (file) {
- compileFileFromPath(file, {
- strict: false,
- compress: compress
+ self.compileFromPath(file, {
+ source: dirPath,
+ destination: newDirPath
});
});
} else {
@@ -69,28 +159,61 @@ function compileFromCommandLine(args) {
return console.log(err);
}
_.each(files, function(file) {
- compileFileFromPath(file, {
- strict: false,
- compress: compress
+ self.compileFromPath(file, {
+ source: dirPath,
+ destination: newDirPath
});
});
});
}
- } else {
- var strict = true;
- if(args.indexOf("-f") > -1 || args.indexOf("--force") > -1) {
- strict = false;
- args = _.reject(args , function(arg) { ["-f", "--force"].indexOf(arg) > -1 });
+ return this;
+ };
+
+ this.compileFromPath = function(filepath, options) {
+ if(typeof options !== 'object' || typeof options.hasOwnProperty === 'undefined') {
+ options = {};
}
+ options.source = options.hasOwnProperty('source') ? options.source : null;
+ options.destination = options.hasOwnProperty('destination') ? options.destination : null;
- _.each(args, function (filepath) {
- compileFileFromPath(filepath, {
- strict: strict,
- compress: compress
- });
+ var filepathSections = filepath.replace(/(?:\\)|(?:\/\/)/g, '/').split('/');
+ var filenameSections = filepathSections[filepathSections.length - 1].split('.');
+ var filename = filenameSections.slice(0, filenameSections.length - 1).join('.');
+ var ext = filenameSections[filenameSections.length - 1];
+ if(ext !== 'wml') {
+ if(this.strict) {
+ return console.log("Invalid extension for (" + filepath + "). Must be .wml.");
+ } else {
+ return;
+ }
+ }
+
+ fs.readFile(filepathSections.join('/'), 'utf8', function(err, data) {
+ if (err) { return console.log(err); }
+
+ var html = new Compiler(data, self.compress).output;
+ var temp = filepath.split('/');
+ temp.pop();
+ tempNewFilepath = temp.join('/') + '/' + filename + '.html';
+
+ if(options.source !== null && options.destination !== null) {
+ newFilepath = options.destination + tempNewFilepath.substring(options.source.length + 1);
+ makeDirsForPath(newFilepath, self.verbose);
+ } else {
+ newFilepath = tempNewFilepath;
+ }
+
+ if(self.verbose) {
+ console.log("Compiling " + newFilepath);
+ }
+ fs.writeFile(newFilepath, html);
});
- }
+
+ return this;
+ };
+
+ this.init(args);
}
-compileFromCommandLine(process.argv.slice(2));
+new Commander(process.argv.slice(2));
View
2 example/markup-test.html → example-html/markup-test.html
@@ -23,7 +23,7 @@
</div>
</div>
<form enctype="multipart/form-data">
- <% var d = new Date(); %>
+<% var d = new Date(); %>
<input class="underscore-template" type="text" readonly="" value="<%= d.getDate() %>" />
<input class="mustache-template" type="text" readonly="" value="{{ val2 }}" />
<p><%= val %> {{ val }} Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
View
0 example/markup-test.wml → example-wml/markup-test.wml
File renamed without changes.
View
24 lib/wieldymarkup.js
@@ -66,15 +66,15 @@
}
nest_level = 0;
while (true) {
- openStringIndex = text.indexOf(openString) > -1 ? text.indexOf(openString) : null;
- closeStringIndex = text.indexOf(closeString) > -1 ? text.indexOf(closeString) : null;
+ openStringIndex = text.indexOf(openString);
+ closeStringIndex = text.indexOf(closeString);
openStringFirst = false;
closeStringFirst = false;
- if (openStringIndex === closeStringIndex) {
+ if (openStringIndex === -1 && closeStringIndex === -1) {
break;
- } else if (openStringIndex !== null) {
+ } else if (openStringIndex !== -1) {
openStringFirst = true;
- } else if (closeStringIndex !== null) {
+ } else if (closeStringIndex !== -1) {
closeStringFirst = true;
} else {
if (openStringIndex < closeStringIndex) {
@@ -203,12 +203,12 @@
};
WieldyMarkup.prototype.closeTag = function() {
- var closingTagTuple;
- closingTagTuple = this.openTags.pop();
- if (!this.compress && closingTagTuple[0] > 0) {
- this.output += _.str.repeat(this.indentToken, closingTagTuple[0]);
+ var closingTagArray;
+ closingTagArray = this.openTags.pop();
+ if (!this.compress && closingTagArray[0] > 0) {
+ this.output += _.str.repeat(this.indentToken, closingTagArray[0]);
}
- this.output += "</" + closingTagTuple[1] + ">";
+ this.output += "</" + closingTagArray[1] + ">";
if (!this.compress) {
this.output += "\n";
}
@@ -291,7 +291,7 @@
WieldyMarkup.prototype.processEmbeddedLine = function(line) {
this.lineStartsWithTick = true;
if (!this.compress) {
- this.output += _.str.repeat(this.indentToken, this.currentLevel);
+ this.output += _.str.repeat(this.indentToken, this.currentLeve);
}
this.output += line.substring(1, line.length);
if (!this.compress) {
@@ -475,7 +475,7 @@
}).call(this);
exports = module.exports = {
- version: '0.1.0',
+ version: '0.2.1',
Compiler: WieldyMarkup
};
View
2 package.json
@@ -1,6 +1,6 @@
{
"name": "wieldymarkup",
- "version": "0.2.0",
+ "version": "0.2.1",
"description": "WieldyMarkup HTML Abstraction Markup Language Compiler",
"main": "wieldymarkup.js",
"bin": {
View
103 src/wieldymarkup.coffee
@@ -13,14 +13,12 @@ class WieldyMarkup
if grouperIndex is -1
output += text if status
text = ''
-
else
output += text.substring(0, grouperIndex) if status
if text.length > grouperIndex + 2
text = text.substring(grouperIndex+1, text.length)
else
text = ''
-
status = not status
output
@@ -30,22 +28,24 @@ class WieldyMarkup
if @whitespace.indexOf(ch) > -1
firstWhitespaceIndex = i
break
- if firstWhitespaceIndex is null then line else line.substring(0, firstWhitespaceIndex)
+ if firstWhitespaceIndex is null
+ line
+ else
+ line.substring(0, firstWhitespaceIndex)
- @getTagNestLevel: (text, openString='<', closeString='>') =>
+ @getTagNestLevel: (text, openString = '<', closeString = '>') =>
nest_level = 0
while true
- openStringIndex = if text.indexOf(openString) > -1 then text.indexOf(openString) else null
- closeStringIndex = if text.indexOf(closeString) > -1 then text.indexOf(closeString) else null
+ openStringIndex = text.indexOf openString
+ closeStringIndex = text.indexOf closeString
openStringFirst = false
closeStringFirst = false
- # Only same if both null
- if openStringIndex is closeStringIndex
+ if openStringIndex is -1 and closeStringIndex is -1
break
- else if openStringIndex isnt null
+ else if openStringIndex isnt -1
openStringFirst = true
- else if closeStringIndex isnt null
+ else if closeStringIndex isnt -1
closeStringFirst = true
else
if openStringIndex < closeStringIndex
@@ -58,13 +58,17 @@ class WieldyMarkup
if text.length is openStringIndex + openString.length
break
else
- text = text.substring(openStringIndex + openString.length, text.length)
+ text = text.substring(
+ openStringIndex + openString.length, text.length
+ )
else if closeStringFirst
nest_level--
if text.length is closeStringIndex + closeString.length
break
else
- text = text.substring(closeStringIndex+closeString.length, text.length)
+ text = text.substring(
+ closeStringIndex+closeString.length, text.length
+ )
nest_level
@getLeadingWhitespaceFromText: (text) =>
@@ -75,15 +79,14 @@ class WieldyMarkup
break
leadingWhitespace
- constructor: (text="", compress=false) ->
+ constructor: (text = "", compress = false) ->
@text = text
@compress = compress
@compile()
- compile: (text=null, compress=null) ->
+ compile: (text = null, compress = null) ->
@text = text if text isnt null
@compress = not not compress if compress isnt null
-
@output = ""
@openTags = []
@indentToken = ""
@@ -104,36 +107,33 @@ class WieldyMarkup
if leadingWhitespace is ""
@currentLevel = 0
-
- # If there is leading whitespace but indentToken is still empty string
else if @indentToken is ""
@indentToken = leadingWhitespace
@currentLevel = 1
-
- # Else, set currentLevel to number of repetitions of index_token in leadingWhitespace
else
i = 0
while _.str.startsWith leadingWhitespace, @indentToken
- leadingWhitespace = leadingWhitespace.substring @indentToken.length, leadingWhitespace.length
+ leadingWhitespace = leadingWhitespace.substring(
+ @indentToken.length, leadingWhitespace.length
+ )
i += 1
@currentLevel = i
-
@
closeLowerLevelTags: =>
- # If indentation level is less than or equal to previous level
if @currentLevel <= @previousLevel
- # Close all indentations greater than or equal to indentation level of this line
- while @openTags.length > 0 and @openTags[@openTags.length - 1][0] >= @currentLevel
+ while @openTags.length > 0 and
+ @openTags[@openTags.length - 1][0] >= @currentLevel
@closeTag()
@
closeTag: =>
- closingTagTuple = @openTags.pop()
- if not @compress and closingTagTuple[0] > 0
- @output += _.str.repeat @indentToken, closingTagTuple[0]
- @output += "</#{closingTagTuple[1]}>"
- @output += "\n" if not @compress
+ closingTagArray = @openTags.pop()
+ if not @compress and closingTagArray[0] > 0
+ @output += _.str.repeat @indentToken, closingTagArray[0]
+ @output += "</#{closingTagArray[1]}>"
+ if not @compress
+ @output += "\n"
@
processNextLine: =>
@@ -154,18 +154,17 @@ class WieldyMarkup
if line.length is 0
return @
- # Whole line embedded HTML, starting with back ticks:
if line[0] is @embeddingToken
@processEmbeddedLine line
-
else
- # Support multiple tags on one line via "\-\" delimiter
lineSplitList = line.split '\\-\\'
while lineSplitList.length > 1
temp_line = _.str.trim lineSplitList.shift()
selector = @constructor.getSelectorFromLine temp_line
@processSelector selector
- restOfLine = _.str.trim temp_line.substring selector.length, temp_line.length
+ restOfLine = _.str.trim(
+ temp_line.substring selector.length, temp_line.length
+ )
restOfLine = @processAttributes restOfLine
@addHtmlToOutput()
@@ -190,7 +189,6 @@ class WieldyMarkup
while @constructor.getTagNestLevel(@innerText) > 0
if @text is ""
throw "Unmatched '<' found on line #{@lineNumber}"
-
else if "\n" in @text
lineBreakIndex = @text.indexOf "\n"
# Guarantee only one space between text between lines.
@@ -199,13 +197,10 @@ class WieldyMarkup
@text = ""
else
@text = @text.substring lineBreakIndex+1, @text.length
-
else
@innerText += @text
@text = ""
-
@innerText = _.str.trim(@innerText).substring 1, @innerText.length - 1
-
else if _.str.startsWith restOfLine, '/'
if restOfLine.length > 0 and restOfLine[restOfLine.length - 1] is '/'
@selfClosing = true
@@ -215,13 +210,14 @@ class WieldyMarkup
processEmbeddedLine: (line) =>
@lineStartsWithTick = true
- @output += _.str.repeat @indentToken, @currentLevel if not @compress
+ if not @compress
+ @output += _.str.repeat @indentToken, @currentLeve
@output += line.substring 1, line.length
- @output += "\n" if not @compress
+ if not @compress
+ @output += "\n"
@
processSelector: (selector) =>
- # Parse the first piece as a selector, defaulting to DIV tag if none is specified
if selector.length > 0 and selector[0] in ['#', '.']
@tag = 'div'
else
@@ -271,11 +267,8 @@ class WieldyMarkup
processAttributes: (restOfLine) =>
@tagAttributes = []
while restOfLine isnt ""
- # If '=' doesn't exist, empty attribute string and break from loop
if '=' not in restOfLine
break
-
- # End line with "and" for coffeescript compiler
else if '=' in restOfLine and '<' in restOfLine and
restOfLine.indexOf('<') < restOfLine.indexOf('=')
break
@@ -288,7 +281,6 @@ class WieldyMarkup
closeIndex = restOfLine.indexOf '}}'
if closeIndex is -1
throw "Unmatched '{{' found in line #{@lineNumber}"
-
else if restOfLine.substr(firstEqualsIndex+1, 2) is '<%'
embeddedAttribute = true
closeIndex = restOfLine.indexOf '%>'
@@ -301,19 +293,18 @@ class WieldyMarkup
restOfLine = ""
else
restOfLine = restOfLine.substr closeIndex+2
-
else if restOfLine.length is firstEqualsIndex+1
currentAttribute = _.str.trim restOfLine
restOfLine = ""
-
else if '=' not in restOfLine.substr(firstEqualsIndex+1)
if '<' in restOfLine
- currentAttribute = _.str.trim restOfLine.substring 0, restOfLine.indexOf '<'
+ currentAttribute = _.str.trim(
+ restOfLine.substring 0, restOfLine.indexOf '<'
+ )
restOfLine = restOfLine.substr restOfLine.indexOf '<'
else
currentAttribute = restOfLine
restOfLine = ""
-
else
secondEqualsIndex = restOfLine.substr(firstEqualsIndex+1).indexOf '='
reversedLettersBetweenEquals = _.str.reverse restOfLine.substring(
@@ -354,15 +345,18 @@ class WieldyMarkup
if @selfClosing
tagHtml += " />"
- @output += _.str.repeat(@indentToken, @currentLevel) if not @compress
+ if not @compress
+ @output += _.str.repeat(@indentToken, @currentLevel)
@output += tagHtml
- @output += "\n" if not @compress
-
+ if not @compress
+ @output += "\n"
else
tagHtml += ">"
- tagHtml += @innerText if @innerText isnt null
+ if @innerText isnt null
+ tagHtml += @innerText
- @output += _.str.repeat(@indentToken, @currentLevel) if not @compress
+ if not @compress
+ @output += _.str.repeat(@indentToken, @currentLevel)
@output += tagHtml
if @innerText is null
@@ -371,13 +365,12 @@ class WieldyMarkup
@openTags.push(
[@currentLevel, @tag]
)
-
else
@output += "</#{@tag}>"
@output += "\n" if not @compress
@
exports = module.exports =
- version: '0.2.0'
+ version: '0.2.1'
Compiler: WieldyMarkup

0 comments on commit b6427ac

Please sign in to comment.