mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
[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
This commit is contained in:
@@ -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},
|
||||
{"&", "&"}, -- 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 é)
|
||||
--- @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 `é`).
|
||||
|
||||
@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)
|
||||
|
||||
Reference in New Issue
Block a user