Pages: 1
Print
Author Topic: MoveToElement() Help  (Read 2560 times)
edporterIII
Member

Posts: 16


« on: December 02, 2014, 08:08:15 AM »

I've written the following script in JavaScript to crawl a document and find/mark spaces at the beginning/ending of specific tags. I've used a similar construction before to step through a document, but I didn't modify the document in the midst of the while loop. In any case, it will crawl the document, but it won't pick up every tag at present. Tags nested within other tags that are also part of the switch/case logic will not be returned. Only top level tags in the select/case loop are returned. Is there a flaw in my logic or is there something going on with the MoveToElement method as a result of me modifying the selection in the loop?

Code:
var rng_Document = ActiveDocument.Range;
rng_Document.MoveToDocumentStart();
var space = " ";
while (rng_Document.MoveToElement()) {
switch (rng_Document.ContainerName) {
case "entry":
rng_Document.SelectContainerContents();
var text = rng_Document.text;
var test = text.charAt(0);
if (test === space) {
text = "<!-- -->" + text.slice(1, text.length);
rng_Document.text = text;}
var test = text.charAt(text.length - 1);
if (test === space) {
text = text.slice(0, text.length - 1) + "<!-- -->";
rng_Document.text = text;}
break;
case "chap-num":
case "xref":
case "emph":
case "title":
case "caption":
case "def":
case "term":
case "footnote":
case "number":
case "head":
case "inline-para":
case "para":
case "chap-num":
case "xref":
case "emph":
rng_Document.SelectContainerContents();
var text = rng_Document.text;
if (text === "" || text === " ") {
text = "<!-- -->";
rng_Document.text = text;}
var test = text.charAt(0);
if (test === space) {
text = "<!-- -->" + text.slice(1, text.length);
rng_Document.text = text;}
var test = text.charAt(text.length - 1);
if (test === space) {
text = text.slice(0, text.length - 1) + "<!-- -->";
rng_Document.text = text;}
break;
}
}
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #1 on: December 02, 2014, 01:13:23 PM »

I don't see any issues with the API, so I guess there's probably an issue with your logic.
Here's a simplified script you can test with that uses the API in a similar way to return all the element names by moving a Range:

Code:
//XMetaL Script Language JScript:
var rng = ActiveDocument.Range;
rng.MoveToDocumentStart();
while(rng.MoveToElement()) {
Application.Alert(rng.ContainerName);
}
« Last Edit: December 02, 2014, 01:21:12 PM by Derek Read » Logged
edporterIII
Member

Posts: 16


« Reply #2 on: December 03, 2014, 12:01:41 PM »

The issue appears to be that when I select the container contents, the while loop won't go any further into that particular container. For example, if there's an entry or emph tag within a para, the code below will not pick them up. If you remove the SelectContainerContents method call, it will.

Code:
var rng_Document = ActiveDocument.Range;
rng_Document.MoveToDocumentStart();
var space = " ";
var tag = "";
while (rng_Document.MoveToElement()) {
tag = tag + rng_Document.ContainerName + "\n";
switch (rng_Document.ContainerName) {
case "emph":
case "entry":
case "para":
rng_Document.SelectContainerContents();

break;
}

My goal is to find a space immediately following an opening tag or preceding a closing tag, and wrap a comment around it. What would be the best way to modify the active document and not disrupt this while loop?
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #3 on: December 04, 2014, 01:19:38 PM »

You are correct. The call to SelectContainerContents() will stop MoveToElement from moving further.
Including it in my example demonstrates that:

Code:
//XMetaL Script Language JScript:
var rng = ActiveDocument.Range;
rng.MoveToDocumentStart();
while(rng.MoveToElement()) {
rng.SelectContainerContents();
Application.Alert(rng.ContainerName);
}

So, I'd say you need to modify your code so that the selection is turned back into an insertion point. Here's the exact same example but doing what I  I think you need:

Code:
//XMetaL Script Language JScript:
var rng = ActiveDocument.Range;
rng.MoveToDocumentStart();
while(rng.MoveToElement()) {
rng.SelectContainerContents();
Application.Alert(rng.ContainerName); //most of your code that modifies stuff would probably go here
rng.Collapse(1);
}
Logged
edporterIII
Member

Posts: 16


« Reply #4 on: December 23, 2014, 08:32:23 AM »

Thanks, that collapse function did the trick!
Logged
Pages: 1
Print
Jump to: