Copy link to clipboard
Copied
Hi. I'm trying to create a JavaScript that will speed up the process of finding stacks (the same final character occuring in a sequence of lines of type) in InDesign stories. I know there are some scripts that already do this, but all the ones I've seen rely on character styles, which have the potential to overwrite the extensive character styles that my books already use.
Programmatically, I'm trying to return the last character of the line of type where my cursor is and then return the last character of the subsequent line. I can get the character from the first line, but I can't figure out how to get the last charactr of the subsequent line. I'm sure I'm just not understanding the logic of InDesign's DOM, but after literally days of trying to figure this out, I thought I'd better ask for help.
Here's a stripped down version of the code that assigns the last letters of each line to a variable:
Hi @LinusCMH
Technically it's often tricky to expand an InsertionPoint to outer range. Better is to use a higher Text container, or simply the Story itself. From there you will easily grab lines, paragraphs, etc.
const END_SIZE = 2;
var ip = app.selection[0];
var hereLine = ip.lines[0];
var nextLine = ip.parentStory.lines.nextItem(hereLine);
var hereEnd = hereLine.contents.slice(-END_SIZE); // End of 1st line
var nextEnd = nextLine.contents.slice(-END_SIZE); // End of next line
alert( [he
...
Anyway, here is a quick draft to illustrate the idea:
const END_SIZE = 2; // >= 1
function findStacks(/*Story*/sto, n,LS,a,i,s,t,r)
//----------------------------------
{
if( !(n=(LS=sto.lines).length) ) return [];
a = LS.everyItem().contents; // array of lines as JS strings.
for
(
r=[], s=a[i=0].slice(-END_SIZE) ;
++i < n ;
s===(t=a[i].slice(-END_SIZE)) ? r.push(i) : (s=t)
);
return r;
}
// Example, assuming some text is selected.
// ---
var sto = app.selection[0].parentStory;
...
Copy link to clipboard
Copied
Hi @LinusCMH
Technically it's often tricky to expand an InsertionPoint to outer range. Better is to use a higher Text container, or simply the Story itself. From there you will easily grab lines, paragraphs, etc.
const END_SIZE = 2;
var ip = app.selection[0];
var hereLine = ip.lines[0];
var nextLine = ip.parentStory.lines.nextItem(hereLine);
var hereEnd = hereLine.contents.slice(-END_SIZE); // End of 1st line
var nextEnd = nextLine.contents.slice(-END_SIZE); // End of next line
alert( [hereEnd,nextEnd].join(' vs. ') );
(But that's a very simplified example. For finding stacks in huge stories, you'll want a stronger (and faster!) algorithm.)
Copy link to clipboard
Copied
Oh gosh. That couldn't have been easier. Thank yo so much, Marc.
I'm content for now with just having the script scan through the story until it finds a stack. As I get better with JavaScript, I don't doubt I'll find ways to speed it up or make it more efficient. Now, on to the looping process, error trapping, and such.
Copy link to clipboard
Copied
Anyway, here is a quick draft to illustrate the idea:
const END_SIZE = 2; // >= 1
function findStacks(/*Story*/sto, n,LS,a,i,s,t,r)
//----------------------------------
{
if( !(n=(LS=sto.lines).length) ) return [];
a = LS.everyItem().contents; // array of lines as JS strings.
for
(
r=[], s=a[i=0].slice(-END_SIZE) ;
++i < n ;
s===(t=a[i].slice(-END_SIZE)) ? r.push(i) : (s=t)
);
return r;
}
// Example, assuming some text is selected.
// ---
var sto = app.selection[0].parentStory;
var indices = findStacks( sto );
if( indices.length )
{
alert( "Stacks found at lines: " + indices );
// Show the first one.
// ---
var tx = sto.lines[indices[0]].characters.itemByRange(-END_SIZE,-1);
app.select(tx);
tx.showText();
}
else
{
alert( "No stack found in this story" );
}
M.
Copy link to clipboard
Copied
Thanks! I'll definitely give this a read through.
Copy link to clipboard
Copied
Also, regarding word stacks, see Kris Coppieters' brilliant script here: https://creativepro.com/free-script-identifies-word-stacks/
Copy link to clipboard
Copied
Thansk, Keith. I am aware of this script, but it relies on character styles to mark stacks. I set books that sometimes have seven or eight different language scripts/alphabets in them that require different fonts, and I rely heavily on GREP styles and character styles to apply those fonts. Using character styles to mark stacks could potentially wipe out my other character styles, so as elegant as it is, it won't work for me.