Different ways of counting characters in Indesign using javascript - javascript

I'm writing a javascript program to handle each character intŠ¾ Indesign document.
To begin with, I wrote two different ways of counting characters, which for some reason give different results for large documents. Why?
var
myDocument, docStories, docCharacters,
docFootnotesCharacters, docTablesCharacters;
myDocument = app.activeDocument;
var TotalChars = 0;
// Fisrt way
docStories = myDocument.stories.everyItem();
docCharacters = docStories.characters.length;
docFootnotesCharacters = docStories.footnotes.everyItem().characters.length;
docTablesCharacters = docStories.tables.everyItem().cells.everyItem().characters.length;
statReport = [];
// Second way
for ( j = 0; j < myDocument.stories.length; j++ ) {
myStory = myDocument.stories.item(j);
var Frames = myStory.textContainers;
for ( i = 0; i < Frames.length; i++ ) {
var Frame = Frames[i];
for (var TextCnt = 0; TextCnt < Frame.texts.length; TextCnt++) {
CurrentText = Frame.texts.item(TextCnt);
TotalChars += CurrentText.characters.length;
}
for (var TableCnt = 0; TableCnt < Frame.tables.length; TableCnt++) {
var CurrentTable = Frame.tables.item(0);
for ( var CellCnt = 0; CellCnt < CurrentTable.cells.length; CellCnt++ ) {
var CurrentCell = CurrentTable.cells.item(CellCnt);
TotalChars += CurrentCell.characters.length;
}
}
for (var FootNoteCnt = 0; FootNoteCnt < Frame.footnotes.length; FootNoteCnt++) {
var CurrentFootNote = Frame.footnotes.item(0);
TotalChars += CurrentFootNote.characters.length;
}
}
}
statReport.push ( "Characters: " + ( docCharacters + docFootnotesCharacters + docTablesCharacters ) );
statReport.push ( "TotalChars: " + TotalChars );
alert ( statReport.join ( "\r" ), "Document Text Statistic" );

In the second method, you're counting all the characters inside text frames in the story. But stories can be overset (the text overflows). The first method will count overset text (because you're counting the characters in a story, but the second method will ignore those, because it's only counting characters in story frames.

Related

Illustrator scripting for text baseline (javascript)

I'm trying to make a script for illustrator but my code seems to not be working and doing nothing on me.
It's supposed to make the "(" and ")" characters baselines to be 3px.
Looking for someone who can make this work.
function test(){
var doc = app.activeDocument;
var t = doc.textFrames[0], thisChar, thisSize, thisBaseline;
for(var i=0; i<t.characters.length; i++){
thisChar = t.characters;
if(thisChar.contents == "(" || thisChar.contents == ")"){
thisSize = thisChar.characterAttributes.size;
thisBaseline = thisChar.characterAttributes.baselineShift;
thisChar.characterAttributes.baselineShift = 3;
}
};
};
test();
var frames = app.activeDocument.selection;
for (var j=0; j<frames.length; j++) {
if (frames[j].typename == "TextFrame") {
for (var i=0; i<frames[j].characters.length; i++) {
var ch = frames[j].characters[i];
if( ch.contents == "(" || ch.contents == ")" ) ch.baselineShift = 3;
}
}
}
It shifts baseline for all brackets within all selected objects.
Note: this simple implementation doesn't handle grouped objects.
var frames = app.activeDocument.textFrames;
for (var j=0; j<frames.length; j++) {
for (var i=0; i<frames[j].characters.length; i++) {
var ch = frames[j].characters[i];
if( ch.contents == "(" || ch.contents == ")" ) ch.baselineShift = 3;
}
}
This variant of the script does the work within all text frames (grouped or not). You don't have to select anything.

how to replace same words in javascript multiple times?

Our developer used this phone number 1-866-579-469 all over the website but the correct phone number is 1-866-579-4269. I have written a javascript function to replace all occurrences:
var nodes,currentElement,oldtext,newtext,replaced,count;
function replaceAll(nodes,oldtext,newtext,replaced) {
count = 0
for (var i = 0; i < nodes.length; i++) {
currentElement = nodes[i].innerHTML;
replaced = currentElement.replace(oldtext,newtext);
count++;
}
console.log("Edited: "+ count + " items");
}
oldtext = "1-866-579-469";
newtext = "1-866-579-4269";
nodes = document.getElementsByTagName('*');
replaceAll(nodes,oldtext,newtext,replaced);
Your code works but you missed to update the replaced string. This should work:
var nodes,currentElement,oldtext,newtext,replaced,count;
function replaceAll(nodes,oldtext,newtext,replaced) {
count = 0
for (var i = 0; i < nodes.length; i++) {
currentElement = nodes[i].innerHTML;
replaced = currentElement.replace(oldtext,newtext);
nodes[i].innerHTML = replaced;
count++;
}
console.log("Edited: "+ count + " items");
}
oldtext = "1-866-579-469";
newtext = "1-866-579-4269";
nodes = document.getElementsByTagName('*');
replaceAll(nodes,oldtext,newtext,replaced);
Codepen Here

