Code
--[[
LuaFunctions
This script generates wikia markup for the Foldit Lua functions V2.
The input to this script is the output of the help command for each function.
The list of functions is generated by running the command:
help ()
in the Foldit client. This list can be converted into another Foldit script,
a series of commands in the form:
help ( functionname )
Each help command in this form returns two lines.
The first line contains the function return value(s), name, and parameters.
The second line contains a description of the function.
For example, the Foldit Lua command:
help ( behavior.SegClashingImportance )
returns these two lines:
void behavior.SetClashImportance(number importance)
Set the clashing importance. (Range 0.0 to 1.0)
This script converts the detailed output into wikia markup.
The markup includes HTML tags, which gives better control over
the final format. For example, the H1 tag is used to group functions
by name space.
This is a command line LUA program. The command line syntax is:
lua LuaFunctions.lua helpfile wikifile [releaseid]
helpfile is the long-form output of the help command for each function
wikifile is the output wikia markup file
releaseid is the optional foldit release id
The output of the foldit help command may contain errors, such as the line
void structure.TweakRotateinteger segmentIndex, number angle)
found in the current foldit release, which is missing the opening "(".
Consider fixing this error before running LuaFunctions.
revision history
----------------
2015/06/04 -- LociOiling -- new function
]]--
function main ()
local Recipe = "Lua Functions"
local Version = "1.0"
local ReVersion = Recipe .. " v" .. Version
--
-- history table -- list V1 versions of functions, some other infomation
--
local histtabl =
{
_print = "print",
absolutebest_Restore = "restore_abs_best",
band_AddBetweenSegments = "band_add_segment_segment",
band_Delete = "band_delete",
band_DeleteAll = "band_delete",
band_Disable = "Similar to band_disable",
band_DisableAll = "band_disable",
band_Enable = "Similar to band_enable",
band_EnableAll = "band_enable",
band_GetCount = "get_band_count",
band_SetGoalLength = "band_set_length",
band_SetStrength = "band_set_strength",
behavior_SetClashImportance = "set_behavior_clash_importance",
creditbest_Restore = "restore_credit_best",
current_GetExplorationMultiplier = "get_exploration_score",
current_GetScore = "get_ranked_score(true)",
current_GetSegmentEnergyScore = "Similar to get_segment_score",
current_GetSegmentEnergySubscore = "Similar to get_segment_score_part",
freeze_FreezeSelected = "do_freeze",
freeze_UnfreezeAll = "do_unfreeze_all",
puzzle_StartOver = "reset_puzzle",
recentbest_Restore = "restore_recent_best",
recentbest_Save = "reset_recent_best",
rotamer_GetCount = "get_sidechain_snap_count",
rotamer_SetRotamer = "do_sidechain_snap",
save_LoadSecondaryStructure = "load_structure",
save_Quickload = "quickload",
save_Quicksave = "quicksave",
save_SaveSecondaryStructure = "save_structure",
selection_Deselect = "Similar to deselect_index",
selection_DeselectAll = "deselect_all",
selection_Select = "Similar to select_index",
selection_SelectAll = "select_all",
selection_SelectRange = "select_index_range",
structure_GetAminoAcid = "Similar to get_aa",
structure_GetCount = "get_segment_count",
structure_GetDistance = "get_segment_distance",
structure_GetSecondaryStructure = "Similar to get_ss",
structure_IsHydrophobic = "Similar to is_hydrophobic",
structure_LocalWiggleSelected = "Similar to do_local_wiggle",
structure_MutateSidechainsSelected = "Similar to do_mutate",
structure_RebuildSelected = "do_local_rebuild",
structure_SetAminoAcidSelected = "replace_aa",
structure_SetSecondaryStructureSelected = "replace_ss",
structure_ShakeSidechainsSelected = "Similar to do_shake",
structure_WiggleSelected = "Similar to do_global_wiggle_all",
}
--
-- nametabl describes the foldit namespaces
--
local nametabl =
{
no_namespace = "The \"no namespace\" functions are general utilities.",
absolutebest = "The absolultebest functions work with the highest-scoring pose, regardless of whether the pose is valid. " ..
"For example, a pose with open cutpoints may have the highest score, but the score is not valid until the cutpoints are closed",
band = "The band functions create and manipulate bands.",
behavior = "The behavior functions control clashing importance and other properties found the client\'s behavior dialog and related places.",
contactmap = "The contactmap functions access contact map information in puzzles which use it.",
creditbest = "The creditbest functions work with the best valid pose, in contrast to the absolutebest functions",
current = "The current functions work with the current pose of the protein.",
dialog = "The dialog functions create the dialog boxes found in many recipes.",
freeze = "The freeze functions freeze and unfreeze the backbone or sidechains of specified segments.",
puzzle = "The puzzle functions get information about the current puzzle. They also allow the puzzle to be reset to a starting point.",
recentbest = "The recentbest functions work with the \"recent best\" pose. Unlike the absolutebest, creditbest, and current poses, the " ..
"recentbest pose can be reset under recipe control.",
recipe = "The recipe functions perform general housekeeping tasks.",
rotamer = "The rotamer functions recipes to manipulate sidechain positions, or rotamers, of a particular segment.",
save = "The save functions allow the current pose to be saved to or restored from numbered \"slots\". ",
"They can also save and restore the secondary structure (helix, sheet, and loop).",
scoreboard = "The scoreboard functions return information about how the current solution relative to other players.",
selection = "The selection functions allows segment to be selected and deselected. Many other functions only work on selected segments.",
structure = "The structure functions perform a variety of tasks related to specific segments of the puzzle." ..
"Most of these tasks can also be performed manually in the client.",
ui = "The ui functions perform miscellaneous \"user interface\" tasks.",
undo = "The undo functions control the undo stack.",
user = "The user functions return information about the logged-in user (player).",
}
--
-- NOOP function table -- lists functions that don't do anything
--
local noopfunc =
{
behavior_GetBandStrengthFactor = "Unimplemented V2 function",
behavior_SetBandStrengthFactor = "Unimplemented V2 function",
behavior_GetWiggleAccuracy = "Unimplemented V2 function",
behavior_SetWiggleAccuracy = "Unimplemented V2 function",
behavior_GetShakeAccuracy = "Unimplemented V2 function",
behavior_SetShakeAccuracy = "Unimplemented V2 function",
behavior_GetBuriedSidechainShakeAccuracy = "Unimplemented V2 function",
behavior_SetBuriedSidechainShakeAccuracy = "Unimplemented V2 function",
behavior_GetExposedSidechainShakeAccuracy = "Unimplemented V2 function",
behavior_SetExposedSidechainShakeAccuracy = "Unimplemented V2 function",
structure_TweakRotate = "Unimplemented V2 function",
structure_TweakShift = "Unimplemented V2 function",
structure_TweakStraighten = "Unimplemented V2 function",
}
--
-- variables used in scanning the input file
--
local ll = 0 -- line count
local oddLine = true
local start
local stop
local tag
local rettype
local funcname
local funcnmsp
local fname2
local rest
local tagcnt = 0
local DEBUG = false
--
-- functabl -- lists functions read from input file
--
local functabl = { { "help", "", "void", "function Func", "Prints the signature and description of Func, or signature of all Foldit functions if no argument is given.", "" } }
local FUNCNAME = 1
local FUNCNMSP = 2
local FUNCRETV = 3
local FUNCARGS = 4
local FUNCDESC = 5
local FUNCV1 = 6
print ( ReVersion )
--
-- I'd like to have an argument, please
--
if arg == nil then
print ( "LuaFunctions is a standalone Lua program " )
print ( "(not a foldit recipe)" )
return
end
if #arg < 2 then
print ( "usage: LuaFunctions helpfile wikifile \[releaseid\]" )
print ( "helpfile is the input, which is the long output of the foldit \"help\" command" )
print ( "wikifile is the output wikia markup" )
print ( "releaseid is the optional foldit release id" )
return
end
local frelease = ""
if #arg >= 3 then
frelease = arg [ 3 ]
else
frelease = "(releaseid)"
end
--
-- scan input file created by a series of calls to foldit "help" function, each with one function namespace
--
--for line in io.lines ( "K:/Documents/Foldit/LUA functions/functions.20150603a.txt" ) do
for line in io.lines ( arg [ 1 ] ) do
ll = ll + 1
--
-- ignore simple XML tags in foldit scriptlog format
--
start, stop, tag = line:find ( "(<*>)" ) -- not 100% but close enough
if tag ~= nil then
if DEBUG then
print ( "XML tag = " .. line )
end
tagcnt = tagcnt + 1
elseif oddLine then
if DEBUG then
print ( "line " .. ll .. " = \"" .. line .. "\"" )
end
--
-- peel off the return values
--
start, stop, rettype, rest = line:find ( "(%l*)% (.*)" )
if DEBUG then
print ( "return type = " .. rettype .. ", rest = \"" .. rest .. "\"" )
end
--
-- get the function name, including the name space if present
--
start, stop, funcname, rest = rest:find ( "(.*)%((.*)%)" )
if rest == nil then rest = "" end
if funcname == nil then
print ( "ERROR: invalid syntax in line " .. ll .. ", \"" .. line .. "\"" )
start, stop, rettype, funcname = line:find ( "(%l*)% (.*)" )
end
if DEBUG then
print ( "function name = " .. funcname .. ", rest = \"" .. rest .. "\"" )
end
--
-- get the name space
--
start, stop, funcaddr, fname2 = funcname:find ( "(.*)%.(.*)" )
if funcaddr == nil then
funcaddr = ""
else
funcname = fname2
if DEBUG then
print ( "name space = " .. funcaddr .. ", function name = " .. funcname )
end
end
--
-- create the key for the history table lookup
--
local funckey = ""
if funcaddr ~= "" then
funckey = funcaddr
end
funckey = funckey .. "_" .. funcname
local histname = histtabl [ funckey ]
if histname == nil then
histname = "New to V2"
end
functabl [ #functabl + 1 ] = { funcname, funcaddr, rettype, rest, "", histname }
oddLine = not oddLine
else
--
-- for even-numbered lines, just add the text as the description of the last function
--
if #functabl > 0 then
functabl [ #functabl ] [ FUNCDESC ] = line
end
oddLine = not oddLine
end
end
--fout = io.open ( "K:/Documents/Foldit/LUA functions/newmarkup.20150603a.txt", "w" )
fout = io.open ( arg [ 2 ], "w" )
fout:write ( "<!-- Foldit Lua Functions automatically generated information -->" .. "\n" )
fout:write ( "<p>Note: This page is generated from the output of the help command in the Foldit client. " ..
"Please don't make changes to this page. Changes may be overwritten when the page is regenerated.</p>" ..
"<p>To add details for a paricular function, click on the \'Details\' link for the function " ..
"and add comments there.</p>" ..
"<p>Use the \'Comments\' section below for comments on this page as a whole. " ..
"Comments are preserved when the page is updated.</p>" ..
"<p>The functions listed here are for the \"V2\" Foldit Lua interface. " ..
"For each function, the \"V1\" equivalent, if any, is listed. The functions are grouped " ..
" by \[http://foldit.wikia.com/wiki/Foldit_Lua_V2_Namespaces\ namespace\].</p>\n" ..
"<p>Last updated: release " .. frelease .. "</p>\n"
)
fout:write ( "__TOC__" .. "\n" )
--
-- isolate unimplemented functions with two passes of table
--
local lastnmsp = ""
local funcout = 0
for ii = 1, #functabl do
local funckey = functabl [ ii ] [ FUNCNMSP ] .. "_" .. functabl [ ii ] [ FUNCNAME ]
if noopfunc [ funckey ] == nil then
funcnmsp = functabl [ ii ] [ FUNCNMSP ]
local functext = funcnmsp
if funcnmsp == "" then
funcnmsp = "no_namespace"
functext = "no namespace"
end
if funcnmsp ~= lastnmsp then
local nmspdes = nametabl [ funcnmsp ]
fout:write ( "\n<h1>" .. functext .. " functions</h1>\n" )
if nmspdes ~= nil then
fout:write ( "<p>" .. nmspdes .. "</p>\n" )
end
lastnmsp = funcnmsp
end
fout:write ( "{{LuaFunction|" ..
"returns="
.. functabl [ ii ] [ FUNCRETV ] .. "|" ..
"namespace="
.. functabl [ ii ] [ FUNCNMSP ] .. "|" ..
"functionname="
.. functabl [ ii ] [ FUNCNAME ] .. "|" ..
"arguments=("
.. functabl [ ii ] [ FUNCARGS ] .. ")|" ..
"description="
.. functabl [ ii ] [ FUNCDESC ] .. "|" ..
"oldfunctionname="
.. functabl [ ii ] [ FUNCV1 ] .. "|" ..
"}}" .. "\n"
)
funcout = funcout + 1
end
end
local funcoutx = 0
--
-- second pass for unimplemented functions
--
local first = true
for ii = 1, #functabl do
local funckey = functabl [ ii ] [ FUNCNMSP ] .. "_" .. functabl [ ii ] [ FUNCNAME ]
local noop = noopfunc [ funckey ]
if noop ~= nil then
if first then
first = false
fout:write ( "\n<h1>Unimplemented/disabled functions</h1>\n" )
fout:write ( "<p>Functions in this category do nothing. " ..
"They were either never implemented, or implemented and then removed.</p>"
)
end
fout:write ( "{{LuaFunction|" ..
"returns="
.. functabl [ ii ] [ FUNCRETV ] .. "|" ..
"namespace="
.. functabl [ ii ] [ FUNCNMSP ] .. "|" ..
"functionname="
.. functabl [ ii ] [ FUNCNAME ] .. "|" ..
"arguments=("
.. functabl [ ii ] [ FUNCARGS ] .. ")|" ..
"description="
.. functabl [ ii ] [ FUNCDESC ] .. "|" ..
"oldfunctionname="
.. noop .. "|" ..
"}}" .. "\n"
)
funcoutx = funcoutx + 1
end
end
fout:close ()
print ( "--" )
print ( ReVersion .. " complete" )
print ( funcout .. " active functions" )
print ( funcoutx .. " unimplemented functions" )
print ( tagcnt .. " XML tags ignored" )
end
main ()