ActiveState Community

Search and Replace

Posted by ric_m on 2009-06-24 05:48

Hi,
I am having real trouble getting S&R to work.

For simple strings with known literals, it's quite easy as in:

Find_ReplaceAllInMacro(window, 0, '1 NOTE \\r\\n2 _ASID 2\\r\\n', '', true, 2, 0, false, false);

This removes all instances of
1 NOTE
2 _ASID
and removes the final EOL

I want to remove something like the following where the order of literals in indeterminate:

1 _FLGS
2 __LIVING Living

as well as

1 _FLGS
2 __1881_CENSUS 1881 Census
2 __1881_CENSUS_E 1881 Census Extract

The only certain delimiter is that on the line following every replacement is the string
1 CHAN

e.g.:
1 _FLGS
2 __DEATH_INDEX Death Index
2 __BIRTH_INDEX Birth Index
2 __MARRIAGE_INDE Marriage Index
2 __1881_CENSUS_E 1881 Census Extract
1 CHAN

Can anyone suggest the syntax to use to remove all instances of these lines including the first "1 _FLGS and up to, but not including the first instance of "1 CHAN"?

Many thanks,
Ric

toddw | Wed, 2009-06-24 11:25

Whilst it may be possible to use search and replace (using a regex) to match what you want, you'll most likely find it much easier to use a Komodo macro to do this work... here is a start JavaScript macro that can be tweaked to do what you want:

// Get the selected text, else the whole document text.
var text = komodo.editor.selText;
if (!text) {
    text = komodo.editor.text;
    komodo.editor.selectAll();
}

// Parse the text.
var result_lines = [];
var lines = text.split("\n");
var removing_lines = false;
var start_line_value = komodo.interpolate("%(ask:Start line:)");
var start_line_depth = parseInt(start_line_value);

for (var i=0; i < lines.length; i++) {
    var line = lines[i];
    if (!removing_lines) {
        if (line == start_line_value) {
            removing_lines = true;
        } else {
            result_lines.push(line);
        }
    } else {
        var match = line.match(/^(\d+)\s+/);
        if (match && parseInt(match[1]) <= start_line_depth) {
            removing_lines = false;
            result_lines.push(line);
        }
    }
}

// Replace the text in the editor.
var result_text = result_lines.join("\n");
if (text != result_text) {
    komodo.editor.replaceSel(result_text);
}

// Get the selected text, else the whole document text.
var text = komodo.editor.selText;
if (!text) {
    text = komodo.editor.text;
    komodo.editor.selectAll();
}

// Parse the text.
var result_lines = [];
var lines = text.split("\n");
var removing_lines = false;
var start_line_value = komodo.interpolate("%(ask:Start line:)");
var start_line_depth = parseInt(start_line_value);

for (var i=0; i < lines.length; i++) {
    var line = lines[i];
    if (!removing_lines) {
        if (line == start_line_value) {
            removing_lines = true;
        } else {
            result_lines.push(line);
        }
    } else {
        var match = line.match(/^(\d+)\s+/);
        if (match && parseInt(match[1]) <= start_line_depth) {
            removing_lines = false;
            result_lines.push(line);
        }
    }
}

// Replace the text in the editor.
var result_text = result_lines.join("\n");
if (text != result_text) {
    komodo.editor.replaceSel(result_text);
}

Cheers,
Todd

ric_m | Wed, 2009-06-24 12:27

Hi Todd,

This looks impressive but my abilities are just not up to this. I have no idea how to use this script nor how to pass parameters for each search and replace. So far my macro contains:

Find_ReplaceAllInMacro(window, 0, '1 _FILE Media\\', '1 FILE media/', true, 0, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '1 NOTE \\r\\n2 _ASID 1\\r\\n', '', true, 2, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '1 NOTE \\r\\n2 _ASID 2\\r\\n', '', true, 2, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '2 _ASID 1\\r\\n', '', true, 2, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '2 _ASID 2\\r\\n', '', true, 2, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '1 _TYPE', '1 TYPE', true, 0, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '1 _FAMS', '1 FAMS', true, 0, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '1 _WIFE', '1 HUSB', true, 0, 0, false, false);
Find_ReplaceAllInMacro(window, 0, '1 _HUSB', '1 WIFE', true, 0, 0, false, false);

I can cope with this level of complexity quite easily. The macro is missing only the more complex S&R for which I am asking for guidance. I am happy to have a go at your script but can you point where to start and we'll take it step by step?

Thanks

Ric

toddw | Wed, 2009-06-24 12:48

Macros are simply JavaScript or Python code that can be executed in the scope of the Komodo application. The API is documented here:
http://docs.activestate.com/komodo/5.1/macroapi.html

The above macro (which I've just updated) is simple JavaScript code that grabs the text, looks for a specific line of text (input from the user - say "1 _FILE Media") and then removes all lines up to (but not including) the line where the index value is less than or equal to the starting value ( <= "1" in this case).

So to use this macro, you would save it into your Komodo toolbox (call it "search_replace" or whatever), then open your file you'd like to run the search and replace upon, double-click the macro, enter the first line of text of the section you'd like to remove and it should then remove that section of the text.

Cheers,
Todd