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

ES for FM10: Adding text at insertion point

Participant ,
Nov 12, 2014 Nov 12, 2014

Copy link to clipboard

Copied

Hello fellows,

What's the code for current insertion point (where the cursor is currently placed?)

I saw code for adding text in the beginning/end of pgf but not at the current insertion point.

Thank you in advance!

TOPICS
Scripting

Views

2.2K

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 1 Correct answer

Community Expert , Nov 13, 2014 Nov 13, 2014

Try using textLoc instead of TextLoc for your variable. TextLoc with this spelling is a reserved word.

Votes

Translate

Translate
Community Expert ,
Nov 13, 2014 Nov 13, 2014

Copy link to clipboard

Copied

Assuming doc is the active document, this will give you the current text selection:

var textRange = doc.TextSelection;

To get the insertion point, use either:

var textLoc = doc.TextSelection.beg;

or

var textLoc = doc.TextSelection.end;

-Rick

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
Participant ,
Nov 13, 2014 Nov 13, 2014

Copy link to clipboard

Copied

Hi Rick,

Thank you for your response and suggestion!

The following code does not do anything while the cursor is in a paragraph,. Am I missing something?

var doc = app.ActiveDoc;

var Tsel = doc.TextSelection;

var TextLoc = Tsel.beg;

doc.AddText (TextLoc, "Test ");

Thank you!

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
Community Expert ,
Nov 13, 2014 Nov 13, 2014

Copy link to clipboard

Copied

Try using textLoc instead of TextLoc for your variable. TextLoc with this spelling is a reserved word.

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
Participant ,
Nov 13, 2014 Nov 13, 2014

Copy link to clipboard

Copied

Hi Rick,

Thank you for your prompt response! The script now works. The only problem is that while using the script to insert the text, there is no Undo. There is no instruction in the code to save the file.

Is there a way to prevent FM from saving the change immediately?

Thanks again!

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
Mentor ,
Nov 18, 2014 Nov 18, 2014

Copy link to clipboard

Copied

rombanks,

Regarding undo, by default there is no undo for FDK/ES actions. However, there is information in the latest FDK manual about setting "checkpoints", which presumably registers the current state of a document in the undo stack. The implication is that you can programmatically allow your changes to be undone. However, I have never used it so I don't know anything about its behavior. Plus, the latest scripting guide (most recent update is for FM10) doesn't really contain any information. Therefore, I'm not clear on whether it works at all for ES and for FM10 period. If you want to explore further, get the latest FDK reference and look up:

F_ApiUndoStartCheckPoint()

F_ApiUndoEndCheckPoint()

Russ

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
Community Expert ,
Nov 18, 2014 Nov 18, 2014

Copy link to clipboard

Copied

Here is an example that illustrates how it works. I tested this in FM 12 so I am not sure about earlier versions.

#target framemaker

// Turn on undo recording.

app.UndoFDKRecording = true;

var doc = app.ActiveDoc;

// Set a starting point for "recording" behavior that can be undone.

// The string is what you will see next to the Undo command in the Edit menu

// and the History panel.

doc.UndoStartCheckPoint ("Add text");

// Add some text at the current insertion point.

var textLoc = doc.TextSelection.beg;

doc.AddText (textLoc, "Test");

// Set an end point for this operation.

doc.UndoEndCheckPoint ();

I believe that this was added back in one of the FrameMaker 7 releases. I used this as far back as 2006 in one of my FrameScript scripts. I haven't found it very useful though; it only shows up in about 20 of over 6,000 scripts that I have written. There are certain operations that are not undoable and clear the undo buffer. For example, if you call a function after line 15 to apply a paragraph format, the undo buffer is cleared and you can't undo the "Add text" that you did in line 15.

The InDesign scripting API is way ahead as far as undos. You can undo an entire script (most of the time) or you can undo each step that the script performs.

-Rick

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
Participant ,
Nov 22, 2014 Nov 22, 2014

Copy link to clipboard

Copied

@Russ, thank you for your suggestion!

@Rick, thank you for the sample script!


I appreciate your help, guys!

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
Participant ,
Jan 15, 2015 Jan 15, 2015

Copy link to clipboard

Copied

Guys,

I need your advice. I am trying to programmatically apply a condition (called Comment) to the string I added at the insertion point. So I wrote the following code:

var doc = app.ActiveDoc;

var Tsel = doc.TextSelection.beg;

var My_comment = "<Check>";

doc.AddText (Tsel, My_comment);

var tr = new TextRange();

tr.beg.obj = tr.end.obj = My_comment;

newFmt = doc.GetNamedCondFmt("Comment");

var props = doc.GetTextPropVal(tr.beg.object, Constants.FP_InCond)

            props.propVal.isval[0] = newFmt.id

            props.propVal.osval[0] = newFmt

            doc.SetTextPropVal(tr, props)

