JavaScript does not support operator overloading. Matrix libraries in JavaScript could not simplify notation. I would like to create operator overloading with a simple trick by adding using syntax like z = x++y. This is not a valid statement in JavaScript.
That is why I would like to create an include method which will parse existing JavaScript files and replace those statements with actual JavaScript code. This is somehow related to coffescript where the compiler is inside JavaScript. What would be the best way to approach that.
I have string manipulation solution:
"z=x++y;".replace(/(.*)=(.*)\+\+(.*)/i,"for(var _i_=0;_i_<$1.length;_i_++){ $1[i] = $2[i]+$3[i]}")
Example run:
for(var _i_=0;_i_<c.length;_i_++){ c[i] = data[0][i]+data[1][i];}
Obtaining Matlab, numpy like environment in JavaScript would be very convenient for easily deploying scientific models as web applications and avoiding computational burden in server side. Also, parallelization would be as easy as opening another browser tab from somewhere.
Related
I want to add new syntax to my JavaScript files much like Sweet.js, but using Clojure/ClojureScript to do the transformation.
Here is what I would like to do:
//original
specialFunction add(a, b) {
return a + b;
}
//transformed
function add(a, b) {
return a + b;
}
registerSpecialFunction({
name: "add",
args: ["a", "b"],
func: add
});
Correct me if I'm wrong, but I think it would work best by:
parse the JS file into an AST
do the transformation
print the resulting AST back out as JavaScript
Any idea on how to do parts 1 and 3? Do I even have the right idea here?
Just as a heads up, this may be a non-trivial task, but probably a great learning exercise.
You'll have to re-implement the concept or macros from Sweet.js or the idea of custom parser extensions from Babylon (parser for Babel) if you want the same control from Clojure.
Either way, you'll need to write a parser that understands a superset of JavaScript's syntax. You might want to look at parser generators such as instaparse (Clojure) and peg.js (JavaScript).
Then you need to decide whether you want to make a fixed number of additions to the language grammar (like Babel) or allow macros to define their own grammar extensions/replacement rules (like Sweet.js). At this point, you'll need to write some kind of engine for transforming the AST generated by your parser.
Macros can be implemented in a number of ways, everything from replacement rules like you'd find in C and C++ to full blown compile-time evaluated functions that work directly with the AST like you'd find in Clojure.
After parsing and transforming the AST with this new tool, you'll need to transform it into a valid JavaScript AST. It'll make things easier to maintain compatibility with the ESTree specification as this will allow you to use tools like escodegen to actually generate the JavaScript code from the AST itself.
Of course, piggybacking tools like peg.js and escodegen is only possible if you're writing your tool as ClojureScript and compiling and running it against NodeJS. The other option is to find compatible tools within the JVM ecosystem and use them with JVM compiled Clojure instead.
The JavaScript ecosystem has a range of good tools available for parsing, transforming and generating ES code (have a look through the Babel packages for example/inspiration) but you'll have to remember that if you are writing ClojureScript and running it under Node, you are in fact creating a JavaScript executable and it might have just been easier to start with JavaScript in the first place.
We would like to exchange PO files with translators, and convert these to i18next's native JSON format. This sounds pretty straightforward using the i18next-conv utility.
However, i18next expects more or less special keys; for example the dot has special meaning with regard to i18next namespaces. In contrast, gettext PO files are intended to carry source strings (in the original language) for their message IDs.
We know that message IDs can be arbitrary, and can thus be mapped to i18next keys directly, but we would like to use source strings and use PO files as they were intended for various reasons.
The main reason is that all the translation tools we would like to use, and probably those of all our translators, expect this. Using symbolic keys would make translating a real pain. In any case, we figured from the debates around this that this is mainly a matter of opinion; we kind of made ours, and we would like to put this restriction as a requirement for this question.
Is it really a bad idea to use source strings as i18next keys from a technical standpoint? How hard is it to escape them? Is there anything else than the dot and namespaces that we should care about?
If we determine that we want to keep using symbolic keys, is there an alternative to i18next-conv that can generate i18next JSON translation files from PO files using source strings as message IDs? We understand that we would most likely need to maintain a separate mapping between the symbolic names and the original language strings, and we're prepared to do so.
Moreover, we wonder about the general workflow. How is the original PO file generated? How are the translation files maintained?
If we use source strings as keys in i18next, what are the best tools to extract strings from the codebase? xgettext doesn't seem to support Javascript.
If we use symbolic keys in i18next, how can we best generate the original PO file? Is writing a POT file by hand a good practice?
Again, if we use symbolic keys, how can we easily invalidate translations whenever we update the original language strings? Are there tools for that?
We understand these questions are very basic, but we were a bit surprised at how little information we could find about i18next-gettext integration. The i18next-conv tool exists and works perfectly as advertised, but is it actually useful? Do people actually use it? If so, are our questions relevant?
Finally, are our expectations about the maturity of the system a little too high?
if you like to use source strings as keys just change the
nsseparator = ':::'
keyseparator = '::'
so . and : could be used inside the key without fear.
You could try using https://github.com/cheton/i18next-text. It allows you using i18next translation without having the key as strings, and you do not need to worry about i18n key naming. Furthermore, you can also register the i18n helper with Handlebars.
Following is a simple example:
var i18n = require('i18next');
// extends i18n object to provide a new _() method
i18n._ = require('i18next-text')._;
i18n._('Save your time and work more efficiently.');
Check out the demo on JSFiddle.
I'm using python-spidermonkey to run JavaScript code.
In order to pass objects (instead of just strings) to Python, I'm thinking of returning a JSON string.
This seems like a common issue, so I wonder whether there are any facilities for this built into either Spidermonkey or python-spidermonkey.
(I do know about uneval but that is not meant to be used for JSON serialization - and I'd rather avoid injecting a block of JavaScript to do this.)
I would use JSON.stringify. It's part of the ECMAScript 5 standard, and it's implemented in the current version of spidermonkey. I don't know if it's in the version used by python-spidermonkey, but if it isn't, you can get a JavaScript implementation from http://www.json.org/js.html.
I need to split a JavaScript file into single instructions. For example
a = 2;
foo()
function bar() {
b = 5;
print("spam");
}
has to be separated into three instructions. (assignment, function call and function definition).
Basically I need to instrument the code, injecting code between these instructions to perform checks. Splitting by ";" wouldn't obviously work because you can also end instructions with newlines and maybe I don't want to instrument code inside function and class definitions (I don't know yet). I took a course about grammars with flex/Bison but in this case the semantic action for this rule would be "print all the descendants in the parse tree and put my code at the end" which can't be done with basic Bison I think. How do I do this? I also need to split the code because I need to interface with Python with python-spidermonkey.
Or... is there a library out there already which saves me from reinventing the wheel? It doesn't have to be in Python.
Why not use a JavaScript parser? There are lots, including a Python API for ANTLR and a Python wrapper around SpiderMonkey.
JavaScript is tricky to parse; you need a full JavaScript parser.
The DMS Software Reengineering Toolkit can parse full JavaScript and build a corresponding AST.
AST operators can then be used to walk over the tree to "split it". Even easier, however, is to apply source-to-source transformations that look for one surface syntax (JavaScript) pattern, and replace it by another. You can use such transformations to insert the instrumentation into the code, rather than splitting the code to make holds in which to do the insertions. After the transformations are complete, DMS can regenerate valid JavaScript code (complete with the orignal comments if unaffected).
Why not use an existing JavaScript interpreter like Rhino (Java) or python-spidermonkey (not sure whether this one is still alive)? It will parse the JS and then you can examine the resulting parse tree. I'm not sure how easy it will be to recreate the original code but that mostly depends on how readable the instrumented code must be. If no one ever looks at it, just generate a really compact form.
pyjamas might also be of interest; this is a Python to JavaScript transpiler.
[EDIT] While this doesn't solve your problem at first glance, you might use it for a different approach: Instead of instrumenting JavaScript, write your code in Python instead (which can be easily instrumented; all the tools are already there) and then convert the result to JavaScript.
Lastly, if you want to solve your problem in Python but can't find a parser: Use a Java engine to add comments to the code which you can then search for in Python to instrument the code.
Why not try a javascript beautifier?
For example http://jsbeautifier.org/
Or see Command line JavaScript code beautifier that works on Windows and Linux
Forget my parser. https://bitbucket.org/mvantellingen/pyjsparser is great and complete parser. I've fixed a couple of it's bugs here: https://bitbucket.org/nullie/pyjsparser
I have a web application that uses TONS of javascript, and as usual, there are a lot of textual constants that will be displayed to the user embedded in the code itself.
What do you think is the best way to make this localizable?
I know I need to take those strings off of the code and replace them with constants, which will be defined into some external place.
For the server side, ASP.Net provides some very neat capabilities for dealing with this.
What's the best to do this in Javascript?
The best idea I have is to have a JS file with ALL the string constants of the JS of the site (i'd have different copies of this, for each language), and then on each page, I include this script first, before all the others.
This seems like the most centralized way, that also wastes the least bandwidth.
Are there any other better approaches?
Thanks!
here's how we did it (in ASP.net), pretty much along the lines of what you've mentioned:
1) Created two javascript files: one which defines all javascript functions/DOM manipulations as required by the site, and, second called Messages.js: this defines all the string literals that need to be localized, something like var ALERT_MSG = "Alert message in english".
2) Created different version of the Messages.js, one for each locale that we are supporting and localized the strings. The localized js files were named using messages.locale.js naming convention (for eg. messages.fr-FR.js).
3) Included the js files within the "ScriptManager" and provided the ResourceUICultures for the Messages.js file: this ensures that the correct localized file is embedded in the html output (if you are not using ASP.net you can build this basic functionality by doing some culture sniffing and including the appropriate js file).
4) Voila!
Your approach makes sense. Details:
I'd have the strings for each language in an object.
localized={"cat":"chat","dog":"chien"};
Then in code:
localized["cat"]
The quotations around of the keys and the array notation (rather than the more common object dot notation) are to avoid collisions with JavaScript reserved words.
There is a gettext library but I haven't used it.
Your approach sounds good enough.
If you have lots of strings and you are concerned about the bulkiness of the file you may want to consider a script that creates a single javascript file for each language by concatenating the code javascript and the locale javascript and then applying something like Minify.
You'll waste some CPU cycles on publishing but you'll save some round trips...
There's a library for localizing JavaScript applications: https://github.com/wikimedia/jquery.i18n
The strings are stored in JSON files, as pretty much everybody else suggests, but it has a few more features:
It can do parameter replacement, supports gender (clever he/she handling), number (clever plural handling, including languages that have more than one plural form), and custom grammar rules that some languages need.
The only requirement is jQuery.