Merge branch 'feature/fastercolor' into develop. Read on for details.

The interface of color has changed.
color.colored(s, 'red') becomes color.dye(s, color.red)
The code behind it is simpler and shorter.

The decision to use color or not is made when the UI class is instanciated,
and the configuration is read. There is no need to handle it on a per-file
basis. The default before repository instanciation is with color, but that
might (should) change.
main
Fabien Benureau 12 years ago
commit db14fb94f3

@ -1,60 +1,38 @@
# 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',
}
"""
Small code to handle colored text
"""
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 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 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
def color_setup(config):
global dye
if config.getboolean(configs.MAIN_SECTION, 'color'):
dye = _dye
else:
end_code = ''
return color_code + s + end_code
def not_colored(s, **kwargs):
return s
dye = _nodye

@ -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()

@ -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))

@ -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()

@ -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)

@ -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)

@ -15,7 +15,6 @@ import os
import shutil
import subprocess
from ...color import colored
from ... import repo
from ...paper import NoDocumentFile
from ... import configs

@ -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,
)

@ -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'))

@ -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))

@ -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()

@ -0,0 +1,3 @@
# Adjusting paths.
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(__file__, '../..')))
Loading…
Cancel
Save