diff options
Diffstat (limited to 'support/texdoc/script/texdoclib-score.tlu')
-rw-r--r-- | support/texdoc/script/texdoclib-score.tlu | 107 |
1 files changed, 72 insertions, 35 deletions
diff --git a/support/texdoc/script/texdoclib-score.tlu b/support/texdoc/script/texdoclib-score.tlu index 01c3818e37..5aca28ef73 100644 --- a/support/texdoc/script/texdoclib-score.tlu +++ b/support/texdoc/script/texdoclib-score.tlu @@ -5,6 +5,7 @@ -- dependencies local md5 = require 'md5' local texdoc = { + const = require 'texdoclib-const', util = require 'texdoclib-util', config = require 'texdoclib-config', } @@ -49,6 +50,26 @@ end ---------------------------- score computation ----------------------------- +-- parse filename into <base>, <lang>, <ext> +local function parse(filename) + local base, lang, ext + ext = texdoc.util.get_ext(filename) + if ext ~= nil and ext ~= '' then + base = filename:sub(1, -#ext - 2) + else + base = filename + end + + for lc, _ in pairs(texdoc.const.lang_codes) do + local hyph_lc = '-' .. lc + if base:sub(-#hyph_lc) == hyph_lc then + return base:sub(1, -#hyph_lc - 1), lc, ext + end + end + + return base, lang, ext +end + -- says if pat is a "subword" of str local function is_subword(str, pat) local function is_delim(str, i) @@ -72,8 +93,8 @@ local function has_bad_basename(file) return false end --- compute a heuristic score -10 <= s < 10 -local function heuristic_score(file, pat, dbg_score) +-- compute a pattern score -10 <= s < 10 +local function pattern_score(name, pat, dbg_score) dbg_score('Start heuristic scoring with pattern: ' .. pat) -- score management @@ -84,42 +105,40 @@ local function heuristic_score(file, pat, dbg_score) dbg_score('New heuristic score: %.1f. Reason: %s', s, reason) end end - local slash = not not string.find(pat, '/', 1, true) -- look for exact or subword match - if M.is_exact_locale(file, pat) then - upscore(5, 'exact match with correct locale') - elseif M.is_exact(file, pat) then + if M.is_exact(name, pat) then upscore(4, 'exact match') - elseif is_subword(file, pat) then + elseif is_subword(name, pat) then upscore(1, 'subword match') end -- try derivatives unless pat contains a slash + local slash = not not string.find(pat, '/', 1, true) if not slash then for _, suffix in ipairs(texdoc.config.get_value('suffix_list')) do local deriv = pat .. suffix - if M.is_exact(file, deriv) then + if M.is_exact(name, deriv) then upscore(4.5, 'exact match for derived pattern: ' .. deriv) - elseif is_subword(file, deriv) then + elseif is_subword(name, deriv) then upscore(3.5, 'subword match for derived pattern: ' .. deriv) end end end -- if extension is bad, score becomes an epsilon - local ext = texdoc.config.get_value('ext_list')[M.ext_pos(file)] + local ext = texdoc.config.get_value('ext_list')[M.ext_pos(name)] if ext and texdoc.config.get_value('badext_list_inv')[ext] and score > 0 then upscore(0.1, 'bad extension', true) end -- if basename is bad, score becomes an epsilon - if has_bad_basename(file) and score > 0 then + if has_bad_basename(name) and score > 0 then upscore(0.1, 'bad basename', true) end -- bonus for being in the right directory - if string.find('/' .. file, '/' .. pat .. '/', 1, true) and not slash then + if string.find('/' .. name, '/' .. pat .. '/', 1, true) and not slash then upscore(score + 1.5, 'directory bonus') end @@ -146,12 +165,18 @@ local function set_score(df, original_kw) -- get score from patterns local score = -10 + local is_alias = false for _, pat in ipairs(df.matches) do local s = -10 local p = string.lower(pat.name) if pat.original then -- non-alias - s = df.tree > -1 and heuristic_score(name, p, dbg_score) or 1 + if df.tree > -1 then + s = pattern_score(name, p, dbg_score) + else + s = 1 + end elseif M.is_exact(name, p) then -- alias + is_alias = true local bonus, note = 0, '' if pat.locale then bonus, note = 5, ', (language-based)' @@ -185,6 +210,22 @@ local function set_score(df, original_kw) end end + -- bonus for locale + if not is_alias then + local config_lang = texdoc.config.get_value('lang') + local file_lang = df.lang + + if not file_lang then + _, file_lang, _ = parse(name) + file_lang = texdoc.const.lang_codes[file_lang] + end + + if config_lang == file_lang then + score = score + 1 + dbg_score('Locale match bonus: +1.0') + end + end + -- adjust from keyword-specific tables if df.tree > -1 and spec_adjscore[original_kw] then for pat, val in pairs(spec_adjscore[original_kw]) do @@ -218,33 +259,29 @@ local function set_list_scores(list, original_kw) end end --- says if file is an exact match for pat -function M.is_exact(file, pat) - file = texdoc.util.parse_zip(file) - local slashes = string.gsub(pat, '[^/]+', '[^/]+') - basename = string.match(file, slashes .. '$') - if not basename then return nil end - if basename == pat then return true end - for _, ext in ipairs(texdoc.config.get_value('ext_list')) do - if ext ~= '' and ext ~= '*' and basename == pat .. '.' .. ext then - return true - end +-- says if filename is an exact match for pat +function M.is_exact(filename, pattern) + local f_base, f_lang, f_ext = parse(filename) + local p_base, p_lang, p_ext = parse(pattern) + + -- if the pattern contains lang, check if identical + if p_lang ~= nil and f_lang ~= p_lang then + return false end - return false -end --- says if file is an exact match for pat and the current locale -function M.is_exact_locale(file, pat) - if string.match(pat, '%-%l%l%l?$') then - -- don't match if the pattern appears to include a language code + -- if the pattern contains ext, check if identical + if p_ext ~= nil and p_ext ~= '' and f_ext ~= p_ext then return false end - local lang = texdoc.config.get_value('lang') - if lang then - return M.is_exact(file, pat .. '-' .. lang) - or M.is_exact(file, lang .. '-' .. pat) + + -- finally check the bases + if (f_base == p_base + or (f_base:sub(-#p_base) == p_base + and f_base:sub(-#p_base - 1, -#p_base - 1) == '/')) then + return true + else + return false end - return false end -- compare two docfile's: (see texdoclib-search.tlu for structure) |