<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[newbee, macros and basic algorithm with Python Script]]></title><description><![CDATA[<p dir="auto">Hello</p>
<p dir="auto">I’m sorry for my bad english.</p>
<p dir="auto">I used to use perso Notepad++ macros : I just record what I do using keyboard, keyboard shortcuts and the mouse only to clic on ‘close (cross) button’ of find window. It often helps me to save a lot of time in order to modify semi automatically a lot of files ‘song.ini’ (arround 5000).</p>
<p dir="auto">Unfortunatly, I’m stuck on the impossibility of using basing conditional tests. I understood that PythonScript plugin in Notepad++ allow this conditionnal tests (and far more).<br />
I never used Python and it would take me a lot of time to code my basic algorithm. For a regular, this will probably only take an hour or less.</p>
<p dir="auto">I wrote my basic algorithm (Algorithme rename.txt) and I hope somebody could code it entirely or help me for the Python part. I have already record a macro (Algorithme rename shortcuts.xml) which is likely what I want without conditionnal tests. I have also two example files (exemple1 song.ini and exemple2 song.ini).</p>
<p dir="auto">Regards</p>
<p dir="auto">Algorithme rename :</p>
<pre><code>One tab open in notepad++ : 'buffer.txt'
Desactivate 'back line auto' in 'display'
Desactivate numeric keypad
Open a second tab : 'song.ini'


Start macro

'ctrl' + 'f'; ### open 'find window'
'n' 'a' 'm' 'e' ' ' '=' 'enter'; ### find("name =")

If (find("name =") == true) :
	clic on 'close (cross) button'; ### close find window
	'end' ### go to line's end with key '1' of numeric keypad 
	'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
	'shift' + 'left arrow'; ### ... and select the precedent line break
	'ctrl' + 'x'; ### cut selection
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'ctrl' + 'v'; ### paste selection
	'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
Else :
	clic on 'close (cross) button'; ### close find window
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'enter' 'n' 'a' 'm' 'e' ' ' '=' ' '; ### create a newline and write "name = "
	'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad


'ctrl' + 'f'; ### open 'find window'
'a' 'r' 't' 'i' 's' 't' ' ' '=' 'enter'; ### find("artist =")

If (find("artist =") == true) :
	clic on 'close (cross) button'; ### close find window
	'end' ### go to line's end with key '1' of numeric keypad 
	'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
	'shift' + 'left arrow'; ### ... and select the precedent line break
	'ctrl' + 'x'; ### cut selection
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'ctrl' + 'v'; ### paste selection
	'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
Else :
	clic on 'close (cross) button'; ### close find window
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'enter' 'a' 'r' 't' 'i' 's' 't' ' ' '=' ' '; ### create a newline and write "artist = " 
	'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad


'ctrl' + 'f'; ### open 'find window'
'a' 'l' 'b' 'u' 'm' ' ' '=' 'enter'; ### find("album =")

If (find("album =") == true) :
	clic on 'close (cross) button'; ### close find window
	'end' ### go to line's end with key '1' of numeric keypad 
	'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
	'shift' + 'left arrow'; ### ... and select the precedent line break
	'ctrl' + 'x'; ### cut selection
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'ctrl' + 'v'; ### paste selection
	'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
Else :
	clic on 'close (cross) button'; ### close find window
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'enter' 'a' 'l' 'b' 'u' 'm' ' ' '='  ' '; ### create a newline and write "album = " 
	'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad

### Do the same routine for 'genre = ', 'year = ', 'track = ', 'loading_phrase = ', 'charter = ', 'frets = '
### And the last

'ctrl' + 'f'; ### open 'find window'
's' 'o' 'n' 'g' '_' 'l' 'e' 'n' 'g' 't' 'h' ' ' '=' 'enter'; ### find("song_length =")

If (find("song_length =") == true) :
	clic on 'close (cross) button'; ### close find window
	'end' ### go to line's end with key '1' of numeric keypad 
	'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
	'shift' + 'left arrow'; ### ... and select the precedent line break
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'ctrl' + 'v'; ### paste selection
Else :
	clic on 'close (cross) button'; ### close find window
	'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
	'enter' 's' 'o' 'n' 'g' '_' 'l' 'e' 'n' 'g' 't' 'h' ' ' '='  ' '; ### create a newline and write "song_length = "

'ctrl' + 'a'; ### select all the lines
'left arrow'; ### go to start of 'buffer.txt'
'delete'; ### delete the empty first line
'ctrl' + 'a'; ### select all the lines
'ctrl' + 'x'; ### cut selection
'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
'ctrl' + 'a'; ### select all the lines
'left arrow'; ### go to start of 'song.ini'
'end' ### go to first line's end with key '1' of numeric keypad
'enter'; ### create a newline
'ctrl' + 'v'; ### paste selection with key '3' of numeric keypad
'ctrl' + 'a'; ### select all the lines
'left arrow'; ### go to start of 'song.ini'

End macro
</code></pre>
]]></description><link>https://community.notepad-plus-plus.org/topic/22412/newbee-macros-and-basic-algorithm-with-python-script</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Jul 2026 18:10:57 GMT</lastBuildDate><atom:link href="https://community.notepad-plus-plus.org/topic/22412.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 21 Jan 2022 20:59:44 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 21:11:13 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: alan-kilborn">@<bdi>alan-kilborn</bdi></a> I’m sorry again. I try to do my best…<br />
Your formulation is perfect.<br />
Just a detail, ‘icon =’ is not important for me. So :<br />
<strong>For any other lines, leave them as they are after the ‘song_length =’ line in the output.</strong></p>
]]></description><link>https://community.notepad-plus-plus.org/post/73302</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73302</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Tue, 25 Jan 2022 21:11:13 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 21:04:28 GMT]]></title><description><![CDATA[<p dir="auto">See how long a discussion thread can go on when the problem statement is imprecise?  I don’t know that it really is precise yet.  Here’s how I see the problem:</p>
<p dir="auto">If lines starting with these items are present, move them to the top, and put them in this exact order:</p>
<pre><code>name =
artist =
album =
genre =
year =
track =
loading_phrase =
charter =
frets =
song_length =
icon =
</code></pre>
<p dir="auto">If they are not present, make them present but be empty, e.g. <code>frets =</code> and then nothing following.</p>
<p dir="auto">For any other lines, leave them as they are after the <code>icon = </code> line in the output.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73301</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73301</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Tue, 25 Jan 2022 21:04:28 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 21:04:22 GMT]]></title><description><![CDATA[<p dir="auto">Otherwise, I’m extremely grateful to <a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a> who gave me the solution “clé en main” (ready to use). I have understood it thanks to his explanations. I have implemented both Notepad++ Python Script and Standalone recursive Python Script : both work perfectly.<br />
I might even consider changing more elements very easily (thanks to list ‘presets’), and, amazing, modify the 5000 files without open them in Notepad++ (a lot of time saving). That’s a lot more than I expected.</p>
<p dir="auto"><strong>BIG THANKS to <a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a> and other for contributions.</strong></p>
<p dir="auto">I share with you the two scripts in final version.<br />
The Notepad++ Python Script :</p>
<pre><code># coding: utf8
# -*- coding: utf-8 -*-
# Here is PythonScript to replace the text in the current editor pane.

def ini_reindex():

    # Get text from the editor pane.
    text = editor.getText()

    if text == '':
        return ''

    # Presets ordered as the top-most keys.
    presets = ['name', 'artist', 'album', 'genre', 'year', 'track',
               'loading_phrase', 'charter', 'frets', 'song_length']

    # Create a list of indexed lines.
    lines = &lsqb;&lsqb;-1, line.replace('\n', '')] for line in text.splitlines()]
	# Creates a list of lists like &lsqb;&lsqb;-1, 'Line 1'], [-1, 'Line 2'], [-1, 'Line 3'], ...]
	# The -1 will be replaced with numbers to order the lines later for sorting.

    # Add preset keys if not found.
    for item in presets:
        for line in lines:
            if line[1].startswith(item + ' = '):
			# item is each of presets list of ['name', 'artist', 'album', 'genre', 'year', 'track', 'loading_phrase', 'charter', 'frets', 'song_length']
			# So 1st one it trys to match is start with name = . Then tries artist = … until all items are tried. If break does not occur, then the else happens and the item key is added to the list.
                break
        else:
            lines.append([-1, item + ' = '])
			# lines is a list and .append is a method to add to the list.
			# If the else ocurrs for not finding example 'name = ', then [-1, 'name = '] is added to the list.

    # Index the preset keys.
    index = 0

    for item in presets:
        for line in lines:
            if line[0] == -1:
			# This is lines with a -1 index, not given a line number yet. If starts with [ (section header) or item + ' = ' assign a line number to line[0], which is replace the -1 with a line number. index is the line number so index += 1 increments the number by adding 1.
                if line[1].startswith('[') or line[1].startswith(item + ' = '):
                    line[0] = index
                    index += 1

    # Index the remaining keys.
    for line in lines:
        if line[0] == -1:
            line[0] = index
            index += 1

    # Sort by index.
    # Sorting the list of lists lines by the first element [0]. lambda is like a nameless function. The sort will look at example &lsqb;&lsqb;2, 'Line 2'], [1, 'Line 1'&rsqb;&rsqb; so it sees the 1 and shifts it into 1st place and then 2 for 2nd place. This gets the list into the order that is wanted.
    lines.sort(key=lambda x: x[0])

    # Create text from lines.
    text = ''

    for line in lines:
        text += line[1] + '\n'

    return text

