Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- The http API is nil when it's not enabled.
- if not http then
- printError "The HTTP API must be enabled!"
- return
- end
- local argv = {...}
- local argc = #argv
- local scrWidth,scrHeight = term.getSize()
- -- Used for code examples. Taken straight from rom/programs/edit.
- local keywords = {
- ["and"] = true,
- ["break"] = true,
- ["do"] = true,
- ["else"] = true,
- ["elseif"] = true,
- ["end"] = true,
- ["false"] = true,
- ["for"] = true,
- ["function"] = true,
- ["if"] = true,
- ["in"] = true,
- ["local"] = true,
- ["nil"] = true,
- ["not"] = true,
- ["or"] = true,
- ["repeat"] = true,
- ["return"] = true,
- ["then"] = true,
- ["true"] = true,
- ["until"] = true,
- ["while"] = true
- }
- CC_WIKI_API = "http://computercraft.info/wiki/api.php"
- -- If the argument count is less than 2, too few arguments were supplied.
- if argc < 2 then
- printError "Usage: doc <api/func> <name>"
- return
- end
- -- Capitalise first letter.
- argv[2]:gsub("^%l", string.upper)
- local function trimString(str)
- return str:gsub("^%s*(.-)", "%1")
- end
- local function writeFormatted(str)
- for word in str:gmatch("%S+") do
- local col, txt = word:gmatch("\\\\(%d+):(.+)//")()
- if col ~= nil then
- if term.isColour() then
- term.setTextColour(tonumber(col))
- end
- txt = txt:gsub("\\\\_//", " ")
- word = txt
- end
- if word == "\\\\nl//" then
- print()
- else
- write(word .. " ")
- end
- term.setTextColour(colours.white)
- end
- end
- local function writeToWnd(wnd, str)
- local oldTerm = nil
- if term.current then
- oldTerm = term.redirect(wnd)
- else
- term.redirect(wnd)
- end
- writeFormatted(str)
- if term.restore then
- term.restore()
- else
- term.redirect(oldTerm)
- end
- end
- local function setDefaultColours(buf)
- buf = buf or term
- buf.setBackgroundColour(colours.black)
- buf.setTextColour(colours.white)
- end
- local function setCaptionColours(buf)
- buf = buf or term
- buf.setBackgroundColour(colours.white)
- buf.setTextColour(colours.black)
- end
- local function makePatternFriendly(str)
- local result = str:gsub("%%", "%%%")
- result = result:gsub("%(", "%%(")
- result = result:gsub("%)", "%%)")
- result = result:gsub("%[", "%%[")
- result = result:gsub("%?", "%%?")
- result = result:gsub("%*", "%%*")
- result = result:gsub("%+", "%%+")
- result = result:gsub("%-", "%%-")
- result = result:gsub("%^", "%%^")
- result = result:gsub("%.", "%%.")
- result = result:gsub("%$", "%%$")
- return result
- end
- local function parseCode(code)
- local result = code
- result = result:gsub("\n", " \\\\nl// ")
- result = result:gsub("\r", "")
- result = result:gsub("<br/?>", " \\\\nl// ")
- for k,v in pairs(keywords) do
- result = result:gsub("%s-(" .. k .. ")%s+", "\\\\" .. colours.yellow .. ":%1//")
- end
- return result
- end
- local function parseExamples(exText)
- local result = ""
- local isFirst = true
- -- error(makePatternFriendly(exText))
- for example in exText:gmatch("{{(.-)}}") do
- local code = example:gmatch("|code=(.+)%s|")()
- if code ~= nil then
- if not isFirst then
- result = result .. "\\\\"
- end
- result = result .. parseCode(code)
- isFirst = false
- end
- end
- return result
- end
- local function convertMarkup(mrkup, isExample)
- if isExample == nil then isExample = false end
- -- Replace the HTML codes with their actual symbols.
- local result = mrkup:gsub(""", "\"")
- result = result:gsub(">", ">")
- result = result:gsub("<", "<")
- result = result:gsub("&", "&")
- -- Replace &#[ascii code]; with the proper character (e.g: '%' -> '%').
- for word, byte in result:gmatch("(&#(%d+);)") do
- local corrected = string.char(byte)
- result = result:gsub(word, makePatternFriendly(corrected))
- end
- if isExample then
- result = parseExamples(result)
- end
- -- Remove HTML tags.
- result = result:gsub("</?.-/?>", "")
- -- Replace type references with highlighted text.
- result = result:gsub("{{.-|(.-)}}", "\\\\" .. colours.lime .. ":%1//")
- -- Replace links with highlighted text.
- result = result:gsub("%[%[.-|(.-)]]", "\\\\" .. colours.blue .. ":%1//")
- result = result:gsub("%[%[(.-)]]", "\\\\" .. colours.blue .. ":%1//")
- -- Replace double quotes with single quotes (''text'' -> 'text').
- result = result:gsub("''(.-)''", "'%1'")
- -- Replace spaces in colour highlighting with "\\_//".
- for word in result:gmatch("\\\\%d+:.-//") do
- local newword = word:gsub("%s", "\\\\_//")
- result = result:gsub(makePatternFriendly(word), makePatternFriendly(newword))
- end
- result = trimString(result)
- return result
- end
- local function renderGUI(elements, activeElement, wnd)
- wnd.setBackgroundColour(colours.black)
- wnd.clear()
- wnd.redraw()
- term.setTextColor(colours.white)
- term.setCursorPos(1, scrHeight)
- term.write("Arrow keys to change category; Enter to quit")
- term.setCursorPos(1, 2)
- term.setBackgroundColour(colours.black)
- term.clearLine()
- term.setCursorPos(1, 3)
- term.setTextColor(colours.white)
- for i=1,scrWidth do
- term.write("-")
- end
- local nextTabPos = 1
- for i,v in ipairs(elements) do
- if v.isTitle ~= nil and v.isTitle then
- local txt = v.body
- term.setCursorPos(scrWidth / 2 - #txt / 2, 1)
- term.setBackgroundColour(colours.white)
- term.setTextColour(colours.black)
- term.write(txt)
- else
- if v.id == activeElement then
- local cap = v.caption
- term.setCursorPos(nextTabPos, 2)
- term.setBackgroundColour(colours.white)
- term.setTextColour(colours.black)
- term.write(cap)
- nextTabPos = nextTabPos + #cap + 1
- wnd.setCursorPos(1, 1)
- if v.body ~= "" then
- writeToWnd(wnd, v.body)
- else
- writeToWnd(wnd, "\\\\" .. colours.red .. ":N/A//")
- end
- else
- local cap = v.caption
- term.setCursorPos(nextTabPos, 2)
- term.setBackgroundColour(colours.black)
- term.setTextColour(colours.white)
- term.write(cap)
- nextTabPos = nextTabPos + #cap + 1
- end
- end
- end
- end
- local function enterGUI(elements)
- term.setBackgroundColour(colours.black)
- term.clear()
- term.setCursorPos(1, 1)
- local guiActive = true
- local activeElement = 1
- local trm = nil
- if term.current then
- trm = term.current()
- else
- trm = term
- end
- local wnd = window.create(trm, 1, 4, scrWidth, scrHeight - 5)
- wnd.setVisible(true)
- renderGUI(elements, activeElement, wnd)
- while guiActive do
- local e,p1,p2,p3 = os.pullEvent()
- local doDraw = true
- if e == "key" then
- if p1 == keys.enter then
- wnd.setVisible(false)
- term.setBackgroundColour(colours.black)
- term.clear()
- term.setCursorPos(1, 1)
- guiActive = false
- doDraw = false
- elseif p1 == keys.up or p1 == keys.left then
- activeElement = activeElement - 1
- if activeElement < 1 then activeElement = 1 end
- elseif p1 == keys.down or p1 == keys.right then
- activeElement = activeElement + 1
- if activeElement > #elements - 1 then activeElement = #elements - 1 end
- end
- end
- if doDraw then
- renderGUI(elements, activeElement, wnd)
- end
- end
- end
- function printWikiInfo(xml)
- -- Get the content from the first found 'rev' tag.
- local content = xml:gmatch("<rev .->(.-)</rev>")()
- if content == nil then
- printError "No such function."
- return
- end
- local name = content:gmatch("|name=(.-)%s|")()
- name = convertMarkup(name or "")
- local description = content:gmatch("|desc=(.-)%s|")()
- description = convertMarkup(description or "")
- local arguments = content:gmatch("|args=(.-)%s|")()
- arguments = convertMarkup(arguments or "")
- local returns = content:gmatch("|returns=(.-)%s|")()
- returns = convertMarkup(returns or "")
- local examples = content:gmatch("|examples=(.-}})")()
- examples = convertMarkup(examples or "", true)
- local elems = {}
- local lastID = 0
- local nextID = 1
- if name ~= "" then
- elems[#elems + 1] = {
- id = 0,
- isTitle = true,
- caption = nil,
- body = name
- }
- end
- if description ~= "" then
- elems[#elems + 1] = {
- id = nextID,
- caption = "Description",
- body = description
- }
- nextID = nextID + 1
- end
- if arguments ~= "" then
- elems[#elems + 1] = {
- id = nextID,
- caption = "Arguments",
- body = arguments
- }
- nextID = nextID + 1
- end
- if returns ~= "" then
- elems[#elems + 1] = {
- id = nextID,
- caption = "Returns",
- body = returns
- }
- nextID = nextID + 1
- end
- if examples ~= "" then
- elems[#elems + 1] = {
- id = nextID,
- caption = "Examples",
- body = examples
- }
- nextID = nextID + 1
- end
- enterGUI(elems)
- end
- setDefaultColours()
- term.clear()
- term.setCursorPos(1, 1)
- print("...")
- term.setCursorPos(1, 1)
- if argv[1] == "func" then
- local headers = {
- ["User-Agent"] = "Doc/1.1"
- }
- local req = http.get(CC_WIKI_API .. "?format=xml&action=query&titles=" .. textutils.urlEncode(argv[2]) .. "&prop=revisions&rvprop=content", headers)
- if req == nil then
- printError "Failed to connect to the CC Wiki!"
- return
- end
- -- If the response code is 404, the page couldn't be found.
- if req.getResponseCode() == 404 then
- printError("There is no documentation available for \"" .. argv[2] .. "\".")
- return
- end
- local contents = req.readAll()
- req.close()
- printWikiInfo(contents)
- elseif argv[1] == "api" then
- setCaptionColours()
- print("Functions in \"" .. argv[2] .. "\":")
- if _G[argv[2]] == nil then
- setDefaultColours()
- printError "No such API."
- return
- end
- local functions = {}
- for k,v in pairs(_G[argv[2]]) do
- if type(v) == "function" then
- functions[#functions + 1] = tostring(k)
- end
- end
- setDefaultColours()
- textutils.pagedTabulate(functions)
- elseif argv[1] == "print" then
- local str = ""
- for i=2,argc do
- str = str .. argv[i] .. " "
- end
- str = decodeMarkup(str)
- writeFormatted(str)
- print()
- end
Advertisement
Add Comment
Please, Sign In to add comment