From e0ac8b5160f499471d82d5735475ee354d8f8dcb Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 25 Nov 2016 15:53:08 +0100 Subject: first commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- dlu.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100755 dlu.py (limited to 'dlu.py') diff --git a/dlu.py b/dlu.py new file mode 100755 index 0000000..6d1eb6f --- /dev/null +++ b/dlu.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +import sys, os + +global dictionary_name, sought_word, display_envs, x_reads, reads, wordmod, standard_page_remap, load_dictionary, open_dictionary + +## Parse command line. +if len(sys.argv) == 2 and sys.argv[1] == '-l': + f_list = True +elif len(sys.argv) != 3: + print('Usage: dlu [DICTIONARY WORD | -l]', file = sys.stderr) + sys.exit(1) +else: + dictionary_name = sys.argv[1] + sought_word = sys.argv[2] + f_list = False + +# Default functions, can be overriden by configurations on call to load_dictionary. +if not f_list: + display_envs = ['MDS_DISPLAY', 'MIR_DISPLAY', 'WAYLAND_DISPLAY', 'DISPLAY'] + x_reads = [ + (lambda f, p : ['atril', f, '-i', p]), + (lambda f, p : ['evince', f, '-i', p]), + (lambda f, p : ['xpdf', f, p]), + ] + reads = dict((disp, list(x_reads)) for disp in display_envs) + reads[None] = [lambda f, p : ['jfbview', '-p', p, '--', f]] + wordmod = lambda x : x.lower() + def standard_page_remap(offset, multiple = 1, multiple_offset = 0): + return lambda p : (0 if p < multiple_offset else p - multiple_offset) // multiple + offset + def open_dictionary(filename, page): + disps = [disp for disp in display_envs if disp in os.environ] + [None] + for command_lambda in reads[disps[0]]: + command = command_lambda(filename, str(page)); + os.execvp(command[0], command) + sys.stderr.print("%s: could find any viewer to use." % sys.argv[0]) + sys.stderr.print("%s: file to open: %s" % (sys.argv[0], filename)) + sys.stderr.print("%s: page to open: %i" % (sys.argv[0], page)) + sys.exit(1) + +## Load configurations, which holds data needed to perform the lookup. +g, l = globals(), dict(locals()) +for key in l: + g[key] = l[key] +# Possible auto-selected configuration scripts, +# earlier ones have precedence, we can only select one. +for file in ('$XDG_CONFIG_HOME/%/%rc', '$HOME/.config/%/%rc', '$HOME/.%rc', '$~/.config/%/%rc', '$~/.%rc', '/etc/%rc'): + # Expand short-hands + file = file.replace('/', os.sep).replace('%', 'dlu') + # Expand environment variables + for arg in ('XDG_CONFIG_HOME', 'HOME'): + # Environment variables are prefixed with $ + if '$' + arg in file: + if arg in os.environ: + # To be sure that do so no treat a $ as a variable prefix + # incorrectly we replace any $ in the value of the variable + # with NUL which is not a value pathname character. + file = file.replace('$' + arg, os.environ[arg].replace('$', '\0')) + else: + file = None + break + # Proceed if there where no errors. + if file is not None: + # With use $~ (instead of ~) for the user's proper home + # directroy. HOME should be defined, but it could be missing. + # It could also be set to another directory. + if file.startswith('$~'): + import pwd + # Get the home (also known as initial) directory + # of the real user, and the rest of the path. + file = pwd.getpwuid(os.getuid()).pw_dir + file[2:] + # Now that we are done we can change back any NUL to $:s. + file = file.replace('\0', '$') + # If the file we exists, + if os.path.exists(file): + # select it, + config_file = file + # and stop trying files with lower precedence. + break +if config_file is not None: + code = None + # Read configuration script file. + with open(config_file, 'rb') as script: + code = script.read() + # Decode configurion script file and add a line break + # at the end to ensure that the last line is empty. + # If it is not, we will get errors. + code = code.decode('utf-8', 'strict') + '\n' + # Compile the configuration script, + code = compile(code, config_file, 'exec') + # and run it, with it have the same + # globals as this module, so that it can + # not only use want we have defined, but + # also redefine it for us. + exec(code, g) +else: + print('No configuration file found') + sys.exit(1) + +## List available dictionaries. +if f_list: + for d in list_dictionaries(): + print(d) + sys.exit(0) + +## Perform lookup. +load_dictionary(dictionary_name) + +sought_word = wordmod(sought_word) +filename, lasts, page_remap = get() +lasts = [(i, word) for i, word in enumerate(lasts)] + +for i, word in lasts: + word = wordmod(word) + if sought_word <= word: + page = i + break +else: + page = lasts[-1][0] + +page = page_remap(page) +open_dictionary(filename, page) -- cgit v1.2.3-70-g09d2