I'm still learning JavaScript, and now I'm in the array chapter and I'm doing this project I have to ask the user for 5 names and stored and my array, then have to sort the names by the location in the array, so i could separed in odd and in even, then i have to add a lastname to the odds, and different last name to the even, but is that part that is not working any help ... THANKS
var numberfirstNames = 5;
var userMessage = " Please enter a first Name" ;
var secondArray = [];
var odd2 = [];
var even2 = [];
for (var i = 0; i < numberfirstNames; i++) // loop 5 times LOOL ASKING FOR "5" FIRST NAMES>> STORING IN NAMES
{
secondArray[i] = getFirstname();
window.alert("second " + secondArray[i] );
}
for (var i = 0; i < secondArray.length; i++) {
if(i % 2 === 0) // index is even
{
even2.push(secondArray[i]);
for ( var i=0 ; i<even2.length; i++)
even2[i]+=" Chavez"
}
else
{
odd2.push(secondArray[i]);
for ( var i=0 ; i<odd2.length; i++)
odd2[i]+=" McCain"
}
}
document.write(" \n all the names: "+ secondArray+'<br>');
document.write(" \n even names: "+ even2+'<br>');
document.write(" \n odd names: "+ odd2+'<br>');
The problem is that you are making a second loop that is unnecessary... the code
for ( var i=0 ; i<even2.length; i++)
and
for ( var i=0 ; i<odd2.length; i++)
should be simply removed.
You need to add first or last name only to last element added to odd2 or even2 and this can be done with:
even2[even2.length-1]+=" Chavez"
and
odd2[odd2.length-1]+=" McCain"
It is important to get used adding correct indentation because this kind of error is much easier to spot in the code when it is properly indented.
You don't need to loop again to add the specific last name. You can just prepend it while you are inserting it into the array like below.
var numberfirstNames = 5;
var userMessage = " Please enter a first Name";
var secondArray = [];
var odd2 = [];
var even2 = [];
// loop 5 times LOOP ASKING FOR "5" FIRST NAMES >> STORING IN NAMES
for (var i = 0; i < numberfirstNames; i++) {
secondArray[i] = getFirstname();
window.alert("second " + secondArray[i]);
if (i % 2 === 0) {
even2.push(secondArray[i] + " Chavez");
} else {
odd2.push(secondArray[i] + " McCain");
}
}
document.write(" \n all the names: " + secondArray.join(",") + '<br>');
document.write(" \n even names: " + even2.join(",") + '<br>');
document.write(" \n odd names: " + odd2.join(",") + '<br>');
I need to be able to keep the same case, i.e. "Attack" will be "Lxfopv", with the key "lemon". In addition, I need to keep any spaces within the message to be encrypted.
I used an if statement to check for whitespace
if(text.charAt(i) == ' '){
continue;
but it doesn't seem to do anything.
function encrypt(text, key) {
var output= '';
var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(var i = 0; i < text.length; i++){
var a= alphabet.indexOf(key.charAt(i % key.length));
var b= alphabet.indexOf(text.charAt(i));
if(text.charAt(i) == ' '){
continue;
}else{
output += alphabet.charAt((a+ b) % alphabet.length);
}
}
return output;
}
if pass in "Attack at Dawn", my desired output should be Lxfopv ef Rnhr but I am recieving LxFopvmHOeIB with the key "lemon".
How can I fix this to get the desired output? Is it something to do with the fact that I have hardcoded my alphabet?
In order to keep the case, you will have to work your transformation on a single case.
Only at the time of adding it to your output, will you convert it to the correct case.
And in order to get the same value than other algorithms which do ignore the space character, you have to use a second iterator variable.
This iterator should get incremented only on valid inputs, and will be used to iterate the key.
inp.oninput = e => log.textContent = encrypt(inp.value, 'lemon');
function encrypt(text, key) {
var output= '';
// single case dictionary
var alphabet = "abcdefghijklmnopqrstuvwxyz";
var low = text.toLowerCase(); // we'll work on this one
for(let i = 0, j = 0; i < text.length; i++){
// here we use `j` for the key
let a = alphabet.indexOf(key.charAt(j % key.length));
let b = alphabet.indexOf(low.charAt(i));
let out = ''; // the character we'll add
if(low.charAt(i) == ' '){
out = ' '; // keep spaces untouched
}else if(b > -1){ // only if valid
out = alphabet.charAt((a+ b) % alphabet.length); // get the ciphered value
j++; // only here we increment `j`
}
if(low[i] !== text[i]) { // if input and lower case are different
// that means that input was upper case
out = out.toUpperCase();
}
output += out;
}
return output;
}
<input id="inp"> <pre id="log"></pre>
Just add the space to your alphabet:
if(text.charAt(i) == ' '){
output += " ";
}
Users will enter various serials in a textarea. Each newline will indicate a new serial. Some requirements/restrictions:
Leading and trailing white spaces are not allowed.
White space within a serial is okay.
Blank serials are not allowed
I'd prefer to not use JQuery.
Store duplicates so they can be shown to the user.
Based on my tests I have a working solution. I want to make sure I'm not missing or overlooking anything. My questions are:
Is there a more efficient ways to check for duplicates?
Are there any glaring test cases that my solution won't catch?
Working Example: http://jsbin.com/ivusuj/1/
function duplicateCheck() {
var output = document.getElementById('Output');
output.innerHTML = '';
var duplicateSerials = [];
var count = 0;
var textArea = document.getElementById('Serials');
var serials = textArea.value.trim().split(/ *\n */);
for(var i = 0;i < serials.length;i++){
var serial = serials[i];
if(serials.indexOf(serial) != serials.lastIndexOf(serial) &&
duplicateSerials.indexOf(serial) == -1 && serial !== '') {
duplicateSerials.push(serial);
}
}
// For testing
output.innerHTML = '<pre>Serials:\t' + serials.toString() + "<br />" +
'Duplicates:\t' + duplicateSerials.toString() + "<br>" +
'</pre>';
}
Note: the above is for a client side check. The same check will be performed server side as well to ensure the data is valid.
Update
Solution comparison: http://jsbin.com/ivusuj/4/edit
I put together a jsfiddle her: http://jsfiddle.net/wrexroad/yFJjR/3/
Actually checking for duplicates that way is pretty inefficient.
Instead of checking for duplicates, this just adds a property to an object where the property's name is is the serial. Then it prints out all of the property names.
This way if you have duplicates, it will just create the property, then overwrite it.
Here is the function:
function duplicateCheck() {
var output = document.getElementById('Output');
output.innerHTML = '';
var textArea = document.getElementById('Serials');
var inputSerials =
textArea.value.trim().split(/ *\n */);
var outputSerials = new Object();
for(var i = 0;i < inputSerials.length;i++){
var serial = inputSerials[i];
//build an object whose properties are serials
//if the serial exists, incremint a counter
if(outputSerials[serial]){
outputSerials[serial]++;
}else{
outputSerials[serial] = 1;
}
}
output.innerHTML =
'Serials: <br />';
for(var i in outputSerials){
output.innerHTML += i + " ";
}
output.innerHTML +=
'<br /><br />Duplicate Serials: <br />';
for(var i in outputSerials){
//check to see if we have any duplicates
if(outputSerials[i] > 1){
output.innerHTML += i + " ";
}
}
}
I think you'd get significantly better performance if you used an object to determine which serials you'd seen before. Something closer to this:
var seen = {};
for (var i = 0, j = serials.length; i < j; ++i) {
var serial = serials[i];
if (seen.hasOwnProperty(serial)) {
// Dupe code goes here.
continue;
}
// Can't be a duplicate if we get to this point.
}
Though that won't work with serials that use periods.
Here's a solution to filter out duplicates.
function formatInput() {
var arrUnique = [], dups = [],
str = document.getElementById('Serials').value
.replace(/\r\n?/g,'\n')
// normalize newlines - not sure what PC's
// return. Mac's are using \n's
.replace(/(^((?!\n)\s)+|((?!\n)\s)+$)/gm,'')
// trim each line
.replace(/^\n+|\n+$|\n+(?=\n(?!\n))/g,''),
// delete empty lines and trim the whole string
arr = str.length ? str.split(/\n/) : [];
// split each line, if any
for (var i = 0; i < arr.length; i++) {
if (arrUnique.indexOf(arr[i]) == -1)
arrUnique.push(arr[i]);
else dups.push(arr[i]);
}
//document.getElementById('Serials').value = arrUnique.join('\n');
console.log('serials:', arr);
console.log('unique:', arrUnique);
console.log('duplicates:', dups);
}
I'm trying to find a way to "pretty print" a JavaScript data structure in a human-readable form for debugging.
I have a rather big and complicated data structure being stored in JS and I need to write some code to manipulate it. In order to work out what I'm doing and where I'm going wrong, what I really need is to be able to see the data structure in its entirety, and update it whenever I make changes through the UI.
All of this stuff I can handle myself, apart from finding a nice way to dump a JavaScript data structure to a human-readable string. JSON would do, but it really needs to be nicely formatted and indented. I'd usually use Firebug's excellent DOM dumping stuff for this, but I really need to be able to see the entire structure at once, which doesn't seem to be possible in Firebug.
Use Crockford's JSON.stringify like this:
var myArray = ['e', {pluribus: 'unum'}];
var text = JSON.stringify(myArray, null, '\t'); //you can specify a number instead of '\t' and that many spaces will be used for indentation...
Variable text would look like this:
[
"e",
{
"pluribus": "unum"
}
]
By the way, this requires nothing more than that JS file - it will work with any library, etc.
I wrote a function to dump a JS object in a readable form, although the output isn't indented, but it shouldn't be too hard to add that: I made this function from one I made for Lua (which is much more complex) which handled this indentation issue.
Here is the "simple" version:
function DumpObject(obj)
{
var od = new Object;
var result = "";
var len = 0;
for (var property in obj)
{
var value = obj[property];
if (typeof value == 'string')
value = "'" + value + "'";
else if (typeof value == 'object')
{
if (value instanceof Array)
{
value = "[ " + value + " ]";
}
else
{
var ood = DumpObject(value);
value = "{ " + ood.dump + " }";
}
}
result += "'" + property + "' : " + value + ", ";
len++;
}
od.dump = result.replace(/, $/, "");
od.len = len;
return od;
}
I will look at improving it a bit.
Note 1: To use it, do od = DumpObject(something) and use od.dump. Convoluted because I wanted the len value too (number of items) for another purpose. It is trivial to make the function return only the string.
Note 2: it doesn't handle loops in references.
EDIT
I made the indented version.
function DumpObjectIndented(obj, indent)
{
var result = "";
if (indent == null) indent = "";
for (var property in obj)
{
var value = obj[property];
if (typeof value == 'string')
value = "'" + value + "'";
else if (typeof value == 'object')
{
if (value instanceof Array)
{
// Just let JS convert the Array to a string!
value = "[ " + value + " ]";
}
else
{
// Recursive dump
// (replace " " by "\t" or something else if you prefer)
var od = DumpObjectIndented(value, indent + " ");
// If you like { on the same line as the key
//value = "{\n" + od + "\n" + indent + "}";
// If you prefer { and } to be aligned
value = "\n" + indent + "{\n" + od + "\n" + indent + "}";
}
}
result += indent + "'" + property + "' : " + value + ",\n";
}
return result.replace(/,\n$/, "");
}
Choose your indentation on the line with the recursive call, and you brace style by switching the commented line after this one.
... I see you whipped up your own version, which is good. Visitors will have a choice.
You can use the following
<pre id="dump"></pre>
<script>
var dump = JSON.stringify(sampleJsonObject, null, 4);
$('#dump').html(dump)
</script>
In Firebug, if you just console.debug ("%o", my_object) you can click on it in the console and enter an interactive object explorer. It shows the entire object, and lets you expand nested objects.
For Node.js, use:
util.inspect(object, [options]);
API Documentation
For those looking for an awesome way to see your object, check prettyPrint.js
Creates a table with configurable view options to be printed somewhere on your doc. Better to look than in the console.
var tbl = prettyPrint( myObject, { /* options such as maxDepth, etc. */ });
document.body.appendChild(tbl);
I'm programming in Rhino and I wasn't satisfied with any of the answers that were posted here. So I've written my own pretty printer:
function pp(object, depth, embedded) {
typeof(depth) == "number" || (depth = 0)
typeof(embedded) == "boolean" || (embedded = false)
var newline = false
var spacer = function(depth) { var spaces = ""; for (var i=0;i<depth;i++) { spaces += " "}; return spaces }
var pretty = ""
if ( typeof(object) == "undefined" ) { pretty += "undefined" }
else if ( typeof(object) == "boolean" ||
typeof(object) == "number" ) { pretty += object.toString() }
else if ( typeof(object) == "string" ) { pretty += "\"" + object + "\"" }
else if ( object == null) { pretty += "null" }
else if ( object instanceof(Array) ) {
if ( object.length > 0 ) {
if (embedded) { newline = true }
var content = ""
for each (var item in object) { content += pp(item, depth+1) + ",\n" + spacer(depth+1) }
content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
pretty += "[ " + content + "\n" + spacer(depth) + "]"
} else { pretty += "[]" }
}
else if (typeof(object) == "object") {
if ( Object.keys(object).length > 0 ){
if (embedded) { newline = true }
var content = ""
for (var key in object) {
content += spacer(depth + 1) + key.toString() + ": " + pp(object[key], depth+2, true) + ",\n"
}
content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
pretty += "{ " + content + "\n" + spacer(depth) + "}"
} else { pretty += "{}"}
}
else { pretty += object.toString() }
return ((newline ? "\n" + spacer(depth) : "") + pretty)
}
The output looks like this:
js> pp({foo:"bar", baz: 1})
{ foo: "bar",
baz: 1
}
js> var taco
js> pp({foo:"bar", baz: [1,"taco",{"blarg": "moo", "mine": "craft"}, null, taco, {}], bleep: {a:null, b:taco, c: []}})
{ foo: "bar",
baz:
[ 1,
"taco",
{ blarg: "moo",
mine: "craft"
},
null,
undefined,
{}
],
bleep:
{ a: null,
b: undefined,
c: []
}
}
I've also posted it as a Gist here for whatever future changes may be required.
jsDump
jsDump.parse([
window,
document,
{ a : 5, '1' : 'foo' },
/^[ab]+$/g,
new RegExp('x(.*?)z','ig'),
alert,
function fn( x, y, z ){
return x + y;
},
true,
undefined,
null,
new Date(),
document.body,
document.getElementById('links')
])
becomes
[
[Window],
[Document],
{
"1": "foo",
"a": 5
},
/^[ab]+$/g,
/x(.*?)z/gi,
function alert( a ){
[code]
},
function fn( a, b, c ){
[code]
},
true,
undefined,
null,
"Fri Feb 19 2010 00:49:45 GMT+0300 (MSK)",
<body id="body" class="node"></body>,
<div id="links">
]
QUnit (Unit-testing framework used by jQuery) using slightly patched version of jsDump.
JSON.stringify() is not best choice on some cases.
JSON.stringify({f:function(){}}) // "{}"
JSON.stringify(document.body) // TypeError: Converting circular structure to JSON
Taking PhiLho's lead (thanks very much :)), I ended up writing my own as I couldn't quite get his to do what I wanted. It's pretty rough and ready, but it does the job I need. Thank you all for the excellent suggestions.
It's not brilliant code, I know, but for what it's worth, here it is. Someone might find it useful:
// Usage: dump(object)
function dump(object, pad){
var indent = '\t'
if (!pad) pad = ''
var out = ''
if (object.constructor == Array){
out += '[\n'
for (var i=0; i<object.length; i++){
out += pad + indent + dump(object[i], pad + indent) + '\n'
}
out += pad + ']'
}else if (object.constructor == Object){
out += '{\n'
for (var i in object){
out += pad + indent + i + ': ' + dump(object[i], pad + indent) + '\n'
}
out += pad + '}'
}else{
out += object
}
return out
}
For anyone checking this question out in 2021 or post-2021
Check out this Other StackOverflow Answer by hassan
TLDR:
JSON.stringify(data,null,2)
here the third parameter is the tab/spaces
This is really just a comment on Jason Bunting's "Use Crockford's JSON.stringify", but I wasn't able to add a comment to that answer.
As noted in the comments, JSON.stringify doesn't play well with the Prototype (www.prototypejs.org) library. However, it is fairly easy to make them play well together by temporarily removing the Array.prototype.toJSON method that prototype adds, run Crockford's stringify(), then put it back like this:
var temp = Array.prototype.toJSON;
delete Array.prototype.toJSON;
$('result').value += JSON.stringify(profile_base, null, 2);
Array.prototype.toJSON = temp;
I thought J. Buntings response on using JSON.stringify was good as well. A an aside, you can use JSON.stringify via YUIs JSON object if you happen to be using YUI. In my case I needed to dump to HTML so it was easier to just tweak/cut/paste PhiLho response.
function dumpObject(obj, indent)
{
var CR = "<br />", SPC = " ", result = "";
if (indent == null) indent = "";
for (var property in obj)
{
var value = obj[property];
if (typeof value == 'string')
{
value = "'" + value + "'";
}
else if (typeof value == 'object')
{
if (value instanceof Array)
{
// Just let JS convert the Array to a string!
value = "[ " + value + " ]";
}
else
{
var od = dumpObject(value, indent + SPC);
value = CR + indent + "{" + CR + od + CR + indent + "}";
}
}
result += indent + "'" + property + "' : " + value + "," + CR;
}
return result;
}
Lots of people writing code in this thread, with many comments about various gotchas. I liked this solution because it seemed complete and was a single file with no dependencies.
browser
nodejs
It worked "out of the box" and has both node and browser versions (presumably just different wrappers but I didn't dig to confirm).
The library also supports pretty printing XML, SQL and CSS, but I haven't tried those features.
A simple one for printing the elements as strings:
var s = "";
var len = array.length;
var lenMinus1 = len - 1
for (var i = 0; i < len; i++) {
s += array[i];
if(i < lenMinus1) {
s += ", ";
}
}
alert(s);
My NeatJSON library has both Ruby and JavaScript versions. It is freely available under a (permissive) MIT License. You can view an online demo/converter at:
http://phrogz.net/JS/neatjson/neatjson.html
Some features (all optional):
Wrap to a specific width; if an object or array can fit on the line, it is kept on one line.
Align the colons for all keys in an object.
Sort the keys to an object alphabetically.
Format floating point numbers to a specific number of decimals.
When wrapping, use a 'short' version that puts the open/close brackets for arrays and objects on the same line as the first/last value.
Control the whitespace for arrays and objects in a granular manner (inside brackets, before/after colons and commas).
Works in the web browser and as a Node.js module.
flexjson includes a prettyPrint() function that might give you what you want.
I was asked to convert some VB6/VBScript code to javascript so after googling it and not finding anything I can use,I wrote a small javascript function to help me do the conversion; it's so crude and only converts (some of) the synatx, but it worked for me for the job I had...now I'm thinking of improving it but the method I used is so primitive (Regular Expression matching and replacing).
So...my question is:
What is the proper way to parse source code? is there any (not so complicated) way of doing it? and I don't want to use Exe's, it must be done entirely in Javascript. I'm not searching for ready-to-use source code (I don't think it exists!) but I want to learn how to be able to start with source code and turn it into objects (the opposite of serialization, I think?).
//here is the code:
var strs=[];
function vbsTojs(vbs){
var s = vbs;
s = HideStrings(s);
//only function block
s = s.match(/Function[\w\W]+End\s+Function/gim)[0];
//line-continuation char
s = s.replace(/_\n/gm,"");
//replace ":" with CRLF
s = s.replace(/:/gm,"\n");
//move inline comment to its own line
s = s.replace(/^(.+)'(.*)$/gim,"'$2\n$1");
//single line if -> multiple line
s = s.replace(/\bthen\b[ \t](.+)/gi,"then\n$1\nEnd If");
//alert(s);
var Vars='';
var Fx='';
var FxHead='';
var Args = '';
a=s.split('\n');
//trim
for(i=0;i<a.length;i++){
a[i]=a[i].replace(/^\s+|\s+$/,"");
}
//remove empty items
a=a.filter(function(val) { return val !== ""; });
//alert(a.join('\n'));
//function
a[0]=a[0].replace(/function\s+/i,"");
Fx = a[0].match(/^\w+/)[0];
a[0]=a[0].replace(Fx,"").replace(/[\(\)]/g,"");
a[0]=a[0].replace(/\bbyval\b/gi,"").replace(/\bbyref\b/gi,"").replace(/\boptional\b/gi,"");
a[0]=a[0].replace(/\bas\s+\w+\b/gi,"");
a[0]=a[0].replace(/\s+/g,"");
a[0]=a[0].replace(/,/gi,", ");
FxHead = "function " + Fx+ " ("+ a[0] + "){";
a[0]="";
//end function
a.length = a.length-1;
for(i=1;i<a.length;i++){
//Vars
if(a[i].search(/^dim\s+/i)>-1){
a[i]=a[i].replace(/dim\s*/i,"");
Vars += a[i] + ",";
a[i]='';
//FOR
}else if(a[i].search(/^\bFOR\b\s+/i)>-1){
a[i]=a[i].replace(/^\bFOR\b\s+/i,"");
counter = a[i].match(/^\w+/)[0];
from = a[i].match(/=\s*[\w\(\)]+/)[0];
from=from.replace(/=/,"").replace(/\s+/g,"");
a[i]=a[i].replace(counter,"").replace(from,"").replace(/\bTO\b/i,"");
to = a[i].match(/\s*[\w\(\)]+\s*/)[0];
to=to.replace(/=/,"").replace(/\s+/g,"");
a[i] = "for(" + counter + "=" + from + "; " + counter + "<=" + to + "; " + counter + "++){"
//NEXT
}else if(a[i].search(/^NEXT\b/i)>-1){
a[i] = "}";
//EXIT FOR
}else if(a[i].search(/\bEXIT\b\s*\bFOR\b/i)>-1){
a[i] = "break";
//IF
}else if(a[i].search(/^\bIF\b\s+/i)>-1){
a[i]=a[i].replace(/^\bIF\b\s+/i,"");
a[i]=a[i].replace(/\bTHEN$\b/i,"");
a[i]=a[i].replace(/=/g,"==").replace(/<>/g,"!="); //TODO: it should not replace if inside a string! <---------------
a[i]=a[i].replace(/\bOR\b/gi,"||").replace(/\bAND\b/gi,"&&"); //TODO: it should not replace if inside a string! <---------------
a[i] = "if(" + a[i] + "){";
//ELSE
}else if(a[i].search(/^ELSE/i)>-1){
a[i] = "}else{";
//END IF
}else if(a[i].search(/^END\s*IF/i)>-1){
a[i] = "}";
//WHILE
}else if(a[i].search(/^WHILE\s/i)>-1){
a[i] = a[i].replace(/^WHILE(.+)/i,"while($1){");
//WEND
}else if(a[i].search(/^WEND/i)>-1){
a[i] = "}";
//DO WHILE
}else if(a[i].search(/^DO\s+WHILE\s/i)>-1){
a[i] = a[i].replace(/^DO\s+WHILE(.+)/i,"while($1){");
//LOOP
}else if(a[i].search(/^LOOP$/i)>-1){
a[i] = "}";
//EXIT FUNCTION
}else if(a[i].search(/\bEXIT\b\s*\bFUNCTION\b/i)>-1){
a[i] = "return";
//SELECT CASE
}else if(a[i].search(/^SELECT\s+CASE(.+$)/i)>-1){
a[i]=a[i].replace(/^SELECT\s+CASE(.+$)/i,"switch($1){");
}else if(a[i].search(/^END\s+SELECT/i)>-1){
a[i] = "}";
}else if(a[i].search(/^CASE\s+ELSE/i)>-1){
a[i] = "default:";
}else if(a[i].search(/^CASE[\w\W]+$/i)>-1){
a[i] = a[i] + ":" ;
}
//CONST
else if(a[i].search(/^CONST/i)>-1){
a[i] = a[i].replace(/^CONST/i,"const");
}
else{
//alert(a[i]);
}
//COMMENT
if(a[i].search(/^\'/)>-1){
a[i]=a[i].replace(/^\'/,"//");
}else if(a[i].search(/\'.*$/)>-1){
a[i]=a[i].replace(/\'(.*)$/,"//$1");
}
}
//alert(a.join("*"));
Vars = Vars.replace(/\s*AS\s+\w+\s*/gi,"");
if(Vars!="") Vars = "var " + Vars.replace(/,$/,";").replace(/,/g,", ");
FxHead + '\n' + Vars;
a=a.filter(function(val) { return val !== ""; }) //remove empty items
for(i=0;i<a.length;i++){
if (a[i].search(/[^}{:]$/)>-1) a[i]+=";";
}
ss = FxHead + '\n' + Vars + '\n' + a.join('\n') + '\n}';
ss = ss.replace(new RegExp(Fx+"\\s*=\\s*","gi"),"return ");
ss = UnHideStrings(ss);
return jsIndenter(ss);
}
//-----------------------------------------------------
function jsIndenter(js){
var a=js.split('\n');
var margin=0;
var s = '';
//trim
for(i=0;i<a.length;i++){ a[i]=a[i].replace(/^\s+|\s+$/,""); }
//remove empty items
a=a.filter(function(val) { return val !== ""; });
for(var i=1;i<a.length;i++){
if(a[i-1].indexOf("{")>-1) margin += 4 ;
if(a[i].indexOf("}")>-1) { margin -= 4; }
if(margin<0) margin = 0;
a[i] = StrFill(margin," ") + a[i] ;
}
return a.join('\n');
}
function StrFill(Count,StrToFill){
var objStr,idx;
if(StrToFill=="" || Count==0){
return "";
}
objStr="";
for(idx=1;idx<=Count;idx++){
objStr += StrToFill;
}
return objStr;
}
function HideStrings(text){
const x = String.fromCharCode(7);
const xxx = String.fromCharCode(8);
text = text.replace(/"""/gim, '"'+xxx); //hide 3 quotes " " "
var idx=0, f=0;
while(f>-1){
f = text.search(/".+?"/gim);
if(f>-1){
strs.push(text.match(/".+?"/)[0]);
//alert(strs[idx]);
text = text.replace(/".+?"/, x+idx+x);
idx++;
}
}
//alert(text);
return text;
}
function UnHideStrings(text){
for(var i=0; i<strs.length; i++){
text = text.replace(new RegExp("\\x07"+i+"\\x07"), strs[i]);
}
//Unhide 3 quotes " " " ***BUG: causes unterminated string if triple-quotes are at the end of the string
text = text.replace(/\x08/gim,'\\"');
text = text.replace(/""/gi,'\\"');
return text;
}
The proper way to parse source code for any programming language is to use a parser. Regular expressions are a useful part of (some) parsers, but a parser is a different sort of thing. There is quite a body of research and techniques in the Computer Science literature on the subject of parsing, and it's a fascinating pursuit to study.
"Converting" a bunch of Visual Basic code to Javascript is a project that seems inherently fraught with peril and mystery. A Visual Basic parser will be just the first significant hurdle to conquer. After that, you'll need to figure out how to semantically represent the Visual Basic operations in Javascript. Depending on the original context of the code, that could be somewhat weird. (You don't mention anything about where this code all runs.)
As enriching a learning experience as this might be, it's not unlikely that translating the code by hand will (in the end) take less time and produce better results. That's particularly true if you're just now finding out that there is such a thing as a "parser".
Nice job. Sounds like you did something that might not be perfect, but it did the job.
I'd recommend looking into parsers and grammars if you want to make it more sophisticated. There are lots of parser generators that would be able to help you. You'd have to come up with a grammar for the source language, generate the lexer/parser, and then use that to generate an abstract syntax tree (AST). Once you have that, you can walk the AST and ask it to emit any code you want.
It's doable but, as Oded says, it's not trivial.