Skip to main content
Topic: Lua as user tool script (Read 10080 times) previous topic - next topic

Lua as user tool script

At the moment, I'm learning the Lua script language. I want to experiment with writing some simple user tools, but I don't know how to access stdin, stdout and stderr.
 
Always look on the bright side of life!

Re: Lua as user tool script

Reply #1
I don't know how to access stdin, stdout and stderr.
Access to stdin is by nwcut.items, stdout is by nwcut.writeline, and stderr is by nwcut.warn.

Here is a quick example that will flip a RestChord:
Code: (Lua) [Select · Download]
nwcut.setlevel(2)

for item in nwcut.items() do
if item:Is("RestChord") then
item.Opts.Opts.Stem = item.Opts.Opts.Stem == "Up" and "Down" or "Up"
end
nwcut.writeline(item)
end

if #arg > 0 then  -- any arg sets warning mode
nwcut.warn(nwcut.clock(), " seconds")
end
More info at: http://lua.noteworthycomposer.com/
Registered user since 1996

Re: Lua as user tool script

Reply #2
Many thanks, Rick!

A few other questions :
  • What does setlevel() do?
  • How do I access the arguments?
  • Is there any documentation on nwcut available?
Always look on the bright side of life!

Re: Lua as user tool script

Reply #3
See: http://lua.noteworthycomposer.com/nwcut.html##(nwcut).setlevel

  • How do I access the arguments?
They are in a global table: arg

  • Is there any documentation on nwcut available?
See: http://lua.noteworthycomposer.com/nwcut.html
Registered user since 1996

Re: Lua as user tool script

Reply #4
Thanks again, Rick.

Now I have something to read, learn and experiment...
Always look on the bright side of life!

Re: Lua as user tool script

Reply #5
My first problems:
1) I want to write several lines on stderr, so I included a string "\r\n" (return/newline) but that has no effect
  See line 4 in:
Code: [Select · Download]
nwcut.setlevel(2)
local DynamicFound = false
for i = 1, #arg do
nwcut.warn(arg[i], "\r\n")
end -- for i
for item in nwcut.items() do
if item:Is("Dynamic") then
if arg[1] == "Absolute" then
item.Opts.Pos = arg[2]
elseif  arg[1] == 'Relative' then
item.Opts.Pos = item.Opts.Pos + arg[2]
elseif arg[1] == 'Keep_position_first_dynamic' then
local FirstPos = DynamicFound and FirstPos or item.Opts.Pos
item.Opts.Pos = FirstPos
end --if arg
end -- if item
nwcut.writeline(item)
end --for item

This is what I get in stderr:
Quote
Absolute -2

This is what I expected:
Quote
Absolute
 -2

2) How can I use the return codes as explained in http://www.noteworthysoftware.com/nwc2/help/intro_usertooldev.htm
 I want to use return code 1 in case of an error and 0 for a warning. Reason : with nwcut.warn, the user can click 'OK' or 'Cancel'. I don't want that in case of an error.

I found out : http://lua.noteworthycomposer.com/nwcut.html##(nwcut.const).rc_Error
Always look on the bright side of life!

Re: Lua as user tool script

Reply #6
My first problems:
1) I want to write several lines on stderr, so I included a string "\r\n" (return/newline) but that has no effect
Don't use "\r". Just use "\n".
Registered user since 1996


Re: Lua as user tool script

Reply #8
Two other problems:
1)
Code: [Select · Download]
local NoteLengths = { "16th" = 48, "32th" = 24, "4th" = 192, "64th" = 12, "8th" = 96, "Half" = 384, "Whole" = 768 }
gives this error:
Code: [Select · Download]
 '}' expected near '=' 

2)
Code: [Select · Download]
local function ShowVar(name, var)
if Testing then
nwcut.warn(name.." ==> ", var, "\n")
end -- if
end -- ShowVar

local line = item:__tostring()
ShowVar("line", line)
local durs = item.Opts.Dur
ShowVar("#durs",#durs)
for i = 1 , #durs do
ShowVar("dur"..i , durs[i])
end -- for

I expected 'durs' to be a string = "Half", but when I treated it as a string I got an error stating that it was a table. So I included the ShowVar() calls, with following result:
Quote
line ==> |Note|Opts:Stem=Down|Pos:1|Dur:Half
#durs ==> 0

What did I do wrong?
Always look on the bright side of life!

Re: Lua as user tool script

Reply #9
Two other problems:
1)
Code: (lua) [Select · Download]
local NoteLengths = { "16th" = 48, "32th" = 24, "4th" = 192, "64th" = 12, "8th" = 96, "Half" = 384, "Whole" = 768 }
gives this error:
Code: [Select · Download]
 '}' expected near '=' 

