It is currently April 24th, 2024, 8:10 pm

Using Regex to escape variables

Get help with creating, editing & fixing problems with skins
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regex to escape variables

Post by jsmorley »

Not to sidetrack this discussion, but I'm very leery of using Lua to directly read the .ini or .inc files of Rainmeter skins.

The reason is that Lua cannot read files encoded as UTF-16 Little Endian, but only ANSI or UTF-8 w/BOM. In Rainmeter, we have taken to strongly encouraging that all .ini files be encoded as UTF-16, so non-ASCII characters can be used in them, The conflict is that Rainmeter hates UTF-8, and Lua hates UTF-16.

The "New skin" functionality in Manage will always create skin files using UTF-16.

My recommendation is that Rainmeter be used to do any "reading" or "writing" to skin .ini or .inc files.

That doesn't mean you can't use Lua to parse and take action based on what is in the file, but I recommend that you use a WebParser parent measure with CodePage=1200 (Unicode) on it to "read" the file, using a RegExp like RegExp=(?siU)^(.*)$ and StringIndex=1.

Then you can get the value of that measure in Lua, and parse it to your hearts content.

To "write" back to the skin .ini or .inc file, you are really going to want to use SKIN:Bang('!WriteKeyValuie",...) so Rainmeter will do the writing, and not Lua.

As long as your skin .ini and .inc files are encoded as ANSI, and have no Unicode characters in them, then directly reading and even writing them is fine in Lua, but over time I expect this to be less and less common, and be careful, or it will bite you.
User avatar
raiguard
Posts: 660
Joined: June 25th, 2015, 7:02 pm
Location: The Sky, USA

Re: Using Regex to escape variables

Post by raiguard »

jsmorley wrote:Not to sidetrack this discussion, but I'm very leery of using Lua to directly read the .ini or .inc files of Rainmeter skins.

The reason is that Lua cannot read files encoded as UTF-16 Little Endian, but only ANSI or UTF-8 w/BOM. In Rainmeter, we have taken to strongly encouraging that all .ini files be encoded as UTF-16, so non-ASCII characters can be used in them, The conflict is that Rainmeter hates UTF-8, and Lua hates UTF-16.

The "New skin" functionality in Manage will always create skin files using UTF-16.

My recommendation is that Rainmeter be used to do any "reading" or "writing" to skin .ini or .inc files.

That doesn't mean you can't use Lua to parse and take action based on what is in the file, but I recommend that you use a WebParser parent measure with CodePage=1200 (Unicode) on it to "read" the file, using a RegExp like RegExp=(?siU)^(.*)$ and StringIndex=1.

Then you can get the value of that measure in Lua, and parse it to your hearts content.

To "write" back to the skin .ini or .inc file, you are really going to want to use SKIN:Bang('!WriteKeyValuie",...) so Rainmeter will do the writing, and not Lua.
I actually used to use WebParser for my update checker and for the gadget toggle buttons. However, I could never get it to work consistently. It would not always parse correctly and would take a few seconds to do the job. So, I switched to using ReadINI for those functions.

I also recently converted all of the files in ModernGadgets to UTF-8, to save on space and make it play nicely with GItHub. So for my specific needs, using LUA won't be an issue.
”We are pretty sure that r2922 resolves the regression in resolution caused by a reversion to a revision.” - jsmorley, 2017
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regex to escape variables

Post by jsmorley »

raiguard wrote:I actually used to use WebParser for my update checker and for the gadget toggle buttons. However, I could never get it to work consistently. It would not always parse correctly and would take a few seconds to do the job. So, I switched to using ReadINI for those functions.

I also recently converted all of the files in ModernGadgets to UTF-8, to save on space and make it play nicely with GItHub. So for my specific needs, using LUA won't be an issue.
Ok, but be aware that Rainmeter is fine with UTF-8 w/o BOM, which is exactly the same thing as ANSI, however that means you must not, cannot, use any Unicode characters in your skin. As soon as you do it won't be ANSI anymore, but UTF-8, and Rainmeter will hate it.
User avatar
smurfier
Moderator
Posts: 1931
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Using Regex to escape variables

Post by smurfier »

SilverAzide wrote:I'm no good at regex, but is there a couple missing "%" signs in this line:

tbl[section][key:lower():match('^s*(%S*)%s*$')] = command:match('^s*(.-)%s*$'):gsub('#(.-)#', '#\*%1\*#')

Is this suppose to be...?

tbl[section][key:lower():match('^[color=#FF0000]%[/color]s*(%S*)%s*$')] = command:match('^[color=#FF0000]%[/color]s*(.-)%s*$'):gsub('#(.-)#', '#\*%1\*#')
Don't know how that mistake made it past the censors.
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using Regex to escape variables

Post by jsmorley »

smurfier wrote:Don't know how that mistake made it past the censors.
Fixed...
User avatar
raiguard
Posts: 660
Joined: June 25th, 2015, 7:02 pm
Location: The Sky, USA

Re: Using Regex to escape variables

Post by raiguard »

SilverAzide wrote:I'm no good at regex, but is there a couple missing "%" signs in this line:

tbl[section][key:lower():match('^s*(%S*)%s*$')] = command:match('^s*(.-)%s*$'):gsub('#(.-)#', '#\*%1\*#')

Is this suppose to be...?

tbl[section][key:lower():match('^[color=#FF0000]%[/color]s*(%S*)%s*$')] = command:match('^[color=#FF0000]%[/color]s*(.-)%s*$'):gsub('#(.-)#', '#\*%1\*#')
This worked! Thanks a lot.
”We are pretty sure that r2922 resolves the regression in resolution caused by a reversion to a revision.” - jsmorley, 2017
User avatar
SilverAzide
Rainmeter Sage
Posts: 2604
Joined: March 23rd, 2015, 5:26 pm

Re: Using Regex to escape variables

Post by SilverAzide »

jsmorley wrote:Fixed...
I know this isn't the proper thread for this, but on the topic of ReadINI, I have a question. Very often (like, a lot) I have an entry in my Rainmeter.ini that looks like this:

Code: Select all

[]
WindowX=1860
WindowY=0
I assume I get this because I've done something naughty, like blow away a skin folder while the skin is loaded, or whatever. Anyway, the issue is that this invalid section stops ReadINI dead in its tracks. I'm not that good at Lua to see how to prevent this junk from killing the function.
Gadgets Wiki GitHub More Gadgets...
User avatar
smurfier
Moderator
Posts: 1931
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: Using Regex to escape variables

Post by smurfier »

SilverAzide wrote:I know this isn't the proper thread for this, but on the topic of ReadINI, I have a question. Very often (like, a lot) I have an entry in my Rainmeter.ini that looks like this:

Code: Select all

[]
WindowX=1860
WindowY=0
I assume I get this because I've done something naughty, like blow away a skin folder while the skin is loaded, or whatever. Anyway, the issue is that this invalid section stops ReadINI dead in its tracks. I'm not that good at Lua to see how to prevent this junk from killing the function.
I assume this would fix your issue.

Code: Select all

function ReadIni(inputfile)
	local file = assert(io.open(inputfile, 'r'), 'Unable to open ' .. inputfile)
	local tbl, num, section = {}, 0

	for line in file:lines() do
		num = num + 1
		if not line:match('^%s-;') then
			local key, command = line:match('^([^=]+)=(.+)')
			if line:match('^%s-%[.+') then
				section = line:match('^%s-%[([^%]]+)'):lower()
				if section == '' or not section then
					section = nil
					print('Empty section name found in ' .. inputfile)
				end
				if not tbl[section] then tbl[section] = {} end
			elseif key and command and section then
				tbl[section][key:lower():match('^%s*(%S*)%s*$')] = command:match('^%s*(.-)%s*$')
			elseif #line > 0 and section and not key or command then
				print(num .. ': Invalid property or value.')
			end
		end
	end

	file:close()
	if not section then print('No sections found in ' .. inputfile) end
	
	return tbl
end -- ReadIni
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
User avatar
SilverAzide
Rainmeter Sage
Posts: 2604
Joined: March 23rd, 2015, 5:26 pm

Re: Using Regex to escape variables

Post by SilverAzide »

smurfier wrote:I assume this would fix your issue.
Yes! Thank you thank you thank you! :cheers:
Gadgets Wiki GitHub More Gadgets...