Numbering Selected Portions of Files

Help with writing and running scripts

Numbering Selected Portions of Files

Postby garbile » Mon Dec 03, 2007 3:45 pm

The task at hand is to iterate through files, select <proc thru </proc> and number the <step1 items like this...<step1 label="1".

I am able to iterate through the <step1>s successfully using the following:

Code: Select all
UltraEdit.ueReOn(); /* Use UE regexp syntax */
UltraEdit.activeDocument.findReplace.regExp = true;
UltraEdit.activeDocument.findReplace.replaceAll = false;
UltraEdit.selectClipboard(9);

// First go to top of document
UltraEdit.activeDocument.top();

var NumberValue = 1; /* Start value */
while ( (UltraEdit.activeDocument.findReplace.find("<step1")) && ! UltraEdit.activeDocument.isEof() ) {
//Make loop depend on presence of <step1 and break at End-of-file
 
   UltraEdit.activeDocument.findReplace.replace("<step1","<step1 label=\""+NumberValue+"\"");
   NumberValue++;   /* Increment the numbering */
}
// reposition to top after renumbering
UltraEdit.activeDocument.top();
UltraEdit.selectClipboard(0);



However, I can't figure out how to segregate the <proc thru </proc> where the file may have 2 or more <proc>s.

Any ideas?
User avatar
garbile
Newbie
 
Posts: 2
Joined: Mon Dec 03, 2007 12:00 am

Re: Numbering Selected Portions of Files

Postby Mofi » Tue Dec 04, 2007 8:09 am

Next time please post also an example input and output text. Here is the script which hopefully works, tested on an example input text which I have had to create by myself.

Code: Select all
UltraEdit.ueReOn(); /* Use UE regexp syntax */
UltraEdit.activeDocument.findReplace.regExp = false;
UltraEdit.activeDocument.findReplace.searchDown=true;
// Don't know why switching clipboard is necessary for this script !!!
UltraEdit.selectClipboard(9);

// First go to top of document
UltraEdit.activeDocument.top();

// Run the following loop until no </proc> found anymore.
while ( UltraEdit.activeDocument.findReplace.find("</proc>") ) {

/* The cursor is right to </proc>. Replace all <step1 from
   this position to end of file with a temporary string. So
   only all <step1 above still exist without modification. */
   UltraEdit.activeDocument.findReplace.replaceAll = true;
   UltraEdit.activeDocument.findReplace.replace("<step1","<step!!!###");
   UltraEdit.activeDocument.findReplace.replaceAll = false;

// Move the cursor with a search upwards back to matching <proc.
   UltraEdit.activeDocument.findReplace.searchDown=false;
   UltraEdit.activeDocument.findReplace.find("<proc")
   UltraEdit.activeDocument.findReplace.searchDown=true;

/* Renumber the labels. Because all <step1 below current </proc>
   temporarily do not exist this loop works like running only
   within current <proc and </proc> block. */
   var NumberValue = 1; /* Start value */
   while ( UltraEdit.activeDocument.findReplace.find("<step1") ) {
   //Make loop depend on presence of <step1
     
      UltraEdit.activeDocument.findReplace.replace("<step1","<step1 label=\""+NumberValue+"\"");
      NumberValue++;   /* Increment the numbering */
   }
/* Now move cursor to end of current </proc> block and replace all temporary
   strings below back to original value. Then continue with next block. */
   UltraEdit.activeDocument.findReplace.find("</proc>");
   UltraEdit.activeDocument.findReplace.replaceAll = true;
   UltraEdit.activeDocument.findReplace.replace("<step!!!###","<step1");
}
// reposition to top after renumbering
UltraEdit.activeDocument.top();
UltraEdit.clearClipboard();
UltraEdit.selectClipboard(0);
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4055
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: Numbering Selected Portions of Files

Postby jorrasdk » Tue Dec 04, 2007 9:04 am

