From f1bf98cd52c76e8ce5e38f920e1d15644e8829e2 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 13 Jun 2013 10:50:07 +0200 Subject: [PATCH 1/4] simpler, faster color code --- papers/color.py | 80 ++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 58 deletions(-) diff --git a/papers/color.py b/papers/color.py index c62d704..23871e0 100644 --- a/papers/color.py +++ b/papers/color.py @@ -1,60 +1,24 @@ # display -BOLD = '\033[1m' -END = '\033[0m' - -COLORS = { - 'black' : '\033[0;30m', - 'red' : '\033[0;31m', - 'green' : '\033[0;32m', - 'yellow': '\033[0;33m', - 'blue' : '\033[0;34m', - 'purple': '\033[0;35m', - 'cyan' : '\033[0;36m', - 'grey' : '\032[0;37m', - } - -# Bold -BCOLORS = { - 'black' : '\033[1;30m', - 'red' : '\033[1;31m', - 'green' : '\033[1;32m', - 'yellow': '\033[1;33m', - 'blue' : '\033[1;34m', - 'purple': '\033[1;35m', - 'cyan' : '\033[1;36m', - 'grey' : '\033[1;37m', - } - -# application specific -ALIASES = { - 'ok' : 'green', - 'error' : 'red', - 'normal' : 'grey', - 'citekey' : 'purple', - 'filepath': 'cyan', - } - - -def colored(s, color=None, bold=False): - if color in ALIASES: - color = ALIASES[color] - try: - if bold: - color_code = BCOLORS[color] - else: - color_code = COLORS[color] - except KeyError: - if bold: - color_code = BOLD - else: - color_code = '' - if color_code != '': - end_code = END - else: - end_code = '' - return color_code + s + end_code - - -def not_colored(s, **kwargs): - return s +bold = '\033[1m' +end = '\033[0m' + +black = '\033[0;30m' +red = '\033[0;31m' +green = '\033[0;32m' +yellow = '\033[0;33m' +blue = '\033[0;34m' +purple = '\033[0;35m' +cyan = '\033[0;36m' +grey = '\033[0;37m' + +ok = green +error = red +normal = grey +citekey = purple +filepath = cyan + +def colored(s, color=end, bold=False): + if bold: + s = '\033[1' + s[3:] + return color + s + end From 840deaccc1276e7dca166851fa9f7f231e0c4909 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 13 Jun 2013 12:28:59 +0200 Subject: [PATCH 2/4] test to measure color performance --- tests/test_color.py | 10 ++++++++++ tests/testenv.py | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 tests/test_color.py create mode 100644 tests/testenv.py diff --git a/tests/test_color.py b/tests/test_color.py new file mode 100644 index 0000000..4dd1b01 --- /dev/null +++ b/tests/test_color.py @@ -0,0 +1,10 @@ +import testenv +from papers import color + +def perf_color(): + s = str(range(1000)) + for _ in range(5000000): + color.dye(s, color.red) + +if __name__ == '__main__': + perf_color() \ No newline at end of file diff --git a/tests/testenv.py b/tests/testenv.py new file mode 100644 index 0000000..bacd731 --- /dev/null +++ b/tests/testenv.py @@ -0,0 +1,3 @@ +# Adjusting paths. +import os, sys +sys.path.insert(0, os.path.abspath(os.path.join(__file__, '../..'))) \ No newline at end of file From facaa2ae6a00ea3e3d44c5f1d158d0eac6377973 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 13 Jun 2013 12:30:14 +0200 Subject: [PATCH 3/4] deactivation mecanism for colors; 'colored' is now 'dye' --- papers/color.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/papers/color.py b/papers/color.py index 23871e0..3139557 100644 --- a/papers/color.py +++ b/papers/color.py @@ -1,4 +1,6 @@ -# display +""" +Small code to handle colored text +""" bold = '\033[1m' end = '\033[0m' @@ -18,7 +20,19 @@ normal = grey citekey = purple filepath = cyan -def colored(s, color=end, bold=False): +def dye(s, color=end, bold=False): + assert color[0] == '\033' if bold: s = '\033[1' + s[3:] return color + s + end + +_dye = dye +def _nodye(s, **kwargs): + return s + +def color_setup(config): + global dye + if config.getboolean(configs.MAIN_SECTION, 'color'): + dye = _dye + else: + dye = _nodye \ No newline at end of file From c8501aa211c26aa81e552a7c196451619ca23b4f Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 13 Jun 2013 12:30:45 +0200 Subject: [PATCH 4/4] updating the code to new color module --- papers/commands/init_cmd.py | 4 ++-- papers/commands/list_cmd.py | 8 +++---- papers/commands/open_cmd.py | 6 ++--- papers/commands/remove_cmd.py | 4 ++-- papers/files.py | 32 +++++++++++++-------------- papers/plugins/texnote/texnote_cmd.py | 1 - papers/pretty.py | 10 +++------ papers/repo.py | 8 +++---- papers/ui.py | 16 +++++--------- 9 files changed, 39 insertions(+), 50 deletions(-) diff --git a/papers/commands/init_cmd.py b/papers/commands/init_cmd.py index 3a79087..a50d165 100644 --- a/papers/commands/init_cmd.py +++ b/papers/commands/init_cmd.py @@ -26,11 +26,11 @@ def command(config, ui, path, doc_dir): configs.add_and_write_option('papers', 'papers-directory', papersdir) if not os.path.exists(papersdir): ui.print_('Initializing papers in {}.'.format( - ui.colored(papersdir, 'filepath'))) + color.dye(papersdir, color.filepath))) repo = Repository() repo.init(papersdir) # Creates directories repo.save() # Saves empty repository description else: ui.error('papers already present in {}.'.format( - ui.colored(papersdir, 'filepath'))) + color.dye(papersdir, color.filepath))) ui.exit() diff --git a/papers/commands/list_cmd.py b/papers/commands/list_cmd.py index 26f33e2..b188226 100644 --- a/papers/commands/list_cmd.py +++ b/papers/commands/list_cmd.py @@ -13,13 +13,13 @@ def command(config, ui, cmd): articles = [] for n, p in enumerate(rp.all_papers()): if test_paper(cmd, p): - bibdesc = pretty.bib_oneliner(p.bibentry, color=ui.color) + bibdesc = pretty.bib_oneliner(p.bibentry) articles.append((u'{num:d}: [{citekey}] {descr} {labels}'.format( num=int(n), - citekey=ui.colored(rp.citekeys[n], 'purple'), + citekey=color.dye(rp.citekeys[n], color.purple), descr=bibdesc, - labels=ui.colored(' '.join(p.metadata.get('labels', [])), - 'purple'), + labels=color.dye(' '.join(p.metadata.get('labels', [])), + color.purple), )).encode('utf-8')) ui.print_('\n'.join(articles)) diff --git a/papers/commands/open_cmd.py b/papers/commands/open_cmd.py index 559fd88..2d6bcfb 100644 --- a/papers/commands/open_cmd.py +++ b/papers/commands/open_cmd.py @@ -20,8 +20,8 @@ def command(config, ui, citekey): filepath = paper.get_document_path() subprocess.Popen([config.get(configs.MAIN_SECTION, 'open-cmd'), filepath]) - print("%s opened." % ui.colored(filepath, 'filepath')) + print('{} opened.'.format(color.dye(filepath, color.filepath))) except NoDocumentFile: - ui.error("No document associated with the entry %s." - % ui.colored(citekey, 'citekey')) + ui.error('No document associated with the entry {}.'.format( + color.dye(citekey, color.citekey))) ui.exit() diff --git a/papers/commands/remove_cmd.py b/papers/commands/remove_cmd.py index 971ea5a..c92365c 100644 --- a/papers/commands/remove_cmd.py +++ b/papers/commands/remove_cmd.py @@ -1,5 +1,5 @@ from .. import repo - +import color def parser(subparsers, config): parser = subparsers.add_parser('remove', help='removes a paper') @@ -14,7 +14,7 @@ def command(config, ui, reference): paper = rp.paper_from_citekey(key) are_you_sure = ("Are you sure you want to delete paper [%s]" " (this will also delete associated documents)?" - % ui.colored(paper.citekey, color='citekey')) + % color.dye(paper.citekey, color.citekey)) sure = ui.input_yn(question=are_you_sure, default='n') if sure: rp.remove(paper.citekey) diff --git a/papers/files.py b/papers/files.py index 248c7f7..b117588 100644 --- a/papers/files.py +++ b/papers/files.py @@ -4,7 +4,7 @@ import tempfile import yaml -from .color import colored +from . import ui from . import configs try: @@ -20,9 +20,9 @@ try: import pybtex.database.output.bibyaml except ImportError: - print(colored('error', 'error') - + ': you need to install Pybtex; try running \'pip install' - 'pybtex\' or \'easy_install pybtex\'') + print(ui.dye('error', ui.error) + + ": you need to install Pybtex; try running 'pip install" + "pybtex' or 'easy_install pybtex'") _papersdir = None @@ -49,9 +49,9 @@ def name_from_path(fullpdfpath, verbose=False): name, ext = os.path.splitext(os.path.split(fullpdfpath)[1]) if verbose: if ext != '.pdf' and ext != '.ps': - print(colored('warning', 'yellow') - + '{: extension {ext} not recognized'.format( - ext=colored(ext, 'cyan'))) + print('{}: extension {} not recognized'.format( + color.dye('warning', color.warning), + color.dye(ext, color.cyan))) return name, ext @@ -73,9 +73,9 @@ def write_yamlfile(filepath, datamap): with open(filepath, 'w') as f: yaml.dump(datamap, f) except IOError: - print(colored('error', 'error') - + ': impossible to read file {}'.format( - colored(filepath, 'filepath'))) + print('{}: impossible to read or write on file {}'.format( + color.dye('error', color.error), + color.dye(filepath, color.filepath))) exit(-1) @@ -85,9 +85,9 @@ def read_yamlfile(filepath): with open(filepath, 'r') as f: return yaml.load(f) except IOError: - print(colored('error', 'error') - + ': impossible to read file {}'.format( - colored(filepath, 'filepath'))) + print('{}: impossible to read file {}'.format( + color.dye('error', color.error), + color.dye(filepath, color.filepath))) exit(-1) @@ -123,9 +123,9 @@ def load_externalbibfile(fullbibpath): with open(fullbibpath) as f: return parse_bibdata(f, ext[1:]) else: - print(colored('error', 'error') - + ': {} not recognized format for bibliography'.format( - colored(ext, 'cyan'))) + print('{}: {} not recognized format for bibliography'.format( + color.dye('error', color.error) + color.dye(ext, color.cyan))) exit(-1) diff --git a/papers/plugins/texnote/texnote_cmd.py b/papers/plugins/texnote/texnote_cmd.py index 390cb84..cce803e 100644 --- a/papers/plugins/texnote/texnote_cmd.py +++ b/papers/plugins/texnote/texnote_cmd.py @@ -15,7 +15,6 @@ import os import shutil import subprocess -from ...color import colored from ... import repo from ...paper import NoDocumentFile from ... import configs diff --git a/papers/pretty.py b/papers/pretty.py index a094a05..edaaafd 100644 --- a/papers/pretty.py +++ b/papers/pretty.py @@ -1,6 +1,6 @@ # display formatting -from color import colored, not_colored +from . import color from pybtex.bibtex.utils import bibtex_purify @@ -27,10 +27,6 @@ def short_authors(bibentry): def bib_oneliner(bibentry, color=True): - if color: - col_func = colored - else: - col_func = not_colored authors = short_authors(bibentry) title = bibtex_purify(bibentry.fields['title']) year = bibtex_purify(bibentry.fields.get('year', '')) @@ -40,9 +36,9 @@ def bib_oneliner(bibentry, color=True): field = 'booktitle' journal = bibtex_purify(bibentry.fields.get(field, '')) return u'{authors} \"{title}\" {journal} ({year})'.format( - authors=col_func(authors, 'cyan'), + authors=color.dye(authors, color.cyan), title=title, - journal=col_func(journal, 'yellow'), + journal=color.dye(journal, color.yellow), year=year, ) diff --git a/papers/repo.py b/papers/repo.py index 2d8d635..d5defa9 100644 --- a/papers/repo.py +++ b/papers/repo.py @@ -4,7 +4,7 @@ import glob from . import files from .paper import PaperInRepo, NoDocumentFile -from .color import colored +from . import color from . import configs @@ -48,9 +48,9 @@ class Repository(object): return self.citekeys[int(ref)] except (IndexError, ValueError): if fatal: - print(colored('error', 'error') - + ': no paper with reference {}'.format( - colored(ref, 'citekey'))) + print('{}: no paper with reference {}'.format( + color.dye('error', color.error) + color.dye(ref, color.citekey))) exit(-1) raise(IOError('file not found')) diff --git a/papers/ui.py b/papers/ui.py index 17fee8c..cb02153 100644 --- a/papers/ui.py +++ b/papers/ui.py @@ -2,7 +2,7 @@ import sys from .beets_ui import _encoding, input_ -from .color import colored +from . import color from . import configs @@ -12,13 +12,7 @@ class UI: def __init__(self, config): self.encoding = _encoding(config) - self.color = config.getboolean(configs.MAIN_SECTION, 'color') - - def colored(self, s, *args, **kwargs): - if self.color: - return colored(s, *args, **kwargs) - else: - return s + color.setup(config) def print_(self, *strings): """Like print, but rather than raising an error when a character @@ -47,7 +41,7 @@ class UI: """ displayed_chars = [s.upper() if i == default else s for i, s in enumerate(option_chars)] - option_str = ', '.join(["[%s]%s" % (self.colored(c, 'cyan'), o) + option_str = ', '.join(["[%s]%s" % (color.dye(c, color.cyan), o) for c, o in zip(displayed_chars, options)]) self.print_(question, option_str) while True: @@ -71,7 +65,7 @@ class UI: sys.exit(error_code) def error(self, message): - self.print_("%s: %s" % (colored('error', 'red'), message)) + self.print_("%s: %s" % (color.dye('error', color.red), message)) def warning(self, message): - self.print_("%s: %s" % (colored('warning', 'yellow'), message)) + self.print_("%s: %s" % (color.dye('warning', color.yellow), message))