Skip to content

Commit 8067f23

Browse files
committed
- Fixed a container bug
- Added onDone to Program
1 parent ea0f31f commit 8067f23

File tree

16 files changed

+671
-5
lines changed

16 files changed

+671
-5
lines changed

src/elements/Container.lua

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ end
102102
function Container:init(props, basalt)
103103
VisualElement.init(self, props, basalt)
104104
self.set("type", "Container")
105+
self:observe("width", function()
106+
self.set("childrenSorted", false)
107+
self.set("childrenEventsSorted", false)
108+
end)
109+
self:observe("height", function()
110+
self.set("childrenSorted", false)
111+
self.set("childrenEventsSorted", false)
112+
end)
105113
end
106114

107115
--- Returns whether a child is visible
@@ -339,11 +347,13 @@ end
339347

340348
local function convertMousePosition(self, event, ...)
341349
local args = {...}
342-
if event:find("mouse_") then
343-
local button, absX, absY = ...
344-
local xOffset, yOffset = self.get("offsetX"), self.get("offsetY")
345-
local relX, relY = self:getRelativePosition(absX + xOffset, absY + yOffset)
346-
args = {button, relX, relY}
350+
if event then
351+
if event:find("mouse_") then
352+
local button, absX, absY = ...
353+
local xOffset, yOffset = self.get("offsetX"), self.get("offsetY")
354+
local relX, relY = self:getRelativePosition(absX + xOffset, absY + yOffset)
355+
args = {button, relX, relY}
356+
end
347357
end
348358
return args
349359
end
@@ -680,6 +690,9 @@ end
680690
--- @private
681691
function Container:destroy()
682692
if not self:isType("BaseFrame") then
693+
for _, child in ipairs(self.get("children")) do
694+
child:destroy()
695+
end
683696
self.set("childrenSorted", false)
684697
VisualElement.destroy(self)
685698
return self

src/elements/Flexbox.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ function Flexbox:addChild(element)
787787
return self
788788
end
789789

790+
--- Removes a child element from the flexbox
790791
--- @shortDescription Removes a child element from the flexbox
791792
--- @param element Element The child element to remove
792793
--- @return Flexbox self The flexbox instance

src/elements/Program.lua

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Program.defineProperty(Program, "path", {default = "", type = "string"})
1717
Program.defineProperty(Program, "running", {default = false, type = "boolean"})
1818
--- @property errorCallback function nil The error callback function
1919
Program.defineProperty(Program, "errorCallback", {default = nil, type = "function"})
20+
--- @property doneCallback function nil The done callback function
21+
Program.defineProperty(Program, "doneCallback", {default = nil, type = "function"})
2022

2123
Program.defineEvent(Program, "*")
2224

@@ -82,6 +84,10 @@ function BasaltProgram:run(path, width, height)
8284
local ok, result = coroutine.resume(self.coroutine)
8385
term.redirect(current)
8486
if not ok then
87+
local doneCallback = self.program.get("doneCallback")
88+
if doneCallback then
89+
doneCallback(self.program, ok, result)
90+
end
8591
local errorCallback = self.program.get("errorCallback")
8692
if errorCallback then
8793
local trace = debug.traceback(self.coroutine, result)
@@ -94,6 +100,14 @@ function BasaltProgram:run(path, width, height)
94100
errorManager.header = "Basalt Program Error ".. path
95101
errorManager.error(result)
96102
end
103+
if coroutine.status(self.coroutine)=="dead" then
104+
self.program.set("running", false)
105+
self.program.set("program", nil)
106+
local doneCallback = self.program.get("doneCallback")
107+
if doneCallback then
108+
doneCallback(self.program, ok, result)
109+
end
110+
end
97111
else
98112
errorManager.header = "Basalt Program Error ".. path
99113
errorManager.error("File not found")
@@ -128,10 +142,23 @@ function BasaltProgram:resume(event, ...)
128142

129143
if ok then
130144
self.filter = result
145+
if coroutine.status(self.coroutine)=="dead" then
146+
self.program.set("running", false)
147+
self.program.set("program", nil)
148+
local doneCallback = self.program.get("doneCallback")
149+
if doneCallback then
150+
doneCallback(self.program, ok, result)
151+
end
152+
end
131153
else
154+
local doneCallback = self.program.get("doneCallback")
155+
if doneCallback then
156+
doneCallback(self.program, ok, result)
157+
end
132158
local errorCallback = self.program.get("errorCallback")
133159
if errorCallback then
134160
local trace = debug.traceback(self.coroutine, result)
161+
trace = trace == nil and "" or trace
135162
local _result = errorCallback(self.program, result, trace:gsub(result, ""))
136163
if(_result==false)then
137164
self.filter = nil
@@ -235,6 +262,15 @@ function Program:onError(fn)
235262
return self
236263
end
237264

