diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/adeptsensedoc.lua | 165 | ||||
-rwxr-xr-x | scripts/gen_iface.lua | 115 | ||||
-rwxr-xr-x | scripts/update_doc | 116 |
3 files changed, 396 insertions, 0 deletions
diff --git a/scripts/adeptsensedoc.lua b/scripts/adeptsensedoc.lua new file mode 100644 index 00000000..ea4e3359 --- /dev/null +++ b/scripts/adeptsensedoc.lua @@ -0,0 +1,165 @@ +-- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. + +--- +-- Adeptsense doclet for LuaDoc. +-- This module is used by LuaDoc to create an adeptsense for Lua with a fake +-- ctags file and an api file. +-- Since LuaDoc does not recognize module fields, this doclet parses the Lua +-- files for comments of the form "-- * `field_name`" to generate a field tag. +-- @usage luadoc -d [output_path] -doclet path/to/adeptsensedoc [file(s)] +module('adeptsensedoc', package.seeall) + +local CTAGS_FMT = '%s\t_\t0;"\t%s\t%s' +local string_format = string.format + +-- Writes a ctag. +-- @param file The file to write to. +-- @param name The name of the tag. +-- @param k The kind of ctag. Lua adeptsense uses 4 kinds: m Module, f Function, +-- t Table, and F Field. +-- @param ext_fields The ext_fields for the ctag. +local function write_tag(file, name, k, ext_fields) + if type(ext_fields) == 'table' then + ext_fields = table.concat(ext_fields, '\t') + end + file[#file + 1] = string_format(CTAGS_FMT, name, k, ext_fields) +end + +-- Writes a function apidoc. +-- @param file The file to write to. +-- @param m The LuaDoc module object. +-- @param f The LuaDoc function object. +local function write_function_apidoc(file, m, f) + -- Function name. + local name = f.name + if not name:find('[%.:]') then name = m.name..'.'..name end + -- Block documentation for the function. + local doc = { 'fmt -s -w 80 <<"EOF"' } + -- Function arguments. + doc[#doc + 1] = name..'('..table.concat(f.param, ', ')..')' + -- Function description. + doc[#doc + 1] = f.description:gsub('\\n', '\\\\n') + -- Function parameters (@param). + if f.param then + for _, p in ipairs(f.param) do + if f.param[p] and #f.param[p] > 0 then + doc[#doc + 1] = '@param '..f.param[p]:gsub('\\n', '\\\\n') + end + end + end + -- Function usage (@usage). + if f.usage then + if type(f.usage) == 'string' then + doc[#doc + 1] = '@usage '..f.usage + else + for _, u in ipairs(f.usage) do doc[#doc + 1] = '@usage '..u end + end + end + -- Function returns (@return). + if f.ret then doc[#doc + 1] = '@return '..f.ret end + -- See also (@see). + if f.see then + if type(f.see) == 'string' then + doc[#doc + 1] = '@see '..f.see + else + for _, s in ipairs(f.see) do doc[#doc + 1] = '@see '..s end + end + end + -- Format the block documentation. + doc[#doc + 1] = 'EOF' + local p = io.popen(table.concat(doc, '\n')) + doc = p:read('*all'):gsub('\n', '\\n') + p:close() + file[#file + 1] = table.concat({ name:match('[^%.:]+$') , doc }, ' ') +end + +-- Called by LuaDoc to process a doc object. +-- @param doc The LuaDoc doc object. +function start(doc) +-- require 'luarocks.require' +-- local profiler = require 'profiler' +-- profiler.start() + + local modules = doc.modules + + -- Convert module functions in the Lua luadoc into LuaDoc modules. + local lua_luadoc = doc.files['../modules/lua/lua.luadoc'] + if lua_luadoc then + for _, f in ipairs(lua_luadoc.functions) do + f = lua_luadoc.functions[f] + local module = f.name:match('^([^%.]+)%.') or '_G' + if not modules[module] then + modules[#modules + 1] = module + modules[module] = { name = module, functions = {} } + end + local module = modules[module] + module.functions[#module.functions + 1] = f.name + module.functions[f.name] = f + end + end + + -- Parse out module fields (-- * `FIELD`) and insert them into their LuaDoc + -- modules. + for _, file in ipairs(doc.files) do + local p = io.popen('grep -r "^-- \\* \\`" '..file) + local output = p:read('*all') + p:close() + for line in output:gmatch('[^\n]+') do + local field = line:match('^%-%- %* `([^`]+)`') + p = io.popen('grep "^module" '..file) + local module = (p:read('*l') or ''):match("module%('([^']+)'") + p:close() + if not module then module = field:match('^[^%.]+') end -- lua.luadoc + local module = modules[module] + if not module.fields then module.fields = {} end + module.fields[#module.fields + 1] = field:match('[^%.]+$') + end + end + + -- Process LuaDoc and write the ctags and api file. + local ctags, apidoc = {}, {} + for _, m in ipairs(modules) do + m = modules[m] + local module = m.name + -- Tag the module. + write_tag(ctags, module, 'm', '') + if module:find('%.') then + -- Tag the last part of the module as a table of the first part. + local parent, child = module:match('^(.-)%.([^%.]+)$') + write_tag(ctags, child, 't', 'class:'..parent) + elseif module ~= '_G' then + -- Tag the module as a global table. + write_tag(ctags, module, 't', 'class:_G') + write_tag(ctags, module, 't', '') + end + -- Tag the functions and write the apidoc. + for _, f in ipairs(m.functions) do + if not f:find('no_functions') then -- ignore placeholders + local func = f:match('[^%.:]+$') + write_tag(ctags, func, 'f', 'class:'..module) + if module == '_G' then write_tag(ctags, func, 'f', '') end -- global + write_function_apidoc(apidoc, m, m.functions[f]) + end + end + -- Tag the tables. + for _, t in ipairs(m.tables or {}) do + write_tag(ctags, t, 't', 'class:'..module) + if module == '_G' then write_tag(ctags, t, 't', '') end -- global + end + -- Tag the fields. + for _, f in ipairs(m.fields or {}) do + write_tag(ctags, f, 'F', 'class:'..module) + if module == '_G' then write_tag(ctags, f, 'F', '') end -- global + end + end + local f = io.open(options.output_dir..'/tags', 'w') + f:write(table.concat(ctags, '\n')) + f:close() + f = io.open(options.output_dir..'api', 'w') + f:write(table.concat(apidoc, '\n')) + f:close() + +-- profiler.stop() +end + +return _M diff --git a/scripts/gen_iface.lua b/scripts/gen_iface.lua new file mode 100755 index 00000000..e8f94560 --- /dev/null +++ b/scripts/gen_iface.lua @@ -0,0 +1,115 @@ +#!/usr/bin/lua +-- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. + +local f = io.open('../../scite-latest/scite/src/IFaceTable.cxx') +local contents = f:read('*all') +f:close() + +local constants = contents:match('ifaceConstants%[%] = (%b{})') +local functions = contents:match('ifaceFunctions%[%] = (%b{})') +local properties = contents:match('ifaceProperties%[%] = (%b{})') + +local out = [[ +-- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. + +--- +-- Scintilla constants, functions, and properties. +-- Do not modify anything in this module. Doing so will result in instability. +module('_SCINTILLA', package.seeall) + +]] + +local types = { + void = 0, int = 1, length = 2, position = 3, colour = 4, bool = 5, + keymod = 6, string = 7, stringresult = 8, cells = 9, textrange = 10, + findtext = 11, formatrange = 12 +} + +out = out..[[ +--- +-- Scintilla constants. +-- @class table +-- @name constants +constants = {]] +-- {"constant", value} +for item in constants:sub(2, -2):gmatch('%b{}') do + local name, value = item:match('^{"(.-)",(.-)}') + if not name:find('^IDM_') and not name:find('^SCE_') and + not name:find('^SCLEX_') then + if name == 'SC_MASK_FOLDERS' then value = '-33554432' end + local line = (" %s = %s,"):format(name, value) + out = out..line + end +end +out = out..string.gsub([[ +SCLEX_CONTAINER = 0, +SCLEX_NULL = 1, +SCLEX_LPEG = 999, +SCLEX_AUTOMATIC = 1000, +SCN_STYLENEEDED = 2000, +SCN_CHARADDED = 2001, +SCN_SAVEPOINTREACHED = 2002, +SCN_SAVEPOINTLEFT = 2003, +SCN_MODIFYATTEMPTRO = 2004, +SCN_KEY = 2005, +SCN_DOUBLECLICK =2006, +SCN_UPDATEUI = 2007, +SCN_MODIFIED = 2008, +SCN_MACRORECORD = 2009, +SCN_MARGINCLICK = 2010, +SCN_NEEDSHOWN = 2011, +SCN_PAINTED = 2013, +SCN_USERLISTSELECTION = 2014, +SCN_URIDROPPED = 2015, +SCN_DWELLSTART = 2016, +SCN_DWELLEND = 2017, +SCN_ZOOM = 2018, +SCN_HOTSPOTCLICK = 2019, +SCN_HOTSPOTDOUBLECLICK = 2020, +SCN_CALLTIPCLICK = 2021, +SCN_AUTOCSELECTION = 2022, +SCN_INDICATORCLICK = 2023, +SCN_INDICATORRELEASE = 2024,]], '\n', ' ') +out = out..' }\n\n' + +out = out..[[ +--- +-- Scintilla functions. +-- @class table +-- @name functions +functions = {]] +-- {"function", msg_id, iface_*, {iface_*, iface_*}} +for item in functions:sub(2, -2):gmatch('%b{}') do + local name, msg_id, rt_type, p1_type, p2_type = + item:match('^{"(.-)"%D+(%d+)%A+iface_(%a+)%A+iface_(%a+)%A+iface_(%a+)') + name = name:gsub('([a-z])([A-Z])', '%1_%2') + name = name:gsub('([A-Z])([A-Z][a-z])', '%1_%2') + name = name:lower() + local line = (" %s = {%d, %d, %d, %d},"):format( + name, msg_id, types[rt_type], types[p1_type], types[p2_type]) + out = out..line +end +out = out..' }\n\n' + +out = out..[[ +--- +-- Scintilla properties. +-- @class table +-- @name properties +properties = {]] +-- {"property", get_id, set_id, rt_type, p1_type} +for item in properties:sub(2, -2):gmatch('%b{}') do + local name, get_id, set_id, rt_type, p1_type = + item:match('^{"(.-)"%D+(%d+)%D+(%d+)%A+iface_(%a+)%A+iface_(%a+)') + name = name:gsub('([a-z])([A-Z])', '%1_%2') + name = name:gsub('([A-Z])([A-Z][a-z])', '%1_%2') + name = name:lower() + local line = (" %s = {%d, %d, %d, %d},"):format( + name, get_id, set_id, types[rt_type], types[p1_type]) + out = out..line +end +out = out..' }\n' + +f = io.open('../core/iface.lua', 'w') +f:write(out) +f:close() diff --git a/scripts/update_doc b/scripts/update_doc new file mode 100755 index 00000000..004fef6f --- /dev/null +++ b/scripts/update_doc @@ -0,0 +1,116 @@ +#!/usr/bin/lua +-- Copyright 2007-2011 Mitchell mitchell<att>caladbolg.net. See LICENSE. + +-- Generate LuaDoc. +os.execute('rm -rf ../doc/modules/') +os.execute('cd ../; luadoc -d doc/ --nofiles modules/ core/ lexers/lexer.lua') + +-- Insert Markdown in modules into LuaDoc. +local p = io.popen('grep -r "\\-\\- Markdown:" ../*') +for file in p:lines() do + local module + + -- Open the Lua file and extract the Markdown lines. + local f = io.open(file:match('^[^:]+')) + local markdown, flag = {}, false + for line in f:lines() do + if flag and line:match('^%-%-') then + local match = line:match('^%-%- ([^\n]+)') + markdown[#markdown + 1] = match or '' + elseif flag then -- markdown ended + break + elseif line:match('^%-%- Markdown:') then + flag = true + elseif line:match('^module') then + module = line:match("^module%('([^']+)") + end + end + f:close() + + -- Convert the Markdown into HTML. + markdown = table.concat(markdown, '\n') + f = io.open('tmp', 'w') + f:write(markdown) + f:close() + f = io.popen('perl ../doc/Markdown.pl tmp') + markdown = f:read('*all') + f:close() + os.execute('rm tmp') + + -- Insert the Marked down HTML in the LuaDoc HTML file. + local filename = '../doc/modules/'..module..'.html' + f = io.open(filename) + local contents = f:read('*all') + f:close() + local s = contents:find('<h2>Functions</h2>') + if not s then s = contents:find('<h2>Tables</h2>') end + contents = contents:sub(1, s - 1)..markdown..contents:sub(s) + f = io.open(filename, 'w') + f:write(contents) + f:close() +end +p:close() + +-- Generate the Manual. +p = io.popen('ls -1 ../doc/manual/*.md') +for mdfile in p:lines() do + local htmlfile = mdfile:match('^(.+).md$')..'.html' + html = [[ + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + <html> + <head> + <title>Textadept Manual</title> + <link rel="stylesheet" href="luadoc.css" type="text/css" /> + </head> + + <body> + <div id="container"> + <div id="main"> + <div id="navigation"> + + %sidebar% + + </div> + <div id="content"> + + %content% + + </div> + </div> + <div id="about"> + <p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p> + </div> + </div> + </body> + </html> + ]] + + local sidebar_md = io.popen('../doc/Markdown.pl ../doc/sidebar.md') + html = html:gsub('%%sidebar%%', sidebar_md:read('*all')) + sidebar_md:close() + local content_md = io.popen('../doc/Markdown.pl '..mdfile) + local md = content_md:read('*all'):gsub('%%', '%%%%') + md = md:gsub('(<h%d>)([^<]+)(</h%d>)', + function(s, text, e) + return string.format('%s<a name="%s"></a>%s%s', s, + text:gsub(' ', '_'):lower(), text, e) + end) + html = html:gsub('%%content%%', md) + content_md:close() + + local f = io.open(htmlfile, 'w') + f:write(html) + f:close() +end +p:close() + +-- Modify default CSS. +os.execute("sed -i 's/pre.example/pre, pre.example/;' ../doc/luadoc.css") + +-- Generate Doxygen documentation. +os.execute('cd ../; doxygen Doxyfile') + +-- Create Lua adeptsense for textadept. +os.execute(table.concat{ 'luadoc -d ../modules/lua -doclet adeptsensedoc ', + '../modules ../core ../lexers/lexer.lua' }) |