Printing an array to screen as formatted javascript

F

Fabian

I have a three tier nested array, used to define a map for a javascript
game, and can be edited within the web page. Is there a way I can
generate a visible copy of this array that I can then c&p into a file? I
think the best solution would be to write into a popup window (this
popup would be purely for map development use, so I don't feel worried
by popup blockers, as only myself would be seeing the popup). However, I
have no idea how to:

a) create the string in a form that a html parser can display as
ready-formatted javascript code

b) generate the popup

tia
 
L

Lee

Fabian said:
I have a three tier nested array, used to define a map for a javascript
game, and can be edited within the web page. Is there a way I can
generate a visible copy of this array that I can then c&p into a file? I
think the best solution would be to write into a popup window (this
popup would be purely for map development use, so I don't feel worried
by popup blockers, as only myself would be seeing the popup). However, I
have no idea how to:

a) create the string in a form that a html parser can display as
ready-formatted javascript code

b) generate the popup

This creates an array with fixed dimensions, but the show() function
works with whatever dimensions it finds. I believe <xmp> is deprecated,
but since this is just for development work, you probably don't care.

<html>
<head>
<script type="text/javascript">
// initialize 3D array with sequential integers
map=new Array();
count=0;
for(var i=0;i<5;i++){
map=new Array();
for(var j=0;j<5;j++){
map[j]=new Array;
for(k=0;k<5;map[j][k++]=++count);
}
}
function show(f){
f.info.value=map[f.indexi.value][f.indexj.value][f.indexk.value];
}
function update(f){
map[f.indexi.value][f.indexj.value][f.indexk.value]=f.info.value;
}
function display(){
globalOutput="<html><body><xmp>";
globalOutput+="map=new Array("+map.length+");\n";
for(var i=0;i<map.length;i++){
globalOutput+="map["+i+"]=new Array("+map.length+");\n";
for(var j=0;j<map.length;j++){
globalOutput+="map["+i+"]["+j+"]=new Array("+map[j].length+");\n";
for(var k=0;k<map[j].length;k++){
globalOutput+="map["+i+"]["+j+"]["+k+"]=\""+map[j][k]+"\";\n";
}
}
}
globalOutput+="</xmp></body></html>";
window.open("javascript:eek:pener.globalOutput","popup");
}
</script>
</head>
<body onload="show(document.forms[0])">
<form>
<input name="indexi" value="0" onchange="show(this.form)">
<input name="indexj" value="0" onchange="show(this.form)">
<input name="indexk" value="0" onchange="show(this.form)">
<input name="info" value="">
<input type="button" value="Update" onclick="update(this.form)">
<br>
<input type="button" value="Display" onclick="display()">
</form>
</body>
</html>
 
R

Richard Cornford

Fabian said:
I have a three tier nested array, ...
a) create the string in a form that a html parser can
display as ready-formatted javascript code

Wrapping the JavaScript source code in <PRE> tags is one obvious way of
presenting pre formatted source code text in HTML.

One way of simply getting nested arrays back to source code form might
be to provide the Array objects with custom toString methods that
overload Array.prototype.toString and return a source code string
representation of the array. That is not without its problems as there
are limitations on the degree to which you can mix the types of contents
in the array, especially mixing strings with other types. This example
demonstrates:-

<html>
<head>
<title></title>
<script type="text/javascript">
function getToStringForStringArray(tabDepth){
var st = ''
for(var c = tabDepth;c--;){
st += '\t';
}
return (function(){
return '[\n'+st+'\t\''+this.join(('\',\n'+st+'\t\''))+
'\'\n'+st+']';
});
}
function getToStringForNonStringArray(tabDepth){
var st = ''
for(var c = tabDepth;c--;){
st += '\t';
}
return (function(){
return '[\n\t'+st+this.join((',\n'+st+'\t'))+'\n'+st+']';
});
}
var a = [
[
[
1,
2,
3,
4,
5,
6
],
[
'a',
'b',
'c',
'd',
'e',
'f',
'g'
]
],
[
12,
13,
14,
15
],
[
'a',
'b',
'c',
'd',
'e',
'f',
'g'
],
[
true,
false,
true,
true
]
];
a.toString = getToStringForNonStringArray(1);
a[0].toString = getToStringForNonStringArray(2);
a[1].toString = getToStringForNonStringArray(2);
a[2].toString = getToStringForStringArray(2);
a[3].toString = getToStringForNonStringArray(2);
a[0][0].toString = getToStringForNonStringArray(3);
a[0][1].toString = getToStringForStringArray(3);
</script>
</head>
<body>
<pre>
<script type="text/javascript">
document.write('var a = '+a+';\n')
</script>
</pre>
</body>
</html>

If you don't need the tabulation the process becomes considerably
simpler.
b) generate the popup

Lee's method for getting the string into a new window is a good as any
(and better than most, though it does still fail on IceBrowser 5 [1], as
do all other methods of writing HTML strings into pop-ups on that
browsers).

Richard.

[1] IceBrowser's javascript: pseudo-protocol implementation is very odd
as, while it will execute side-effect function calls, it does not use
the return value of the expression used (if present) as replacement HTML
source for targeted window/frame. It looks like they designed the
behaviour around the (generally considered incorrect) common use of
javascript: URLs instead of the behaviour of existing implementations.
Still, I have never been able to find a specification of how javascript
URLs should be handled so it is difficult to say that any particular
implementation is wrong.
 
F

Fabian

Lee hu kiteb:
Fabian said:

This creates an array with fixed dimensions, but the show() function
works with whatever dimensions it finds. I believe <xmp> is
deprecated, but since this is just for development work, you probably
don't care.

For the benefit of anyoen else trying this, I have c+p the code below.
Richard suggested simply wrapping the source in PRE tags, but as this
array is being manipulated dynamically, that won't work for me.

I suspect that looking up the generated array after I c+p it into a new
map file will become prohibitively slow before this becomes an issue for
me, but is there a limit to the length of the string that can be
generated/manipulated in javascript?

function display() {
// read map dimensions from current map
// this could just as easily be looked up from form fields
var x = mpdef_n[0].length;
var y = mpdef_n.length;
var z = mpdef_n[0][0].length;

var t;
t = "<pre>";
t += "var mpdef_n = [\n";
for(i=0;i<y;i++) {
t += "\t[ ";
for(j=0;j<x;j++) {
t += "[";
for(k=0;k<z;k++) {
// comment this line if making a blank map
t += mpdef_n[j][k];
// uncomment this line if making a blank map
// t += "0";
if (k == z - 1) { t += "]"; }
else { t += ","; }
}
if (j == x - 1) { t += " ]"; }
else { t += ", "; }
}
if (i == y - 1) { t += "\n"; }
else { t += ",\n"; }
}
t += "];";
t += "</pre>";
// write the string to wherever
document.getElementById("op").innerHTML = t;
}
 
R

Richard Cornford

Richard suggested simply wrapping the source in PRE tags, but as
this array is being manipulated dynamically, that won't work for me.
<snip>

Strange thing to say when -
t = "<pre>";

- you have wrapped your JavaScript source code output in PRE tags
anyway. ;-)
t += "var mpdef_n = [\n";
for(i=0;i<y;i++) {

i is a global variable, it probably should not be.
t += "\t[ ";
for(j=0;j<x;j++) {

j is a global variable, it probably should not be.
t += "[";
for(k=0;k<z;k++) {
<snip>

k is a global variable, it probably should not be.
t += "</pre>";
<snip>

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top