diff --git a/base b/base
index 81e789e72..feca07cc6 160000
--- a/base
+++ b/base
@@ -1 +1 @@
-Subproject commit 81e789e724c7417c1691652532c3ea0a574cba2a
+Subproject commit feca07cc6f32271c9a904f67372719b13fe292d7
diff --git a/frontend/apps/reader/modules/readerdictionary.lua b/frontend/apps/reader/modules/readerdictionary.lua
index 87166c8a7..f16536935 100644
--- a/frontend/apps/reader/modules/readerdictionary.lua
+++ b/frontend/apps/reader/modules/readerdictionary.lua
@@ -67,6 +67,17 @@ local ReaderDictionary = InputContainer:new{
lookup_msg = _("Searching dictionary for:\n%1"),
}
+local function readDictionaryCss(path)
+ local f = io.open(path, "r")
+ if not f then
+ return nil
+ end
+
+ local content = f:read("*all")
+ f:close()
+ return content
+end
+
function ReaderDictionary:init()
self.ui.menu:registerToMainMenu(self)
self.data_dir = os.getenv("STARDICT_DATA_DIR") or
@@ -90,11 +101,14 @@ function ReaderDictionary:init()
local content = f:read("*all")
f:close()
local dictname = content:match("\nbookname=(.-)\n")
+ local is_html = content:find("sametypesequence=h", 1, true) ~= nil
-- sdcv won't use dict that don't have a bookname=
if dictname then
table.insert(available_ifos, {
file = ifo_file,
name = dictname,
+ is_html = is_html,
+ css = readDictionaryCss(ifo_file:gsub("%.ifo$", ".css"))
})
end
end
@@ -331,26 +345,42 @@ local function dictDirsEmpty(dict_dirs)
return true
end
+local function getAvailableIfoByName(dictionary_name)
+ for _, ifo in ipairs(available_ifos) do
+ if ifo.name == dictionary_name then
+ return ifo
+ end
+ end
+
+ return nil
+end
+
local function tidyMarkup(results)
local cdata_tag = ""
local format_escape = "&[29Ib%+]{(.-)}"
for _, result in ipairs(results) do
- local def = result.definition
- -- preserve the
tag for line break
- def = def:gsub("<[bB][rR] ?/?>", "\n")
- -- parse CDATA text in XML
- if def:find(cdata_tag) then
- def = def:gsub(cdata_tag, "%1")
- -- ignore format strings
- while def:find(format_escape) do
- def = def:gsub(format_escape, "%1")
+ local ifo = getAvailableIfoByName(result.dict)
+ if ifo and ifo.is_html then
+ result.is_html = ifo.is_html
+ result.css = ifo.css
+ else
+ local def = result.definition
+ -- preserve the
tag for line break
+ def = def:gsub("<[bB][rR] ?/?>", "\n")
+ -- parse CDATA text in XML
+ if def:find(cdata_tag) then
+ def = def:gsub(cdata_tag, "%1")
+ -- ignore format strings
+ while def:find(format_escape) do
+ def = def:gsub(format_escape, "%1")
+ end
end
+ -- ignore all markup tags
+ def = def:gsub("%b<>", "")
+ -- strip all leading empty lines/spaces
+ def = def:gsub("^%s+", "")
+ result.definition = def
end
- -- ignore all markup tags
- def = def:gsub("%b<>", "")
- -- strip all leading empty lines/spaces
- def = def:gsub("^%s+", "")
- result.definition = def
end
return results
end
diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua
index 74ba28cb5..6adf3cea2 100644
--- a/frontend/ui/widget/dictquicklookup.lua
+++ b/frontend/ui/widget/dictquicklookup.lua
@@ -14,6 +14,7 @@ local InputDialog = require("ui/widget/inputdialog")
local LeftContainer = require("ui/widget/container/leftcontainer")
local LineWidget = require("ui/widget/linewidget")
local OverlapGroup = require("ui/widget/overlapgroup")
+local ScrollHtmlWidget = require("ui/widget/scrollhtmlwidget")
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
local Size = require("ui/size")
local TextWidget = require("ui/widget/textwidget")
@@ -37,6 +38,7 @@ local DictQuickLookup = InputContainer:new{
displayword = nil,
is_wiki = false,
is_fullpage = false,
+ is_html = false,
dict_index = 1,
title_face = Font:getFace("x_smalltfont"),
content_face = Font:getFace("cfont", DDICT_FONT_SIZE),
@@ -156,6 +158,25 @@ function DictQuickLookup:isDocless()
return self.ui == nil or self.ui.highlight == nil
end
+function DictQuickLookup:getHtmlDictionaryCss()
+ -- Using Noto Sans because Nimbus doesn't contain the IPA symbols.
+ local css = [[
+ @page {
+ margin: 0;
+ font-family: 'Noto Sans';
+ }
+
+ body {
+ margin: 0;
+ }
+ ]]
+
+ if self.css then
+ return css .. self.css
+ end
+ return css
+end
+
function DictQuickLookup:update()
local orig_dimen = self.dict_frame and self.dict_frame.dimen or Geom:new{}
-- calculate window dimension
@@ -236,12 +257,20 @@ function DictQuickLookup:update()
text_font_size = lookup_word_font_size,
hold_callback = function() self:lookupInputWord(self.lookupword) end,
}
- -- word definition
- local definition = FrameContainer:new{
- padding = self.definition_padding,
- margin = self.definition_margin,
- bordersize = 0,
- ScrollTextWidget:new{
+
+ local text_widget
+
+ if self.is_html then
+ text_widget = ScrollHtmlWidget:new{
+ html_body = self.definition,
+ css = self:getHtmlDictionaryCss(),
+ default_font_size = DDICT_FONT_SIZE,
+ width = self.width,
+ height = self.is_fullpage and self.height*0.75 or self.height*0.7,
+ dialog = self,
+ }
+ else
+ text_widget = ScrollTextWidget:new{
text = self.definition,
face = self.content_face,
width = self.width,
@@ -250,7 +279,15 @@ function DictQuickLookup:update()
dialog = self,
-- allow for disabling justification
justified = G_reader_settings:nilOrTrue("dict_justify"),
- },
+ }
+ end
+
+ -- word definition
+ local definition = FrameContainer:new{
+ padding = self.definition_padding,
+ margin = self.definition_margin,
+ bordersize = 0,
+ text_widget,
}
-- Different sets of buttons if fullpage or not
local buttons
@@ -538,6 +575,8 @@ function DictQuickLookup:changeDictionary(index)
self.lookupword = self.results[index].word
self.definition = self.results[index].definition
self.is_fullpage = self.results[index].is_fullpage
+ self.is_html = self.results[index].is_html
+ self.css = self.results[index].css
self.lang = self.results[index].lang
if self.is_fullpage then
self.displayword = self.lookupword
diff --git a/frontend/ui/widget/htmlboxwidget.lua b/frontend/ui/widget/htmlboxwidget.lua
new file mode 100644
index 000000000..8cb29ca52
--- /dev/null
+++ b/frontend/ui/widget/htmlboxwidget.lua
@@ -0,0 +1,189 @@
+--[[--
+HTML widget (without scroll bars).
+--]]
+
+local DrawContext = require("ffi/drawcontext")
+local Geom = require("ui/geometry")
+local InputContainer = require("ui/widget/container/inputcontainer")
+local logger = require("logger")
+local Mupdf = require("ffi/mupdf")
+local util = require("util")
+local TimeVal = require("ui/timeval")
+
+local HtmlBoxWidget = InputContainer:new{
+ bb = nil,
+ dimen = nil,
+ document = nil,
+ page_count = 0,
+ page_number = 1,
+ hold_start_pos = nil,
+ hold_start_tv = nil,
+}
+
+function HtmlBoxWidget:setContent(body, css, default_font_size)
+ -- fz_set_user_css is tied to the context instead of the document so to easily support multiple
+ -- HTML dictionaries with different CSS, we embed the stylesheet into the HTML instead of using
+ -- that function.
+ local head = ""
+ if css then
+ head = string.format("