• Login
Community
  • Login

Macro Complex instructions.

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
9 Posts 4 Posters 4.0k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A
    Annas Taher
    last edited by Dec 18, 2017, 11:36 PM

    Well. I don’t know how to explain it so I will give the example right away:
    I have 2 Files
    File1 is a list:
    aaa
    bbb
    ccc
    ddd
    etc…
    And File2: all X are the same value
    Blue Box xxx
    It contains grapes and xxx
    Red Box xxx
    It contains tomatoes and xxx
    Green Box xxx
    It contains oranges and xxx
    Yellow Box xxx
    It contains lemons and xxx
    etc.

    I want is so macro can take from File1 and replace the first two xxx with aaa the 2nd two xxx with bbb and so on .

    How do I do that?

    C 2 Replies Last reply Dec 19, 2017, 3:35 PM Reply Quote 0
    • P
      PeterJones
      last edited by PeterJones Dec 19, 2017, 2:44 PM Dec 19, 2017, 2:42 PM

      You could use a scripting language, like PythonScript . The general procedure would be akin to

      1. Open both File1 and File2.

      2. RClick on the File2 tab, and Move to Other View

      3. Run a PythonScript that does something like the following (not valid PythonScript… this just gives an outline in pseudocode.)

         // editor1 is the PythonScript object instance for the first (left or top) document window in NPP
         // editor2 is the instance for the second (right or bottom) document window
         for( lineNumber = 1 to editor1.getLineCount() )
             // grab the nth line from File1
             editor1.gotoLine(lineNumber)
             newValue = editor1.getCurLine()
             for ( time = 1 to 2 )
                 // look for the first occurrence of 'xxx'
                 position = editor2.findText( flags, 0, end, "xxx")      // Look in the PythonScript documentation
                 //      for Editor Object > Scintilla Methods:
                 //      I would need to study .findText() and the associated SCI_FINDTEXT more
                 //      to figure out the right values for flags, and then search thru to find
                 //      the right command for finding the end-location of editor2
                 editor2.????(position, position+3)                      // select the text from "position" to "position+3" or whatever length of "xxx" is
                 editor2.replaceSel(newValue)                            // replace the selected "xxx" with the newValue
        

      Sorry, I’m not a Python/PythonScript expert, and didn’t have much time this morning, otherwise I could have researched a bit more and tried to get valid/running code. Hopefully, this outline will spark a PythonScript guru (@Claudia-Frank , hint, hint) could turn this pseudocode into a valid PythonScript in a few minutes.

      (edit: added the for time=1 to 2 loop, because I forgot you wanted to replace two instances of each “xxx” with a given newValue)

      1 Reply Last reply Reply Quote 1
      • C
        Claudia Frank @Annas Taher
        last edited by Dec 19, 2017, 3:35 PM

        @Annas-Taher

        Thx to Peter :-), I already have the logic to follow - should be straightforward.
        When back home I will build something but in the meantime you need to install
        the python script plugin (preferable use the msi ) to make it work. And you have to use the 32bit version of notepad++
        as there is no python script plugin for 64 bit available yet.

        Cheers
        Claudia

        1 Reply Last reply Reply Quote 0
        • P
          PeterJones
          last edited by Dec 19, 2017, 3:44 PM

          Actually, it was pestering me so much I couldn’t think about anything else…

          This appears to do what @Annas-Taher described:

          # editor1 is the PythonScript object instance for the first (left or top) document window in NPP
          # editor2 is the instance for the second (right or bottom) document window
          
          for lineNumber in range(0, editor1.getLineCount() ):
              # grab the nth line from File1 (exclude newline)
              editor1.gotoLine(lineNumber)
              newValue = editor1.getCurLine().rstrip()
              console.write("editor1: #" + str(lineNumber) + " = \"" + newValue + "\"\n")
          
              editor2.documentEnd()               # go to the last position
              end2 = editor2.getCurrentPos()      # record the position
              console.write("editor2.end = " + str(end2)+"\n")
              editor2.documentStart()             # back to the beginning
              start2 = editor2.getCurrentPos()    # record the position
              console.write("editor2.start = " + str(start2)+"\n")
          
              # want to replace two "xxx" entries in File2 with each line from File1
              for time in range(1, 2):
          
                  # look for the first occurrence of 'xxx', starting at start2 and ending at end2
                  #  position is a tuple with the start and end locations of the match
                  position = editor2.findText( FINDOPTION.MATCHCASE, start2, end2, "xxx")
                  console.write("editor2: findText @ " + str(position[0]) + ":" + str(position[1]) + "\n")
          
                  # select the "xxx"
                  editor2.setSelectionStart(position[0])
                  editor2.setSelectionEnd(position[1])
          
                  # replace the selection with newValue
                  editor2.replaceSel(newValue)
          
                  # the cursor is now at the end of the replaced value, and we want to
                  start2 = editor2.getCurrentPos()
                  console.write("Start2: " + str(start2)+"\n")
          
          C 1 Reply Last reply Dec 19, 2017, 3:50 PM Reply Quote 1
          • C
            Claudia Frank @PeterJones
            last edited by Dec 19, 2017, 3:50 PM

            @PeterJones

            So you gave me a job and fired me instantly :-D
            To quote Meat Loaf: “Is this the way to treat an employee (well he said “an expensive guitar”)” :-D

            Cheers
            Claudia

            1 Reply Last reply Reply Quote 1
            • P
              PeterJones
              last edited by Dec 19, 2017, 3:53 PM

              Well, there is a bug in the code: The nested loop isn’t working, and it’s just replacing one of each, rather than two xxx with each line from File1. So whichever of us finds the Round Tuit to debug the code first will get credit for final solution. :-)

              1 Reply Last reply Reply Quote 1
              • C
                Claudia Frank @Annas Taher
                last edited by Dec 19, 2017, 4:54 PM

                @Annas-Taher
                @PeterJones

                from your description I would solve it like this

                editor1_list = editor1.getText().split()
                string_to_be_replaced = 'xxx'
                line_counter_editor2 = 0
                
                editor.beginUndoAction()
                for i in editor1_list:
                    editor2.replaceLine(line_counter_editor2, editor2.getLine(line_counter_editor2).replace(string_to_be_replaced, i).rstrip())
                    editor2.replaceLine(line_counter_editor2+1, editor2.getLine(line_counter_editor2+1).replace(string_to_be_replaced, i).rstrip())
                    line_counter_editor2 += 2
                editor.endUndoAction()
                

                If the code doesn’t explain itself, let me know.

                Cheers
                Claudia

                1 Reply Last reply Reply Quote 2
                • G
                  guy038
                  last edited by guy038 Dec 20, 2017, 9:35 PM Dec 19, 2017, 9:25 PM

                  Hello @annas-taher, and All,

                  Surely, Claudia and Peter, your Python scripts should give nice results. I just imagined … a regex S/R equivalent method :-))

                  Annas, my method, below, will work, assuming two facts :

                  • The expression xxx ends all the lines of File2

                  • The number of lines of the list, in File1, is, exactly, half the number of lines of File2


                  If so, first, merge the File1 contents, right after the File2 contents, as below, and save these contents as File3 :

                  Blue Box xxx
                  It contains grapes and xxx
                  Red Box xxx
                  It contains tomatoes and xxx
                  Green Box xxx
                  It contains oranges and xxx
                  Yellow Box xxx
                  It contains lemons and xxx
                  aaa
                  bbb
                  ccc
                  ddd
                  

                  Then, in File3, with a first regex S/R, we join two consecutive lines, ending with the xxx expression

                  SEARCH (?-s)^(.+xxx)\R(.+xxx)

                  REPLACE \1\2

                  OPTIONS Wrap Around and Regular expression checked

                  ACTION Click on the Replace All button

                  You should obtain the text, below :

                  Blue Box xxxIt contains grapes and xxx
                  Red Box xxxIt contains tomatoes and xxx
                  Green Box xxxIt contains oranges and xxx
                  Yellow Box xxxIt contains lemons and xxx
                  aaa
                  bbb
                  ccc
                  ddd
                  

                  Notes :

                  • As usual, the (?-s) modifier, ensures that the dot special character will match standard characters, only

                  • The ^ assertion represents the position beginning of line, which must be verified

                  • The two syntaxes (.+xxx) catch the contents of two consecutive lines, ending with xxx, and stored, successively, in group1 and group 2, due to each pair of parentheses

                  • The \R form represents the line-break characters between these two lines

                  • In replacement, we rewrite the contents of the two lines, \1\2, except for the line break


                  Well. now, note that after the first line, you have to cross 3 complete lines to get the aaa first line of your list

                  Therefore, we’ll use the second and last regex S/R, below :

                  SEARCH (?-s)^(.+)xxx(.+)xxx\R(?=(?:.+\R){3}(.+\R))

                  REPLACE \1\3\2\3

                  OPTIONS Wrap Around and Regular expression checked

                  ACTION Click on the Replace All button

                  => Your File3 contents should be as below :

                  Blue Box aaa
                  It contains grapes and aaa
                  Red Box bbb
                  It contains tomatoes and bbb
                  Green Box ccc
                  It contains oranges and ccc
                  Yellow Box ddd
                  It contains lemons and ddd
                  aaa
                  bbb
                  ccc
                  ddd
                  

                  Notes :

                  • This time, group 1 and group 2, (.+), contain the totality of the two consecutive lines, apart from the xxx expression

                  • So, the part ^(.+)xxx(.+)xxx\R matches each complete line, with its line-break

                  • But, ONLY IF, further on, the positive look-ahead (?=(?:.+\R){3}(.+\R)), ( where it looks for 3 complete lines, with its line-break character(s), in a non-capturing group, (?:.+\R){3}, followed with an other complete line (.+\R) ) , is verified

                  • Note that this condition is always true, but, thanks to this syntax, we can store any line of the list aaa, bbb,… as group 3

                  • In replacement, we simply, rewrite groups 1 and 2, replacing the old expression xxx by \3 which represents any value of the list aaa, bbb and so on…, with its line breaks, to get the initial form of the text


                  Finally, just get rid of the list aaa......ddd, at the end of File3 ( Ctrl + Shift + End and Del ! )

                  Of course, for n lines, between the first one and the aaa line, simply change the search regex as :

                  (?-s)^(.+?)xxx(.+?)xxx\R(?=(?:.+\R){n}(.+\R)) , with the appropriate integer n

                  Best Regards,

                  guy038

                  1 Reply Last reply Reply Quote 2
                  • P
                    PeterJones
                    last edited by Dec 19, 2017, 10:10 PM

                    For completeness, I eventually found the bug in mine: I was misusing range(start, end) – I thought it included end when iterating over the range, but it only uses the values less than end.

                    The following is my code, with the bug fixed (and some of my debug prints left in) that I think now does what was requested… though @Claudia-Frank did it much more succinctly… and the magic of @guy038 regex ability is virtually limitless. :-)

                    # editor1 is the PythonScript object instance for the first (left or top) document window in NPP
                    # editor2 is the instance for the second (right or bottom) document window
                    
                    # Python's range(start, stop) operator will keep going while the index variable is LESS THAN stop, so it will never use stop: https://docs.python.org/2/library/functions.html#range
                    for lineNumber in range(0, editor1.getLineCount() ):
                        # grab the nth line from File1 (exclude newline)
                        editor1.gotoLine(lineNumber)
                        newValue = editor1.getCurLine().rstrip()
                        console.write("editor1: #" + str(lineNumber) + " = \"" + newValue + "\"\n")
                    
                        editor2.documentEnd()               # go to the last position
                        end2 = editor2.getCurrentPos()      # record the position
                        console.write("editor2.end = " + str(end2)+"\n")
                        editor2.documentStart()             # back to the beginning
                        start2 = editor2.getCurrentPos()    # record the position
                        console.write("editor2.start = " + str(start2)+"\n")
                    
                        # want to replace two "xxx" entries in File2 with each line from File1
                        for time in range(0, 2):
                            console.write("time# " + str(time) + "!!!\n")
                    
                            # look for the first occurrence of 'xxx', starting at start2 and ending at end2
                            #  position is a tuple with the start and end locations of the match
                            position = editor2.findText( FINDOPTION.MATCHCASE, start2, end2, "xxx")
                            if position is None:
                                console.write("editor2.position is NONE, so skipping...\n")
                                break                   # don't try to replace
                    
                            console.write("editor2: findText @ " + str(position[0]) + ":" + str(position[1]) + "\n")
                    
                            # select the "xxx"
                            editor2.setSelectionStart(position[0])
                            editor2.setSelectionEnd(position[1])
                    
                            # replace the selection with newValue
                            editor2.replaceSel(newValue)
                    
                            # the cursor is now at the end of the replaced value, and we want to
                            start2 = editor2.getCurrentPos()
                            console.write("Start2: " + str(start2)+"\n")
                    
                        console.write("next source line...\n")
                    
                    1 Reply Last reply Reply Quote 1
                    1 out of 9
                    • First post
                      1/9
                      Last post
                    The Community of users of the Notepad++ text editor.
                    Powered by NodeBB | Contributors