diff options
Diffstat (limited to 'Master/texmf-dist/scripts/texdoc/search.tlu')
-rw-r--r-- | Master/texmf-dist/scripts/texdoc/search.tlu | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/Master/texmf-dist/scripts/texdoc/search.tlu b/Master/texmf-dist/scripts/texdoc/search.tlu index 3fb77c1a1be..3978021f769 100644 --- a/Master/texmf-dist/scripts/texdoc/search.tlu +++ b/Master/texmf-dist/scripts/texdoc/search.tlu @@ -1,6 +1,7 @@ -- search.tlu: file searching functions for texdoc. -- --- Manuel Pégourié-Gonnard, GPLv3, see texdoclib.tlu for details +-- Manuel Pégourié-Gonnard and the TeX Live team, GPLv3, +-- see texdoclib.tlu for details -- Warning: every single function here assumes init_databases() has been called. @@ -595,6 +596,44 @@ function get_doclist_tlpdb(pattern) end end +-- fuzzy search by using levenshtein distance +function fuzzy_search(pattern) + local tmp_d + local min = 100 + local result + + for p in pairs(tlp_doclist) do + tmp_d = levenshtein(pattern, p) + if tmp_d < min then + min, result = tmp_d, p + end + end + + if min <= config.fuzzy_level then + return result + else + return '' + end +end + +-- calculate levenshtein distance by dynamic programming +-- cf. http://lua-users.org/lists/lua-l/2008-01/msg00095.html +function levenshtein(s, t) + local s, t = tostring(s), tostring(t) + if type(s) == 'string' and type(t) == 'string' then + local m, n, d = #s, #t, {} + for i = 0, m do d[i] = { [0] = i } end + for j = 1, n do d[0][j] = j end + for i = 1, m do + for j = 1, n do + local cost = s:sub(i,i) == t:sub(j,j) and 0 or 1 + d[i][j] = math.min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost) + end + end + return d[m][n] + end +end + end --scope of tlpinfo table ------------------------------ main function ------------------------------- @@ -607,19 +646,33 @@ end -- find docfiles according to pattern function get_doclist(pattern, no_alias) - -- get patterns (inc. aliases) - local normal, sty = normal_vs_sty(get_patterns(pattern, no_alias)) -- initialise result list s_doclist = Doclist:new() + -- 1. normal search with the input pattern + doc_search(pattern, no_alias) + -- 2. if no result, execute fuzzy search + if not s_doclist[1] then + local f_res = fuzzy_search(pattern) + if f_res ~= '' then + err_print('info', 'Fuzzy search result: ' .. f_res) + pattern = f_res + doc_search(pattern, no_alias) + end + end + -- finally, sort results + sort_doclist(s_doclist, pattern) + return s_doclist +end + +function doc_search(pattern, no_alias) + -- get patterns (inc. aliases) + local normal, sty = normal_vs_sty(get_patterns(pattern, no_alias)) -- get results; _texdocs search comes after _tlpdb search so that -- files found by both will have the priority of the _texdocs tree. -- (https://puszcza.gnu.org.ua/bugs/?369) get_doclist_sty(sty) get_doclist_tlpdb(pattern) get_doclist_texdocs(normal) - -- finally, sort results - sort_doclist(s_doclist, pattern) - return s_doclist end -- separate sty patterns from the rest @@ -639,3 +692,5 @@ return { init_databases = init_databases, get_doclist = get_doclist, } + +-- vim: ft=lua: |