# __name__ is the name of the running script. If named __main__, run the following code.
# ini_reindex() is the function call and the returned value is saved in text. If the text returned is not an empty string, then call editor.setText(text) to replace edit pane contents with the value of text.
if __name__ == '__main__':
    text = ini_reindex()

    if text != '':
        editor.setText(text)
</code></pre>
<p dir="auto">And the Standalone recursive Python Script :</p>
<pre><code>import glob

# Presets ordered as the top-most keys.
presets = ['name', 'artist', 'album', 'genre', 'year', 'track',
           'loading_phrase', 'charter', 'frets', 'song_length']

# Start processing each 'song.ini' file.
print('file:')

# for file in glob.iglob('song.ini'): # This will do 'song.ini' in current directorie.
for file in glob.iglob(r'**\song.ini', recursive=True): # This will do 'song.ini' in current and subdirectories.
    print(' ', file)

    # Read the 'song.ini' file and create a list of indexed lines.
    with open(file, 'r', encoding='utf8') as r:
        lines = &lsqb;&lsqb;-1, line.replace('\n', '')] for line in r]

    # Add preset keys if not found.
    for item in presets:
        for line in lines:
            if line[1].startswith(item + ' = '):
                break
        else:
            lines.append([-1, item + ' = '])

    # Index the preset keys.
    index = 0

    for item in presets:
        for line in lines:
            if line[0] == -1:
                if line[1].startswith('[') or line[1].startswith(item + ' = '):
                    line[0] = index
                    index += 1

    # Index the remaining keys.
    for line in lines:
        if line[0] == -1:
            line[0] = index
            index += 1

    # Sort by index.
    lines.sort(key=lambda x: x[0])

    # Save 'song.ini' file.
    with open(file, 'w', encoding='utf8') as w:
        for line in lines:
            w.write(line[1] + '\n')

