Skip to content

Commit

Permalink
improve tmlanguage.js
Browse files Browse the repository at this point in the history
  • Loading branch information
nightwing committed Oct 9, 2014
1 parent 9683d80 commit ed40c1f
Show file tree
Hide file tree
Showing 12 changed files with 895 additions and 172 deletions.
2 changes: 1 addition & 1 deletion Makefile.dryice.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function jsFileList(path, filter) {
filter = /_test/;

return fs.readdirSync(path).map(function(x) {
if (x.slice(-3) == ".js" && !filter.test(x) && !/\s/.test(x))
if (x.slice(-3) == ".js" && !filter.test(x) && !/\s|BASE|(\b|_)dummy(\b|_)/.test(x))
return x.slice(0, -3);
}).filter(Boolean);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/ace/ext/modelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ var supportedModes = {
Diff: ["diff|patch"],
Dockerfile: ["^Dockerfile"],
Dot: ["dot"],
Dummy: ["dummy"],
DummySyntax: ["dummy"],
Eiffel: ["e"],
EJS: ["ejs"],
Elm: ["elm"],
Expand Down
26 changes: 26 additions & 0 deletions tool/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Helper Scripts for Ace
======================

To use this you need to install node.js. and run `npm install` in this directory.


# add_mode.js

Run
```
node add_mode.js ModeName "extension1|extension2|^FullName"
```
to create all the files needed for a new mode named `ModeName`
this adds stubs for:
`ace/mode/mode_name.js`
`ace/mode/mode_name_hightlight_rules.js`
`ace/snippets/mode_name.js`
`ace/demo/kitchen_sink/docs/mode_name.extension1`
and adds entry for the new mode to `ace/ext/modelist.js`


# tmlanguage.js

```
node tmlanguage.js ./templates/dummy.JSON-tmLanguage
```
185 changes: 95 additions & 90 deletions tool/add_mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,105 @@ var fs = require('fs');
var lib = require('./lib');
var path = require('path');

var args = process.argv.slice(2);
function main(displayName, extRe) {
var name = lib.snakeCase(displayName).replace(/[^\w]/g, "");

/** demo **/
var demoFileExt = extRe.split("|")[0] || name;
var demoFileName = demoFileExt[0] == "^" ? demoFileExt.substr(1) : name + "." + demoFileExt;
var demoFilePath = lib.AceRoot + "demo/kitchen-sink/docs/" + demoFileName;
fs.writeFileSync(demoFilePath, "TODO add a nice demo!", "utf8");
console.log("Created demo file at: " + path.normalize(demoFilePath));

var displayName = args[0];
var extRe = args[1];
if (!displayName || ! extRe) {
console.log("Usage: ModeName ext1|ext2");
process.exit(1);
}

var name = lib.snakeCase(displayName).replace(/[^\w]/g, "");

/** demo **/
var demoFileExt = extRe.split("|")[0] || name;
var demoFileName = demoFileExt[0] == "^" ? demoFileExt.substr(1) : name + "." + demoFileExt;
var demoFilePath = lib.AceRoot + "demo/kitchen-sink/docs/" + demoFileName;
fs.writeFileSync(demoFilePath, "TODO add a nice demo!", "utf8");
console.log("Created demo file at: " + path.normalize(demoFilePath));

/** mode **/
var template = fs.readFileSync(__dirname + "/templates/mode.js", "utf8");
var modePath = lib.AceLib + "ace/mode/" + name + ".js";
var text = lib.fillTemplate(template, {
languageHighlightFilename: name,
languagename: name,
lineCommentStart: "TODO",
blockCommentStart: "TODO",
blockCommentEnd: "TODO"
});
fs.writeFileSync(modePath, text);
console.log("Created mode file at: " + path.normalize(modePath));

/** highlight rules **/
template = fs.readFileSync(__dirname + "/templates/highlight_rules.js", "utf8");
var hlPath = lib.AceLib + "ace/mode/" + name + "_highlight_rules.js";
template = template.replace(/\/\* THIS[\s\S]*?\*{3}\/\s*/, "");
text = lib.fillTemplate(template, {
language: name,
languageTokens: '{\n\
start: [{\n\
token: "string.start",\n\
regex: \'"\',\n\
next: "qstring"\n\
}],\n\
qstring: [{\n\
token: "escape",\n\
regex: /\\\\./,\n\
}, {\n\
token: "string.end",\n\
regex: \'"\',\n\
next: "start"\n\
}],\n\
}'
});
fs.writeFileSync(hlPath, text);
console.log("Created mode file at: " + path.normalize(hlPath));

/** snippets **/
template = fs.readFileSync(__dirname + "/templates/snippets.js", "utf8");
var snipetsPath = lib.AceLib + "ace/snippets/" + name + ".js";
text = lib.fillTemplate(template, {
languagename: name,
snippets: ""
});
fs.writeFileSync(snipetsPath, text);
console.log("Created snippets file at: " + path.normalize(snipetsPath));
/** mode **/
var template = fs.readFileSync(__dirname + "/templates/mode.js", "utf8");
var modePath = lib.AceLib + "ace/mode/" + name + ".js";
var text = lib.fillTemplate(template, {
languageHighlightFilename: name,
languagename: name,
lineCommentStart: "TODO",
blockCommentStart: "TODO",
blockCommentEnd: "TODO"
});
fs.writeFileSync(modePath, text);
console.log("Created mode file at: " + path.normalize(modePath));

/** modelist **/
var modelistPath = lib.AceLib + "ace/ext/modelist.js";
var modelist = fs.readFileSync(modelistPath, "utf8").replace(/\r\n?/g, "\n");
modelist = modelist.replace(/(supportedModes = {\n)([\s\S]*?)(\n^};)/m, function(_, m1, m2, m3) {
var langs = m2.split(/,\n/);
var offset = langs[0].trim().indexOf("[");
var padding = Array(Math.max(offset - displayName.length - 1, 0) + 1).join(" ");
var newLang = " " + displayName + ":" + padding + "[\"" + extRe + "\"]";
langs = langs.concat(newLang).map(function(x) {
return {
value: x,
id: x.match(/[^"':\s]+/)[0].toLowerCase()
};
/** highlight rules **/
template = fs.readFileSync(__dirname + "/templates/highlight_rules.js", "utf8");
var hlPath = lib.AceLib + "ace/mode/" + name + "_highlight_rules.js";
template = template.replace(/\/\* THIS[\s\S]*?\*{3}\/\s*/, "");
text = lib.fillTemplate(template, {
language: name,
languageTokens: '{\n\
start: [{\n\
token: "string.start",\n\
regex: \'"\',\n\
next: "qstring"\n\
}],\n\
qstring: [{\n\
token: "escape",\n\
regex: /\\\\./,\n\
}, {\n\
token: "string.end",\n\
regex: \'"\',\n\
next: "start"\n\
}],\n\
}'
});
langs[langs.length - 1].isNew = true;

langs = langs.filter(function(x) {
return x.id != name || x.isNew;
fs.writeFileSync(hlPath, text);
console.log("Created mode file at: " + path.normalize(hlPath));

/** snippets **/
template = fs.readFileSync(__dirname + "/templates/snippets.js", "utf8");
var snipetsPath = lib.AceLib + "ace/snippets/" + name + ".js";
text = lib.fillTemplate(template, {
languagename: name,
snippets: ""
});
langs = langs.sort(function(a, b) {
return a.id.localeCompare(b.id);
}).map(function(x) {
return x.value;
fs.writeFileSync(snipetsPath, text);
console.log("Created snippets file at: " + path.normalize(snipetsPath));

/** modelist **/
var modelistPath = lib.AceLib + "ace/ext/modelist.js";
var modelist = fs.readFileSync(modelistPath, "utf8").replace(/\r\n?/g, "\n");
modelist = modelist.replace(/(supportedModes = {\n)([\s\S]*?)(\n^};)/m, function(_, m1, m2, m3) {
var langs = m2.split(/,\n/);
var offset = langs[0].trim().indexOf("[");
var padding = Array(Math.max(offset - displayName.length - 1, 0) + 1).join(" ");
var newLang = " " + displayName + ":" + padding + "[\"" + extRe + "\"]";
langs = langs.concat(newLang).map(function(x) {
return {
value: x,
id: x.match(/[^"':\s]+/)[0].toLowerCase()
};
});
langs[langs.length - 1].isNew = true;

langs = langs.filter(function(x) {
console.log(x.id, displayName)
return x.id != displayName.toLowerCase() || x.isNew;
});
langs = langs.sort(function(a, b) {
return a.id.localeCompare(b.id);
}).map(function(x) {
return x.value;
});

return m1 + langs.join(",\n") + m3;
});

return m1 + langs.join(",\n") + m3;
});
fs.writeFileSync(modelistPath, modelist, "utf8");
console.log("Updated modelist at: " + path.normalize(modelistPath));
fs.writeFileSync(modelistPath, modelist, "utf8");
console.log("Updated modelist at: " + path.normalize(modelistPath));
}

if (!module.parent) {
var args = process.argv.slice(2);
var displayName = args[0];
var extRe = args[1];
if (!displayName || ! extRe) {
console.log("Usage: ModeName ext1|ext2");
process.exit(1);
}
} else {
module.exports = main;
}

19 changes: 12 additions & 7 deletions tool/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ var url = require("url");
var https = require("https");
var http = require("http");

exports.parsePlist = function(themeXml, callback) {
var result = "";
plist.parseString(themeXml, function(_, theme) {
result = theme[0];
callback && callback(theme[0]);
});
return result;
exports.parsePlist = function(xmlOrJSON, callback) {
var json;
if (xmlOrJSON[0] == "<") {
plist.parseString(xmlOrJSON, function(_, result) {
json = result[0];
});
} else {
xmlOrJSON = xmlOrJSON.replace(/^\s*\/\/.*/gm, "");
json = JSON.parse(xmlOrJSON)
}
callback && callback(json);
return json;
};

exports.formatJSON = function(object, initialIndent) {
Expand Down
6 changes: 3 additions & 3 deletions tool/mode_creator.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ document.getElementById("perfTest").onclick = function() {
}

var tk = new Tokenizer(currentRules);
var testPerf = function(lines, tk){
var testPerf = function(lines, tk) {
var state = "start";
for (var i=0, l = lines.length; i <l; i++) {
state = tk.getLineTokens(lines[i], state).state;
Expand Down Expand Up @@ -126,7 +126,7 @@ util.bindDropdown("themeEl", function(value) {

function getDeps(src, path) {
var deps = [];
src.replace(/require\((['"])(.*?)\1/g, function(a,b,c){
src.replace(/require\((['"])(.*?)\1/g, function(a,b,c) {
if (c[0] == ".") {
var base = path.split("/");
c.split("/").forEach(function(part) {
Expand All @@ -151,7 +151,7 @@ function run() {
var path = "ace/mode/new";
var deps = getDeps(src, path);
window.require.undef(path);
src = src.replace("define(", 'define("' + path +'", ["require","exports","module",' + deps +'],');
src = src.replace("define(", 'define("' + path +'", ["require","exports","module",' + deps +'],');
try {
eval(src);
require(["ace/mode/new"], function(e) {
Expand Down
Loading

0 comments on commit ed40c1f

Please sign in to comment.