I am not sure how to select the text string I've inserted.

I've tried to select the text range by using  tr.beg.obj = tr.end.obj = My_comment; but this does not seem to work. Please, advise!

Thank you in advance!

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
Community Expert ,
Jan 15, 2015 Jan 15, 2015

Copy link to clipboard

Copied

Hi Roman, Try the code below:

var doc = app.ActiveDoc;

var Tsel = doc.TextSelection.beg;

var My_comment = "<Check>";

var textLoc = doc.AddText (Tsel, My_comment);

var tr = new TextRange(new TextLoc (textLoc.obj, textLoc.offset - My_comment.length), textLoc);

doc.TextSelection = tr;

-Rick

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
Participant ,
Jan 15, 2015 Jan 15, 2015

Copy link to clipboard

Copied

Hi Rick,

Thank you for your response! Could you please explain line 05?

For some reason, running the script adds the text string and FM (10) crashes immediately after that.

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
Community Expert ,
Jan 15, 2015 Jan 15, 2015

Copy link to clipboard

Copied

First of all, try commenting out line 06. Does FrameMaker still crash?

Here is the explanation: a document's TextSelection property is the current text selection or insertion point in the document. It is a TextRange object. A TextRange is made up of two TextLoc objects, one at the beginning of the selection and one at the end. (If you just have an insertion point, but TextLocs will be the same.)

Here is how to make a TextRange for the first 2 characters of the paragraph containing the insertion point:

var doc = app.ActiveDoc;

var pgf = doc.TextSelection.beg.obj;

var tr = new TextRange (new TextLoc (pgf, 0), new TextLoc (pgf, 2));

// Select the text range.

doc.TextSelection = tr; // Does this crash FM 10?

I have a meeting to attend, but will follow up later. See if FrameMaker still crashes if you comment out line 06.

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
Participant ,
Jan 15, 2015 Jan 15, 2015

Copy link to clipboard

Copied

Hi Rick,

Thank you for your explanations! I appreciate your help!

FM crashes even if you comment out line 6. BTW, why do we need "textLoc" in the end of line 5?

And what's the difference between

doc.TextSelection.beg and doc.TextSelection.beg.obj


Thank you again and have a great day!

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
Participant ,
Feb 05, 2015 Feb 05, 2015

Copy link to clipboard

Copied

Hi Rick,

After looking into the object reference guide, it seemed to me that the following script should have worked correctly.

var doc = app.ActiveDoc; 

var Tsel = doc.TextSelection.beg; 

var My_comment = "<Check>"; 

var textLoc = doc.AddText (Tsel, My_comment); 

var offs = textLoc.offset - My_comment.length;

var Tbeg = new TextLoc (textLoc.obj, offs);

var trange = new TextRange(Tbeg, textLoc); 

doc.TextSelection = trange;

newFmt = doc.GetNamedCondFmt("Comment");

var props = doc.GetTextPropVal(trange.beg.Object, Constants.FP_InCond)

            props.propVal.isval[0] = newFmt.id

            props.propVal.osval[0] = newFmt

            doc.SetTextPropVal(trange, props)

It adds the text, but does not apply the condition to the text range. Moreover, when trying to run the script again, I get an error message saying "Engine is Busy". I have to restart FM to run the script again. Have you encountered this issue before?

Thanks you!

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
Community Expert ,
Feb 05, 2015 Feb 05, 2015

Copy link to clipboard

Copied

This

var props = doc.GetTextPropVal(trange.beg.Object, Constants.FP_InCond)

should be this

var props = doc.GetTextPropVal(trange.beg, Constants.FP_InCond);

-Rick

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
Participant ,
Feb 08, 2015 Feb 08, 2015

Copy link to clipboard

Copied

Hi Rick,

Thank you for your response and for the suggestion! The condition is indeed applied.

The problem is that Framemaker crashes right after the text is inserted.

The question is if there is something wrong with the script (although I doubt) or with FM v10 (that partially supports ES)...

I'll try to port this script to Framescript. It seems that it is a more mature and stable scripting environment and provides better integration with FM.

Thank you again!

Best wishes,

Roman

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
Community Expert ,
Feb 08, 2015 Feb 08, 2015

Copy link to clipboard

Copied

Hi Roman, I am not sure what is going on. I tried it in 10 and 12 and didn't get the crash. -Rick

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
Participant ,
Feb 09, 2015 Feb 09, 2015

Copy link to clipboard

Copied

Hi Rick,.

To rule out a local problem, I tested the script on 2 computers with Framemaker v.10.0.2.419 installed. FM crashes immediately after running the script.


In any case, I've started porting the script to Framescript, and there is something that is not clear to me.


When you deduct My_comment.length from textLoc.offset (as below), aren't you supposed to get the offset of the text that comes to the left of textLoc.offset? That's what at least happens when using Framescript.