print('done')
</code></pre>
]]></description><link>https://community.notepad-plus-plus.org/post/73300</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73300</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Tue, 25 Jan 2022 21:04:22 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 20:47:44 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/paul-wormer" aria-label="Profile: paul-wormer">@<bdi>paul-wormer</bdi></a> It’s true, I have not been very clear.<br />
I had just proposed two very different examples. I were thinking that was enough to illustrate it.<br />
In my 5000 ‘song.ini’, there is all the configurations. That’s why I want to organize that.<br />
I’m sorry for this imprecision which makes you contribute out of the subject.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73299</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73299</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Tue, 25 Jan 2022 20:47:44 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 16:46:16 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: alan-kilborn">@<bdi>alan-kilborn</bdi></a><br />
The OP wasn’t very clear about what he wanted exactly, but I assumed  that he wanted a definite order  for <em>all</em>  keywords appearing in a certain file. If he wanted to distinguish two kinds of keywords - those with a well-defined order and a those  with no order  (except perhaps that they come after the ordered ones) - he should have stated this  explicitly.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73291</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73291</guid><dc:creator><![CDATA[Paul Wormer]]></dc:creator><pubDate>Tue, 25 Jan 2022 16:46:16 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 14:24:33 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/paul-wormer" aria-label="Profile: paul-wormer">@<bdi>paul-wormer</bdi></a> said in <a href="/post/73271">newbee, macros and basic algorithm with Python Script</a>:</p>
<blockquote>
<p dir="auto">If you want any script to work you have to define a fixed set of keywords  that appear in each and every one  of your files</p>
</blockquote>
<p dir="auto">I don’t know that this is true.  A keyword could belong to the set of undefined keywords, it just couldn’t be specially manipulated (reordered into the top grouping the OP seems to want for some keywords).  It could certainly “tag along” in the reformatting effort (although apparently not in the script you wrote).</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73287</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73287</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Tue, 25 Jan 2022 14:24:33 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Tue, 25 Jan 2022 09:12:56 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mathias-lujan" aria-label="Profile: mathias-lujan">@<bdi>mathias-lujan</bdi></a><br />
I tested my little script on your first example and it worked exactly the way you wanted. Today I tested the script on your second example and it works fine again, except that it fails on many undefined items (keywords).</p>
<p dir="auto">If you want <em>any</em> script to work you have to <strong>define a fixed set of keywords  that appear in each and every one  of your files</strong>. The fact that the sets of keywords change between your files makes me wonder how much coding experience you have. Any programmer understands that  automatizing your editing is impossible  when the keywords vary between files. When you have to introduce a separate set of keywords for every file, you may as well do the editing by hand.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73271</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73271</guid><dc:creator><![CDATA[Paul Wormer]]></dc:creator><pubDate>Tue, 25 Jan 2022 09:12:56 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Mon, 24 Jan 2022 15:21:38 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/paul-wormer" aria-label="Profile: paul-wormer">@<bdi>paul-wormer</bdi></a><br />
Bug: add the line</p>
<pre><code>lenFile  = editor.getLength()
</code></pre>
<p dir="auto">as first line to the function <code>moveLine</code> (it is the default of <code>findText</code>, which is why I did not see it)</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73238</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73238</guid><dc:creator><![CDATA[Paul Wormer]]></dc:creator><pubDate>Mon, 24 Jan 2022 15:21:38 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Mon, 24 Jan 2022 15:06:32 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mathias-lujan" aria-label="Profile: mathias-lujan">@<bdi>mathias-lujan</bdi></a><br />
Maybe this is mustard after the meal as we say in Dutch, but here is another solution to your problem:</p>
<pre><code># -*- coding: utf-8 -*-
from __future__ import print_function # Python 2.7
from Npp import *

