aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/adeptsensedoc.lua165
-rwxr-xr-xscripts/gen_iface.lua115
-rwxr-xr-xscripts/update_doc116
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' })