It is currently September 20th, 2019, 5:33 pm

Understanding the Enigma notes LUA

Discuss the use of Lua in Script measures.
DanielPodo
Posts: 66
Joined: March 30th, 2016, 1:50 pm

Understanding the Enigma notes LUA

DanielPodo » August 3rd, 2016, 8:51 pm

So this thread is a two parter.

1st part: I've had a look at the LUA script for the notes skin in the Enigma suite as a way to understand what is going on, as I want to create my own version of that particular skin. However, I'm having a little trouble understanding what is going on. Could anyone break it down please?

Code: Select all

function Initialize()
	-- GET NOTE PATHS
	Notes = {}
	local AllPaths = SELF:GetOption('Path', '')
	for Path in AllPaths:gmatch('[^%|]+') do
		local Path = SKIN:MakePathAbsolute(Path)
		local Dir, Name, Ext = Path:match('(.-)([^\\]-)%.([^%.]+)$')
		table.insert(Notes, {
			Path = Path,
			Name = Name
			})
	end

	-- SET STARTING NOTE
	n = n or 1
end

function Update()
	local Queue = {}

	-- BUILD QUEUE
	Queue['CurrentNote'] = n
	Queue['Name']        = Notes[n].Name
	Queue['Path']        = Notes[n].Path
	
	-- READ FILE	
	local File    = io.input(Notes[n].Path)
	local Content = nil
	if File then
		Content = File:read('*all')
		File:close()
	else
		Content = 'Could not open file: '..Notes[n].Path
	end
	
	-- STRIP CONTENT DIVIDER & FORMAT LISTS
	local Divider    = SELF:GetOption('ContentDivider','')
	local Content    = Content:gsub(Divider..'.*', '')
	local Content    = Content:gsub('- ', '· ')
	Queue['Content'] = Content
		
	-- OUTPUT
	local VariablePrefix = SELF:GetOption('VariablePrefix', '')
	for k, v in pairs(Queue) do
		SKIN:Bang('!SetVariable', VariablePrefix..k, v)
	end
	
	-- FINISH ACTION   
	local FinishAction = SELF:GetOption('FinishAction', '')
	if FinishAction ~= '' then
		SKIN:Bang(FinishAction)
	end
	
	return 'Finished #'..n..' ('..Notes[n].Path..').'
end

-----------------------------------------------------------------------
-- EXTERNAL COMMANDS

function Show(a)
	n = tonumber(a)
	SKIN:Bang('!UpdateMeasure', SELF:GetName())
end

function ShowPrevious()
	n = (n == 1) and #Notes or (n - 1)
	SKIN:Bang('!UpdateMeasure', SELF:GetName())
end

function ShowNext()
	n = (n % #Notes) + 1
	SKIN:Bang('!UpdateMeasure', SELF:GetName())
end
2nd part: As mentioned, I want my own version but it would be simpler in that a) it would only have 1 tab and b) follow my styles. Looking at the notes.inc file, I don't know what the "grabber" meters are, nor the "measureActive" measures are doing.
MikeG621
Posts: 75
Joined: March 18th, 2013, 1:59 pm

Re: Understanding the Enigma notes LUA

MikeG621 » August 8th, 2016, 2:48 pm

This is one that I've torn apart and re-written for my own suite (albeit starting from a different version than what you have there), so I'll go over it in general.

First off, if you only want a single tab, then start with Notes1\Notes1.ini (or 2, or 3...) instead of Notes.ini. That's a standalone tab that does away with stuff like the Switcher, Grabbers, etc. With that in mind, I'm not going to go into the details on those mechanisms (unless you want to).

To start, the Initialize() function is grabbing the note locations from the measure and loading them into a Notes array with the directory and filename without extension. For a single-tab skin, there should only be one name.

During each Update(), it determines the CurrentNote (again, for you should be 1, the only option) and grabs the filename and directory out of Notes, storing it in a key/value array Queue (so 'CurrentNote' is '1', 'Name' will be the filename...). It uses io to read the text into Content. It does some cleanup by first getting rid of hidden text (I use "<hide>" as my Divider, so that and any file content below that doesn't show in the skin) before storing it in Queue.
Then it sets the appropriate skin variables by stepping through the contents of Queue (so a key 'k' of "Content" would have a value 'v' of whatever was in the file), which the skin meters then read to display the content.

The commands down at the bottom are for tab switching and in effect are just three different ways to change CurrentNote, which for a single tab won't get used.

The best way to work the styles into your own suite is to either just reference your stylesheet variables or the long way, which is to backtrace all of the Enigma .inc files and copy/paste the options into the .ini so it's not chasing several @includes. From there you can link it to your styles as needed.