def moveLine(stringToBeMoved, targetString):    
    try:
        startW, endW  = editor.findText(FINDOPTION.WHOLEWORD, 0, lenFile, stringToBeMoved)
    except:
        line = stringToBeMoved
        #notepad.messageBox(stringToBeMoved + ' not found')
    else: 
        lineNmbr = editor.lineFromPosition(startW)
        line = editor.getLine(lineNmbr).replace('\r\n', '')
        editor.deleteLine(lineNmbr)
    
    try:
        startW, endW  = editor.findText(FINDOPTION.WHOLEWORD, 0, lenFile,  targetString )
    except:
        notepad.messageBox(targetString + ' not found') 
        return  
    else:
        endLine = editor.getLineEndPosition(editor.lineFromPosition(endW)) 
        editor.gotoPos(endLine)
        editor.addText('\r\n'+line)
	
items = [
    '[song]',
    'name =',
    'artist =',
    'album =',
    'genre =',
    'year =',
    'track =',
    'loading_phrase =',
    'charter =',
    'frets =',
    'song_length =',
    'delay =',
    'diff_guitar =',
    'diff_bass =',
    'diff_guitar_coop =',
    'diff_rhythm =',
    'diff_vocals =',
    'diff_keys =',
    'diff_bass_real =',
    'diff_guitar_real =',
    'diff_dance =',
    'diff_bass_real_22 =',
    'diff_guitar_real_22 =',
    'diff_vocals_harm =',
    'sysex_high_hat_ctrl =',
    'multiplier_note =',
    'pro_drums =',
    'background =',
    'last_play ='
    ]
    
