Updated markdown parser, testing it
This commit is contained in:
@@ -75,7 +75,7 @@ function BaseElement:init(props, basalt)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Post initialization hook
|
||||
--- Post initialization
|
||||
--- @return table self The BaseElement instance
|
||||
function BaseElement:postInit()
|
||||
if(self._props)then
|
||||
@@ -174,6 +174,8 @@ function BaseElement:handleEvent(event, ...)
|
||||
return false
|
||||
end
|
||||
|
||||
--- Returns the base frame of the element
|
||||
--- @return table BaseFrame The base frame of the element
|
||||
function BaseElement:getBaseFrame()
|
||||
if self.parent then
|
||||
return self.parent:getBaseFrame()
|
||||
@@ -181,8 +183,26 @@ function BaseElement:getBaseFrame()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Destroys the element and cleans up all references
|
||||
--- @usage element:destroy()
|
||||
function BaseElement:destroy()
|
||||
-- Remove from parent if exists
|
||||
if self.parent then
|
||||
self.parent:removeChild(self)
|
||||
end
|
||||
|
||||
for event in pairs(self._registeredEvents) do
|
||||
self:listenEvent(event, false)
|
||||
end
|
||||
self._values.eventCallbacks = {}
|
||||
|
||||
self._props = nil
|
||||
self._values = nil
|
||||
self.basalt = nil
|
||||
self.parent = nil
|
||||
self.__index = nil
|
||||
|
||||
setmetatable(self, nil)
|
||||
end
|
||||
|
||||
--- Requests a render update for this element
|
||||
|
||||
@@ -464,4 +464,11 @@ function Container:render()
|
||||
end
|
||||
end
|
||||
|
||||
function Container:destroy()
|
||||
for _, child in ipairs(self._values.children) do
|
||||
child:destroy()
|
||||
end
|
||||
VisualElement.destroy(self)
|
||||
end
|
||||
|
||||
return Container
|
||||
@@ -47,7 +47,7 @@ end
|
||||
function Table:sortData(columnIndex)
|
||||
local data = self.get("data")
|
||||
local direction = self.get("sortDirection")
|
||||
|
||||
|
||||
table.sort(data, function(a, b)
|
||||
if direction == "asc" then
|
||||
return a[columnIndex] < b[columnIndex]
|
||||
@@ -55,7 +55,7 @@ function Table:sortData(columnIndex)
|
||||
return a[columnIndex] > b[columnIndex]
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
self.set("data", data)
|
||||
return self
|
||||
end
|
||||
@@ -65,7 +65,6 @@ function Table:mouse_click(button, x, y)
|
||||
|
||||
local relX, relY = self:getRelativePosition(x, y)
|
||||
|
||||
-- Header-Click für Sorting
|
||||
if relY == 1 then
|
||||
local currentX = 1
|
||||
for i, col in ipairs(self.get("columns")) do
|
||||
@@ -83,7 +82,6 @@ function Table:mouse_click(button, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
-- Row-Selection (berücksichtigt Scroll-Offset)
|
||||
if relY > 1 then
|
||||
local rowIndex = relY - 2 + self.get("scrollOffset")
|
||||
if rowIndex >= 0 and rowIndex < #self.get("data") then
|
||||
@@ -98,7 +96,7 @@ function Table:mouse_scroll(direction, x, y)
|
||||
local data = self.get("data")
|
||||
local height = self.get("height")
|
||||
local visibleRows = height - 2
|
||||
local maxScroll = math.max(0, #data - visibleRows + 1) -- +1 korrigiert den Scroll-Bereich
|
||||
local maxScroll = math.max(0, #data - visibleRows + 1)
|
||||
local newOffset = math.min(maxScroll, math.max(0, self.get("scrollOffset") + direction))
|
||||
|
||||
self.set("scrollOffset", newOffset)
|
||||
@@ -125,14 +123,12 @@ function Table:render()
|
||||
currentX = currentX + col.width
|
||||
end
|
||||
|
||||
-- Angepasste Berechnung der sichtbaren Zeilen
|
||||
local visibleRows = height - 2 -- Verfügbare Zeilen (minus Header)
|
||||
local visibleRows = height - 2
|
||||
for y = 2, height do
|
||||
local rowIndex = y - 2 + scrollOffset
|
||||
local rowData = data[rowIndex + 1]
|
||||
|
||||
-- Zeile nur rendern wenn es auch Daten dafür gibt
|
||||
if rowData and (rowIndex + 1) <= #data then -- Korrigierte Bedingung
|
||||
if rowData and (rowIndex + 1) <= #data then
|
||||
currentX = 1
|
||||
local bg = (rowIndex + 1) == selected and self.get("selectedColor") or self.get("background")
|
||||
|
||||
@@ -145,33 +141,28 @@ function Table:render()
|
||||
currentX = currentX + col.width
|
||||
end
|
||||
else
|
||||
-- Leere Zeile füllen
|
||||
self:blit(1, y, string.rep(" ", self.get("width")),
|
||||
string.rep(tHex[self.get("foreground")], self.get("width")),
|
||||
string.rep(tHex[self.get("background")], self.get("width")))
|
||||
end
|
||||
end
|
||||
|
||||
-- Scrollbar Berechnung überarbeitet
|
||||
if #data > height - 2 then
|
||||
local scrollbarHeight = height - 2
|
||||
local thumbSize = math.max(1, math.floor(scrollbarHeight * (height - 2) / #data))
|
||||
|
||||
-- Thumb Position korrigiert
|
||||
local maxScroll = #data - (height - 2) + 1 -- +1 für korrekte End-Position
|
||||
|
||||
local maxScroll = #data - (height - 2) + 1
|
||||
local scrollPercent = scrollOffset / maxScroll
|
||||
local thumbPos = 2 + math.floor(scrollPercent * (scrollbarHeight - thumbSize))
|
||||
|
||||
|
||||
if scrollOffset >= maxScroll then
|
||||
thumbPos = height - thumbSize -- Exakt am Ende
|
||||
thumbPos = height - thumbSize
|
||||
end
|
||||
|
||||
-- Scrollbar Background
|
||||
for y = 2, height do
|
||||
self:blit(self.get("width"), y, "\127", tHex[colors.gray], tHex[colors.gray])
|
||||
end
|
||||
|
||||
-- Thumb zeichnen
|
||||
for y = thumbPos, math.min(height, thumbPos + thumbSize - 1) do
|
||||
self:blit(self.get("width"), y, "\127", tHex[colors.white], tHex[colors.white])
|
||||
end
|
||||
|
||||
@@ -2,8 +2,6 @@ local elementManager = require("elementManager")
|
||||
local BaseElement = elementManager.getElement("BaseElement")
|
||||
local tHex = require("libraries/colorHex")
|
||||
|
||||
---@alias color number
|
||||
|
||||
---@class VisualElement : BaseElement
|
||||
local VisualElement = setmetatable({}, BaseElement)
|
||||
VisualElement.__index = VisualElement
|
||||
@@ -62,13 +60,24 @@ VisualElement.defineProperty(VisualElement, "visible", {default = true, type = "
|
||||
return value
|
||||
end})
|
||||
|
||||
---@combinedProperty position x y
|
||||
---@combinedProperty position {x y} Position of the element
|
||||
VisualElement.combineProperties(VisualElement, "position", "x", "y")
|
||||
---@combinedProperty size width height
|
||||
---@combinedProperty size {width height} Size of the element
|
||||
VisualElement.combineProperties(VisualElement, "size", "width", "height")
|
||||
---@combinedProperty color foreground background
|
||||
---@combinedProperty color {foreground background} Color of the element
|
||||
VisualElement.combineProperties(VisualElement, "color", "foreground", "background")
|
||||
|
||||
---@event onMouseClick {button number, x number, y number} Fired when the element is clicked
|
||||
---@event onMouseUp {button number, x number, y number} Fired when the mouse is released
|
||||
---@event onMouseRelease {button number, x number, y number} Fired when the mouse is released
|
||||
---@event onMouseDrag {button number, x number, y number} Fired when the mouse is dragged
|
||||
---@event onFocus {-} Fired when the element is focused
|
||||
---@event onBlur {-} Fired when the element is blurred
|
||||
---@event onKey {key number, code number, isRepeat boolean} Fired when a key is pressed
|
||||
---@event onKeyUp {key number, code number} Fired when a key is released
|
||||
---@event onChar {char string} Fired when a key is pressed
|
||||
|
||||
|
||||
VisualElement.listenTo(VisualElement, "focus")
|
||||
VisualElement.listenTo(VisualElement, "blur")
|
||||
|
||||
@@ -90,14 +99,7 @@ function VisualElement:init(props, basalt)
|
||||
self.set("type", "VisualElement")
|
||||
end
|
||||
|
||||
--- Draws a text character/fg/bg at the specified position with a certain size, used in the rendering system
|
||||
--- @param x number The x position to draw
|
||||
--- @param y number The y position to draw
|
||||
--- @param width number The width of the element
|
||||
--- @param height number The height of the element
|
||||
--- @param text string The text char to draw
|
||||
--- @param fg color The foreground color
|
||||
--- @param bg color The background color
|
||||
---@protected
|
||||
function VisualElement:multiBlit(x, y, width, height, text, fg, bg)
|
||||
x = x + self.get("x") - 1
|
||||
y = y + self.get("y") - 1
|
||||
@@ -260,7 +262,6 @@ function VisualElement:setCursor(x, y, blink)
|
||||
end
|
||||
|
||||
--- Renders the element
|
||||
--- @usage element:render()
|
||||
function VisualElement:render()
|
||||
if(not self.get("backgroundEnabled"))then
|
||||
return
|
||||
|
||||
19
src/log.lua
19
src/log.lua
@@ -1,3 +1,8 @@
|
||||
---@class Log
|
||||
---@field _logs table
|
||||
---@field _enabled boolean
|
||||
---@field _logToFile boolean
|
||||
---@field _logFile string
|
||||
local Log = {}
|
||||
Log._logs = {}
|
||||
Log._enabled = true
|
||||
@@ -6,7 +11,6 @@ Log._logFile = "basalt.log"
|
||||
|
||||
fs.delete(Log._logFile)
|
||||
|
||||
-- Log levels
|
||||
Log.LEVEL = {
|
||||
DEBUG = 1,
|
||||
INFO = 2,
|
||||
@@ -28,10 +32,12 @@ local levelColors = {
|
||||
[Log.LEVEL.ERROR] = colors.red
|
||||
}
|
||||
|
||||
--- Sets if the logger should log to a file.
|
||||
function Log.setLogToFile(enable)
|
||||
Log._logToFile = enable
|
||||
end
|
||||
|
||||
--- sets if the logger should log
|
||||
function Log.setEnabled(enable)
|
||||
Log._enabled = enable
|
||||
end
|
||||
@@ -51,7 +57,6 @@ local function log(level, ...)
|
||||
|
||||
local timeStr = os.date("%H:%M:%S")
|
||||
|
||||
-- Get caller info (skip log function and Log.debug/info/etc functions)
|
||||
local info = debug.getinfo(3, "Sl")
|
||||
local source = info.source:match("@?(.*)")
|
||||
local line = info.currentline
|
||||
@@ -69,9 +74,7 @@ local function log(level, ...)
|
||||
|
||||
local fullMessage = string.format("%s %s%s %s", timeStr, levelStr, levelMsg, message)
|
||||
|
||||
-- File output
|
||||
writeToFile(fullMessage)
|
||||
-- Store in memory
|
||||
table.insert(Log._logs, {
|
||||
time = timeStr,
|
||||
level = level,
|
||||
@@ -79,9 +82,17 @@ local function log(level, ...)
|
||||
})
|
||||
end
|
||||
|
||||
--- Sends a debug message to the logger.
|
||||
--- @vararg string The message to log
|
||||
function Log.debug(...) log(Log.LEVEL.DEBUG, ...) end
|
||||
--- Sends an info message to the logger.
|
||||
--- @vararg string The message to log
|
||||
function Log.info(...) log(Log.LEVEL.INFO, ...) end
|
||||
--- Sends a warning message to the logger.
|
||||
--- @vararg string The message to log
|
||||
function Log.warn(...) log(Log.LEVEL.WARN, ...) end
|
||||
--- Sends an error message to the logger.
|
||||
--- @vararg string The message to log
|
||||
function Log.error(...) log(Log.LEVEL.ERROR, ...) end
|
||||
|
||||
Log.info("Logger initialized")
|
||||
|
||||
28
src/main.lua
28
src/main.lua
@@ -8,7 +8,14 @@ local propertySystem = require("propertySystem")
|
||||
--- Before you can access Basalt, you need to add the following code on top of your file:
|
||||
--- @usage local basalt = require("basalt")
|
||||
--- What this code does is it loads basalt into the project, and you can access it by using the variable defined as "basalt".
|
||||
-- @module Basalt
|
||||
|
||||
--- @class Basalt
|
||||
--- @field traceback boolean Whether to show a traceback on errors
|
||||
--- @field _events table A table of events and their callbacks
|
||||
--- @field _schedule function[] A table of scheduled functions
|
||||
--- @field _plugins table A table of plugins
|
||||
--- @field LOGGER Log The logger instance
|
||||
--- @field path string The path to the Basalt library
|
||||
local basalt = {}
|
||||
basalt.traceback = true
|
||||
basalt._events = {}
|
||||
@@ -79,7 +86,8 @@ function basalt.create(type, properties, lazyLoading, parent)
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates and returns a new frame
|
||||
--- Creates and returns a new BaseFrame
|
||||
--- @shortDescription Creates a new BaseFrame
|
||||
--- @return table BaseFrame The created frame instance
|
||||
--- @usage local mainFrame = basalt.createFrame()
|
||||
function basalt.createFrame()
|
||||
@@ -90,6 +98,7 @@ function basalt.createFrame()
|
||||
end
|
||||
|
||||
--- Returns the element manager instance
|
||||
--- @shortDescription Returns the element manager
|
||||
--- @return table ElementManager The element manager
|
||||
--- @usage local manager = basalt.getElementManager()
|
||||
function basalt.getElementManager()
|
||||
@@ -97,6 +106,7 @@ function basalt.getElementManager()
|
||||
end
|
||||
|
||||
--- Gets or creates the main frame
|
||||
--- @shortDescription Gets or creates the main frame
|
||||
--- @return BaseFrame table The main frame instance
|
||||
--- @usage local frame = basalt.getMainFrame()
|
||||
function basalt.getMainFrame()
|
||||
@@ -107,6 +117,7 @@ function basalt.getMainFrame()
|
||||
end
|
||||
|
||||
--- Sets the active frame
|
||||
--- @shortDescription Sets the active frame
|
||||
--- @param frame table The frame to set as active
|
||||
--- @usage basalt.setActiveFrame(myFrame)
|
||||
function basalt.setActiveFrame(frame)
|
||||
@@ -114,6 +125,7 @@ function basalt.setActiveFrame(frame)
|
||||
end
|
||||
|
||||
--- Schedules a function to be updated
|
||||
--- @shortDescription Schedules a function to be updated
|
||||
--- @function scheduleUpdate
|
||||
--- @param func function The function to schedule
|
||||
--- @return number Id The schedule ID
|
||||
@@ -124,6 +136,7 @@ function basalt.scheduleUpdate(func)
|
||||
end
|
||||
|
||||
--- Removes a scheduled update
|
||||
--- @shortDescription Removes a scheduled update
|
||||
--- @function removeSchedule
|
||||
--- @param id number The schedule ID to remove
|
||||
--- @usage basalt.removeSchedule(scheduleId)
|
||||
@@ -131,7 +144,7 @@ function basalt.removeSchedule(id)
|
||||
basalt._schedule[id] = nil
|
||||
end
|
||||
|
||||
--- @local Internal event handler
|
||||
---@private
|
||||
local function updateEvent(event, ...)
|
||||
if(event=="terminate")then basalt.stop() end
|
||||
if lazyElementsEventHandler(event, ...) then return end
|
||||
@@ -149,7 +162,7 @@ local function updateEvent(event, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--- @local Internal render function
|
||||
---@private
|
||||
local function renderFrames()
|
||||
if(mainFrame)then
|
||||
mainFrame:render()
|
||||
@@ -157,6 +170,7 @@ local function renderFrames()
|
||||
end
|
||||
|
||||
--- Updates all scheduled functions
|
||||
--- @shortDescription Updates all scheduled functions
|
||||
--- @usage basalt.update()
|
||||
function basalt.update()
|
||||
for k,v in pairs(basalt._schedule) do
|
||||
@@ -167,6 +181,7 @@ function basalt.update()
|
||||
end
|
||||
|
||||
--- Stops the Basalt runtime
|
||||
--- @shortDescription Stops the Basalt runtime
|
||||
--- @usage basalt.stop()
|
||||
function basalt.stop()
|
||||
term.clear()
|
||||
@@ -175,6 +190,7 @@ function basalt.stop()
|
||||
end
|
||||
|
||||
--- Starts the Basalt runtime
|
||||
--- @shortDescription Starts the Basalt runtime
|
||||
--- @param isActive? boolean Whether to start active (default: true)
|
||||
--- @usage basalt.run()
|
||||
--- @usage basalt.run(false)
|
||||
@@ -197,6 +213,10 @@ function basalt.run(isActive)
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a Plugin API
|
||||
--- @shortDescription Returns a Plugin API
|
||||
--- @param name string The name of the plugin
|
||||
--- @return table Plugin The plugin API
|
||||
function basalt.getAPI(name)
|
||||
return elementManager.getAPI(name)
|
||||
end
|
||||
|
||||
@@ -11,7 +11,12 @@ local commentTypes = {
|
||||
"function",
|
||||
"local",
|
||||
"shortDescription",
|
||||
"property"
|
||||
"property",
|
||||
"combinedProperty",
|
||||
"event",
|
||||
"private",
|
||||
"protected",
|
||||
"field"
|
||||
}
|
||||
|
||||
local function extractComment(line)
|
||||
@@ -60,8 +65,11 @@ end
|
||||
function markdown.parse(content)
|
||||
local blocks = {}
|
||||
local properties = {}
|
||||
local combinedProperties = {}
|
||||
local events = {}
|
||||
local fields = {}
|
||||
local currentBlock = {type = "comment", desc = {}}
|
||||
local skipNextFunction = false
|
||||
|
||||
for line in content:gsub("\r\n", "\n"):gmatch("([^\n]*)\n?") do
|
||||
if line:match("^%s*$") or line == "" then
|
||||
@@ -76,6 +84,8 @@ function markdown.parse(content)
|
||||
if(commentType == "desc") then
|
||||
currentBlock.usageIsActive = false
|
||||
table.insert(currentBlock.desc, value)
|
||||
elseif(commentType == "private")or(commentType == "protected")then
|
||||
skipNextFunction = true
|
||||
else
|
||||
if(commentType == "module")then
|
||||
currentBlock.usageIsActive = false
|
||||
@@ -100,6 +110,11 @@ function markdown.parse(content)
|
||||
elseif(commentType == "property")then
|
||||
currentBlock = {type = "comment", desc = {}}
|
||||
table.insert(properties, value)
|
||||
elseif(commentType == "combinedProperty")then
|
||||
currentBlock = {type = "comment", desc = {}}
|
||||
table.insert(combinedProperties, value)
|
||||
elseif(commentType == "field")then
|
||||
table.insert(fields, value)
|
||||
elseif(commentType == "event")then
|
||||
currentBlock = {type = "comment", desc = {}}
|
||||
table.insert(events, value)
|
||||
@@ -113,10 +128,14 @@ function markdown.parse(content)
|
||||
|
||||
end
|
||||
else
|
||||
local funcName = getFunctionName(line)
|
||||
if funcName then
|
||||
currentBlock.func = funcName
|
||||
currentBlock.type = "function"
|
||||
if(skipNextFunction)then
|
||||
skipNextFunction = false
|
||||
else
|
||||
local funcName = getFunctionName(line)
|
||||
if funcName then
|
||||
currentBlock.func = funcName
|
||||
currentBlock.type = "function"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -141,7 +160,7 @@ function markdown.parse(content)
|
||||
return a.func < b.func
|
||||
end)
|
||||
|
||||
markdown.blocks = {properties = properties, events = events}
|
||||
markdown.blocks = {combinedProperties = combinedProperties, properties = properties, events = events, fields = fields}
|
||||
for _, block in ipairs(otherBlocks) do
|
||||
table.insert(markdown.blocks, block)
|
||||
end
|
||||
@@ -192,6 +211,27 @@ local function markdownFunction(block)
|
||||
return output
|
||||
end
|
||||
|
||||
local function markdownFields()
|
||||
if(#markdown.blocks.fields<=0)then
|
||||
return ""
|
||||
end
|
||||
local output = "\n## Fields\n\n|Field|Type|Description|\n|---|---|---|\n"
|
||||
for _, block in pairs(markdown.blocks.fields) do
|
||||
local name, rest = block:match("([%w_]+)%s+(.+)")
|
||||
if name and rest then
|
||||
local fieldType, desc = rest:match("([^%s].-)%s+([^%s].*)")
|
||||
if fieldType and desc then
|
||||
output = output .. string.format("|%s|`%s`|%s|\n",
|
||||
name,
|
||||
fieldType,
|
||||
desc or ""
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
local function markdownProperties()
|
||||
if(#markdown.blocks.properties<=0)then
|
||||
return ""
|
||||
@@ -204,18 +244,36 @@ local function markdownProperties()
|
||||
return output
|
||||
end
|
||||
|
||||
local function markdownCombinedProperties()
|
||||
if(markdown.blocks.combinedProperties==nil)then
|
||||
return ""
|
||||
end
|
||||
if(#markdown.blocks.combinedProperties<=0)then
|
||||
return ""
|
||||
end
|
||||
local output = "\n## Combined Properties\n\n|Name|Properties|Description|\n|---|---|---|\n"
|
||||
for _, block in pairs(markdown.blocks.combinedProperties) do
|
||||
local name, paramType, defaultValue, desc = block:match("([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+(.*)")
|
||||
output = output .. string.format("|%s|%s|%s|%s\n", name, paramType, defaultValue, desc)
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
local function markdownEvents()
|
||||
if(#markdown.blocks.events<=0)then
|
||||
return ""
|
||||
end
|
||||
local output = "\n## Events\n\n"
|
||||
for _, block in pairs(markdown.blocks) do
|
||||
if block.type == "module" or block.type == "class" then
|
||||
if(block.event~=nil)then
|
||||
for _, line in pairs(block.event) do
|
||||
output = output .. "* " .. line .. "\n"
|
||||
end
|
||||
end
|
||||
local output = "\n## Events\n\n|Event|Parameters|Description|\n|---|---|---|\n"
|
||||
|
||||
for _, event in pairs(markdown.blocks.events) do
|
||||
local name, params, desc = event:match("([%w_]+)%s+{([^}]+)}%s*(.*)")
|
||||
if name and params then
|
||||
local formattedParams = params:gsub("%s*,%s*", ", ")
|
||||
output = output .. string.format("|%s|`%s`|%s|\n",
|
||||
name,
|
||||
formattedParams,
|
||||
desc or ""
|
||||
)
|
||||
end
|
||||
end
|
||||
return output
|
||||
@@ -263,7 +321,9 @@ local function markdownModule(block)
|
||||
output = output .. line .. "\n"
|
||||
end
|
||||
|
||||
output = output .. markdownFields()
|
||||
output = output .. markdownProperties()
|
||||
output = output .. markdownCombinedProperties()
|
||||
output = output .. markdownEvents()
|
||||
output = output .. markdownModuleOrClassFunctions(block)
|
||||
output = output .. "\n"
|
||||
@@ -288,7 +348,9 @@ local function markdownClass(block)
|
||||
output = output .. line .. "\n"
|
||||
end
|
||||
|
||||
output = output .. markdownFields()
|
||||
output = output .. markdownProperties()
|
||||
output = output .. markdownCombinedProperties()
|
||||
output = output .. markdownEvents()
|
||||
output = output .. markdownModuleOrClassFunctions(block)
|
||||
output = output .. "\n"
|
||||
|
||||
Reference in New Issue
Block a user