• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

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

682

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

Votes

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

Votes

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

Votes

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.

 

Votes

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.

Votes

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.

Votes

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/

Votes

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.

Votes

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