Framescript: Retrieving text from a broken xref

Participant ,
Jan 26, 2017 Jan 26, 2017

Copy link to clipboard

Copied

Hello fellows,

I'd like to write a script that will find broken external xrefs and attempt to restore them.  In my case, the xrefs get broken because the xref markers appearing in the source files are often updated by a system that generates these source files. I'd like to restore the xrefs by retrieving the xref string and attempting to find this string in the source files. But here is a problem: when an xref is broken, it no longer allows to retrieve XRefSrcText properly. The xref string no longer appears in XRefSrcText. I used the following code to test that:

Set vCurrentDoc = ActiveDoc;

Set vXRef = vCurrentDoc.FirstXRefInDoc;

Loop While(vXRef)

If vXRef.XRefIsUnresolved

Write Console  vXRef.XRefSrcText;

EndIf

Set vXRef = vXRef.NextXRefInDoc;

EndLoop

So, the XRefSrcText of an unresolved xref appears as follows:

25117: TableTitleTable Entry: ;2511718;2511719

While the XRefSrcText  of a live xref  appears as follows:

41369: TableTitle: Table 329: Item Numbering

What I would need to extract from here is the string "Item Numbering" and then find it in the xref source file to create a new link.

My question is how can one retrieve the text string from a broken xref? One way I could think of is converting the xrefs to text, copying the relevant part into a variable using regex. Any other ideas?

Thank you!

TOPICS
Scripting

Views

6.8K

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

Adobe Community Professional , Jan 30, 2017 Jan 30, 2017
You don't need to make a text range object; an XRef already has one.Display oXRef.TextRange.Text;Rick

Likes

Translate

Translate
Participant ,
Feb 16, 2017 Feb 16, 2017

Copy link to clipboard

Copied

Hi Rick,

I appreciate your response and your helpful input!

Question: Why defining targetLoc via a TextLoc is the wrong approach here?

My biggest concern right now is that I can't figure out how to extract Text Goes Here from <Text Goes Here> using the regex, without the ability to use lookbehind. So far, after checking multiple discussions on the lookbehind alternatives, I haven't found any similar example. Do you have an idea how to drop the angle brackets from <Text Goes Here>?

Thank you in advance!

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
Participant ,
Feb 19, 2017 Feb 19, 2017

Copy link to clipboard

Copied

Here is the strangest thing:

When I use the regexp ^<.*> in the FM search window, it finds <Text Goes Here> at the beginning of a line.

When I do the same with the code, Display oMatches.Count returns 1, but the following code doesn't retrieve the matching value:

Loop While(i <= oMatches.Count) LoopVar(i) Init(0) Incr(1)

      SET TrgtValue = oMatches.Value;

      Display TrgtValue;

EndLoop

In addition, how can I leave this loop and return to the main one in case there is no match?

Thank you!

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
Participant ,
Feb 28, 2017 Feb 28, 2017

Copy link to clipboard

Copied

Hello fellows,

After a lot of experimenting, I have resolved the issues I had with my regex. The script can now find and extract the required text from the broken xrefs, loop through the broken links, but for some unclear reason, it fails to find the text in the source file and fix the corresponding xref. It is important to note that the text to which I'd like to link to is located either in a table caption or in a table cell.

I went over the code line by line, and I don't see what can cause the script not to work. I obviously miss something. I hope you'll be able to point out where is problem is hiding. Here is the full code:

SET oDoc = ActiveDoc;

New EActiveXObject ProgId('VBScript.RegExp') NewVar(oRegex);

    If oRegex.ErrorCode <> 0

        MsgBox 'The VBScript.RegExp object could not be initialized.';

        LeaveSub; // Exit

    EndIf

      

Loop ForEach(XRef) In(oDoc) LoopVar(vXRef)

    SET vXrefTxt = vXRef.TextRange.Text;

    SET vXrefFmt = vXRef.XRefFmt.Name; 

    SET vXrefSrc = vXRef.XRefFile;

 