Replacing array elements using regex and replace() in javascript

I'm bit new to JavaScript, I'm trying to replacing the array element using regex that matches the string, here is a code which I tried
<button onclick="myFunction()">ClickHere</button>
<p id="demo"></p>
<script>
function myFunction() {
var abc = ["deno", "eno","pqr","lenovo"];
var i,text;
for(i = 0; i < abc.length; i++) {
text += abc[i].replace(/no/i, "po");
document.getElementById("demo").innerHTML = text;
}
}
</script>
I want to replace array element with "po" wherever it encounters "no" in the array element string.
This is what I expect:
abc["depo","epo","pqr","lepovo"]
You can do this for every element:
for(var i=0; i < abc.length; i++) {
abc[i] = abc[i].replace('no', 'po');
}
or using one line
abc = abc.map(function(x){return x.replace('no', 'po');});
or using one line with "arrow functions":
abc = abc.map(x => x.replace('no', 'po'));
After you changed the array, you can convert it to a string using:
var text = 'abc[';
for ( var i = 0 ; i < abc.length ; i++ ) {
text+='\"'+abc[i]+'\"';
if ( i != abc.length - 1) {
text+=',';
}
}
text += ']';
Test:
function myFunction() {
var abc = ["deno", "eno","pqr","lenovo"];
abc = abc.map(x => x.replace('no', 'po')); // see other 2 alternatives above
var text = 'abc[';
for ( var i = 0 ; i < abc.length ; i++ ) {
text+='\"'+abc[i]+'\"';
if ( i != abc.length - 1) {
text+=',';
}
}
text += ']';
document.getElementById("demo").innerHTML = text;
}
<button onclick="myFunction()">ClickHere</button>
<p id="demo"></p>
var i, text;
for(i = 0; i < abc.length, i++) {
text += abc[i].replace("no", "po");
}
console.log(text);
There are three changes required in your code:
Initialiize text with empty string.Because it is undefined by default.
Change abc[i].length to abc.length.
Replace comma with a semicolon after abc[i].length in for loop.
var abc = ["deno", "eno","pqr","lenovo"];
var i;
var text = "";
for(i = 0; i < abc.length; i++) {
text += abc[i].replace("no", "po");
}

Javascript - String split does not work well

