-- eLua doc builder tool
-- List here all the sections for which we're generating the documentation
local doc_sections = { "arch_platform", "refman_gen" }
-- List here all the components of each section
local components =
{
arch_platform = { "ll", "pio", "spi", "uart", "timers", "pwm", "cpu", "eth", "adc" },
refman_gen = { "bit", "pd", "pack", "tmr", "pwm", "cpu", "adc" }
}
-- List here all languages for the documentation (make sure to keep English ("en") the first one)
local languages = { "en", "pt" }
-- Also list here the translation for a bunch of fixed strings
local overview_tr = { en = "Overview", pt = "##Overview" }
local structures_tr = { en = "Data structures", pt = "##Data structures" }
local functions_tr = { en = "Functions", pt = "##Functions" }
-- Format a name to a link by changing all the spaces to "_" and
-- making all letters lowercase
local function name2link( str )
str = str:gsub( " ", "_" )
return str:lower()
end
-- Returns the part of the string enclosed between two '#' chars
-- Used for parsing function sig.
local function namefromsig( str )
local _, _, name = str:find( "#(.*)#" )
return name
end
--[[ Process the given string as follows:
- $string$ becomes string
- %string% becomes string
- @ref@text@ becomes text
- ^ref^text^ becomes text
- $$, %%, @@, ^^ become $, %, @, ^ respectively
- the string "eLua" becomes eLua
- strings between two tildas (~~) get special code-like formatting
- newlines are changed to ' ' if 'keepnl' isn't true
- '&' is translated to its corresponding HTML code.
- '<<' and '>>" are also translated to the corresponding HTML codes (note the repetition).
--]]
local function format_string( str, keepnl )
-- replace double "special chars" with "temps" for later use
str = str:gsub( "%$%$", "\001" )
str = str:gsub( "%%%%", "\002" )
str = str:gsub( "@@", "\003" )
str = str:gsub( "%^%^", "\004" )
str = str:gsub( "~~", "\005" )
-- Translate 'special' HTML chars to their equivalents
local tr_table =
{
[ "%&" ] = "&",
}
for char, rep in pairs( tr_table ) do
str = str:gsub( char, rep )
end
-- some double chars are replaced directly with their HTML codes
str = str:gsub( "<<", "<" )
str = str:gsub( ">>", ">" )
-- replace eLua with eLua
str = str:gsub( "eLua", "eLua" )
-- $string$ becomes string>
str = str:gsub( "%$([^%s%$][^%$]*)%$", "%1" )
-- %string% becomes string
str = str:gsub( "%%([^%s%%][^%%]*)%%", "%1" )
-- @ref@text@ becomes text
str = str:gsub( "@([^%s@][^@]*)@([^%s@][^@]*)@", '%2' )
-- ^ref^text^ becomes text
str = str:gsub( "%^([^%s%^][^%^]*)%^([^%s%^][^%^]*)%^", '%2' )
-- strings between two tildas (~~) get special code-like formatting
str = str:gsub( "~([^%s~][^~]*)~", function( x )
x = x:gsub( "\n", "
" )
x = x:gsub( "%s%s+", function( x ) return ( " " ):rep( #x ) end )
return "
" .. x .. "
' .. format_string( r.overview ) .. "
\n\n" -- process structures if needed if r.structures then local structures = r.structures wb.structs = {} page = page .. '" .. format_string( s.text, true ) .. "
"
page = page .. ""
-- description
page = page .. "\n" .. format_string( s.desc ) .. "
\n\n" end end -- process functions now if not r.funcs then return false, "funcs not found" end local funcs = r.funcs page = page .. '" .. f.sig:gsub( '#', '' ) .. "
"
page = page .. ""
-- description
page = page .. "\n" .. format_string( f.desc ) .. "
\n" -- arguments page = page .. "Arguments: " if f.args then local a = f.args if type( a ) == "string" or ( type( a ) == "table" and #a == 1 ) then local text = type( a ) == "string" and a or a[ 1 ] page = page .. format_string( text ) else page = page .. "\n
Returns: " if f.ret then local r = f.ret if type( r ) == "string" or ( type( r ) == "table" and #r == 1 ) then local text = type( r ) == "string" and r or r[ 1 ] page = page .. format_string( text ) else page = page .. "\n
" .. format_string( a.desc ) .. "
\n\n" end end -- footer page = page .. "\n" res[ lang ].page = page end return res end -- Helper function to get strings in all languages when needed local function alllangs( getstr ) local str = "name = {" for _, lang in pairs( languages ) do str = str .. string.format( ' %s = "%s",', lang, getstr( lang ) ) end return str .. " }" end -- Transform the data from the wb dictionary (in 'fulldata') for module 'modname' to a wb string, for section 'sect' local function wb2str( fulldata, modname, sect ) local relfname = sect .. "_" .. modname .. ".html" local res = fulldata[ modname ] local wbstr = string.format( ' { %s,\n link = "%s",\n folder =\n {\n', alllangs( function( x ) return res[ x ].wb.name end ), relfname ) -- Overview wbstr = wbstr .. string.format( ' { %s,\n link = "%s#overview"\n },\n', alllangs( function( x ) return overview_tr[ x ] end ), relfname ) -- Data structures (if needed) if res.en.wb.structs then wbstr = wbstr .. string.format( ' { %s,\n link = "%s#structures",\n folder =\n {\n', alllangs( function( x ) return structures_tr[ x ] end ), relfname ) for i = 1, #res.en.wb.structs do local v = res.en.wb.structs[ i ] wbstr = wbstr .. string.format( ' { %s,\n link = "%s#%s",\n },\n', alllangs( function( x ) return res[ x ].wb.structs[ i ] end ), relfname, name2link( v ) ) end wbstr = wbstr .. " }\n },\n" end -- Functions wbstr = wbstr .. string.format( ' { %s,\n link = "%s#funcs",\n folder =\n {\n', alllangs( function( x ) return functions_tr[ x ] end ), relfname ) for _, v in pairs( res.en.wb.funcs ) do wbstr = wbstr .. string.format( ' { name = { en = "%s", pt = "%s" },\n link = "%s#%s",\n },\n', v, v, relfname, name2link( v ) ) end wbstr = wbstr .. " }\n },\n" -- Aux data (if needed) if res.en.wb.auxdata then for i = 1, #res.en.wb.auxdata do local v = res.en.wb.auxdata[ i ] wbstr = wbstr .. string.format( ' { %s,\n link = "%s#%s"\n },\n', alllangs( function( x ) return res[ x ].wb.auxdata[ i ] end ), relfname, name2link( v ) ) end end -- Close the structure and return wbstr = wbstr .. " }\n },\n" return wbstr end -- Read our complete template for wb_usr.lua local wbloc = "wb/wb_usr_template.lua" local realwbloc = "wb/wb_usr.lua" local wbf = io.open( wbloc, "rb" ) if not wbf then print( string.format( "Cannot open %s for reading", wbloc ) ) return 1 end local wbdata = wbf:read( "*a" ) wbf:close() -- Open the actual wb_usr.lua in write mode local realwbf = io.open( realwbloc, "wb" ) if not realwbf then print( string.format( "Cannot open %s for writing", realwbloc ) ) return 1 end -- Generate documentation for each section in part for _, section in pairs( doc_sections ) do -- Check for pattern in wb_usr_template.lua local pattern = "%$%$" .. section:upper() .. "%$%$" if not wbdata:find( pattern ) then print( string.format( "$$%s$$ not found in wb_usr_template.lua", section:upper(), modname ) ) return 1 end -- Generate documentation for each module in turn local fulldata = {} for _, modname in pairs( components[ section ] ) do local descfname = string.format( "luadoc/%s_%s.lua", section, modname ) local res, err = build_file( descfname ) if res then fulldata[ modname ] = res -- Write doc for each language for _, lang in pairs( languages ) do local fname = string.format( "%s/%s_%s.html", lang, section, modname ) local f = io.open( fname, "wb" ) if not f then print( string.format( "Unable to open %s for writing", fname ) ) return 1 else f:write( res[ lang ].page ) f:close() print( ( "Wrote %s" ):format( fname ) ) end end else print( string.format( "Error processing module '%s': %s", modname, err ) ) return 1 end print "" end -- Now it's finally time to get our wb/wb_usr.lua local fullwb = '' for _, modname in pairs( components[ section ] ) do local wbstr = wb2str( fulldata, modname, section ) fullwb = fullwb .. wbstr end -- Substitute our pattern and write everything back to disk wbdata = wbdata:gsub( pattern, fullwb ) end -- Write wb_usr.lua to disk (finally) realwbf:write( wbdata ) realwbf:close() print "All done, remember to run 'lua wb_build.lua' in the 'wb' directory to build your navigation tree"