That code looks correct to me too, but you might want to look at the preceding or following statement. Sometimes Lua will "complain" about the wrong line.

I think you need to put [ ] around the keys in your assignment (i.e. around the "16th", etc.). Also, you probably want to change 32th to 32nd :)

2)
Code: (lua) [Select · Download]
local function ShowVar(name, var)
if Testing then
nwcut.warn(name.." ==> ", var, "\n")
end -- if
end -- ShowVar

local line = item:__tostring()
ShowVar("line", line)
local durs = item.Opts.Dur
ShowVar("#durs",#durs)
for i = 1 , #durs do
ShowVar("dur"..i , durs[i])
end -- for

I expected 'durs' to be a string = "Half", but when I treated it as a string I got an error stating that it was a table. So I included the ShowVar() calls, with following result:
What did I do wrong?

Mind you, I have not done much with nwcut, but I think your problem is that Dur is not part of the Opts segment of the nwctext. (Opts only contains the Stem=Down part.) Try changing "item.Opts.Dur" to "item.Dur".

Mike

Re: Lua as user tool script

Reply #10
I think you need to put [ ] around the keys in your assignment (i.e. around the "16th", etc.). Also, you probably want to change 32th to 32nd :)

The square brackets do the job! I also changes 32th into 32nd, thanks.

Mind you, I have not done much with nwcut, but I think your problem is that Dur is not part of the Opts segment of the nwctext. (Opts only contains the Stem=Down part.) Try changing "item.Opts.Dur" to "item.Dur".

That's not the reason. For accessing the Stem, I have to use "item.Opts.Opts.Stem".
Thanks anyway, I'm sure Rick will  come with the answer soon :)
Always look on the bright side of life!

Re: Lua as user tool script

Reply #11
Thanks anyway, I'm sure Rick will  come with the answer soon :)
setlevel(1) is a string. setlevel(2) is a table mostly of keys, i.e. a Set. The exception is Triplet which might be: 'First', '', or 'End'
Code: (nwc) [Select · Download]
!NoteWorthyComposerClip(2.0,Single)
|Note|Dur:8th,Triplet=First|Pos:0|Opts:Stem=Down
|Note|Dur:8th,Triplet|Pos:0|Opts:Stem=Down
|Note|Dur:8th,Triplet=End|Pos:0|Opts:Stem=Down
!NoteWorthyComposerClip-End
Registered user since 1996

Re: Lua as user tool script

Reply #12
I realise now I didn't show the output of my coding. Here are both the code and the output
Code: [Select · Download]
local function ShowVar(name, var)
if Testing then
nwcut.warn(name.." ==> ", var, "\n")
end -- if
end -- ShowVar
 
local line = item:__tostring()
ShowVar("line", line)
local durs = item.Opts.Dur
ShowVar("#durs",#durs)
for i = 1 , #durs do
ShowVar("dur"..i , durs[i])
end -- for
Output:
Quote
line ==> |Note|Opts:Stem=Down|Pos:1|Dur:Half
#durs ==> 0

I had setlevel(2). That's why I included to _tostring line, to show the contents of item.
The result shows that the item.Opts.Dur is nil. Why isn't it = "Half"?
Always look on the bright side of life!

Re: Lua as user tool script

Reply #13
I realise now I didn't show the output of my coding. Here are both the code and the output
Code: [Select · Download]
local function ShowVar(name, var)
if Testing then
nwcut.warn(name.." ==> ", var, "\n")
end -- if
end -- ShowVar
 
local line = item:__tostring()
ShowVar("line", line)
local durs = item.Opts.Dur
ShowVar("#durs",#durs)
for i = 1 , #durs do
ShowVar("dur"..i , durs[i])
end -- for
Output:
I had setlevel(2). That's why I included to _tostring line, to show the contents of item.
The result shows that the item.Opts.Dur is nil. Why isn't it = "Half"?

Now that I've thought about it a bit more, I think the problem is #durs. I think you would be better off iterating through the table using pairs(..) rather than a counting loop.

This article describes the issue a bit better:

http://stackoverflow.com/questions/2705793/how-to-get-number-of-entries-in-a-lua-table

Mike

Re: Lua as user tool script

Reply #14
I think you would be better off iterating through the table using pairs(..) rather than a counting loop.

Thanks Mike, pairs() does it!
Always look on the bright side of life!