I don't know if this post is relevant to your situation garbile, but since learning that UE supports ECMAScript for XML (E4X), I have been looking for problems where I could utilize E4X to solve the problem.

Since You, as Mofi also points out, do not include a before and after example, let's assume we have a xml like document like this:

Code: Select all
<roottag>
<proc>
  <step1>
    <foo>dummy text
    </foo>
  </step1>
  <step1>
  <bar>
  dummy text
  </bar>
  </step1>
</proc>
<proc>
  <step1/>
  <step1>
  <acme>1</acme>
  </step1>
</proc>
</roottag>


I then made this script which takes a completely different approach than Mofis script. But it will only work if your input is a valid XML file, while Mofis will work regardless as long as it finds <proc>'s and <step1>'s.

Code: Select all
// Misc options for global XML object:
// http://developer.mozilla.org/en/docs/E4X_Tutorial:The_global_XML_object
XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
XML.ignoreWhitespace = true;
XML.prettyPrinting = true;
XML.prettyIndent = 2;

// Do the rest of the processing in a function, so we can quit the script
renumberLabels();

function renumberLabels() {
  // Retrieve whole document into XML List object.
  UltraEdit.activeDocument.selectAll();
  var xmlDoc = UltraEdit.activeDocument.selection;
 
  // Try and create a XML object from the document contents:
  try {
    var xmlRoot = new XML( xmlDoc );
  }
  catch (xmlException) {
    UltraEdit.messageBox("Document is not valid XML");
    return; // quit the rest of the script
  }

  // Get XMLlist of <proc>'s
  // http://developer.mozilla.org/en/docs/E4X_Tutorial:Accessing_XML_children
  var xmlProcList = xmlRoot.proc;

  // Iterate through <proc>'s
  for (i in xmlProcList) {
    // set renumber variable to 1 for each <proc>
    var stepRenumber = 1;

    // get <step1>'s in <proc> group
    var xmlStep1List = xmlProcList[i].step1;
 
    // Iterate over <step1>
    for (j in xmlStep1List) {
      // Assign label attribute for each <step1>
        xmlStep1List[j].@label = (stepRenumber++);
    }
  }

  // Write XML document back into editor while PrettyPrint formatting as well
  UltraEdit.activeDocument.write( xmlRoot.toXMLString() );
}


The script will produce this output:

Code: Select all
<roottag>
  <proc>
    <step1 label="1">
      <foo>dummy text</foo>
    </step1>
    <step1 label="2">
      <bar>dummy text</bar>
    </step1>
  </proc>
  <proc>
    <step1 label="1"/>
    <step1 label="2">
      <acme>1</acme>
    </step1>
  </proc>
</roottag>


You can run the script again and again even when label properties is already inserted. They will be renumbered if you reorganize some of them.

I learned something about E4X in the process and I hope other sees the potential in this to manipulate XML documents in UE.
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Numbering Selected Portions of Files

Postby garbile » Tue Dec 04, 2007 1:09 pm

Thanks to you both!

jorrasdk - You are on the mark about ECMAScript and S1000D for that matter. I wish to iterate through any number of content tagged groupings that may or may not parse (I specialize in fixing other people's mistakes).

Mofi - Your method is perfect for the multitude of mutilated documents I am tasked to recover/reuse.

And now to correct my mistake...sample code follows:

<proc>
<step1><para></para>
<step2><para></para></step2>
<step2><para></para></step2>
<step2><para></para></step2>
</step1>
<step1><para></para>
<step2><para></para>
<step3><para></para></step3>
<step3><para></para></step3>
<step3><para></para></step3>
</step2>
<step2><para></para>
<step3><para></para></step3>
<step3><para></para></step3>
<step3><para></para></step3>
</step2>
</step1>
</proc>

Typical Standard numbering is step1 = 1., step2 = a., step3 = (1.)

Thank you!
User avatar
garbile
Newbie
 
Posts: 2
Joined: Mon Dec 03, 2007 12:00 am


Return to Scripts