This commit is contained in:
Kovid Goyal 2010-12-25 18:18:31 -07:00
commit ef45d613b2
5 changed files with 35 additions and 31 deletions

View File

@ -14,22 +14,7 @@ from calibre.constants import preferred_encoding
from calibre import isbytestring, force_unicode
from calibre.utils.config import prefs, tweaks
from calibre.utils.icu import strcmp
from calibre.utils.formatter import TemplateFormatter
class SafeFormat(TemplateFormatter):
'''
Provides a format function that substitutes '' for any missing value
'''
def get_value(self, key, args, kwargs):
try:
if key in kwargs:
return kwargs[key]
return key
except:
return key
safe_formatter = SafeFormat()
from calibre.utils.formatter import eval_formatter
class Book(Metadata):
def __init__(self, prefix, lpath, size=None, other=None):
@ -131,10 +116,10 @@ class CollectionsBookList(BookList):
field_name = field_meta['name']
else:
field_name = ''
cat_name = safe_formatter.safe_format(
cat_name = eval_formatter.safe_format(
fmt=tweaks['sony_collection_name_template'],
kwargs={'category':field_name, 'value':field_value},
error_value='', book=None)
error_value='GET_CATEGORY', book=None)
return cat_name.strip()
def get_collections(self, collection_attributes):

View File

@ -46,6 +46,7 @@ def render_rows(data):
txt = txt.decode(preferred_encoding, 'replace')
if key.endswith(u':html'):
key = key[:-5]
txt = comments_to_html(txt)
elif '</font>' not in txt:
txt = prepare_string_for_xml(txt)
if 'id' in data:

View File

@ -19,6 +19,7 @@ from calibre.gui2.comments_editor import Editor as CommentsEditor
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
from calibre.utils.config import tweaks
from calibre.utils.icu import sort_key
from calibre.library.comments import comments_to_html
class Base(object):
@ -197,7 +198,7 @@ class Comments(Base):
def setter(self, val):
if val is None:
val = ''
self._tb.html = val
self._tb.html = comments_to_html(val)
def getter(self):
val = unicode(self._tb.html).strip()

View File

@ -136,6 +136,7 @@ class BookInfo(QDialog, Ui_BookInfo):
txt = info[key]
if key.endswith(':html'):
key = key[:-5]
txt = comments_to_html(txt)
if key != _('Path'):
txt = u'<br />\n'.join(textwrap.wrap(txt, 120))
rows += u'<tr><td><b>%s:</b></td><td>%s</td></tr>'%(key, txt)

View File

@ -36,7 +36,7 @@ class _Parser(object):
return gt
def _assign(self, target, value):
setattr(self, target, value)
self.variables[target] = value
return value
def _concat(self, *args):
@ -55,18 +55,23 @@ class _Parser(object):
}
x = float(x if x else 0)
y = float(y if y else 0)
return ops[op](x, y)
return unicode(ops[op](x, y))
def _template(self, template):
template = template.replace('[[', '{').replace(']]', '}')
return self.parent.safe_format(template, self.parent.kwargs, 'TEMPLATE',
self.parent.book)
def _eval(self, template):
template = template.replace('[[', '{').replace(']]', '}')
return eval_formatter.safe_format(template, self.variables, 'EVAL', None)
local_functions = {
'add' : (2, partial(_math, op='+')),
'assign' : (2, _assign),
'cmp' : (5, _cmp),
'divide' : (2, partial(_math, op='/')),
'eval' : (1, _eval),
'field' : (1, lambda s, x: s.parent.get_value(x, [], s.parent.kwargs)),
'multiply' : (2, partial(_math, op='*')),
'strcat' : (-1, _concat),
@ -82,7 +87,7 @@ class _Parser(object):
if prog[1] != '':
self.error(_('failed to scan program. Invalid input {0}').format(prog[1]))
self.parent = parent
setattr(self, '$', val)
self.variables = {'$':val}
def error(self, message):
m = 'Formatter: ' + message + _(' near ')
@ -144,7 +149,7 @@ class _Parser(object):
# We have an identifier. Determine if it is a function
id = self.token()
if not self.token_op_is_a('('):
return getattr(self, id, _('unknown id ') + id)
return self.variables.get(id, _('unknown id ') + id)
# We have a function.
# Check if it is a known one. We do this here so error reporting is
# better, as it can identify the tokens near the problem.
@ -417,15 +422,18 @@ class TemplateFormatter(string.Formatter):
self.kwargs = kwargs
self.book = book
self.composite_values = {}
try:
ans = self.vformat(fmt, [], kwargs).strip()
except Exception, e:
if DEBUG:
traceback.print_exc()
ans = error_value + ' ' + e.message
if fmt.startswith('program:'):
ans = self._eval_program(None, fmt[8:])
else:
try:
ans = self.vformat(fmt, [], kwargs).strip()
except Exception, e:
if DEBUG:
traceback.print_exc()
ans = error_value + ' ' + e.message
return ans
class ValidateFormat(TemplateFormatter):
class ValidateFormatter(TemplateFormatter):
'''
Provides a format function that substitutes '' for any missing value
'''
@ -435,6 +443,14 @@ class ValidateFormat(TemplateFormatter):
def validate(self, x):
return self.vformat(x, [], {})
validation_formatter = ValidateFormat()
validation_formatter = ValidateFormatter()
class EvalFormatter(TemplateFormatter):
'''
A template formatter that uses a simple dict instead of an mi instance
'''
def get_value(self, key, args, kwargs):
return kwargs.get(key, _('No such variable ') + key)
eval_formatter = EvalFormatter()