If (vXRef.XRefIsUnresolved)

                   

        If (vXrefFmt = 'Table Entry and Table') or (vXrefFmt = 'Table Entry') or (vXrefFmt = 'Cell and Table')

            SET oRegex.Pattern = '^.+(?=(>))';

        ElseIf (vXrefFmt = 'Catalog Name') or (vXrefFmt = 'Catalog Name, Number, Page (short)')

            SET oRegex.Pattern = '^.+Catalog';

        EndIf

      

        SET oRegex.Global = False;

              

        SET oMatches = oRegex.Execute{vXrefTxt};     

    

        If (oMatches.Count > 0)

            //Display oMatches.Count;

            Loop While(i < oMatches.Count) LoopVar(i) Init(0) Incr(1)

             SET vTrgtValue = oMatches.Value;

             //Display vTrgtValue;

            EndLoop

        Else

           MsgBox 'No matches found.';

           Write Console 'No matches found for: 'vXrefTxt;

           LeaveLoop;

        Endif

      

        //Lookbehind issue workaround

        If (vXrefFmt = 'Table Entry and Table') or (vXrefFmt = 'Table Entry') or (vXrefFmt = 'Cell and Table')

            Find String('<') InString(vTrgtValue) Backward ReturnPos(vPos);

            //Drop the left bracket.

            Get String FromString(vTrgtValue) StartPos(vPos+1)

            NewVar(vTrgtValue);

            Display vTrgtValue;

        EndIf

      

        SET objTarget = ActiveDoc;

        OPEN Document File(vXrefSrc);

        If vXrefSrc

            SET objSource = ActiveDoc;

            SET objDoc = objSource;

        Else

         MsgBox 'Cannot find' + vXrefSrc+'.';

        EndIf

        LOOP ForEach(Pgf) In(objDoc) LoopVar(pgfvar)

            If (pgfvar.Page.ObjectName = 'BodyPage')

                Find String(vTrgtValue)

                InObject(pgfvar)

                ReturnRange(vrangevar)

                ReturnStatus(vfound)

                ReturnString(vfoundstr);

              

                If vfound

                    If (pgfvar.Name == 'CellEntry') or (pgfvar.Name == 'TableTitleCatalog')

                        Get TextList NewVar(vMarkerList) MarkerAnchor InObject(pgfvar);

                  

                        If (vMarkerList.Count > 0)

                            Get Member Number(1) From(vMarkerList) NewVar(vXRefBegin);

                            SET vXRefType = vXRefBegin.TextData.MarkerTypeId.Name;

                            If (vXRefType = 'Cross-Ref')

                                SET vTrgtMarkerTxt = vXRefBegin.TextData.MarkerText;

                                //Display vTrgtMarkerTxt;

                            Endif

                        Endif

                  

                        Displaying = False;      

                        //Create XRef in target file;

                        SET ActiveDoc = objTarget;

                        SET vXRef.XRefSrcText = vTrgtMarkerTxt;

                        SET vXRef.XRefFile = vXrefSrc;

                                                        

                        //Update Xrefs and redisplay;

                        Update Xrefs OpenDocs ClosedDocs;

                        Displaying = True;

                        Update ReDisplay;

                        //LeaveLoop;           

                    EndIf

                  

                Else

                    SET ActiveDoc = objTarget;

                    //Display vXrefTxt + 'not found in ' +vXrefSrc +'.';  

                    Write Console vXrefTxt + ' not found in ' +vXrefSrc +'.';

                    LeaveLoop;

                EndIf

                         

            EndIf

            

        EndLoop     

  

    EndIf

  

EndLoop

Delete Object(oRegex);   

Thank you in advance!

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
Participant ,
Mar 01, 2017 Mar 01, 2017

Copy link to clipboard

Copied

Guys,

Any ideas what could be wrong syntax-wise?

Thank you in advance!

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
New Here ,
Jun 10, 2020 Jun 10, 2020

Copy link to clipboard

Copied

Hi @rombanks,   Did you ever resolve the  Run Error (Read Only Variable on command SET at line 86 and line 87... message?  I just ran into the same problem today.

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
New Here ,
Jun 18, 2020 Jun 18, 2020

Copy link to clipboard

Copied

LATEST

Hi @rombanks,   

   did you ever figure out this error?   I am currently seeing the exact same thing.

 

Cheers

 

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
Advocate ,
Jan 30, 2017 Jan 30, 2017

Copy link to clipboard

Copied

I moved away from FrameScript as soon as ExtendScript became available. Not that I think FrameScript is not a decent product, but the clients I worked for always had trouble ordering even the smallest add-on for Frame, and ExtendScript does not require any additional installs. That is a decisive benefit in a world that is ruled by paranoiac (and often lazy) software security departments.

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
Participant ,
Jan 31, 2017 Jan 31, 2017

Copy link to clipboard

Copied

Hi Jang,

I am not against using Extendscript, although it is still buggy in some cases (e.g., event scripts). The worst thing is that several years have passed since Extendscript had been released, and its documentation is still in horrible state. It's still too concise, misleading, lacking details and examples. Adobe did a very bad job in this area, as if they are not interested in having their customers use Extendscript.

Regards,

Roman

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
Adobe Community Professional ,
Jan 31, 2017 Jan 31, 2017

Copy link to clipboard

Copied

I am a big fan of FrameScript, having built my business around it since the late 1990s. It does allows you to do some interesting and powerful things through its EActiveXObject object:

* Work with regular expressions via VBScript.RegExp

* Work with XML using MSXML

* Work with Excel and Word through their COM interface

There are now native ways of working with regular expressions and XML, but I still find the EActiveXObject approach easier, mainly because I have so much existing code that I can reuse (over 6,000 scripts).

FrameScript also has ODBC support for working directly with databases. The developer, Frank Elmore, has always been responsive to help requests, suggestions, and feature requests. Although FrameScript rides on top of the FDK (like ExtendScript), Frank has done a good job of hiding some of the FDK "ugliness" and providing shortcuts for commonly used tasks (like displaying an object's properties).

On the other hand, there is a lot to like about ExtendScript, especially its dialog box model, native XML/XPath support, and the fact that it is built into FrameMaker. Also, since it is based on JavaScript, there are a lot more ways to learn the language. The majority of my script work over the last couple of years has been with ExtendScript instead of FrameScript.

One thing that can help you cope with the lack of ExtendScript documentation is the FDK documentation. The FDK examples are in C, but they give you a good overview of the FrameMaker object model and you can learn to translate the C examples into ExtendScript.

-Rick

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
Participant ,
Jan 31, 2017 Jan 31, 2017

Copy link to clipboard

Copied

Hi Rick,

Thank you for sharing your insights on these 2 languages.

You've definitely been one of the prominent pioneers in this field, and thank you for your great and invaluable contribution to the Framers' community!

Best Regards,

Roman

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
New Here ,
Apr 15, 2018 Apr 15, 2018

Copy link to clipboard

Copied

Hi,

"Address=" string appears when the table is generated .

Please find the code

Get String From String (gv.RegAddr.Text) NewVar(gvRegAddressExtract) RemoveLeading('Address=");

But this does work.

Can you help...

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