for i in range(0, len(items)-1): 
    stringToBeMoved = items[i+1]
    targetString = items[i]
    moveLine(stringToBeMoved, targetString)
</code></pre>
]]></description><link>https://community.notepad-plus-plus.org/post/73235</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73235</guid><dc:creator><![CDATA[Paul Wormer]]></dc:creator><pubDate>Mon, 24 Jan 2022 15:06:32 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 22:19:38 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mathias-lujan" aria-label="Profile: mathias-lujan">@<bdi>mathias-lujan</bdi></a> said in <a href="/post/73142">newbee, macros and basic algorithm with Python Script</a>:</p>
<blockquote>
<p dir="auto">I never used Python and it would take me a lot of time to code my basic algorithm. For a regular, this will probably only take an hour or less.<br />
I wrote my basic algorithm (Algorithme rename.txt) and I hope somebody could code it entirely or help me for the Python part.</p>
</blockquote>
<p dir="auto">When I wrote :</p>
<blockquote>
<p dir="auto">I don’t want to learn Python programming, I just want solve my problem.</p>
</blockquote>
<p dir="auto">I would say : I just want to solve my problem with basic Python programming, not to code in general.</p>
<p dir="auto">Anyway, I feel that most of the work is already done by <a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a> and I just have to implement and test his code. I will try to do that this week.<br />
Thanks again for all.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73206</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73206</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Sun, 23 Jan 2022 22:19:38 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 21:22:26 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mathias-lujan" aria-label="Profile: mathias-lujan">@<bdi>mathias-lujan</bdi></a> said in <a href="/post/73189">newbee, macros and basic algorithm with Python Script</a>:</p>
<blockquote>
<p dir="auto">I don’t want to learn Python programming, I just want solve my problem.</p>
</blockquote>
<p dir="auto">That’s fine, for you.  But this forum doesn’t take kindly to those that don’t want to learn.  It means someone else has to (choose to) do your work for you.  It also probably means that when you need changes, however small, you’ll come here, expecting more free work done on your behalf.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73197</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73197</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Sun, 23 Jan 2022 21:22:26 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 16:32:29 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: alan-kilborn">@<bdi>alan-kilborn</bdi></a> I think we are near to the solution. Let me just understand and implement it. I don’t want to learn Python programming, I just want solve my problem.</p>
<p dir="auto">As I said :<br />
" <em>I would love to find a solution with a basic macro which I can set up myself with your help. It would be easier for everybody.</em></p>
<p dir="auto"><em>I think my problem can’t be solve with REPLACE.<br />
I just have to :<br />
IF (find() == true)<br />
then MOVE a line;<br />
ELSE<br />
then CREATE a line;</em> "</p>
<p dir="auto">So, macro N++ or Python Script to solve my problem ?</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73189</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73189</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Sun, 23 Jan 2022 16:32:29 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 16:17:26 GMT]]></title><description><![CDATA[<p dir="auto">I don’t know that this is an appropriate forum for teaching someone the ins and outs of programming Python for solving a very specific problem.</p>
<p dir="auto">While I appreciate that there are some tie-ins to editor objects to get and set the active tab’s text, really this is just a straight Python programming problem.</p>
<p dir="auto">As such, since <a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a> seems interest in helping <a class="plugin-mentions-user plugin-mentions-a" href="/user/mathias-lujan" aria-label="Profile: Mathias-Lujan">@<bdi>Mathias-Lujan</bdi></a> with this, can I suggest they get together using the forum’s  direct chat feature and expand/explain the effort in that way?</p>
<p dir="auto">Use this button to do so:</p>
<p dir="auto"><img src="/assets/uploads/files/1642954632531-a44d4267-a461-4bdf-be46-569a1f7fbd0f-image.png" alt="a44d4267-a461-4bdf-be46-569a1f7fbd0f-image.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://community.notepad-plus-plus.org/post/73188</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73188</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Sun, 23 Jan 2022 16:17:26 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 16:12:26 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a> said in <a href="/post/73171">newbee, macros and basic algorithm with Python Script</a>:</p>
<blockquote>
<p dir="auto">The replaced text may have \n EOLs. If \r\n is wanted, then change this section</p>
</blockquote>
<p dir="auto">A smooth way to handle this would be, using your line of code as a basis:</p>
<pre><code>text += line[1] + ['\r\n', '\r', '\n'][editor.getEOLMode()]
</code></pre>
<p dir="auto">This will put the correct line-ending on according to the current tab’s setup.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73187</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73187</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Sun, 23 Jan 2022 16:12:26 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 14:29:49 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a> Thanks for the explanations.</p>
<p dir="auto">I think I’m disturbed by the fact that variables are not declared.  For example, I was confused between ‘line’ and ‘lines’.<br />
Moreover, what is ‘line[0]’ ? The ‘line’ number ? The first character of ‘line’ ? The first element of ‘line’ ?</p>
<p dir="auto">I’m gonna comment your original code with your explanations in order to improve readability and my comprehension too. I will work on it during this next week and I’ll reply as soon as I progress.</p>
<p dir="auto">Read you soon.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73185</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73185</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Sun, 23 Jan 2022 14:29:49 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 10:49:20 GMT]]></title><description><![CDATA[<p dir="auto">Note: The 2nd script can be made recursive with changing:</p>
<pre><code>for file in glob.iglob('*.ini'):
</code></pre>
<p dir="auto">to</p>
<pre><code>for file in glob.iglob(r'**\song.ini', recursive=True):
</code></pre>
<p dir="auto">This will do <code>song.ini</code> in current and subdirectories.</p>
<p dir="auto">Now your questions answered:</p>
<p dir="auto">3.1 -</p>
<blockquote>
<p dir="auto"><code>lines = &lsqb;&lsqb;-1, line.replace('\n', '')] for line in text.splitlines()]</code></p>
</blockquote>
<p dir="auto">Creates a list of lists like <code>&lsqb;&lsqb;-1, 'Line 1'], [-1, 'Line 2'], [-1, 'Line 3'], ...]</code></p>
<p dir="auto">The <code>-1</code> will be replaced with numbers to order the lines later for sorting.</p>
<p dir="auto">3.2 -</p>
<blockquote>
<pre><code>```line[1].startswith(item + ' = '):```
</code></pre>
</blockquote>
<p dir="auto"><code>item</code> is each of <code>presets</code> list of <code>['name', 'artist', 'album', 'genre', 'year', 'track',            'loading_phrase', 'charter', 'frets', 'song_length']</code></p>
<p dir="auto">So 1st one it trys to match is start with <code>name = </code>. Then tries <code>artist = </code> … until all items are tried. If <code>break</code> does not occur, then the <code>else</code> happens and the <code>item</code> key is added to the list.</p>
<p dir="auto">3.3 -</p>
<blockquote>
<pre><code>```lines.append([-1, item + ' = '])```
</code></pre>
</blockquote>
<p dir="auto"><code>lines</code> is a list and <code>.append</code> is a method to add to the list.</p>
<p dir="auto">Like in 3.2, if the <code>else</code> ocurrs for not finding example <code>name = </code>, then <code>[-1, 'name = ']</code> is added to the list.</p>
<p dir="auto">3.4 -</p>
<blockquote>
<pre><code>if line[0] == -1:
     if line[1].startswith('[') or line[1].startswith(item + ' = '):
          line[0] = index
          index += 1
