UltraEdit crashes repeatedly in script

UltraEdit crashes repeatedly in script

5

    Feb 12, 2015#1

    I have a script which works fine... except that it repeatedly crashes UltraEdit. I'm thinking memory allocation problems and have tried to code around the activedocument.selection problem, but may not have done this sufficiently well. Alternatively, there may be other known problems I'm tripping over. Or I may need to report a new error to IDM. All advice welcome!

    UltraEdit Version 21.30.0.1024 and Windows 8.1 64-bit.

    (N.B. code also includes latest versions of FIndSelectInnerOuter.js, FileNameFunctions.js and GetListOfFiles.js) but I have cut these out for brevity.)

    Code: Select all

    /* processtreefiles.js
    
    This script processes the html output of two applications to produce a hybrid set of html.
    
    It takes as input:
    - two directories containing websites (gedmilldir and fhdir) each with 1000s or 10s of 1000s of files 
    
    and creates as output:
    - a re-used directory containing the modified fh website (fhdir)
    
    */
    
    // *** Parameters governing the script behaviours -- edit and select these as required -- these are NOT regular expressions ***
    
    var gedmilldir = "C:\\Users\\Helen\\Genealogy\\Website FH content\\GEDmill\\"; //directory containing GEDmill files
    var fhdir = "C:\\Users\\Helen\\Genealogy\\Website FH content\\FH\\"; //directory containing Family Historian files 
    var treefiletype = "png"; //should be gif or png -- whatever is being used for GEDmill tree diagrams
    
    // ***String constants***
    // *** Shouldn't need to edit these unless GEDmill or Family Historian change the content or format of their output or MZP changes its installation instructions***
    // *** These are NOT regular expressions ***
    
    var gedmillminitreestart = "<div id=\"minitree\"" ;
    var gedmillminitreeend = "</div>";
    
    var	fhseealsostart = "<div class=\"FhSeeAlso\">";				// the See also div identifier in the raw html files from FH web production.
    var	fhseealsoend = "</div>";									// end of the div.
    var fhseealsostart2 = "<div class=\"fhcontent fhpageInd\">"; //Alternative start for the insertion point for the minitree
    var fhseealsoend2 = "<h1 class=\"FhHdg1\">"; //and end
    
    var lyteboxheadcss = "lytebox.css";
    var lyteboxheadjs= "lytebox.js";
    var mzpheadcss = "MagicZoomPlus.css";
    var mzpheadjs= "MagicZoomPlus.js";
    var lyteboxclass = "rel=\"lytebox\"";
    var mzpclass = "class = \"MagicZoomPlus\"";
    
    var navregex = "<li><span><a href=\"index.html\">Home</a></span></li>";
    
    // ** Following variable defines the error reporting behaviours in some functions **
    
    var DebugMessage = 1; //Enable error reporting, and use message boxes. Set to 1 to use the output window, to 2 to use message boxes and to 0 or any other value to not report errors
    
    // Define a set of functions -- general utilities first
    
    function ReportError(ErrorString,ErrorSource) {
    	/* Determine the type of output for debug messages from the global
    	variable DebugMessage: 1 ... debug to output window, 2 ... debug
    	to message dialog, all others ... no debug messages. If the global
    	variable DebugMessage does not exist, don't show debug messages. */
    	var OutputType = (typeof(DebugMessage) == "number") ? DebugMessage : 0;
    	if (OutputType == 2) {
    		UltraEdit.messageBox(ErrorString,ErrorSource);
    	} else if (OutputType == 1) {
    		if (UltraEdit.outputWindow.visible === false) UltraEdit.outputWindow.showWindow(true);
    		UltraEdit.outputWindow.write(ErrorSource +": " +ErrorString);
    	}
    }
    			
    function SetDefaultSearchHandling (){
    	UltraEdit.perlReOn(); //Use Perl Regular expressions
    	UltraEdit.activeDocument.findReplace.regExp = false; //Disable regular expressions in find and replace
    	UltraEdit.activeDocument.findReplace.matchCase = false; //case insensitive
    	UltraEdit.activeDocument.findReplace.replaceAll = false; //Replace only first instance of found strings in each file
    	UltraEdit.activeDocument.findReplace.searchDown=true;//Search down form current position in file
    }
    function GetSelectedTextViaClipboard () {//this is used to avoid the memory problems associated with document.selection
    	UltraEdit.selectClipboard(1);
    	UltraEdit.activeDocument.copy(); //Get the selection onto clipboard 1
    	var strtemp = UltraEdit.clipboardContent;
    	UltraEdit.clearClipboard;
    	return strtemp;
    }
    
    //Now functions specific to processing GEDmill- and FH-generated html
    
    function FixGEDmillFileLinks () {
    	/*Fix the links originating from GEdmill files to point to their fh equivalents*/
    
    	UltraEdit.activeDocument.top();//since we don't know where the cursor is in the file concerned
    	SetDefaultSearchHandling();
    	UltraEdit.activeDocument.findReplace.regExp = true; //Enable regular expressions in find and replace
    	UltraEdit.activeDocument.findReplace.replaceAll = true; //Replace all instances of found strings in each file
    	UltraEdit.activeDocument.findReplace.replace("indiI(\\d+)\\.html","ind\\1\\.html");//Fix the links originating from GEdmill files to point to their fh equivalents
    }
    function ChangeLyteboxToMagicZoomPlus () {
    	/*Change all reference to Lytebox to use Magiczoomplus instead*/
    
    	SetDefaultSearchHandling();
    	UltraEdit.activeDocument.findReplace.replaceAll = true; //Replace all instances of found strings in each file
    	UltraEdit.activeDocument.top();//since we don't know where the cursor is in the file concerned
    	UltraEdit.activeDocument.findReplace.replace(lyteboxheadcss,mzpheadcss);
    	UltraEdit.activeDocument.top();//since we don't know where the cursor is in the file concerned
    	UltraEdit.activeDocument.findReplace.replace(lyteboxheadjs,mzpheadjs);
      UltraEdit.activeDocument.top();//since we don't know where the cursor is in the file concerned
    	UltraEdit.activeDocument.findReplace.replace(lyteboxclass,mzpclass);
    	
    }
    function RemoveNavigationString () {
    
    	SetDefaultSearchHandling();
    	UltraEdit.activeDocument.findReplace.regExp = true; //Enable regular expressions in find and replace
    	UltraEdit.activeDocument.top();
    	UltraEdit.activeDocument.findReplace.replace(navregex,"");
    	return true;
    }
    function ProcessNameIndexFile (InputDir) {
    	//Update the fh index of individuals to have the correct navigation string
    
    	var fhfilename = InputDir + "_nameindex.html"; //file name with path
    	UltraEdit.open(fhfilename); //Active document is FH index of individuals; position is top of file
    	RemoveNavigationString();
    	UltraEdit.closeFile(fhfilename,1);//close and save fh file 
    	return true;
    
    }
    function ModifyActiveIndividualFile(fhstring,gedmillstring) {
    			UltraEdit.activeDocument.top();
    			UltraEdit.activeDocument.findReplace.replace(fhstring,gedmillstring );//Now replace the see also text in the FH file with the minitree from the gedmillfile
    			FixGEDmillFileLinks();
    			ChangeLyteboxToMagicZoomPlus();
    			RemoveNavigationString();
    		  UltraEdit.closeFile(UltraEdit.activeDocument.path,1); //close and save active document
    			return true;
    }
    function ProcessIndividualFile (Individual) {
    
    	var gedmillfilename = gedmilldir + "indiI" + Individual +".html"; //construct the gedmill filename;
    	var fhfilename = fhdir + "ind" + Individual +".html"; //construct the fh filename;
    
    	UltraEdit.open(gedmillfilename); //Active document is gedmill
    	SetDefaultSearchHandling();
    	//Get the text wanted from the gedmill file
    	if (!FindSelectOuter (gedmillminitreestart,gedmillminitreeend,-1,false)) {//get minitree from gedmillfile that will be inserted into fh file
    		//String not found in gedmill file -- report error, close file and finish
    		ReportError("FH individual minitree not found: " + Individual,"ProcessIndividualFile");
    		UltraEdit.closeFile(UltraEdit.activeDocument.path,2); //close gedmill document without saving
    		return false;
    	}
    	else {
    		var gedmillstring = GetSelectedTextViaClipboard();
    		UltraEdit.closeFile(UltraEdit.activeDocument.path,2); //close gedmill document without saving
    		//Modify the fh file
    		UltraEdit.open(fhfilename); //Active document is fh
    		SetDefaultSearchHandling();
    		if (!FindSelectOuter (fhseealsostart,fhseealsoend,-1,false)) {//get individual text to be replaced in fh file
    			//Option 1 not found in fh file -- try option 2
    			if (!FindSelectInner(fhseealsostart2,fhseealsoend2,-1,false)) {
    				//Neither option found in fh file -- report error, close file and finish
    				ReportError("FH individual 'See also' text not found: " + Individual,"ProcessIndividualFile");
    				UltraEdit.closeFile(UltraEdit.activeDocument.path,2); //close fh file without saving
    				return false;
    			}
    			else {
    				  ModifyActiveIndividualFile(GetSelectedTextViaClipboard(),gedmillstring);
    			}
    		}
    		else {
    				  ModifyActiveIndividualFile(GetSelectedTextViaClipboard(),gedmillstring);
    		}
    	}
    				//Now copy the tree file
    				var gedmilltreename = gedmilldir + "treeI" + Individual +"." + treefiletype;
    				var fhtreename = fhdir + "treeI"+Individual + "." + treefiletype;
    				UltraEdit.open(gedmilltreename);//Active document
    				UltraEdit.saveAs(fhtreename);
    				UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
    	      return true;
    }
    
    function ProcessFamilyTree () {
    	if (GetListOfFiles(0,gedmilldir,"indiI*.html",false)){
    		//Document [0] is now the list of GEDmill files.
    		//Process all the individuals' files
    		while (!UltraEdit.document[0].isEof()) { //Loop through the lines in this file until end of file is reached
    			SetDefaultSearchHandling();
    			UltraEdit.activeDocument.findReplace.regExp = true; //Enable regular expressions in find and replace
    			UltraEdit.document[0].selectLine();//read the filename from the next line
    			var ind=UltraEdit.document[0].selection.match(/\d+/);
    			ProcessIndividualFile(ind);
    			UltraEdit.document[0].key("RIGHT ARROW"); //move to the next line in the list of files
    		}
    		UltraEdit.closeFile(UltraEdit.document[0].path,2); //Close the file list without saving
    	}
    	else {
    		ReportError("NO GEDmill files. Terminating.","ProcessFamilyTree");
    	}
    		
    }
    
    
    //Main script below here
    
    UltraEdit.outputWindow.clear();//empty the output window
    if (UltraEdit.document.length > 0) {
    	//First check that there are no open files to confuse the script, which relies on the order in which various files are opened.
    	ReportError("Please close open files before trying again","MainScript");
    }
    else {
    			
    	//Process family tree contents
    	if (!ProcessNameIndexFile(fhdir)) {
    		//Error reporting was done in ProcessNameFileIndex
    		UltraEdit.closeFile(UltraEdit.document[0].path,2); //Close the file list without saving
    	}
    	else {
    		ProcessFamilyTree();
    	}
    }
    
    
    
    
    

    6,675585
    Grand MasterGrand Master
    6,675585

      Feb 13, 2015#2

      I will look on your script at weekend.

      See topic Find strings with a regular expression and output them to new file and file FindStringsReadMe.txt in ZIP file with information how to workaround "out of memory" situations if that is really needed and why they occur even with lots of free RAM.

      BTW: How large are the files on which this script usually is executed?
      Best regards from an UC/UE/UES for Windows user from Austria

      5

        Feb 14, 2015#3

        Thanks -- I'll look at the scripts/topic suggested.

        The current data test set is 1385 pairs of html files, all less than 20k each. (The largest file has 250 lines)

        The data selected from one file to paste into the other is typically less than 1600 bytes.
        The text replaced is always smaller still.

        Having reviewed FindStringsToNewFileExtended.js, I see that I could adapt the clipboard technique to keep track of the progress through the list of files and restart part way through (i.e. batching up the work), so will work on that pending any further comments.

        I also suspect that changing some elements of the editing to use frInFiles will speed the script up, if nothing else.

        6,675585
        Grand MasterGrand Master
        6,675585

          Feb 14, 2015#4

          I have looked already on the script on Friday evening and thought also that using Replace in Files would make the script faster and avoids lots of opening and closing of files.

          Also usage of FindSelectInner and FindSelectOuter can be most likely replaced by Perl regular expression multi-line finds as the blocks to select are small which would speed up the script further.

          Unfortunately it is not possible to run a Find in Files to find all the blocks to copy with results written to a temporary file. Find in Files always returns only the first line of each found block.

          Instead of getting each found block into memory into a string variable, it is much better to just copy each block to a user clipboard and paste it into the other file. This avoids the frequent memory allocations for the selections as done at the moment which are most likely the reason for out of memory condition resulting finally in a crash of UltraEdit.

          I think it is even possible to open just the GEDmill files for getting the block to copy and write the found block with Replace in Files with complete filename as file type to the FH files. In an UltraEdit regular expression Replace in Files it is possible to use ^c in replace string to reference contents of active user clipboard.

          The disadvantage on using Replace in files on single file only to write the block into the FH files is more difficult error handling, i.e. detection if block to replace was found and replaced. This is possible by writing Replace in Files summary to output window and evaluate output window contents after each Replace in Files. However, this approach could be slower than opening also FH files as they are small and making the replaces with Replace command.

          But I think, it should be no problem to recode with a few small changes the script to avoid frequent memory allocations for the small strings and therefore avoid out of memory situation. I will post tomorrow the recoded script.

            Feb 15, 2015#5

            Okay, here is a completely re-coded script tested on a set of five files which was enough to test all lines of code.

            Code: Select all

            /* processtreefiles.js
            
            This script processes the HTML output of two applications to produce a hybrid set of HTML.
            
            It takes as input:
            - two directories containing websites (gedmilldir and fhdir) each with 1000s or 10s of 1000s of files
            
            and creates as output:
            - a re-used directory containing the modified fh website (fhdir)
            
            */
            
            // *** Parameters governing the script behaviors -- edit and select these as required -- these are NOT regular expressions ***
            
            var g_sDirectoryGE = "C:\\Users\\Helen\\Genealogy\\Website FH content\\GEDmill\\"; // Directory containing GEDmill files.
            var g_sDirectoryFH = "C:\\Users\\Helen\\Genealogy\\Website FH content\\FH\\";      // Directory containing Family Historian files.
            var g_sTreeFileExt = ".png"; // Should be gif or png -- whatever is being used for GEDmill tree diagrams.
            
            // *** String constants ***
            // *** Shouldn't need to edit these unless GEDmill or Family Historian change the contents or format of their output or MZP changes its installation instructions ***
            // *** These are Perl regular expressions which find blocks, i.e. single or multi-line strings. ***
            
            var g_sMiniTreeGE = '(?s)<div id="minitree".*?</div>';
            // The See also div identifier in the raw html files from FH web production.
            var g_sSeeAlsoFH1 = '(?s)<div class="FhSeeAlso">.*?</div>';
            // Alternative start for the insertion point for the minitree.
            var g_sSeeAlsoFH2 = '(?s)(?<=<div class="fhcontent fhpageInd">).*?(?=<h1 class="FhHdg1">)';
            
            var sLyteBox_Head_css = "lytebox.css";
            var sLyteBox_Head_js  = "lytebox.js";
            var sMagicZP_Head_css = "MagicZoomPlus.css";
            var sMagicZP_Head_js  = "MagicZoomPlus.js";
            var sLyteBox_Class    = 'rel="lytebox"';
            var sMagicZP_Class    = 'class="MagicZoomPlus"';
            var sHomeLink         = '<li><span><a href="index.html">Home</a></span></li>';
            
            // ** Following variable defines the error reporting behaviors in some functions. **
            
            // Set to 1 to use the output window, to 2 to use message boxes and to 0 or any other value to not report errors.
            var g_nDebugMessage = 1; // Enable error reporting and use message boxes.
            
            // Define a set of functions -- general utilities first.
            
            function ReportError (sErrorString,sErrorSource) {
               /* Determine the type of output for debug messages from the global
               variable DebugMessage: 1 ... debug to output window, 2 ... debug
               to message dialog, all others ... no debug messages. If the global
               variable DebugMessage does not exist, don't show debug messages. */
               var nOutputType = (typeof(g_nDebugMessage) == "number") ? g_nDebugMessage : 0;
               if (nOutputType == 2) {
                  UltraEdit.messageBox(sErrorString,sErrorSource);
               } else if (nOutputType == 1) {
                  if (UltraEdit.outputWindow.visible === false) UltraEdit.outputWindow.showWindow(true);
                  UltraEdit.outputWindow.write(sErrorSource + ": " + sErrorString);
               }
            }
            
            function SetDefaultSearchHandling () {
               UltraEdit.activeDocument.findReplace.mode=0;                // Find/replace in current file.
               UltraEdit.activeDocument.findReplace.regExp=false;          // Disable regular expressions in find/replace.
               UltraEdit.activeDocument.findReplace.matchCase=false;       // Process find/replace case-insensitive.
               UltraEdit.activeDocument.findReplace.matchWord=false;       // Match any string not just complete words.
               UltraEdit.activeDocument.findReplace.searchDown=true;       // Search downwards from current position in file.
               UltraEdit.activeDocument.findReplace.searchInColumn=false;  // Disable search in column feature.
               // The replace options are also set to defaults.
               UltraEdit.activeDocument.findReplace.replaceAll=false;      // Replace only first instance of found string.
               UltraEdit.activeDocument.findReplace.preserveCase=false;    // Do not preserve case on replace.
               UltraEdit.activeDocument.findReplace.replaceInAllOpen=false;// Replace only in current file.
            }
            
            // Now functions specific to processing GEDmill and Family History generated HTML files.
            
            function ProcessIndividualFile (sFileNameGE) {
            
               // Get the file number from file name and build FH file name.
               var sFileNumber = sFileNameGE.replace(/^.*indiI\D*(\d+)\.html$/,"$1");
               // The replace function never modifies source string. It always creates a copy of
               // the source string with all characters not matched by the expression being copied.
               // So if the expression above designed for matching all characters of file name does
               // not match and replace the entire file name by just the file number, the replace
               // function produces a 100% copy of the source file. This is just for security to
               // avoid an undetermined script behavior because of an unexpected file in directory.
               if (sFileNumber == sFileNameGE) return;
               var sFileNameFH = g_sDirectoryFH + "ind" + sFileNumber + ".html";
            
               UltraEdit.open(sFileNameGE);  // Active document is the GEDmill file.
               SetDefaultSearchHandling();
            
               // Get the text wanted from the GEDmill file.
               UltraEdit.activeDocument.findReplace.regExp=true;
               if (!UltraEdit.activeDocument.findReplace.find(g_sMiniTreeGE)) {
                  // Block not found in GEDmill file -- report error, close file and finish.
                  ReportError("FH individual minitree not found: " + sFileNumber,"ProcessIndividualFile");
                  UltraEdit.closeFile(UltraEdit.activeDocument.path,2); // Close GEDmill file without saving.
                  return;
               }
            
               // Copy found block to active clipboard and close the GEDmill file without saving.
               UltraEdit.activeDocument.copy();
               UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
            
               // Modify the Family Historian file.
               UltraEdit.open(sFileNameFH);  // Active document is the Family Historian file.
               SetDefaultSearchHandling();
            
               // Find individual text to be replaced in Family Historian file.
               UltraEdit.activeDocument.findReplace.regExp=true;
               if (!UltraEdit.activeDocument.findReplace.find(g_sSeeAlsoFH1)) {
                  if (!UltraEdit.activeDocument.findReplace.find(g_sSeeAlsoFH2)) {
                     // Neither block found in Family Historian file -- report error, close file and finish.
                     ReportError("FH individual 'See also' text not found: " + sFileNumber,"ProcessIndividualFile");
                     UltraEdit.closeFile(UltraEdit.activeDocument.path,2); // Close Family Historian file without saving.
                     return;
                  }
               }
            
               // Replace found and selected 'see also' text block in Family Historian file
               // by the minitree block copied before from GEDmill file to active clipboard.
               UltraEdit.activeDocument.paste();
            
               // Since we don't know where the cursor is in the file concerned.
               // UltraEdit.activeDocument.top();
               // Those replaces are made at end of script execution using Replace in Files.
               // UltraEdit.activeDocument.findReplace.replaceAll=true;
               // UltraEdit.activeDocument.findReplace.replace("indiI(\\d+\\.html)","ind\\1");
               // UltraEdit.activeDocument.findReplace.regExp=false;
               // UltraEdit.activeDocument.findReplace.replace(sLyteBox_Head_css,sMagicZP_Head_css);
               // UltraEdit.activeDocument.findReplace.replace(sLyteBox_Head_js,sMagicZP_Head_js);
               // UltraEdit.activeDocument.findReplace.replace(sLyteBox_Class,sMagicZP_Class);
               // UltraEdit.activeDocument.findReplace.replaceAll=false;
               // UltraEdit.activeDocument.findReplace.replace(sHomeLink,"");
            
               // Close and save modified Family Historian file.
               UltraEdit.closeFile(UltraEdit.activeDocument.path,1);
            
               // Now copy the tree file.
               sFileNameGE = g_sDirectoryGE + "treeI" + sFileNumber + g_sTreeFileExt;
               sFileNameFH = g_sDirectoryFH + "treeI" + sFileNumber + g_sTreeFileExt;
               UltraEdit.open(sFileNameGE);
               UltraEdit.saveAs(sFileNameFH);
               UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
            }
            
            // Main script below here.
            
            UltraEdit.outputWindow.clear(); // Clear the output window.
            if (UltraEdit.document.length > 0) {
               // First check that there are no open files to confuse the script,
               // which depends on the order in which various files are opened.
               ReportError("Please close open files before trying again","MainScript");
            }
            else {
            
               UltraEdit.insertMode();
               if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
               else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
               UltraEdit.perlReOn();
            
               if (GetListOfFiles(0,g_sDirectoryGE,"indiI*.html",false)) {
            
                  // Get the list of GEDmill file names into an array.
                  UltraEdit.activeDocument.selectAll();
                  var asFileNames = UltraEdit.activeDocument.selection.split("\r\n");
                  // Close the list file without saving.
                  UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
            
                  UltraEdit.selectClipboard(1);
                  for (var nFile = 0; nFile < asFileNames.length; ++nFile) {
                     ProcessIndividualFile(asFileNames[nFile]);
                  }
            
                  // Backup error report in output window.
                  UltraEdit.clearClipboard();
                  UltraEdit.outputWindow.copy();
            
                  UltraEdit.frInFiles.filesToSearch=0;
                  UltraEdit.frInFiles.directoryStart=g_sDirectoryFH;
                  UltraEdit.frInFiles.searchInFilesTypes="*.html";
                  UltraEdit.frInFiles.ignoreHiddenSubs=true;
                  UltraEdit.frInFiles.searchSubs=false;
                  UltraEdit.frInFiles.logChanges=true;
                  UltraEdit.frInFiles.matchCase=false;
                  UltraEdit.frInFiles.matchWord=false;
                  UltraEdit.frInFiles.preserveCase=false;
                  UltraEdit.frInFiles.useEncoding=false;
                  UltraEdit.frInFiles.regExp=false;
                  // Remove home link in all Family Historian HTML files.
                  UltraEdit.frInFiles.replace(sHomeLink,"");
                  // Change all references to Lytebox to use Magiczoomplus instead.
                  UltraEdit.frInFiles.replace(sLyteBox_Head_css,sMagicZP_Head_css);
                  UltraEdit.frInFiles.replace(sLyteBox_Head_js,sMagicZP_Head_js);
                  UltraEdit.frInFiles.replace(sLyteBox_Class,sMagicZP_Class);
                  UltraEdit.frInFiles.regExp=true;
                  // Fix the links originating from GEDmill files to point to their Family Historian equivalents.
                  UltraEdit.frInFiles.replace("indiI(\\d+\\.html)","ind\\1");
            
                  // Results of those replace in files are not of interest.
                  UltraEdit.outputWindow.clear();
            
                  // Restore error report in output window.
                  if(UltraEdit.clipboardContent.length) {
                     UltraEdit.outputWindow.write(UltraEdit.clipboardContent);
                  }
                  UltraEdit.clearClipboard();
                  UltraEdit.selectClipboard(0);
               }
               else {
                  ReportError("No GEDmill files. Terminating.","ProcessFamilyTree");
               }
            }
            
            Function GetListOfFiles must be still included in this script. The functions FindSelectOuter and FindSelectInner were replaced by Perl regular expression finds.

            All GEDmill and Family Historian HTML files with a number are still opened for copying the block via user clipboard 1 and error handling/reporting. All other replaces are made at beginning using Replace in Files without any error checking/reporting.

            In general it should be made sure that for each GEDmill HTML file there is the corresponding Family Historian HTML file and GEDmill tree file as this is not verified by the script, i.e. no error check on failed file open. But nothing bad happened than showing an error message prompt for each missing file for confirmation by user. No crash of UltraEdit because of executing commands on active document with no document open.

            This error case is different to before because in your script there was always an active document - the unnamed file with the list of GEDmill file names. Now the list of file names is loaded to memory for faster processing and the list file is immediately closed without saving. This changed behavior on list file helps in case of opening a file fails because no file open in this case and so all commands working with a file are ignored.

            Please let me no if you have questions. It is important that you understand the code here for future updates.

            One more note:

            Take a look on description of String.prototype.match(). It is important to know that this function returns an array of strings or null. You used the result of match assigned to variable ind like a string object although it was an array object. Without testing I think JavaScript corrected this for you and used ind.join("") where you used ind in string concatenation. By luck there was always exactly 1 number in each file name with path. Now you know why I'm using a prefix on each variable name to know of what type this variable is. For example asFileNames is an array of strings with each containing a file name.

            My last hint: See Cannot create/open new file - solution with a description how to cleanup the folder for temporary files. It could be that your temporary files folder contains already lots of files and subdirectories.
            Best regards from an UC/UE/UES for Windows user from Austria

            5

              Feb 15, 2015#6

              Thank you -- it's very instructive to see how a master codes that script. :D

              It's certainly faster than it was before but unfortunately :( it's still crashing UltraEdit, so I shall continue looking at the technique to process the files in batches (tracked via one of the UltraEdit clipboards). Unless you have another suggestion?

              I shall also move this code to the end of the script (as it isn't needed until the minitrees have been pasted into the fh files), or modify the text of each minitree before it's pasted.

              Code: Select all

                     		
              // Fix the links originating from GEDmill files to point to their Family Historian equivalents.
                     		UltraEdit.frInFiles.regExp=true;
                     		UltraEdit.frInFiles.replace("indiI(\\d+\\.html)","ind\\1");
                     		UltraEdit.frInFiles.regExp=false;
              

              6,675585
              Grand MasterGrand Master
              6,675585

                Feb 16, 2015#7

                There is still a serious problem although no selection is loaded anymore into memory except the list of file names. That is very interesting and completely unexpected. It should be really analyzed why there is a crash.

                By the way: What exactly crash? Does the script stop execution or does UltraEdit really terminate unexpected and UltraEdit respectively Windows offers to create a crash report? What does the crash report contain? A crash of UltraEdit is recorded in Application event list of Windows which can be viewed by running event viewer via Windows start menu.

                In case of a crash of UltraEdit it would be best to pack the script and the 2 directories into a RAR or ZIP file and send it to IDM support by email for further investigation by the developers of IDM. I'm sure that the script is now well coded. Therefore UltraEdit should not crash at all and if it does it nevertheless, there is most likely a bug in code of UltraEdit resulting in the crash.

                I changed the script in my previous post according to requirement of updating links after copying the data from GEDmill to FH files.
                Best regards from an UC/UE/UES for Windows user from Austria

                5

                  Feb 16, 2015#8

                  UltraEdit terminates unexpectedly and Windows creates a crash report. I'll package it all up and send it to support.

                  Updated to add: IDM can reproduce this, so now I wait for a fix.... and code the batching workaround.

                    Feb 18, 2015#9

                    Alas, batching the files up doesn't help. I'll just have to wait for a fix.