[doc] Tag @todo, @fixme and @warning (#5244)

This commit standardizes the various todos around the code a bit in a manner recognized by LDoc.

Besides drawing more attention by being displayed in the developer docs, they're also extractable with LDoc on the command line:

```sh
ldoc --tags todo,fixme *.lua
```

However, whether that particular usage offers any advantage over other search tools is questionable at best.

* and some random beautification
pull/5254/head
Frans de Jonge 5 years ago committed by GitHub
parent dc6d4085ea
commit a2dcfe9aec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -28,10 +28,11 @@ if [ "${tab_detected}" ]; then
exit 1
fi
newline_split=$(grep -Pzo "(_|gettext)\((\n|\s)+('|\"|\[\[)" --include \*.lua --exclude={dateparser.lua,xml.lua} --recursive {reader,setupkoenv,datastorage}.lua frontend plugins spec || true)
if [ "${newline_split}" ]; then
echo -e "\\n${ANSI_RED}Warning: whitespace detected between gettext() call and string."
echo "${newline_split}"
untagged_todo=$(grep -Pin "[^\-]\-\-\s+@?(todo|fixme|warning)" --include \*.lua --exclude={dateparser.lua,xml.lua} --recursive {reader,setupkoenv,datastorage}.lua frontend plugins spec || true)
if [ "${untagged_todo}" ]; then
echo -e "\\n${ANSI_RED}Warning: possible improperly tagged todo, fixme or warning detected."
echo -e "\\n${ANSI_RED} use --- followed by @todo, @fixme or @warning."
echo "${untagged_todo}"
exit 1
fi

@ -21,4 +21,5 @@ sort_modules = true
file = {
'../frontend',
'../base/ffi',
'../platform/android/luajit-launcher/assets',
}

@ -86,10 +86,10 @@ function FileSearcher:close()
if self.search_value then
UIManager:close(self.search_dialog)
if string.len(self.search_value) > 0 then
self:readDir() -- TODO this probably doesn't need to be repeated once it's been done
self:setSearchResults() -- TODO doesn't have to be repeated if the search term is the same
self:readDir() --- @todo this probably doesn't need to be repeated once it's been done
self:setSearchResults() --- @todo doesn't have to be repeated if the search term is the same
if #self.results > 0 then
self:showSearchResults() -- TODO something about no results
self:showSearchResults() --- @todo something about no results
else
UIManager:show(
InfoMessage:new{

@ -83,7 +83,7 @@ function SetDefaults:init()
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
}
-- FIXME:
--- @fixme
-- in this use case (an input dialog is closed and the menu container is
-- opened immediately) we need to set the full screen dirty because
-- otherwise only the input dialog part of the screen is refreshed.

@ -346,7 +346,7 @@ function ReaderGesture:addToMainMenu(menu_items)
end
custom_multiswipes:addTableItem("multiswipes", recorded_multiswipe)
-- TODO implement some nicer method in TouchMenu than this ugly hack for updating the menu
--- @todo Implement some nicer method in TouchMenu than this ugly hack for updating the menu.
touchmenu_instance.item_table[3] = self:genMultiswipeSubmenu()
touchmenu_instance:updateItems()
UIManager:close(multiswipe_recorder)

@ -436,7 +436,7 @@ function ReaderHighlight:onHold(arg, ges)
self.view.highlight.temp[self.hold_pos.page] = boxes
end
UIManager:setDirty(self.dialog, "ui")
-- TODO: only mark word?
--- @todo only mark word?
-- Unfortunately, CREngine does not return good coordinates
-- UIManager:setDirty(self.dialog, "partial", self.selected_word.sbox)
self.hold_start_tv = TimeVal.now()

@ -182,7 +182,7 @@ function ReaderPaging:onReadSettings(config)
end
function ReaderPaging:onSaveSettings()
-- TODO: only save current_page page position
--- @todo only save current_page page position
self.ui.doc_settings:saveSetting("page_positions", self.page_positions)
self.ui.doc_settings:saveSetting("last_page", self:getTopPage())
self.ui.doc_settings:saveSetting("percent_finished", self:getLastPercent())
@ -203,7 +203,7 @@ function ReaderPaging:getLastPercent()
end
function ReaderPaging:addToMainMenu(menu_items)
-- FIXME: repeated code with page overlap menu for readerrolling
--- @fixme repeated code with page overlap menu for readerrolling
-- needs to keep only one copy of the logic as for the DRY principle.
-- The difference between the two menus is only the enabled func.
local page_overlap_menu = {

@ -159,7 +159,7 @@ function ReaderRolling:onReadSettings(config)
self.ui.document:gotoXPointer(self.xpointer)
end
-- we read last_percent just for backward compatibility
-- FIXME: remove this branch with migration script
--- @fixme remove this branch with migration script
elseif last_per then
self.setupXpointer = function()
self:_gotoPercent(last_per)
@ -343,7 +343,7 @@ function ReaderRolling:getLastProgress()
end
function ReaderRolling:addToMainMenu(menu_items)
-- FIXME: repeated code with page overlap menu for readerpaging
--- @fixme repeated code with page overlap menu for readerpaging
-- needs to keep only one copy of the logic as for the DRY principle.
-- The difference between the two menus is only the enabled func.
local overlap_lines_help_text = _([[
@ -407,7 +407,7 @@ function ReaderRolling:getLastPercent()
if self.view.view_mode == "page" then
return self.current_page / self.old_page
else
-- FIXME: the calculated percent is not accurate in "scroll" mode.
--- @fixme the calculated percent is not accurate in "scroll" mode.
return self.ui.document:getPosFromXPointer(
self.ui.document:getXPointer()) / self.ui.document.info.doc_height
end

@ -23,7 +23,7 @@ function ReaderRotation:init()
end
end
-- @TODO: reset rotation on new document, maybe on new page?
--- @todo Reset rotation on new document, maybe on new page?
function ReaderRotation:onRotate(rotate_by)
self.current_rotation = (self.current_rotation + rotate_by) % 360

@ -147,7 +147,7 @@ function ReaderSearch:onShowSearchDialog(text)
}
do_search(self.searchFromCurrent, text, 0)()
UIManager:show(self.search_dialog)
-- TODO: regional
--- @todo regional
UIManager:setDirty(self.dialog, "partial")
return true
end

@ -698,8 +698,8 @@ function ReaderView:onSetScreenMode(new_mode, rotation, noskip)
if new_mode == "landscape" or new_mode == "portrait" then
self.screen_mode = new_mode
-- NOTE: Hacky hack! If rotation is "true", that's actually an "interactive" flag for setScreenMode
-- FIXME: That's because we can't store nils in a table, which is what Event:new attempts to do ;).
-- c.f., https://stackoverflow.com/q/7183998/ & http://lua-users.org/wiki/VarargTheSecondClassCitizen
--- @fixme That's because we can't store nils in a table, which is what Event:new attempts to do ;).
-- c.f., <https://stackoverflow.com/q/7183998/> & <http://lua-users.org/wiki/VarargTheSecondClassCitizen>
-- With a fixed Event implementation, we'd instead stick "interactive" in a third argument,
-- which we could happily pass while still keeping rotation nil ;).
if rotation ~= nil and rotation ~= true then

@ -116,9 +116,6 @@ function ReaderZooming:init()
end
function ReaderZooming:onReadSettings(config)
-- @TODO config file from old code base uses globalzoom_mode
-- instead of zoom_mode, we need to handle this imcompatibility
-- 04.12 2012 (houqp)
local zoom_mode = config:readSetting("zoom_mode") or
G_reader_settings:readSetting("zoom_mode") or
self.DEFAULT_ZOOM_MODE

@ -451,7 +451,7 @@ function ReaderUI:showReader(file, provider)
return
end
-- prevent crash due to incompatible bookmarks
-- @TODO split bookmarks from metadata and do per-engine in conversion
--- @todo Split bookmarks from metadata and do per-engine in conversion.
provider = provider or DocumentRegistry:getProvider(file)
if provider.provider then
local doc_settings = DocSettings:open(file)

@ -52,7 +52,7 @@ function Dbg:turnOn()
return check
end
-- TODO: close ev.log fd for children
--- @todo close ev.log fd for children
-- create or clear ev log file
self.ev_log = io.open("ev.log", "w")
end

@ -497,7 +497,7 @@ function GestureDetector:handleSwipe(tev)
logger.dbg("multiswipe", multiswipe_directions)
end
-- TODO: dirty hack for some weird devices, replace it with better solution
--- @todo dirty hack for some weird devices, replace it with better solution
if swipe_direction == "west" and DCHANGE_WEST_SWIPE_TO_EAST then
swipe_direction = "east"
elseif swipe_direction == "east" and DCHANGE_EAST_SWIPE_TO_WEST then

@ -415,11 +415,11 @@ function Input:handleKeyBoardEv(ev)
or keycode == "RPgBack"
or keycode == "LPgFwd"
or keycode == "RPgFwd" then
-- FIXME: Crappy event staggering!
--- @fixme Crappy event staggering!
-- The Forma repeats every 80ms after a 400ms delay, and 500ms roughly corresponds to a flashing update,
-- so stuff is usually in sync when you release the key.
-- Obvious downside is that this ends up slower than just mashing the key.
-- FIXME: A better approach would be an onKeyRelease handler that flushes the Event queue...
--- @fixme A better approach would be an onKeyRelease handler that flushes the Event queue...
self.repeat_count = self.repeat_count + 1
if self.repeat_count == 1 then
return Event:new("KeyRepeat", key)
@ -841,7 +841,7 @@ function Input:waitEvent(timeout_us)
ev = nil
break
elseif ev == "application forced to quit" then
-- TODO: return an event that can be handled
--- @todo return an event that can be handled
os.exit(0)
end
logger.warn("got error waiting for events:", ev)

@ -665,11 +665,11 @@ function KindleOasis2:init()
}
}
-- FIXME: When starting KOReader with the device upside down ("D"), touch input is registered wrong
--- @fixme When starting KOReader with the device upside down ("D"), touch input is registered wrong
-- (i.e., probably upside down).
-- If it's started upright ("U"), everything's okay, and turning it upside down after that works just fine.
-- See #2206 & #2209 for the original KOA implementation, which obviously doesn't quite cut it here...
-- See also https://www.mobileread.com/forums/showthread.php?t=298302&page=5
-- See also <https://www.mobileread.com/forums/showthread.php?t=298302&page=5>
-- NOTE: It'd take some effort to actually start KOReader while in a LANDSCAPE orientation,
-- since they're only exposed inside the stock reader, and not the Home/KUAL Booklets.
local haslipc, lipc = pcall(require, "liblipclua")