var textLoc = doc.AddText (Tsel, My_comment);

var offs = textLoc.offset - My_comment.length;

Thank you for your help in advance!

Roman

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
Participant ,
Feb 09, 2015 Feb 09, 2015

Copy link to clipboard

Copied

I am basically done with porting this script to Framescript. I would also like to add a marker in the middle of the text string I am adding with the script.

AFAIK, the New Marker definition includes the TextLoc parameter that defines the location of the marker. If the TextLoc is not specified, the marker is added at the insertion point.

So, in my script, I specified the TextLoc as the text range end offset - (minus)  3.

However, the TextLoc is for some reason ignored and the marker is added before the 1st character of the added text string.

Any ideas what could be wrong?

Thank you in advance!

Roman

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
Community Expert ,
Feb 09, 2015 Feb 09, 2015

Copy link to clipboard

Copied

Roman, can you post your code so I can take a look? Thanks. -Rick

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
Participant ,
Feb 09, 2015 Feb 09, 2015

Copy link to clipboard

Copied

Hi Rick,

No problem, here it is:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

IF ActiveDoc = 0

MsgBox 'There is no active document.';

LeaveSub;

ELSE

SET vCurrentDoc = ActiveDoc;

ENDIF

Set Tsel = vCurrentDoc.TextSelection;

Set My_comment = '<Sample Text>';

New Text TextLoc (Tsel) My_comment;

Set vStartOffset = Tsel.Offset;

Set vEndOffset = Tsel.Offset + My_comment.Size +1;

New TextRange NewVar(vTextRange) Object(Tsel) Offset (vStartOffset) Object(Tsel) Offset(vEndOffset);

Set vMarkerLoc = vEndOffset - 5;

New Marker NewVar(vMarker) MarkerName('Index') MarkerText('sample marker') TextLoc(vMarkerLoc);

Apply TextProperties CondFmt('Comment') TextRange(vTextRange);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Thanks!

Roman

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
Community Expert ,
Feb 09, 2015 Feb 09, 2015

Copy link to clipboard

Copied

OK, a few small corrections with explanations:

New Text TextLoc(Tsel.Begin) My_comment;

Tsel is a TextRange (so is vCurrentDoc.TextSelection) and New Text requires a TextLoc. So you use .Begin to get the TextLoc at the beginning of the TextRange.

Set vStartOffset = Tsel.Begin.Offset;

Set vEndOffset = Tsel.Begin.Offset + My_comment.Size +1;

Since Tsel is a TextRange, it doesn't have an Offset property. A TextLoc does so you use Tsel.Begin.

New TextRange NewVar(vTextRange) Object(Tsel.Begin.Object) Offset (vStartOffset) Offset(vEndOffset);

Tsel is a TextRange, not a text object, so you need Tsel.Begin.Object to get the text object for the TextRange. Since your TextRange is in a single paragraph, you only need one Object parameter.

Set vMarkerLoc = vEndOffset - 5;

You don't need this any more.

New TextLoc NewVar(vMarkerLoc) Object(Tsel.Begin.Object)

  Offset(vTextRange.Begin.Offset+3);

You can use this to make a location for the Index marker. It will offset the marker 3 characters from the front of the text range.

Here is the whole thing:

IF ActiveDoc = 0

  MsgBox 'There is no active document.';

  LeaveSub;

ELSE

  SET vCurrentDoc = ActiveDoc;

ENDIF

Set Tsel = vCurrentDoc.TextSelection;

Set My_comment = '<Sample Text>';

New Text TextLoc (Tsel.Begin) My_comment;

Set vStartOffset = Tsel.Begin.Offset;

Set vEndOffset = Tsel.Begin.Offset + My_comment.Size+1;

New TextRange NewVar(vTextRange) Object(Tsel.Begin.Object) Offset (vStartOffset) Offset(vEndOffset);

New TextLoc NewVar(vMarkerLoc) Object(Tsel.Begin.Object)

  Offset(vTextRange.Begin.Offset+3);

New Marker NewVar(vMarker) MarkerName('Index') MarkerText('sample marker') TextLoc(vMarkerLoc);

Apply TextProperties CondFmt('Comment') TextRange(vTextRange);

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
Participant ,
Feb 10, 2015 Feb 10, 2015

Copy link to clipboard

Copied

LATEST

Hi Rick,

First of all, thank you for reviewing the code and providing your valuable input!

It was a great coding lesson, and I learnt a lot, owing to your great input.

It is interesting that the text insertion part did work with the "dirty" code I originally created. I wonder why Framescript allows for such flexibility (which is a great capability too, by the way :-)).

My next step is trying to understand what went wrong with the Extendscript. I'll download a trial version of FM12 and see if I can reproduce the crash.

Thanks again for your help!

My best regards,

Roman

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