</code></pre>
</blockquote>
<p dir="auto">This is lines with a <code>-1</code> index, not given a line number yet. If starts with <code>[</code> (section header) or <code>item + ' = '</code> assign a line number to <code>line[0]</code>, which is replace the <code>-1</code> with a line number. <code>index</code> is the line number so <code>index += 1</code> increments the number by adding <code>1</code>.</p>
<p dir="auto">3.5 -</p>
<blockquote>
<pre><code>```lines.sort(key=lambda x: x[0])```
</code></pre>
</blockquote>
<p dir="auto">Sorting the list of lists <code>lines</code> by the first element <code>[0]</code>. <code>lambda</code> is like a nameless function. The sort will look at example <code>&lsqb;&lsqb;2, 'Line 2'], [1, 'Line 1'&rsqb;&rsqb;</code> so it sees the <code>1</code> and shifts it into 1st place and then <code>2</code> for 2nd place. This gets the list into the order that is wanted.</p>
<p dir="auto">3.6 -</p>
<blockquote>
<pre><code>```if __name__ == '__main__':
       text = ini_reindex()

       if text != '':
           editor.setText(text)
```
</code></pre>
</blockquote>
<p dir="auto"><code>__name__</code> is the name of the running script. If named <code>__main__</code>, run the following code.</p>
<p dir="auto"><code>ini_reindex()</code> is the function call and the returned value is saved in <code>text</code>. If the text returned is not an empty string, then call <code>editor.setText(text)</code> to replace edit pane contents with the value of <code>text</code>.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73181</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73181</guid><dc:creator><![CDATA[mpheath]]></dc:creator><pubDate>Sun, 23 Jan 2022 10:49:20 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 10:30:40 GMT]]></title><description><![CDATA[<p dir="auto">I’m very grateful for the attention you give to my problem.<br />
I will try to precise it.</p>
<p dir="auto">1 - I have over 5000 song’s folder which contains several files (.ogg, .mid, .bpm, .ini…). In each folder, there is an unique file ‘song.ini’. I used to navigate manually in this 5000 folders : it take me a long long time but I have no alternative for now.<br />
In each folder, I open the ‘song.ini’, operate on it launching with a key shortcut a unique macro to save time on basic manipulations (ideally 1 macro or 2 or 3 if there is no way to do an unique macro due to my incapacity to implement conditional tests), check visually the modifications and IF ‘success’ {save/close (with ‘ctrl’ + ‘w’ and ‘enter’ to validate)} ELSE {close file without saving in order to re-operate it manually correctly following}.</p>
<p dir="auto">2 - I would love to find a solution with a basic macro which I can set up myself with your help. It would be easier for everybody.<br />
<em>find: (artist = .</em>?\R)(name = .<em>?\R)<br />
repl: $2$1</em></p>
<p dir="auto">Your 2 lines “open my mind”…<br />
First you make me realize I can open replace window whith ‘ctrl’ + ‘h’ (it could be useful for me in the future).<br />
Second, I discover ‘.*?\R’ and ‘$2$1’. This expressions are perhaps multiple and powerful. Where can I found information on that kind of expressions ?</p>
<p dir="auto">I think my problem can’t be solve with REPLACE.<br />
I just have to :</p>
<pre><code>IF (find() == true)
	then MOVE a line;
ELSE
	then CREATE a line;
</code></pre>
<p dir="auto">I re-wrote my algorithm to simplify it :</p>
<pre><code>
Open : 'song.ini'
Desactivate 'back line auto' in 'display'
Desactivate numeric keypad


Start macro

# move "name ="
If (find("name =") == true) :
	cut ("name =" line with precedent line break) and paste it after ("[song]" line);
Else :
	create a line after ("[song]" line) and write "name = ";

# move "artist ="
If (find("artist =") == true) :
	cut ("artist =" line with precedent line break) and paste it after ("name =" line);
Else :
	create a line after ("name =" line) and write "artist = ";

# move "album ="
If (find("album =") == true) :
	cut ("album =" line with precedent line break) and paste it after ("artist =" line);
Else :
	create a line after ("artist =" line) and write "album = ";


# Do the same routine to move "genre = ", "year = ", "track = ", "loading_phrase = ", "charter = ", "frets = "
# And the last

# move "song_length ="
If (find("song_length =") == true) :
	cut ("song_length =" line with precedent line break) and paste it after ("frets =" line);
Else :
	create a line after ("frets =" line) and write "song_length = ";

# move cursor to the first line to make easier the visual check before close/save or close/non-save
'ctrl' + 'a'; # select all the lines
'left arrow'; # move cursor to the start of 'song.ini'

End macro

</code></pre>
<p dir="auto">Any proposition ?</p>
<p dir="auto">3 - Looking at <a class="plugin-mentions-user plugin-mentions-a" href="/user/mpheath" aria-label="Profile: mpheath">@<bdi>mpheath</bdi></a>’s proposition (which inevitably go away of my algorithm). The second proposition without open editor is not “satisfying” me because I can’t check after modifications and cancel them if necessary. Concerning the first proposition (which is surely the way I have to go), I hope you could take mention of my problem’s details upper to amend this code in consequences.<br />
Otherwise, could you explain more the sense of this lines :<br />
3.1 -</p>
<pre><code>lines = &lsqb;&lsqb;-1, line.replace('\n', '')] for line in text.splitlines()]
</code></pre>
<p dir="auto">3.2 -</p>
<pre><code>line[1].startswith(item + ' = '):
</code></pre>
<p dir="auto">3.3 -</p>
<pre><code>lines.append([-1, item + ' = '])
</code></pre>
<p dir="auto">3.4 -</p>
<pre><code>if line[0] == -1:
                if line[1].startswith('[') or line[1].startswith(item + ' = '):
                    line[0] = index
                    index += 1
