diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/index.js b/index.js old mode 100644 new mode 100755 diff --git a/lib/JossyParser.js b/lib/JossyParser.js index 5222beb..37493db 100644 --- a/lib/JossyParser.js +++ b/lib/JossyParser.js @@ -1,159 +1,170 @@ -module.exports = JossyParser; +var FileStructure, JossyError, fileExists; + +FileStructure = require('./FileStructure'); +JossyError = require('./JossyError'); +fileExists = require('fs').exists || require('path').exists; + +function _include(file, params, callback) { + var paramsParts = params.split('::'); + var includeFileName = paramsParts.shift(); + if (includeFileName) { + var absFileName = file.getRelativePathOf(includeFileName); + this.parseFile(absFileName, function(err, includeFile) { + if (err) { + callback(err); + return; + } + file.addInclude(includeFile, paramsParts); + callback(); + }); + } else { + try { + file.addInclude(file, paramsParts); + callback(); + } catch (err) { + callback(err); + } + } +} -var FileStructure = require('./FileStructure'); -var JossyError = require('./JossyError'); +function _without(file, params, callback) { + var paramsParts = params.split('::'); + var includeFname = file.getRelativePathOf(paramsParts.shift()); + this.parseFile(includeFname, function(err, includeFile) { + if (err) { + callback(err); + return; + } + file.addWithout(includeFile, paramsParts); + callback(); + }); +} -var fileExists = require('fs').exists || require('path').exists; +function _label(file, label) { + file.beginLabel(label); +} -function JossyParser() { - this._cache = {}; +function _endlabel(file) { + file.endLabel(); } -JossyParser.prototype = { - parseFile: function(fname, callback) { - var that = this; - normalizePath(fname, function(err, fname) { +function _if(file, params) { + if (!params.trim()) { + throw new Error('Bad "if" directive'); + } + var args = params.split(/\s+/); + var value = true; + if (args.length > 1 && args[0] == 'not') { + value = false; + args.shift(); + } + file.beginIf(args[0], value); +} + +function _endif(file) { + file.endIf(); +} + +function _set(file, params) { + if (!params.trim()) { + throw new Error('Bad set directive'); + } + var args = params.split(/\s+/); + file.addSet(args[0]); +} + +function _unset(file, params) { + if (!params.trim()) { + throw new Error('Bad unset directive'); + } + var args = params.split(/\s+/); + file.addUnset(args[0]); +} + +function parseFile(fname, callback) { + var that = this; + normalizePath(fname, function(err, fname) { + if (err) { + callback(err); + return; + } + if (that._cache[fname]) { + callback(null, that._cache[fname]); + return; + } + require('fs').readFile(fname, 'utf8', function(err, content) { if (err) { callback(err); return; } - if (that._cache[fname]) { - callback(null, that._cache[fname]); - return; - } - require('fs').readFile(fname, 'utf8', function(err, content) { - if (err) { - callback(err); - return; - } - var fileStructure = new FileStructure(fname); - that._cache[fname] = fileStructure; - var lines = content.split(/\r?\n/); - (function parseLines(start) { - var i; - var errors = []; - - var appendError = function(err) { - var msg = err.message; - var line = i + 1; - errors.push(new JossyError(msg, fname, line)); - fileStructure.error(msg); - }; - - var asyncParseCallback = function(err) { - if (err) { - appendError(err); - } - parseLines(i + 1); - }; - - for (i = start; i < lines.length; i++) { - var line = lines[i]; - if (line.match(/^\s*\/\/#([\s\S]*)$/)) { - if (RegExp.$1) { - var command = RegExp.$1.split(' '); - var directive = command.shift(); - var params = command.join(' '); - if (/^(include|without)$/.test(directive)) { - that['_' + directive](fileStructure, params, asyncParseCallback); - return; - } else if (/^(label|endlabel|if|endif|set|unset)$/.test(directive)) { - try { - that['_' + directive](fileStructure, params); - } catch (err) { - appendError(err); - } - } else { - appendError(new Error('Unknown directive ' + directive)); + var fileStructure = new FileStructure(fname); + that._cache[fname] = fileStructure; + var lines = content.split(/\r?\n/); + (function parseLines(start) { + var i; + var errors = []; + + var appendError = function(err) { + var msg = err.message; + var line = i + 1; + errors.push(new JossyError(msg, fname, line)); + fileStructure.error(msg); + }; + + var asyncParseCallback = function(err) { + if (err) { + appendError(err); + } + parseLines(i + 1); + }; + + for (i = start; i < lines.length; i++) { + var line = lines[i]; + if (line.match(/^\s*\/\/(#|\s*@)([\s\S]*)$/)) { + if (RegExp.$2) { + var command = RegExp.$2.split(' '); + var directive = command.shift(); + var params = command.join(' '); + if (/^(require|include|without)$/.test(directive)) { + that['_' + directive](fileStructure, params, asyncParseCallback); + return; + } else if (/^(label|endlabel|if|endif|set|unset)$/.test(directive)) { + try { + that['_' + directive](fileStructure, params); + } catch (err) { + appendError(err); } + } else if (RegExp.$1.indexOf('@') === -1) { + appendError(new Error('Unknown directive ' + directive)); } - } else { - fileStructure.addCode(line + (i < lines.length - 1 ? '\n' : '')); } + } else { + fileStructure.addCode(line + (i < lines.length - 1 ? '\n' : '')); } - - callback(null, fileStructure); - })(0); - }); - }); - }, - - _include: function(file, params, callback) { - var paramsParts = params.split('::'); - var includeFileName = paramsParts.shift(); - if (includeFileName) { - var absFileName = file.getRelativePathOf(includeFileName); - this.parseFile(absFileName, function(err, includeFile) { - if (err) { - callback(err); - return; } - file.addInclude(includeFile, paramsParts); - callback(); - }); - } else { - try { - file.addInclude(file, paramsParts); - callback(); - } catch (err) { - callback(err); - } - } - }, - _without: function(file, params, callback) { - var paramsParts = params.split('::'); - var includeFname = file.getRelativePathOf(paramsParts.shift()); - this.parseFile(includeFname, function(err, includeFile) { - if (err) { - callback(err); - return; - } - file.addWithout(includeFile, paramsParts); - callback(); + callback(null, fileStructure); + })(0); }); - }, - - _label: function(file, label) { - file.beginLabel(label); - }, - - _endlabel: function(file) { - file.endLabel(); - }, - - _if: function(file, params) { - if (!params.trim()) { - throw new Error('Bad "if" directive'); - } - var args = params.split(/\s+/); - var value = true; - if (args.length > 1 && args[0] == 'not') { - value = false; - args.shift(); - } - file.beginIf(args[0], value); - }, - - _endif: function(file) { - file.endIf(); - }, + }); +} - _set: function(file, params) { - if (!params.trim()) { - throw new Error('Bad set directive'); - } - var args = params.split(/\s+/); - file.addSet(args[0]); - }, +function JossyParser() { + this._cache = {}; +} - _unset: function(file, params) { - if (!params.trim()) { - throw new Error('Bad unset directive'); - } - var args = params.split(/\s+/); - file.addUnset(args[0]); - } +JossyParser.prototype = { + parseFile: parseFile, + + _include: _include, + _require: _include, + _without: _without, + _label: _label, + _endlabel: _endlabel, + _if: _if, + _endif: _endif, + _set: _set, + _unset: _unset }; var realpathCache = {}; @@ -188,3 +199,5 @@ function normalizePath(fname, callback) { }); } } + +module.exports = JossyParser; diff --git a/package.json b/package.json index f643516..b0df845 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "author": { - "name": "Kolyaj", - "email": "kolyaj@yandex.ru", - "url": "https://github.com/Kolyaj" - }, + "author": "Kolyaj (https://github.com/Kolyaj)", + "contributors": [ + "Kolyaj (https://github.com/Kolyaj)", + "Pavel Akhmetchanov (http://github.com/pavelpower)" + ], "name": "jossy", "description": "JavaScript files builder", - "version": "0.0.2", + "version": "0.0.3", "homepage": "https://github.com/Kolyaj/Jossy", "repository": { "type": "git", diff --git a/readme.md b/readme.md index a06e03b..e4a35cf 100644 --- a/readme.md +++ b/readme.md @@ -18,6 +18,10 @@ Jossy необходим только на этапе разработки, по //#include file.js +Альтернативная декларация аналог `#include`: + + // @require file.js + Путь к файлу указывается относительно расположения текущего файла. Технически, вместо строки с директивой просто вставляется содержимое указанного файла. Однако, если указанный файл уже подключен в текущем модуле ранее, то повторно он включен не будет. Например, файл f1.js alert(1); diff --git a/tests/require/result.js b/tests/require/result.js new file mode 100644 index 0000000..6f17f69 --- /dev/null +++ b/tests/require/result.js @@ -0,0 +1,5 @@ +alert(1); + +alert(2); + +alert(3); \ No newline at end of file diff --git a/tests/require/test-1.js b/tests/require/test-1.js new file mode 100644 index 0000000..881eccf --- /dev/null +++ b/tests/require/test-1.js @@ -0,0 +1 @@ +alert(2); diff --git a/tests/require/test.js b/tests/require/test.js new file mode 100644 index 0000000..d31d6c3 --- /dev/null +++ b/tests/require/test.js @@ -0,0 +1,6 @@ +alert(1); + +// @decl test-1.js +// @require test-1.js + +alert(3); \ No newline at end of file