I am having trouble deleting a document dictionary in InDesign CS 5.5.
I can clear the contents of a user dictionary using this script:
var myUserDictionaries = app.userDictionaries;
var myCountDict = myUserDictionaries.count();
for (var i = myCountDict-1; i >= 0; i-- ) {
myUserDictionary = myUserDictionaries[i];
var myAddedWords = myUserDictionary.addedWords;
myUserDictionary.removeWord(myAddedWords);
}
But this leaves the document dictionary untouched. A few years ago, this was an unresolved problem as seen on the Adobe forums.
But I found this code (from here):
var myHyphenations = app.activeDocument.hyphenationExceptions;
for (var i = 0; i < myHyphenations.length; i++) {
if (myHyphenations[i].name === "Danish") {
var mySourceDictionary = myHyphenations[i];
mySourceHyphenations = mySourceDictionary.addedExceptions;
break
}
}
Which seems to be able to access the document dictionary. But my question is (since I'm not much of a programmer), how to modify this code to clear or delete the document dictionary (for English:USA)?
Actually this turned out to be more simple than I anticipated.
Here's the script that will delete/clear a document dictionary:
var myHyphenations = app.activeDocument.hyphenationExceptions;
var myCountDict = myHyphenations.count();
for (var i = myCountDict-1; i >= 0; i-- ) {
myHyphenation = myHyphenations[i];
var myAddedWords = myHyphenation.addedExceptions;
myHyphenation.removeException(myAddedWords);
}
Related
I've searched high and wide for an answer but can't seem to find it. I am trying to alter my custom function that looks up sitemap URL's and the date they were updated to accept a range of inputs.
Here is the current function that works:
function sitemap(sitemapUrl, namespace) {
var array = [];
var xml = UrlFetchApp.fetch(sitemapUrl).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
var sitemapNameSpace = XmlService.getNamespace("http://www.sitemaps.org/schemas/sitemap/0.9");
var urls = root.getChildren('url', sitemapNameSpace);
for (var i = 0; i < urls.length; i++) {
var loc = urls[i].getChild('loc', sitemapNameSpace).getText();
var lastmod = urls[i].getChild('lastmod', sitemapNameSpace).getText();
array.push([loc, lastmod]);
}
return array;
}
I've tried using Google's example below but doesn't seem to work however I incorporate it into my function. Any ideas?
function DOUBLE(input) {
if (input.map) { // Test whether input is an array.
return input.map(DOUBLE); // Recurse over array if so.
} else {
return input * 2;
}
}
Edit: This is how I tried to use Google's example for my function:
function sitemaps(sitemapUrl) {
var array = [];
var xml = UrlFetchApp.fetch(sitemapUrl).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement()
var sitemapNameSpace = XmlService.getNamespace("http://www.sitemaps.org/schemas/sitemap/0.9")
var urls = root.getChildren('url', sitemapNameSpace)
for (var i = 0; i < urls.length; i++) {
var loc = urls[i].getChild('loc',sitemapNameSpace).getText();
var lastmod = urls[i].getChild('lastmod',sitemapNameSpace).getText();
array.push([loc, lastmod]);
}
if (sitemapUrl.map) {
return sitemapUrl.map(sitemaps);
} else {
return array
}
You are no using the same format as the Google example. As of right now you are checking if the input is an array after actually retrieving the data.
But you using fetch with an array as input could trigger an Error and the function may no get to the point where it checks if the sitemapUrl can be used with map.
Also take into account that map will call the function in every single element of the array and return an array with a result for each of element. So in your case B3:B6 would call the function for the value at B3, B4, B5 and B6 and return an array of length 4 with the result. For your case in which you want a single list you need to flattern the array afterwards
I would change your function to be like this:
function sitemaps(sitemapUrl) {
if (sitemapUrl.map) {
return sitemapUrl.map(sitemaps).flat();
} else {
var array = [];
var xml = UrlFetchApp.fetch(sitemapUrl).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement()
var sitemapNameSpace = XmlService.getNamespace("http://www.sitemaps.org/schemas/sitemap/0.9")
var urls = root.getChildren('url', sitemapNameSpace)
for (var i = 0; i < urls.length; i++) {
var loc = urls[i].getChild('loc', sitemapNameSpace).getText();
var lastmod = urls[i].getChild('lastmod', sitemapNameSpace).getText();
array.push([loc, lastmod]);
}
return array
}
}
Although what you are doing is fine take into account that it also exists a way to retrieve all the request at the same time (
UrlFetchApp.fetch()) but for this specific case you would need to flatten a reshape the input array.
function computerSetManapool(cost) {
var splittedCost = cost.split(',');
for (var i = 0; i < splittedCost.length; i++) {
if (splittedCost[i] === "CL") {
for (var j = 0; j < computerLands.length; j++) {
if (!computerLands[j].tapped) {
computerLands[j].tapped = true;
console.log(computerLands[j].name + " gets tapped");
break;
}
}
}
}
}
I'm having a bit of trouble with this little piece of code, it's a Windows Store App, though I'm not using anything like the WinJS library or jQuery or what not.
Especially this line worries me:
computerLands[j].tapped = true;
I was debugging this in Visual Studio, while j had the value of 1. Therefore computerLands[1].tapped was supposed to be set to true.
Instead it set computerLands[1].tapped = true AND computerLands[3].tapped = true.
It does not happen every time, but many times and therefore I can't see what the problem is.
computerLands is an initially empty array, which then gets dynamically pushed objects into it.
If someone even has a remote idea what problem this could be, I would be really grateful.
Edit: This is the code where computerLands gets populated:
function computerTurn() {
untapAll("computer");
drawCards(1, "computer");
for (var i = 0; i < computerHand.length; i++) {
if (computerHand[i].type === "land") {
var container = document.getElementById("computerLandsContainer");
var newItem = document.createElement("div");
newItem.id = computerLandsID;
computerLandsID++;
newItem.style.backgroundImage = "url("+computerHand[i].image+")";
newItem.style.backgroundSize = "100%";
var btn1 = document.createElement("button");
btn1.id = "tapButtonComputer";
btn1.innerText = "˜";
newItem.appendChild(createEnlargeButton(newItem,"computer"));
newItem.appendChild(btn1);
container.appendChild(newItem);
computerLands.push(computerHand[i]);
console.log("Computer plays: " + computerHand[i].name);
computerLands[computerLands.length - 1].id = newItem.id;
var index = computerHand.indexOf(computerHand[i]);
computerHand.splice(index,1);
break;
}
}
}
The actual line is just this:
computerLands.push(computerHand[i]);
After pushing it into computerLands it gets removed from computerHand via splice().
var index = computerHand.indexOf(computerHand[i]);
computerHand.splice(index,1);
Finally I found a solution, I got it from this page: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/f79b2e68-15a9-4d5e-8aad-e15f78d94840/how-do-i-clone-an-object?forum=winappswithhtml5
It describes how to deep copy in Javascript in Windows Store Apps (this other solution I found http://james.padolsey.com/javascript/deep-copying-of-objects-and-arrays/ is not allowed in Windows Store Apps strict mode), basically you create a new object and copy every property into it. Now here's my new working code:
function populateComputerLands() {
for (var i = 0; i < 4; i++) {
//computerLands.push(availableComputerCards[0]); <--- old code
var objectToCopy = availableComputerCards[0]; // new code
var newObject = Object.create(Object.getPrototypeOf(objectToCopy));
var newObjectProperties = Object.getOwnPropertyNames(objectToCopy);
var propertyName;
for (var p in newObjectProperties) {
propertyName = newObjectProperties[p];
Object.defineProperty(newObject, propertyName, Object.getOwnPropertyDescriptor(objectToCopy, propertyName));
};
computerLands.push(newObject);
}
}
I have written a function that automatically inserts an attribute (i.e. a per case adapted onclick function) in input elements. It also makes a few exceptions. It looks like this, somewhat simplified for clarity reasons:
function insertAttribute() {
var allInputs = document.getElementsByTagName('input');
var allInputsCount = allInputs.length;
var thatInput = null;
for (i = 0; i < allInputsCount; i++) {
thatInput = allInputs[i];
var highlightFunction = "highlightItem('"+thatInput.name+"-row','"+thatInput.name+"-button')";
if ((thatInput.name != "A") && (thatInput.name != "B") && (thatInput.name != "C"))
thatInput.setAttribute("onclick",highlightFunction);
}
}
The problem is, there are some 20 exceptions. I could expand the if line, but I would rather do it with an array. But how do I do that? I googled how to use array in javascript function, and the (two top) results suggest I should do it like this:
function insertAttribute() {
var allInputs = document.getElementsByTagName('input');
var allInputsCount = allInputs.length;
var thatInput = null;
for (i = 0; i < allInputsCount; i++) {
thatInput = allInputs[i];
var highlightFunction = "highlightItem('"+thatInput.name+"-row','"+thatInput.name+"-button')";
var exceptedArray = ["A","B","C"];
if (thatInput.name != exceptedArray)
thatInput.setAttribute("onclick",highlightFunction);
}
}
But that doesn't work -- the attribute is still inserted in the exceptions. How should it be done? I would need a vanilla script solution. I'll be happy with a good tutorial, too. As you might have guessed, this is the first time I'm using such an array sub-function.
The solution offered in the comment, exceptedArray.indexOf(thatInput.name)==-1 worked in most browsers, but not in IE8. Its script debugger said that it did not support indexOf. It does in other contexts, but apparently not in this context.
In the meantime, I learned how to make a script loop through an array myself. And this works in all browsers:
var allInputs = document.getElementsByTagName('input');
var allInputsCount = allInputs.length;
var thatInput = null;
for (var i=0; i<allInputsCount; i++) {
thatInput = allInputs[i];
var highlightFunction = "highlightItem('"+thatInput.name+"-row','"+thatInput.name+"-button')";
var exceptedNamesArray = ["A","B","C","A4dTInput","A4eTInput"];
var excNamesArrayCount = exceptedNamesArray.length;
var excName = null;
for (var j=0; j<excNamesArrayCount; j++) {
excName = exceptedNamesArray[j];
if (thatInput.name != excName)
thatInput.setAttribute("onclick",highlightFunction);
}
}
How could I populate a second select element? I've figured out how to do the first one. But how could I do the same for the second depending on which "Make" is selected? I've tried to talk myself through it while taking small steps but I'm thinking this may be too advanced for me.
var cars = '{"USED":[{"name":"Acura","value":"20001","models":[{"name":"CL","value":"20773"},{"name":"ILX","value":"47843"},{"name":"ILX Hybrid","value":"48964"},{"name":"Integra","value":"21266"},{"name":"Legend","value":"21380"},{"name":"MDX","value":"21422"},{"name":"NSX","value":"21685"},{"name":"RDX","value":"21831"},{"name":"RL","value":"21782"},{"name":"RSX","value":"21784"},{"name":"SLX","value":"21879"},{"name":"TL","value":"22237"},{"name":"TSX","value":"22248"},{"name":"Vigor","value":"22362"},{"name":"ZDX","value":"32888"}]},{"name":"Alfa Romeo","value":"20047","models":[{"name":"164","value":"20325"},{"name":"8c Competizione","value":"34963"},{"name":"Spider","value":"22172"}]}';
var carobj = eval ("(" + cars + ")");
var select = document.getElementsByTagName('select')[0];
//print array elements out
for (var i = 0; i < carobj.USED.length; i++) {
var d = carobj.USED[i];
select.options.add(new Option(d.name, i))
};
If I read your question right, you want to populate a second select with the models for the make in the first select. See below for a purely JS approach (with jsfiddle). If possible, I would recommend looking into jQuery, since I would prefer a jQuery solution.
http://jsfiddle.net/m5U8r/1/
var carobj;
window.onload = function () {
var cars = '{"USED":[{"name":"Acura","value":"20001","models":[{"name":"CL","value":"20773"},{"name":"ILX","value":"47843"},{"name":"ILX Hybrid","value":"48964"},{"name":"Integra","value":"21266"},{"name":"Legend","value":"21380"},{"name":"MDX","value":"21422"},{"name":"NSX","value":"21685"},{"name":"RDX","value":"21831"},{"name":"RL","value":"21782"},{"name":"RSX","value":"21784"},{"name":"SLX","value":"21879"},{"name":"TL","value":"22237"},{"name":"TSX","value":"22248"},{"name":"Vigor","value":"22362"},{"name":"ZDX","value":"32888"}]},{"name":"Alfa Romeo","value":"20047","models":[{"name":"164","value":"20325"},{"name":"8c Competizione","value":"34963"}, {"name":"Spider","value":"22172"}]}]}';
carobj = eval ("(" + cars + ")");
var makes = document.getElementById('make');
for (var i = 0; i < carobj.USED.length; i++) {
var d = carobj.USED[i];
makes.options.add(new Option(d.name, i));
}
makes.onchange = getModels;
getModels();
}
// add models based on make
function getModels () {
var makes = document.getElementById('make');
var make = makes.options[makes.selectedIndex].text;
for (var i = 0; i < carobj.USED.length; i++) {
if (carobj.USED[i].name == make) {
var models = document.getElementById('model');
models.options.length = 0;
for (var j= 0; j < carobj.USED[i].models.length; j++) {
var model = carobj.USED[i].models[j];
models.options.add(new Option(model.name, j));
}
break;
}
}
}
I would also recommend looking into safer JSON parsing. There is a security risk in using eval if it runs on any user input. You could look into JSON.org and their json2.js. Or if you want to use jQuery: parseJSON. Below is the jQuery version:
jQuery.parseJSON(jsonString);
JSON parsing tips from: Safely turning a JSON string into an object.
I have been searching online all day and I cant seem to find my answer. (and I know that there must be a way to do this in javascript).
Basically, I want to be able to search through an array of objects and return the object that has the information I need.
Example:
Each time someone connects to a server:
var new_client = new client_connection_info(client_connect.id, client_connect.remoteAddress, 1);
function client_connection_info ( socket_id, ip_address, client_status) {
this.socket_id=socket_id;
this.ip_address=ip_address;
this.client_status=client_status; // 0 = offline 1 = online
};
Now, I want to be able to search for "client_connection.id" or "ip_address", and bring up that object and be able to use it. Example:
var results = SomeFunction(ip_address, object_to_search);
print_to_screen(results.socket_id);
I am new to javascript, and this would help me dearly!
Sounds like you simply want a selector method, assuming I understood your problem correctly:
function where(array, predicate)
{
var matches = [];
for(var j = 0; j < array.length; j++)
if(predicate(j))
matches.push(j);
return matches;
}
Then you could simply call it like so:
var sample = [];
for(var j = 0; j < 10; j++)
sample.push(j);
var evenNumbers = where(sample, function(elem)
{
return elem % 2 == 0;
});
If you wanted to find a specific item:
var specificguy = 6;
var sixNumber = where(sample, function(elem)
{
return elem == specificguy;
});
What have you tried? Have you looked into converting the data from JSON and looking it up as you would in a dictionary? (in case you don't know, that would look like object['ip_address'])
jQuery has a function for this jQuery.parseJSON(object).
You're going to need to loop through your array, and stop when you find the object you want.
var arr = [new_client, new_client2, new_client3]; // array of objects
var found; // variable to store the found object
var search = '127.0.0.1'; // what we are looking for
for(var i = 0, len = arr.length; i < len; i++){ // loop through array
var x = arr[i]; // get current object
if(x.ip_address === search){ // does this object contain what we want?
found = x; // store the object
break; // stop looping, we've found it
}
}