</code></pre>
<p dir="auto">3.5 -</p>
<pre><code>lines.sort(key=lambda x: x[0])
</code></pre>
<p dir="auto">3.6 -</p>
<pre><code>if __name__ == '__main__':
    text = ini_reindex()

    if text != '':
        editor.setText(text)
</code></pre>
<p dir="auto">Best regards and thanks a lot.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73179</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73179</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Sun, 23 Jan 2022 10:30:40 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 10:26:54 GMT]]></title><description><![CDATA[<p dir="auto">I’m sorry.<br />
I really have problems with posting and editing in this forum : bots are thinking I produce spam :(</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73178</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73178</guid><dc:creator><![CDATA[Mathias Lujan]]></dc:creator><pubDate>Sun, 23 Jan 2022 10:26:54 GMT</pubDate></item><item><title><![CDATA[Reply to newbee, macros and basic algorithm with Python Script on Sun, 23 Jan 2022 09:46:00 GMT]]></title><description><![CDATA[<p dir="auto">I cannot edit my last post so the correction is done here.</p>
<p dir="auto">The PythonScript I posted can read the edit pane with <code>\r\n</code> EOLs. The replaced text may have <code>\n</code> EOLs. If <code>\r\n</code> is wanted, then change this section:</p>
<pre><code>    # Create text from lines.
    text = ''

    for line in lines:
        text += line[1] + '\n'

    return text
</code></pre>
<p dir="auto">to</p>
<pre><code>    # Create text from lines.
    text = ''

    for line in lines:
        text += line[1] + '\r\n'

    return text
</code></pre>
<p dir="auto">This will not be a problem with the standalone script as Python will convert <code>\n</code> to <code>\r\n</code> on write.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/73171</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/73171</guid><dc:creator><![CDATA[mpheath]]></dc:creator><pubDate>Sun, 23 Jan 2022 09:46:00 GMT</pubDate></item></channel></rss>