265+
--- Registers a callback for the program's done event
266+
--- @shortDescription Registers a callback for the program's done event
267+
--- @param fn function The callback function to register
268+
--- @return Program self The Program instance
269+
function Program:onDone(fn)
270+
self.set("doneCallback", fn)
271+
return self
272+
end
273+
238274
--- @shortDescription Handles all incomming events
239275
--- @param event string The event to handle
240276
--- @param ... any The event arguments

tools/BasaltDoc/Button.lua

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
local elementManager = require("elementManager")
2+
local VisualElement = elementManager.getElement("VisualElement")
3+
local getCenteredPosition = require("libraries/utils").getCenteredPosition
4+
---@cofnigDescription The Button is a standard button element with click handling and state management.
5+
6+
--- The Button is a standard button element with click handling and state management.
7+
---@class Button : VisualElement
8+
local Button = setmetatable({}, VisualElement)
9+
Button.__index = Button
10+
11+
---@property text string Button Button text
12+
Button.defineProperty(Button, "text", {default = "Button", type = "string", canTriggerRender = true})
13+
14+
Button.defineEvent(Button, "mouse_click")
15+
Button.defineEvent(Button, "mouse_up")
16+
17+
--- @shortDescription Creates a new Button instance
18+
--- @return table self The created instance
19+
--- @private
20+
function Button.new()
21+
local self = setmetatable({}, Button):__init()
22+
self.class = Button
23+
self.set("width", 10)
24+
self.set("height", 3)
25+
self.set("z", 5)
26+
return self
27+
end
28+
29+
--- @shortDescription Initializes the Button instance
30+
--- @param props table The properties to initialize the element with
31+
--- @param basalt table The basalt instance
32+
--- @protected
33+
function Button:init(props, basalt)
34+
VisualElement.init(self, props, basalt)
35+
self.set("type", "Button")
36+
end
37+
38+
--- @shortDescription Renders the Button
39+
--- @protected
40+
function Button:render()
41+
VisualElement.render(self)
42+
local text = self.get("text")
43+
text = text:sub(1, self.get("width"))
44+
local xO, yO = getCenteredPosition(text, self.get("width"), self.get("height"))
45+
self:textFg(xO, yO, text, self.get("foreground"))
46+
end
47+
48+
return Button
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# ldoc-markdown-parser
2+
3+
## Overview
4+
`ldoc-markdown-parser` is a simple and extensible Lua documentation parser that converts Lua documentation comments into Markdown format. It supports both single-line and multi-line comments, making it easy to document your Lua code in a structured way.
5+
6+
## Features
7+
- Extracts single-line and multi-line comments from Lua files.
8+
- Parses custom tags such as `@property`, `@shortDescription`, `@param`, and `@return`.
9+
- Converts extracted comments and parsed tags into Markdown format.
10+
- Easy to extend and customize for additional tags or formatting options.
11+
12+
## Installation
13+
To install the `ldoc-markdown-parser`, clone the repository and navigate to the project directory:
14+
15+
```bash
16+
git clone <repository-url>
17+
cd ldoc-markdown-parser
18+
```
19+
20+
## Usage
21+
To use the parser, run the `main.lua` file with the Lua interpreter, providing the path to the Lua file you want to parse:
22+
23+
```bash
24+
lua src/main.lua path/to/your/lua_file.lua
25+
```
26+
27+
The output will be generated in Markdown format and can be found in the specified output directory.
28+
29+
## Example
30+
An example Lua file can be found in the `examples/input/example.lua`, and the expected output Markdown file is located in `examples/output/example.md`.
31+
32+
## Contributing
33+
Contributions are welcome! Please feel free to submit a pull request or open an issue for any enhancements or bug fixes.
34+
35+
## License
36+
This project is licensed under the MIT License. See the LICENSE file for more details.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
local FunctionParser = {}
2+
3+
--- Check if a block represents a function
4+
function FunctionParser.canParse(block)
5+
return block.context and block.context.type == "function"
6+
end
7+
8+
--- Parse a complete function documentation block
9+
function FunctionParser.parse(block)
10+
local functionDoc = {
11+
type = "function",
12+
name = block.context.name,
13+
shortDescription = nil,
14+
params = {},
15+
returns = {},
16+
visibility = "public", -- default
17+
context = block.context,
18+
content = {}
19+
}
20+
21+
for _, line in ipairs(block.comments) do
22+
-- Parse shortDescription
23+
local shortDesc = line:match("^%-*%s*@shortDescription%s+(.*)$")
24+
if shortDesc then
25+
functionDoc.shortDescription = shortDesc
26+
27+
-- Parse param
28+
elseif line:match("^%-*%s*@param") then
29+
local paramName, paramType, paramDesc = line:match("^%-*%s*@param%s+(%S+)%s+(%S+)%s+(.*)$")
30+
if paramName then
31+
table.insert(functionDoc.params, {
32+
name = paramName,
33+
type = paramType,
34+
description = paramDesc or ""
35+
})
36+
end
37+
38+
-- Parse return
39+
elseif line:match("^%-*%s*@return") then
40+
local returnType, returnName, returnDesc = line:match("^%-*%s*@return%s+(%S+)%s+(%S+)%s+(.*)$")
41+
if returnType then
42+
table.insert(functionDoc.returns, {
43+
type = returnType,
44+
name = returnName or "",
45+
description = returnDesc or ""
46+
})
47+
end
48+
49+
-- Parse visibility
50+
elseif line:match("^%-*%s*@private%s*$") then
51+
functionDoc.visibility = "private"
52+
elseif line:match("^%-*%s*@protected%s*$") then
53+
functionDoc.visibility = "protected"
54+
55+
-- Regular content
56+
else
57+
table.insert(functionDoc.content, line)
58+
end
59+
end
60+
61+
return functionDoc
62+
end
63+
64+
return FunctionParser
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
local CommentExtractor = {}
2+
3+
--- Extracts comments with their associated code context
4+
-- @param lines table The lines of the Lua file as a table of strings.
5+
-- @return table A table containing comment blocks with context.
6+
function CommentExtractor.extractComments(lines)
7+
local blocks = {}
8+
local currentCommentBlock = {}
9+
local i = 1
10+
11+
while i <= #lines do
12+
local line = lines[i]:match("^%s*(.*)") -- Trim leading whitespace
13+
14+
-- Check if this is a comment line
15+
if line:find("^%-%-%-") or line:find("^%-%-") then
16+
table.insert(currentCommentBlock, line)
17+
elseif #currentCommentBlock > 0 then
18+
-- We have accumulated comments, check if next non-empty line is code
19+
local codeContext = nil
20+
local j = i
21+
22+
-- Skip empty lines to find the actual code
23+
while j <= #lines and lines[j]:match("^%s*$") do
24+
j = j + 1
25+
end
26+
27+
if j <= #lines then
28+
local codeLine = lines[j]:match("^%s*(.*)")
29+
-- Check if it's a function, class, property, etc.
30+
if codeLine:find("^function") or
31+
codeLine:find("^local function") or
32+
codeLine:find("^local%s+%w+%s*=") or
33+
codeLine:find("^%w+%.%w+") then
34+
codeContext = {
35+
type = CommentExtractor.getCodeType(codeLine),
36+
name = CommentExtractor.extractName(codeLine),
37+
line = codeLine,
38+
lineNumber = j
39+
}
40+
end
41+
end
42+
43+
-- Add the comment block with its context
44+
table.insert(blocks, {
45+
comments = currentCommentBlock,
46+
context = codeContext
47+
})
48+
49+
currentCommentBlock = {}
50+
end
51+
52+
i = i + 1
53+
end
54+
55+
-- Handle any remaining comments
56+
if #currentCommentBlock > 0 then
57+
table.insert(blocks, {
58+
comments = currentCommentBlock,
59+
context = nil
60+
})
61+
end
62+
63+
return blocks
64+
end
65+
66+
--- Determines the type of code (function, class, property, etc.)
67+
function CommentExtractor.getCodeType(codeLine)
68+
if codeLine:find("^function") or codeLine:find("^local function") then
69+
return "function"
70+
elseif codeLine:find("^local%s+%w+%s*=%s*setmetatable") then
71+
return "class"
72+
elseif codeLine:find("^local%s+%w+%s*=") then
73+
return "variable"
74+
elseif codeLine:find("^%w+%.defineProperty") then
75+
return "property_definition"
76+
else
77+
return "unknown"
78+
end
79+
end
80+
81+
--- Extracts the name from a code line
82+
function CommentExtractor.extractName(codeLine)
83+
-- Function patterns
84+
local funcName = codeLine:match("^function%s+([%w%.%:]+)")
85+
if funcName then return funcName end
86+
87+
local localFuncName = codeLine:match("^local%s+function%s+([%w%.%:]+)")
88+
if localFuncName then return localFuncName end
89+
90+
-- Variable/class patterns
91+
local varName = codeLine:match("^local%s+([%w_]+)%s*=")
92+
if varName then return varName end
93+
94+
-- Method patterns
95+
local methodName = codeLine:match("^([%w%.%:]+)%s*=")
96+
if methodName then return methodName end
97+
98+
return "unknown"
99+
end
100+
101+
return CommentExtractor

0 commit comments

Comments
 (0)