I am making a script which receives a String and separate it on smaller Strings.
Ex: "This is a long sentence, and I will separate it into smaller parts. Lalala"
It will return "This is a long sentence","and I will separate it into smaller parts","Lalala"
The aim of this is to use Google translator to transform text to speech, but this feature has a limit of about 70-80 chars, so if the string is too large I need to chop it.
First I chop in sentences separated by a dot ("."), then if there are still too long sentences, I split them with the commas (",") and if there are still too long strings I separate them in unique words.
Everything works well until I try to join some words so the audio become more continuous. For some reason the strings separated by commas get joined again. I do not know why.
This is the code:
Edit: Relevant section split out and formatted
function talk(text){
var audios = document.createElement('audio');
audios.setAttribute('id','audio_speech');
var playlist = new Array()
if(text.length >= 75) {
playlist = text.split(".");
for (var i = 0;i<playlist.length;i++) {
if (playlist[i].length >= 75) {
auxarr = playlist[i].split(",");
//alert(auxarr.length);
for(var j=0;j<auxarr.length;j++) {
auxarr2 = auxarr[j].split(" ");
document.write(auxarr2+"<br>");
if (auxarr[j].length >= 75) {
auxarr2 = auxarr[j].split(" ");
for(var x=0; x < auxarr2.length; x++){
if(auxarr2[x].length < 50) {
aux = auxarr2[x];
while (aux.length < 50 && auxarr2[x+1]) {
aux = aux + " " + auxarr2[x+1];
auxarr2.splice(x,1);
auxarr2[x]=aux;
}
}
//...
Edit: Full original code
function talk(text)
{
var audios = document.createElement('audio');
audios.setAttribute('id','audio_speech');
var playlist = new Array()
if(text.length >= 75) {
playlist = text.split(".");
for (var i = 0;i<playlist.length;i++) {
if (playlist[i].length >= 75) {
auxarr = playlist[i].split(",");
//alert(auxarr.length);
for(var j=0;j<auxarr.length;j++) {
auxarr2 = auxarr[j].split(" ");
document.write(auxarr2+"<br>");
if (auxarr[j].length >= 75) {
auxarr2 = auxarr[j].split(" ");
for(var x=0; x < auxarr2.length; x++){
if(auxarr2[x].length < 50) {
aux = auxarr2[x];
while (aux.length < 50 && auxarr2[x+1]) {
aux = aux + " " + auxarr2[x+1];
auxarr2.splice(x,1);
}
auxarr2[x]=aux;
}
}
auxarr_end = auxarr.slice(j+1,auxarr.length);
auxarr_begin = auxarr.slice(0,j);
document.write("<br>"+auxarr+"<br> aca");
document.write("<br>"+auxarr_end+"<br> aca1");
document.write("<br>"+auxarr_begin+"<br> aca2");
auxarr.splice(j,1);
auxarr_begin = auxarr_begin.concat(auxarr2);
j = auxarr.length;
auxarr = auxarr_begin.concat(auxarr_end);
alert(auxarr);
}
}
//alert("current: "+playlist[i]);
//alert("current length:"+playlist[i].length);
//alert("auxarr: "+auxarr);
playlist_end = playlist.slice(i+1,playlist.length);
playlist_begin = playlist.slice(0, i);
playlist.splice(i,1);
playlist_begin = playlist_begin.concat(auxarr);
i = playlist.length;
playlist = playlist_begin.concat(playlist_end);
//alert("new "+playlist[i]);
}
}
/*do {
textAux = text.substring(0, 74);
text = text.substring(textAux.length, text.length);
playlist.push(textAux);
}while(text.length >= 75);*/
} else {
playlist.push(text);
}
//
//playlist.push(text);
/*for(var a=0; a<playlist.length;a++){
document.write(playlist[a]+"<br>");}*/
audios.setAttribute('src', 'http://translate.google.com/translate_tts?tl=es&q=' + encodeURIComponent(playlist[0]));
playlist.splice(0,1);
audios.load();
audios.play();
/*
*/
audios.addEventListener('ended', function(){
if (playlist[0]){
audios.setAttribute('src', 'http://translate.google.com/translate_tts?tl=es&q=' + encodeURIComponent(playlist[0]));
playlist.splice(0,1);
audios.play();
}
}, false);
}
</script>
Try this, modify it to work with your constants and parameters.
var LIMIT = 20;
var res = new Array()
//strats with spliting by dot
var dotArr = "This is a long sentence. and I will separate it into smaller parts. Lalala".split(/[.]/);
for (var i = 0; i < dotArr.length; i++) {
if (dotArr[i].length > LIMIT){
//only when have to, split by comma
var comArr = dotArr[i].split(/[,]/);
for (var j = 0; j < comArr.length; j++) {
//only when have to and that a space exists, split by space
if (comArr[j].length > LIMIT && comArr[j].indexOf(" ") != -1 ){
var spaceArr = comArr[j].split(/[ ]/);
//accomulate words until we reach the limit and then push the value to res
for (var k = 0; k < spaceArr.length;){
var sMerge = spaceArr[k++];
while (k < spaceArr.length && sMerge.length + spaceArr[k].length + 1 < LIMIT){
sMerge = sMerge + " " + spaceArr[k];
k++;
}
res.push(sMerge)
}
}else{
res.push(comArr[j]);
}
}
}else{
res.push(dotArr[i]);
}
}
//res contain all optimized sentences.

Print PDF from javascript

I am using the below mentioned code in my VB.net application to print two copies of pdf document.
js.Append("var pp = this.getPrintParams();")
js.Append("var iCopies = 2;")
js.Append("var iPages = this.numPages;")
js.Append("pp.NumCopies = iCopies;")
js.Append("pp.interactive = pp.constants.interactionLevel.silent;")
js.Append("for ( var i = 0; i < iPages; i++ ) { pp.firstPage = i; pp.lastPage = i;")
js.Append("this.print(pp);")
js.Append("}")
It is working great. But how can I make the last page print only 1 copy instead of two copies.
Your help greatly appreciated.
js.Append("for ( var i = 0; i < iPages; i++ ) { pp.firstPage = i; pp.lastPage = i;")
js.Append("if(i == (iPages - 1)) pp.NumCopies = 1; ") ' This line does it
js.Append("this.print(pp);")
js.Append("}")

Categories