Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Determining in which line of the paragraph (or story) is my selection?

Explorer ,
Aug 26, 2021 Aug 26, 2021

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:

 

var ip = app.selection[0];
var firstLine = app.selection[0].lines[0].characters[-2].contents;
var secondLine = app.selection[0].lines[(ip.index + 1)].characters[-2].contents;
 
The last line always throws an error, "Error Code# 45: Object is invalid @ file ...."
 
I'll be grateful for any help.
TOPICS
Scripting

Views

226

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Guide , Aug 26, 2021 Aug 26, 2021
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...

Likes

Translate

Translate
Guide , Aug 26, 2021 Aug 26, 2021
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;...

Likes

Translate

Translate
Guide ,
Aug 26, 2021 Aug 26, 2021

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.)

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 26, 2021 Aug 26, 2021

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.

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 26, 2021 Aug 26, 2021

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

Thanks! I'll definitely give this a read through.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

Also, regarding word stacks, see Kris Coppieters' brilliant script here: https://creativepro.com/free-script-identifies-word-stacks/

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

LATEST

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines