Extendscript load content from var - javascript

In Javascript or PHP this is fairly easy but doesn't seem to work for extendscript.
I have a search function that stores it's results in a var. I want to see what is in the var after the function runs. So usually I use a alert() but InDesign comes up with a box containing [object Word].
Here is what I do:
var myFound = myDoc.findGrep();
alert(myFound);
InDesign throws me this box:
If I do the following:
alert(myFound.length);
Any ideas how to "reveal" my content?

If someone wants to know how to fix it:
Create an array around the for loop and gather the information in it.
After that alert the array like this:
var myFound = myDoc.findGrep();
var result = new Array();
for(i=0; i<myFound.length; i++)
{
result[result.length] = myFound[i].contents;
}
alert(result);

The result of a grep search is an array. You need loop through it and access the word.contents

In this case, I entirely use $.writeln() instead of alert().
or use
milligramme/scriptui_scrollable_alert

I have found this site (http://jongware.mit.edu/idcs6js) immensely useful in understanding ExtendScripts InDesign objects. In particular, your Words object is here, which is an array of Word instances.
In addition, I've used Use Visual Studio Code with the ExtendScript Debugger which helpful for watching variables.

Related

Replace text using an array of placeholder : replacement pairs in JavaScript

This is a simple problem (I am new to JavaScript and have a limited knowledge of the syntax and using arrays etc.), so I am sure someone more knowledgeable will be able to advise the simplest solution fairly easily!
I would like to replace a number of text placeholders in an existing Google Doc template with variable text inputs, which I ultimately plan to populate from one or more external sources via APIs (such as a form).
function replaceAllPlaceholders() {
var body = DocumentApp.getActiveDocument().getBody(); //defines the range within which to replace text
body.replaceText('placeholder1', 'replacement1');
body.replaceText('placeholder2', 'replacement2');
body.replaceText('placeholder3', 'replacement3');
// ...
body.replaceText('placeholder98', 'replacement98');
body.replaceText('placeholder99', 'replacement99'); }
Rather than repeat the replaceText( function for each replacement as I have done above, how can I instead layout the information out as an array of placeholder:replacement pairs, and then loop through each?
// for example something like this (pseudo):
//
// var obj = {
// 'placeholder1': 'replacement1' // I would like to keep open the option to retrieve this array from an external source instead
// 'placeholder2': 'replacement2'
// 'placeholder3': 'replacement3' };
//
// body.replaceText(*all placeholders*,*all replacements*);
I imagine this would allow greater flexibility in editing the set of placeholders and or replacements going forward, either directly within Google Apps Script or by replacing the whole array to one retrieved from an external source (as well as reducing the code required). The problem is I have not been able to figure out the correct method to do this. Any suggestions?
Alternatively, is there a better way to achieve my goal?
I am open to all recommendations!
Try this
var placeholders = [
['placeholder1', 'replacement1'],
['placeholder2', 'replacement2'],
['placeholder3', 'replacement3']
];
placeholders.forEach(function(pair) {
body.replaceText(pair[0], pair[1]);
});

How to set number of copies getPrintParams()

I am trying to add some JS to my pdf creation process to save some time. My goal is to basically click a button generate a PDF and have it print.
Right now I have:
var pp = this.getPrintParams();
pp.interactive = pp.constants.interactionLevel.full;
this.print(pp);
The only problem is that I don't know how to set the number of copies to print. I want pass a variable and print that many copies. The problem is that I can't really find any documentation discusses the methods in this class.
I know, this question is old. But I was looking for a solution, too. And I found here, that it should work with the following:
//no of copies
var n = 3;
var pp = this.getPrintParams();
//here is the magic
pp.NumCopies=eval(n);
this.print(pp);
For me, this is working with tcpdf and Adobe Reader.
Try this
var n = 3;
var pp = this.getPrintParams();
pp.NumCopies=eval(n);
this.print({bUI: false,bSilent: true,bShrinkToFit: true,printParams:pp});
Not possible, which is a good thing; since otherwise some websites would specify a high number and people who don't expect this would accidentally print lots of pages instead of just a single one.
You should call print method twice or more times, like the following:
this.print({bUI: false,bSilent: true,bShrinkToFit: true});
this.print({bUI: false,bSilent: true,bShrinkToFit: true});
I think it's not possible to set the number of copies.
See also:
Adobe's Print Production documentation

creating an object from JSON

I've seen a lot of different answers to this question and have tried applying their code to my project but none of these solutions seem to work for the data I have.
I need to turn this output into several objects:
[{"creature":{"id":1,"name":"R.I.P.","sprite_location":null,"health_points":0,"attack":0,"defense":0,"action_points":0,"attack_cost":0}},{"creature":{"id":2,"name":"R.I.P.","sprite_location":"http://chunkofwhat.com/games/Parousia/sprites/rip.gif","health_points":0,"attack":0,"defense":0,"action_points":0,"attack_cost":0}},{"creature":{"id":3,"name":"Bull.","sprite_location":"http://chunkofwhat.com/games/Parousia/sprites/bull.gif","health_points":50,"attack":8,"defense":20,"action_points":9,"attack_cost":5}},{"creature":{"id":4,"name":"Swallow.","sprite_location":"http://chunkofwhat.com/games/Parousia/sprites/swallow.gif","health_points":30,"attack":12,"defense":10,"action_points":13,"attack_cost":5}},{"creature":{"id":5,"name":"Kappa.","sprite_location":"http://chunkofwhat.com/games/Parousia/sprites/kappa.gif","health_points":40,"attack":6,"defense":15,"action_points":9,"attack_cost":3}},{"creature":{"id":6,"name":null,"sprite_location":null,"health_points":null,"attack":null,"defense":null,"action_points":null,"attack_cost":null}}]
When I try jQuery.parseJSON(), it just gives me a bunch of [object Object]s but I can't refer to creature[1].id etc.
Again, I know this is a frequently asked question. I really have been through many other examples but they just didn't work out for me.
Thank you.
Each object has one property (creature) with another object as it's value.
result_of_parsing_json[1].creature.id
var creatures = JSON.parse('big_json_string');
for (var i = 0; i < creatures.length; i++) {
var creature = creatures[i].creature; // this is how your object is formatted
console.log(creature.name);
}
/*
R.I.P.
R.I.P.
Bull.
Swallow.
Kappa.
null
*/
Each creature is nested within another object, and since it's an array of objects (that contain the creature), you have to iterate over it with a for loop, to make use of it.
Your parsing of the JSON, then, was most likely correct, but the logic that came afterwards was not (at a total guess).
Your code seems perfectly valid. Try this jsfiddle.
var creatures = $.parseJSON(yourJSONString);
alert(creatures[0].creature.name);​ // alerts "R.I.P"
Do you need any specific clarifications?

How do I extract a JavaScript function from the following page?

I'm trying to follow this tutorial
http://eloquentjavascript.net/chapter8.html
It mentions a function inPlacePrinter. I cannot find the source code for this in the actual text. I have tried poking around in view source since the interactive version seems to work but cannot locate the raw code. How do I find it?
It is defined in http://eloquentjavascript.net/js/chapter/oo.js.
In oo.js there is this line:
var div = __ENV.parent.DIV();
__ENV is not defined elsewhere, nor in any of the other js files, maybe is part of the MochiKit framework used on page.
You can replace inPlacePrinter() with this 2 functions in order to show the output in browser console:
function show(x){
var show = "";
for (var y = 0; y < arguments.length; y++) {
show += arguments[y];
}
console.log(show);
}
function showTerrarium(terrarium){
this.show(terrarium);
return function() {
console.clear();
this.showTerrarium(terrarium);
}
}
And used them in this way
/*replace:*/ terrarium.onStep = partial(inPlacePrinter(), terrarium);
/*with:*/ terrarium.onStep = partial(showTerrarium(terrarium), terrarium);
Maybe there is a better solution, but this worked.
thats a big tutorial. About half way down the page is this statement:
But all these extra variables can get messy. Another good solution is to use a function similar to partial from chapter 6. Instead of adding arguments to a function, this one adds a this object, using the first argument to the function's apply method:
Is the function inPlacePrinter in the object called partial in chapter 6?
Try using something like Firebug to look at the JavaScript files.

'Best' way to pull data relative to a div?

This answer suggested i should put my data in JS instead of a textarea.
Thinking about it i could have scripts and do something like myarray[i]="data" where i is the index of my for loop. However when i click a div how do i find out what i is? I have used var data = $(this).parent('.parent').find('.valuestr').eq(0).val(); which is extremely simple. Should i use a script or should i continue to do it with a textarea? if i should use a script 1) Whats the easiest way to find i and 2) Is it bad pratice to have dozens or hundreds of <script> in my html? or i can go through the loop twice but i still dont know the easiest way to find i. I would have to store it somewhere or go through multiple tags and count them.
Answering the other part of your question:
2) Is it bad pratice to have dozens or
hundreds of in my html?
It will depend on who you talk to, but in general, yes, I think it is. There's actually a push for html to be completely devoid of Javascript, save loading of .js files. For more info, look into unobtrusive javascript.
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript
jQuery has a data() function just for that.
You store arbitrary data related to some element like this:
$('#my_div').data('foo', 'bar');
$('#my_div').data('hello', 'world');
Then you retrieve it like this:
alert($('#my_div').data('foo')); // alerts "bar".
alert($('#my_div').data('hello')); // alerts "world".
Since each DOM_Element is just an object, you can declare a variable in the object.
for(var i = 0; i < elements.length; i++)
{
elements[i].i = i;
elements[i].onclick = function(){
alert(this.i);
}
}

Categories