@ -45,7 +45,7 @@ local Kobo = Generic:new{
canHWInvert = yes,
}
-- TODO: hasKeys for some devices?
--- @todo hasKeys for some devices?
-- Kobo Touch:
local KoboTrilogy = Kobo:new{
@ -140,7 +140,7 @@ local KoboSnow = Kobo:new{
}
-- Kobo Aura H2O2, Rev2:
-- FIXME: Check if the Clara fix actually helps here... (#4015)
--- @fixme Check if the Clara fix actually helps here... (#4015)
local KoboSnowRev2 = Kobo:new{
model = "Kobo_snow_r2",
hasFrontlight = yes,
@ -163,7 +163,7 @@ local KoboStar = Kobo:new{
}
-- Kobo Aura second edition, Rev 2:
-- FIXME: Confirm that this is accurate? If it is, and matches the Rev1, ditch the special casing.
--- @fixme Confirm that this is accurate? If it is, and matches the Rev1, ditch the special casing.
local KoboStarRev2 = Kobo:new{
model = "Kobo_star_r2",
hasFrontlight = yes,
@ -452,7 +452,7 @@ function Kobo:initEventAdjustHooks()
if self.touch_mirrored_x then
self.input:registerEventAdjustHook(
self.input.adjustTouchMirrorX,
-- FIXME: what if we change the screen portrait mode?
--- @fixme what if we change the screen portrait mode?
self.screen:getWidth()
)
end

@ -24,7 +24,7 @@ local KoboPowerD = BasePowerD:new{
fl_was_on = nil,
}
-- TODO: Remove KOBO_LIGHT_ON_START
--- @todo Remove KOBO_LIGHT_ON_START
function KoboPowerD:_syncKoboLightOnStart()
local new_intensity = nil
local is_frontlight_on = nil

@ -68,7 +68,7 @@ function PocketBook:blacklistCBB()
local C = ffi.C
-- As well as on those than can't do HW inversion, as otherwise NightMode would be ineffective.
-- FIXME: Either relax the HWInvert check, or actually enable HWInvert on PB if it's safe and it works,
--- @fixme Either relax the HWInvert check, or actually enable HWInvert on PB if it's safe and it works,
-- as, currently, no PB device is marked as canHWInvert, so, the C BB is essentially *always* blacklisted.
if not self:canUseCBB() or not self:canHWInvert() then
logger.info("Blacklisting the C BB on this device")

@ -201,7 +201,8 @@ function Device:init()
-- this means we can't just return one ScreenResize or SetDimensons event
UIManager:broadcastEvent(Event:new("SetDimensions", new_size))
UIManager:broadcastEvent(Event:new("ScreenResize", new_size))
-- @TODO toggle this elsewhere based on ScreenResize?
--- @todo Toggle this elsewhere based on ScreenResize?
-- this triggers paged media like PDF and DjVu to redraw
-- CreDocument doesn't need it
UIManager:broadcastEvent(Event:new("RedrawCurrentPage"))

@ -93,7 +93,7 @@ end
-- @string docfile path to the document (e.g., `/foo/bar.pdf`)
-- @treturn DocSettings object
function DocSettings:open(docfile)
-- TODO(zijiehe): Remove history_path, use only sidecar.
--- @todo (zijiehe): Remove history_path, use only sidecar.
local new = {}
new.history_file = self:getHistoryPath(docfile)

@ -366,7 +366,7 @@ function CreDocument:drawCurrentView(target, x, y, rect, pos)
-- to match the screen's BB type, allowing us to take shortcuts when blitting.
self.buffer = Blitbuffer.new(rect.w, rect.h, self.render_color and Blitbuffer.TYPE_BBRGB32 or nil)
end
-- TODO: self.buffer could be re-used when no page/layout/highlights
--- @todo self.buffer could be re-used when no page/layout/highlights
-- change has been made, to avoid having crengine redraw the exact
-- same buffer. And it could only change when some other methods
-- from here are called
@ -714,7 +714,7 @@ function CreDocument:setStyleSheet(new_css_file, appended_css_content )
end
function CreDocument:setEmbeddedStyleSheet(toggle)
-- FIXME: occasional segmentation fault when switching embedded style sheet
--- @fixme occasional segmentation fault when switching embedded style sheet
logger.dbg("CreDocument: set embedded style sheet", toggle)
self._document:setIntProperty("crengine.doc.embedded.styles.enabled", toggle)
end
@ -748,7 +748,7 @@ function CreDocument:setNightmodeImages(toggle)
end
function CreDocument:setFloatingPunctuation(enabled)
-- FIXME: occasional segmentation fault when toggling floating punctuation
--- @fixme occasional segmentation fault when toggling floating punctuation
logger.dbg("CreDocument: set floating punctuation", enabled)
self._document:setIntProperty("crengine.style.floating.punctuation.enabled", enabled)
end

@ -331,7 +331,7 @@ function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
if not Cache:willAccept(size.w * size.h + 64) then
-- whole page won't fit into cache
logger.dbg("rendering only part of the page")
-- TODO: figure out how to better segment the page
--- @todo figure out how to better segment the page
if not rect then
logger.warn("aborting, since we do not have a specification for that part")
-- required part not given, so abort
@ -380,7 +380,7 @@ function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
end
-- a hint for the cache engine to paint a full page to the cache
-- TODO: this should trigger a background operation
--- @todo this should trigger a background operation
function Document:hintPage(pageno, zoom, rotation, gamma, render_mode)
logger.dbg("hinting page", pageno)
self:renderPage(pageno, nil, zoom, rotation, gamma, render_mode)

@ -105,7 +105,7 @@ end
function DocumentRegistry:getProviders(file)
local providers = {}
-- TODO: some implementation based on mime types?
--- @todo some implementation based on mime types?
for _, provider in ipairs(self.providers) do
local suffix = string.sub(file, -string.len(provider.extension) - 1)
if string.lower(suffix) == "."..provider.extension then

@ -49,7 +49,7 @@ local function _serialize(what, outt, indent, max_lv, history)
insert(outt, string.format("%q", what))
elseif type(what) == "number" then
if isUbuntuTouch then
-- FIXME: the `SDL_CreateRenderer` function in Ubuntu touch somehow
--- @fixme The `SDL_CreateRenderer` function in Ubuntu touch somehow
-- use a strange locale that formats number like this: 1.10000000000000g+02
-- which cannot be recognized by loadfile after the number is dumped.
-- Here the workaround is to preserve enough precision in "%.13e" format.

@ -43,7 +43,7 @@ function LuaSettings:open(file_path)
return setmetatable(new, {__index = LuaSettings})
end
-- TODO: DocSettings can return a LuaSettings to use following awesome features.
--- @todo DocSettings can return a LuaSettings to use following awesome features.
function LuaSettings:wrap(data)
local new = {data = type(data) == "table" and data or {}}
return setmetatable(new, {__index = LuaSettings})

@ -46,7 +46,7 @@ end
function ReadHistory:_indexing(start)
assert(self ~= nil)
-- TODO(Hzj_jie): Use binary search to find an item when deleting it.
--- @todo (Hzj_jie): Use binary search to find an item when deleting it.
for i = start, #self.hist, 1 do
self.hist[i].index = i
end
@ -60,7 +60,7 @@ function ReadHistory:_sort()
self:clearMissing()
end
table.sort(self.hist, fileFirstOrdering)
-- TODO(zijiehe): Use binary insert instead of a loop to deduplicate.
--- @todo (zijiehe): Use binary insert instead of a loop to deduplicate.
for i = #self.hist, 2, -1 do
if self.hist[i].file == self.hist[i - 1].file then
table.remove(self.hist, i)
@ -186,7 +186,7 @@ function ReadHistory:addItem(file)
if file ~= nil and lfs.attributes(file, "mode") == "file" then
local now = os.time()
table.insert(self.hist, 1, buildEntry(now, file))
-- TODO(zijiehe): We do not need to sort if we can use binary insert and
--- @todo (zijiehe): We do not need to sort if we can use binary insert and
-- binary search.
-- util.execute("/bin/touch", "-a", file)
-- This emulates `touch -a` in LuaFileSystem's API, since it may be absent (Android)

@ -320,14 +320,14 @@ return {
"Q",
north = "[",
northeast = "{",
-- todo render q̃ correctly on key (not a problem in textbox?)
--- @todo Render q̃ correctly on key (not a problem in textbox?)
--east = {"q̃"}, -- Old/Middle French abbreviation of que
},
_q_ = {
"q",
north = "[",
northeast = "{",
-- todo render q̃ correctly on key (not a problem in textbox?)
--- @todo Render q̃ correctly on key (not a problem in textbox?)
--east = {"q̃"}, -- Old/Middle French abbreviation of que
},
_R_ = {

@ -166,7 +166,7 @@ Returns a new rectangle for the part that we and a given rectangle share
@tparam Geom rect_b
@treturn Geom
]]--
-- TODO: what happens if there is no rectangle shared? currently behaviour is undefined.
--- @todo what happens if there is no rectangle shared? currently behaviour is undefined.
function Geom:intersect(rect_b)
-- make a copy of self
local intersected = self:copy()

@ -16,10 +16,10 @@ function FileMessageQueue:init()
self.filemq = self.client
self.poller = czmq.zpoller_new(filemq.fmq_client_handle(self.client), nil)
elseif self.server ~= nil then
-- TODO: currently fmq_server_recv API is not available
--- @todo currently fmq_server_recv API is not available
--self.fmq_recv = filemq.fmq_server_recv
self.filemq = self.server
-- TODO: currently fmq_server_handle API is not available
--- @todo currently fmq_server_handle API is not available
--self.poller = czmq.zpoller_new(filemq.fmq_server_handle(self.server), nil)
end
end

@ -24,7 +24,7 @@ function StreamMessageQueue:start()
end
local id_size = ffi.new("size_t[1]", 256)
local buffer = ffi.new("uint8_t[?]", id_size[0])
-- @todo: check return of zmq_getsockopt
--- @todo: Check return of zmq_getsockopt()
zmq.zmq_getsockopt(self.socket, C.ZMQ_IDENTITY, buffer, id_size)
self.id = ffi.string(buffer, id_size[0])
logger.dbg("id", #self.id, self.id)

@ -266,7 +266,7 @@ function NetworkMgr:getInfoMenuTable()
return {
text = _("Network info"),
keep_menu_open = true,
-- TODO: also show network info when device is authenticated to router but offline
--- @todo also show network info when device is authenticated to router but offline
enabled_func = function() return self:isWifiOn() end,
callback = function()
if Device.retrieveNetworkInfo then
@ -350,7 +350,7 @@ function NetworkMgr:showNetworkMenu(complete_callback)
end
-- NOTE: Fairly hackish workaround for #4387,
-- rescan if the first scan appeared to yield an empty list.
-- FIXME: This *might* be an issue better handled in lj-wpaclient...
--- @fixme This *might* be an issue better handled in lj-wpaclient...
if (table.getn(network_list) == 0) then
network_list, err = self:getNetworkList()
if network_list == nil then

@ -1,3 +1,7 @@
--[[--
WPA client helper for Kobo.
]]
local InfoMessage = require("ui/widget/infomessage")
local WpaClient = require('lj-wpaclient/wpaclient')
local UIManager = require("ui/uimanager")
@ -9,6 +13,7 @@ local CLIENT_INIT_ERR_MSG = _("Failed to initialize network control client: %1."
local WpaSupplicant = {}
--- Gets network list.
function WpaSupplicant:getNetworkList()
local wcli, err = WpaClient.new(self.wpa_supplicant.ctrl_interface)
if wcli == nil then
@ -25,12 +30,12 @@ function WpaSupplicant:getNetworkList()
network.signal_quality = network:getSignalQuality()
local saved_nw = saved_networks:readSetting(network.ssid)
if saved_nw then
-- TODO: verify saved_nw.flags == network.flags? This will break if user changed the
--- @todo verify saved_nw.flags == network.flags? This will break if user changed the
-- network setting from [WPA-PSK-TKIP+CCMP][WPS][ESS] to [WPA-PSK-TKIP+CCMP][ESS]
network.password = saved_nw.password
network.psk = saved_nw.psk
end
-- TODO: also verify bssid if it is not set to any
--- @todo also verify bssid if it is not set to any
if curr_network and curr_network.ssid == network.ssid then
network.connected = true
network.wpa_supplicant_id = curr_network.id
@ -40,20 +45,21 @@ function WpaSupplicant:getNetworkList()
end
local function calculatePsk(ssid, pwd)
-- TODO: calculate PSK with native function instead of shelling out
--- @todo calculate PSK with native function instead of shelling out
-- hostap's reference implementation is available at:
-- * /wpa_supplicant/wpa_passphrase.c
-- * /src/crypto/sha1-pbkdf2.c
-- see: http://docs.ros.org/diamondback/api/wpa_supplicant/html/sha1-pbkdf2_8c_source.html
-- see: <http://docs.ros.org/diamondback/api/wpa_supplicant/html/sha1-pbkdf2_8c_source.html>
local fp = io.popen(("wpa_passphrase %q %q"):format(ssid, pwd))
local out = fp:read("*a")
fp:close()
return string.match(out, 'psk=([a-f0-9]+)')
end
--- Authenticates network.
function WpaSupplicant:authenticateNetwork(network)
-- TODO: support passwordless network
local err, wcli, nw_id
--- @todo support passwordless network
wcli, err = WpaClient.new(self.wpa_supplicant.ctrl_interface)
if not wcli then
return false, T(CLIENT_INIT_ERR_MSG, err)

@ -1,3 +1,7 @@
--[[--
Checks for updates on the specified nightly build server.
]]
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Device = require("device")
@ -334,8 +338,9 @@ function OTAManager:fetchAndProcessUpdate()
end
end
---- Uses zsync and tar to prepare an update package.
function OTAManager:_buildLocalPackage()
-- TODO: validate the installed package?
--- @todo Validate the installed package?
local installed_package = self.installed_package
if lfs.attributes(installed_package, "mode") == "file" then
return 0

@ -37,7 +37,7 @@ local function utf8Chars(input_text)
if string.len(input) < pos then return nil end
local value = string.byte(input, pos)
if band(value, 0x80) == 0 then
-- TODO: check valid ranges
--- @todo check valid ranges
return pos+1, value, string.sub(input, pos, pos)
elseif band(value, 0xC0) == 0x80 -- invalid, continuation
or band(value, 0xF8) == 0xF8 -- 5-or-more byte sequence, illegal due to RFC3629
@ -70,7 +70,7 @@ local function utf8Chars(input_text)
return pos+1, 0xFFFD, "\xFF\xFD"
end
end
-- TODO: check for valid ranges here!
--- @todo check for valid ranges here!
return pos+bytes_left+1, glyph, string.sub(input, pos, pos+bytes_left)
end
end

@ -184,7 +184,7 @@ function Trapper:info(text, fast_refresh)
-- continue processing
end
-- TODO We should try to flush any pending tap, so past
--- @todo We should try to flush any pending tap, so past
-- events won't be considered action on the yet to be displayed
-- widget
@ -266,7 +266,7 @@ function Trapper:confirm(text, cancel_text, ok_text)
return true -- always select "OK" in ConfirmBox if no UI
end
-- TODO We should try to flush any pending tap, so past
--- @todo We should try to flush any pending tap, so past
-- events won't be considered action on the yet to be displayed
-- widget

@ -544,7 +544,7 @@ function UIManager:setDirty(widget, refreshtype, refreshregion, refreshdither)
-- callback, will be issued after painting
table.insert(self._refresh_func_stack, refreshtype)
if dbg.is_on then
-- FIXME: We can't consume the return values of refreshtype by running it, because for a reason that is beyond me (scoping? gc?), that renders it useless later, meaning we then enqueue refreshes with bogus arguments...
--- @fixme We can't consume the return values of refreshtype by running it, because for a reason that is beyond me (scoping? gc?), that renders it useless later, meaning we then enqueue refreshes with bogus arguments...
-- Thankfully, we can track them in _refresh()'s logging very soon after that...
logger.dbg("setDirty via a func from widget", widget and (widget.name or widget.id or tostring(widget)) or "nil")
end
@ -1050,7 +1050,7 @@ function UIManager:handleInput()
if self.looper then
logger.info("handle input in turbo I/O looper")
self.looper:add_callback(function()
-- FIXME: force close looper when there is unhandled error,
--- @fixme Force close looper when there is unhandled error,
-- otherwise the looper will hang. Any better solution?
xpcall(function() self:handleInput() end, function(err)
io.stderr:write(err .. "\n")

@ -208,7 +208,7 @@ function BBoxWidget:onSwipeAdjust(arg, ges)
end
function BBoxWidget:onHoldAdjust(arg, ges)
-- FIXME: this is a dirty hack to disable hold gesture in page cropping
--- @fixme this is a dirty hack to disable hold gesture in page cropping
-- since Kobo devices may append hold gestures to each swipe gesture rendering
-- relative replacement impossible. See koreader/koreader#987 at Github.
--self:adjustScreenBBox(ges)

@ -187,7 +187,7 @@ function ConfigOption:init()
local padding_small = Size.padding.small -- internal padding for options names (left)
local padding_button = Size.padding.button -- padding for underline below letters and icons
-- @TODO restore setting when there are more advanced settings
--- @todo Restore setting when there are more advanced settings.
--local show_advanced = G_reader_settings:readSetting("show_advanced") or false
local show_advanced = true

@ -65,7 +65,7 @@ function AlphaContainer:paintTo(bb, x, y)
end
-- now have our childs paint to the private blitbuffer
-- TODO: should we clean before painting?
--- @todo should we clean before painting?
self[1]:paintTo(private_bb, 0, 0)
-- blit the private blitbuffer to our parent blitbuffer

@ -10,7 +10,7 @@ local BottomContainer = WidgetContainer:new()
function BottomContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
-- FIXME
--- @fixme
-- if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this

@ -8,7 +8,7 @@ local CenterContainer = WidgetContainer:new()
function CenterContainer:paintTo(bb, x, y)
local content_size = self[1]:getSize()
-- FIXME
--- @fixme
-- if content_size.w > self.dimen.w or content_size.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this

@ -8,7 +8,7 @@ local LeftContainer = WidgetContainer:new()
function LeftContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
-- FIXME
--- @fixme
-- if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this

@ -8,7 +8,7 @@ local RightContainer = WidgetContainer:new()
function RightContainer:paintTo(bb, x, y)
local contentSize = self[1]:getSize()
-- FIXME
--- @fixme
-- if contentSize.w > self.dimen.w or contentSize.h > self.dimen.h then
-- throw error? paint to scrap buffer and blit partially?
-- for now, we ignore this

@ -12,7 +12,7 @@ local WidgetContainer = require("ui/widget/container/widgetcontainer")
local UnderlineContainer = WidgetContainer:new{
linesize = Size.line.thick,
padding = Size.padding.tiny,
-- TODO: shouldn't this default to black instead?
--- @todo shouldn't this default to black instead?
color = Blitbuffer.COLOR_WHITE,
vertical_align = "top",
}

@ -411,7 +411,7 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
})
local text_auto_nl = TextBoxWidget:new{
-- @TODO implement padding_right (etc.) on TextBoxWidget and remove the two-space hack
--- @todo Implement padding_right (etc.) on TextBoxWidget and remove the two-space hack.
text = _("Max. at:") .. " ",
face = self.larger_font_face,
alignment = "right",

@ -84,7 +84,7 @@ function InfoMessage:init()
local image_widget
if self.show_icon then
-- TODO: remove self.image support, only used in filemanagersearch
--- @todo remove self.image support, only used in filemanagersearch
-- this requires self.image's lifecycle to be managed by ImageWidget
-- instead of caller, which is easy to introduce bugs
if self.image then

@ -362,7 +362,7 @@ function InputText:initTextBox(text, char_added)
}
self[1] = self._frame
self.dimen = self._frame:getSize()
-- FIXME: self.parent is not always in the widget stack (BookStatusWidget)
--- @fixme self.parent is not always in the widget stack (BookStatusWidget)
UIManager:setDirty(self.parent, function()
return "ui", self.dimen
end)

@ -879,7 +879,7 @@ function Menu:truncatePath(text)
end
function Menu:onCloseWidget()
-- FIXME:
--- @fixme
-- we cannot refresh regionally using the dimen field
-- because some menus without menu title use VerticalGroup to include
-- a text widget which is not calculated into the dimen.
@ -1037,7 +1037,7 @@ function Menu:switchItemTable(new_title, new_item_table, itemnumber, itemmatch)
end
function Menu:onScreenResize(dimen)
-- @TODO investigate: could this cause minor memory leaks?
--- @todo Investigate: could this cause minor memory leaks?
self:init()
return false
end

@ -61,7 +61,7 @@ local Screen = Device.screen
local band = bit.band
local function obtainIP()
-- TODO: check for DHCP result
--- @todo check for DHCP result
local info = InfoMessage:new{text = _("Obtaining IP address…")}
UIManager:show(info)
UIManager:forceRePaint()

@ -182,7 +182,7 @@ function OPDSBrowser:editCalibreServer()
title = _("Edit local calibre host and port"),
fields = {
{
-- TODO: get IP address of current device
--- @todo get IP address of current device
text = calibre.host or "192.168.1.1",
hint = _("calibre host"),
},

@ -350,6 +350,7 @@ function TextBoxWidget:_getLinePads(vertical_string)
return pads
end
---- Lays out text.
function TextBoxWidget:_renderText(start_row_idx, end_row_idx)
local font_height = self.face.size
if start_row_idx < 1 then start_row_idx = 1 end
@ -374,8 +375,8 @@ function TextBoxWidget:_renderText(start_row_idx, end_row_idx)
elseif self.alignment == "right" then
pen_x = (self.width - line.width)
end
--@todo don't use kerning for monospaced fonts. (houqp)
-- refert to cb25029dddc42693cc7aaefbe47e9bd3b7e1a750 in master tree
--- @todo don't use kerning for monospaced fonts. (houqp)
--- refer to [cb25029dddc42693cc7aaefbe47e9bd3b7e1a750](https://github.com/koreader/koreader/commit/cb25029dddc42693cc7aaefbe47e9bd3b7e1a750) in master tree
RenderText:renderUtf8Text(self._bb, pen_x, y, self.face, self:_getLineText(line), true, self.bold, self.fgcolor, nil, self:_getLinePads(line))
y = y + self.line_height_px
end
@ -1100,7 +1101,7 @@ function TextBoxWidget:onHoldWord(callback, ges)
local idx = char_start
-- find which character the touch is holding
while idx < char_end do
-- FIXME: this might break if kerning is enabled
--- @fixme This might break if kerning is enabled.
char_probe_x = char_probe_x + self.char_width[self.charlist[idx]] + (self.idx_pad[idx] or 0)
if char_probe_x > x then
-- ignore spaces

@ -1168,7 +1168,7 @@ table {
-- external link for us, so let's remove this link.
html = html:gsub("<a[^>]*>%s*(<%s*img [^>]*>)%s*</a>", "%1")
-- TODO: do something for <li class="gallerybox"...> so they are no more
--- @todo do something for <li class="gallerybox"...> so they are no more
-- a <li> (crengine displays them one above the other) and can be displayed
-- side by side

@ -99,9 +99,7 @@ function util.secondsToClock(seconds, withoutSeconds)
end
end
-- Converts seconds to a period of time string.
--- Converts seconds to a period of time string.
---- @int seconds number of seconds
---- @bool withoutSeconds if true 1h30', if false 1h30'10''
---- @bool hmsFormat, if true format 1h30m10s
@ -187,7 +185,7 @@ end
--[[--
Compares values in two different tables.
Source: <a href="https://stackoverflow.com/a/32660766/2470572">https://stackoverflow.com/a/32660766/2470572</a>
Source: <https://stackoverflow.com/a/32660766/2470572>
]]
---- @param o1 Lua table
---- @param o2 Lua table
@ -227,7 +225,7 @@ end
--[[--
Makes a deep copy of a table.
Source: <a href="https://stackoverflow.com/a/16077650/2470572">https://stackoverflow.com/a/16077650/2470572</a>
Source: <https://stackoverflow.com/a/16077650/2470572>
]]
---- @param o Lua table
---- @treturn Lua table
@ -297,7 +295,7 @@ end
--- Reverse the individual greater-than-single-byte characters
-- @string string to reverse
-- Taken from https://github.com/blitmap/lua-utf8-simple#utf8reverses
-- Taken from <https://github.com/blitmap/lua-utf8-simple#utf8reverses>
function util.utf8Reverse(text)
text = text:gsub('[%z\1-\127\194-\244][\128-\191]*', function (c) return #c > 1 and c:reverse() end)
return text:reverse()
@ -524,10 +522,10 @@ function util.pathExists(path)
end
--- As `mkdir -p`.
--- Unlike lfs.mkdir(), does not error if the directory already exists, and
--- creates intermediate directories as needed.
---- @string path the directory to create
---- @treturn bool true on success; nil, err_message on error
-- Unlike [lfs.mkdir](https://keplerproject.github.io/luafilesystem/manual.html#mkdir)(),
-- does not error if the directory already exists, and creates intermediate directories as needed.
-- @string path the directory to create
-- @treturn bool true on success; nil, err_message on error
function util.makePath(path)
path = path:gsub("/+$", "")
if util.pathExists(path) then return true end
@ -563,18 +561,17 @@ local function replaceSlashChar(str)
end
end
--- Replaces characters that are invalid filenames.
--
-- Replaces the characters <code>\/:*?"<>|</code> with an <code>_</code>
-- unless an optional path is provided.
-- These characters are problematic on Windows filesystems. On Linux only
-- <code>/</code> poses a problem.
-- If an optional path is provided, util.getFilesystemType() will be used
-- to determine whether stricter VFAT restrictions should be applied.
--[[--
Replaces characters that are invalid filenames.
Replaces the characters `\/:*?"<>|` with an `_` unless an optional path is provided. These characters are problematic on Windows filesystems. On Linux only the `/` poses a problem.
If an optional path is provided, @{util.getFilesystemType}() will be used to determine whether stricter VFAT restrictions should be applied.
]]
---- @string str
---- @string path
---- @int limit
---- @treturn string
---- @treturn string safe filename
function util.getSafeFilename(str, path, limit, limit_ext)
local filename, suffix = util.splitFileNameSuffix(str)
local replaceFunc = replaceAllInvalidChars
@ -683,12 +680,14 @@ function util.getMenuText(item)
return text
end
--- Replaces invalid UTF-8 characters with a replacement string.
--
-- Based on http://notebook.kulchenko.com/programming/fixing-malformed-utf8-in-lua
---- @string str the string to be checked for invalid characters
---- @string replacement the string to replace invalid characters with
---- @treturn string valid UTF-8
--[[--
Replaces invalid UTF-8 characters with a replacement string.
Based on <http://notebook.kulchenko.com/programming/fixing-malformed-utf8-in-lua>.
@string str the string to be checked for invalid characters
@string replacement the string to replace invalid characters with
@treturn string valid UTF-8
]]
function util.fixUtf8(str, replacement)
local pos = 1
local len = #str
@ -754,12 +753,14 @@ local HTML_ENTITIES_TO_UTF8 = {
{"&#x(%x+);", function(x) return util.unicodeCodepointToUtf8(tonumber(x,16)) end},
{"&amp;", "&"}, -- must be last
}
--- Replace HTML entities with their UTF8 equivalent in text
--
-- Supports only basic ones and those with numbers (no support
-- for named entities like &eacute;)
--- @int string text with HTML entities
--- @treturn string UTF8 text
--[[--
Replace HTML entities with their UTF8 equivalent in text.
Supports only basic ones and those with numbers (no support for named entities like `&eacute;`).
@int string text with HTML entities
@treturn string UTF8 text
]]
function util.htmlEntitiesToUtf8(text)
for _, t in ipairs(HTML_ENTITIES_TO_UTF8) do
text = text:gsub(t[1], t[2])
@ -767,12 +768,14 @@ function util.htmlEntitiesToUtf8(text)
return text
end
--- Convert simple HTML to plain text
-- This may fail on complex HTML (with styles, scripts, comments), but should
-- be fine enough with simple HTML as found in EPUB's <dc:description>.
--
--- @string text HTML text
--- @treturn string plain text
--[[--
Convert simple HTML to plain text.
This may fail on complex HTML (with styles, scripts, comments), but should be fine enough with simple HTML as found in EPUB's `<dc:description>`.
@string text HTML text
@treturn string plain text
]]
function util.htmlToPlainText(text)
-- Replace <br> and <p> with \n
text = text:gsub("%s*<%s*br%s*/?>%s*", "\n") -- <br> and <br/>

@ -184,7 +184,7 @@ function BackgroundRunner:_execute()
should_ignore = true
end
elseif type(job.when) == "string" then
-- TODO(Hzj_jie): Implement "idle" mode
--- @todo (Hzj_jie): Implement "idle" mode
if job.when == "best-effort" then
should_execute = (round > 0)
elseif job.when == "idle" then

@ -410,8 +410,8 @@ end
function CalibreCompanion:getFreeSpace(arg)
logger.dbg("FREE_SPACE", arg)
-- TODO: portable free space calculation?
-- assume we have 1GB of free space on device
--- @todo Portable free space calculation?
-- Assume we have 1GB of free space on device.
local free_space = {
free_space_on_device = 1024*1024*1024,
}

@ -248,7 +248,7 @@ function MyClipping:parseHighlight(highlights, book)
image.drawer = item.drawer
clipping.image = self:getImage(image)
end
-- TODO: store chapter info when exporting highlights
--- @todo Store chapter info when exporting highlights.
if clipping.text and clipping.text ~= "" or clipping.image then
table.insert(book, { clipping })
end

@ -32,7 +32,7 @@ local function include_fold(template, start_tag, end_tag, fold_func, init_func)
local filename = assert(loadstring('return '..string.sub(template, end1 + 1, start2 - 1)))()
assert(filename)
local fin = assert(io.open(filename))
-- TODO: detect cyclic inclusion?
--- @todo Detect cyclic inclusion?
result = fold_func(result, include_fold(fin:read('*a'), start_tag, end_tag, fold_func, init_func), filename)
fin:close()
end

@ -382,7 +382,7 @@ function EpubDownloadBackend:createEpub(epub_path, html, url, include_images, me
-- ----------------------------------------------------------------
-- OEBPS/stylesheet.css
-- TODO: We told it we'd include a stylesheet.css, so it's probably best
--- @todo We told it we'd include a stylesheet.css, so it's probably best
-- that we do. In theory, we could try to fetch any *.css files linked in
-- the main html.
epub:add("OEBPS/stylesheet.css", [[
@ -400,7 +400,7 @@ function EpubDownloadBackend:createEpub(epub_path, html, url, include_images, me
-- Add our own first section for first page, with page name as title
table.insert(toc_ncx_parts, string.format([[<navPoint id="navpoint-%s" playOrder="%s"><navLabel><text>%s</text></navLabel><content src="content.html"/>]], num, num, page_htmltitle))
table.insert(toc_ncx_parts, np_end)
-- TODO: Not essential for most articles, but longer articles might benefit
--- @todo Not essential for most articles, but longer articles might benefit
-- from parsing <h*> tags and constructing a proper TOC
while cur_level > 0 do
table.insert(toc_ncx_parts, np_end)

@ -57,7 +57,7 @@ local function getFeedLink(possible_link)
end
end
-- TODO: implement as NetworkMgr:afterWifiAction with configuration options
--- @todo Implement as NetworkMgr:afterWifiAction with configuration options.
function NewsDownloader:afterWifiAction()
if not wifi_enabled_before_action then
NetworkMgr:promptWifiOff()

@ -44,7 +44,7 @@ function Send2Ebook:downloadFileAndRemove(connection_url, remote_path, local_dow
end
end
-- TODO: implement as NetworkMgr:afterWifiAction with configuration options
--- @todo Implement as NetworkMgr:afterWifiAction with configuration options.
function Send2Ebook:afterWifiAction()
if not wifi_enabled_before_action then
NetworkMgr:promptWifiOff()

@ -629,7 +629,7 @@ end
function ReaderStatistics:getBookProperties()
local props = self.view.document:getProps()
if props.title == "No document" or props.title == "" then
-- FIXME: sometimes crengine returns "No document", try one more time
--- @fixme Sometimes crengine returns "No document", try one more time.
props = self.view.document:getProps()
end
return props

@ -1,7 +1,7 @@
local Device = require("device")
local command
-- TODO(hzj-jie): Does pocketbook provide ntpdate?
--- @todo (hzj-jie): Does pocketbook provide ntpdate?
if Device:isKobo() then
command = "ntpd -q -n -p pool.ntp.org"
elseif Device:isCervantes() or Device:isKindle() or Device:isPocketBook() then

@ -1,3 +1,7 @@
--[[--
@module koplugin.wallabag
]]
local DataStorage = require("datastorage")
local DocSettings = require("docsettings")
local Event = require("ui/event")
@ -320,6 +324,9 @@ function Wallabag:getArticleList()
return self:callAPI( "GET", articles_url, nil, "", "" )
end
--- Download Wallabag article.
-- @string article
-- @treturn int 1 failed, 2 skipped, 3 downloaded
function Wallabag:download(article)
local skip_article = false
local item_url = "/api/entries/" .. article.id .. "/export.epub"
@ -333,7 +340,7 @@ function Wallabag:download(article)
if attr then
-- File already exists, skip it. Preferably only skip if the date of local file is newer than server's.
-- newsdownloader.koplugin has a date parser but it is available only if the plugin is activated.
-- TODO: find a better solution
--- @todo find a better solution
if self.is_dateparser_available then
local server_date = self.dateparser.parse(article.updated_at)
if server_date < attr.modification then

@ -185,7 +185,7 @@ describe("KOSync modules #notest #nocov", function()
body = {}
}
-- TODO: Test kosync module
--- @todo Test kosync module
local function mockKOSyncClient() --luacheck: ignore
package.loaded["KOSyncClient"] = nil
local c = require("KOSyncClient")

@ -21,8 +21,7 @@ describe("ReaderBookmark module", function()
readerui.highlight:onHoldRelease()
assert.truthy(readerui.highlight.highlight_dialog)
readerui.highlight:onHighlight()
-- TODO: replace scheduleIn with nextTick
UIManager:scheduleIn(1, function()
UIManager:nextTick(function()
UIManager:close(readerui.highlight.highlight_dialog)
UIManager:close(readerui)
end)
@ -30,20 +29,21 @@ describe("ReaderBookmark module", function()
end
local function toggler_dogear(readerui)
readerui.bookmark:onToggleBookmark()
--- @todo Replace scheduleIn with nextTick
UIManager:scheduleIn(1, function()
UIManager:close(readerui)
end)
UIManager:run()
end
local function show_bookmark_menu(readerui)
UIManager:scheduleIn(1, function()
UIManager:nextTick(function()
UIManager:close(readerui.bookmark.bookmark_menu)
UIManager:close(readerui)
end)
UIManager:run()
end
describe("bookmark for EPUB document", function()
describe("EPUB document", function()
local readerui
setup(function()
DocSettings:open(sample_epub):purge()
@ -57,7 +57,7 @@ describe("ReaderBookmark module", function()
UIManager:show(readerui)
readerui.rolling:onGotoPage(10)
end)
it("should does bookmark comparison properly", function()
it("should compare bookmarks properly", function()
assert.truthy(readerui.bookmark:isBookmarkSame(
{ notes = 'foo', page = 1, pos0 = 0, pos1 = 2, },
{ notes = 'foo', page = 1, pos0 = 0, pos1 = 2, }))
@ -68,13 +68,13 @@ describe("ReaderBookmark module", function()
{ notes = 'foo0', page = 1, pos0 = 0, pos1 = 0, },
{ notes = 'foo', page = 1, pos0 = 0, pos1 = 2, }))
end)
it("should show dogear after togglering non-bookmarked page", function()
it("should show dogear after toggling non-bookmarked page", function()
assert.falsy(readerui.view.dogear_visible)
toggler_dogear(readerui)
Screen:shot("screenshots/reader_bookmark_dogear_epub.png")
assert.truthy(readerui.view.dogear_visible)
end)
it("should not show dogear after togglering bookmarked page", function()
it("should not show dogear after toggling bookmarked page", function()
assert.truthy(readerui.view.dogear_visible)
toggler_dogear(readerui)
Screen:shot("screenshots/reader_bookmark_nodogear_epub.png")
@ -125,7 +125,7 @@ describe("ReaderBookmark module", function()
end)
end)
describe("bookmark for PDF document", function()
describe("PDF document", function()
local readerui
setup(function()
DocSettings:open(sample_pdf):purge()
@ -167,12 +167,12 @@ describe("ReaderBookmark module", function()
{ notes = 'foo', pos0 = { page = 1 , x = 1, y = 3},
pos1 = { page = 1, x = 20, y = 2 }, }))
end)
it("should show dogear after togglering non-bookmarked page", function()
it("should show dogear after toggling non-bookmarked page", function()
toggler_dogear(readerui)
Screen:shot("screenshots/reader_bookmark_dogear_pdf.png")
assert.truthy(readerui.view.dogear_visible)
end)
it("should not show dogear after togglering bookmarked page", function()
it("should not show dogear after toggling bookmarked page", function()
toggler_dogear(readerui)
Screen:shot("screenshots/reader_bookmark_nodogear_pdf.png")
assert.truthy(not readerui.view.dogear_visible)

@ -77,8 +77,8 @@ describe("Readerhighlight module", function()
UIManager:quit()
readerui.rolling:onGotoPage(page)
UIManager:show(readerui)
-- HACK: Mock UIManager:run x and y for readerui.dimen
-- TODO: refactor readerview's dimen handling so we can get rid of
--- @fixme HACK: Mock UIManager:run x and y for readerui.dimen
--- @todo Refactor readerview's dimen handling so we can get rid of
-- this workaround
readerui:paintTo(Screen.bb, 0, 0)
end)

Loading…
Cancel
Save