From 353e7c2b3629397511123c775266babaf079d2f2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 5 Dec 2016 17:07:11 +0530 Subject: [PATCH] Fix subsetting of fonts whose names start with "and" not working Caused by a bug in the font-family parsing routines of cssutils, workaround by quoting the family name before passing it to cssutils. --- src/tinycss/fonts3.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tinycss/fonts3.py b/src/tinycss/fonts3.py index bc24c215d4..27d9f30afb 100644 --- a/src/tinycss/fonts3.py +++ b/src/tinycss/fonts3.py @@ -16,6 +16,7 @@ from .tokenizer import tokenize_grouped def parse_font_family_tokens(tokens): families = [] current_family = '' + def commit(): val = current_family.strip() if val: @@ -37,19 +38,23 @@ def parse_font_family_tokens(tokens): commit() return families + def parse_font_family(css_string): return parse_font_family_tokens(tokenize_grouped(type('')(css_string).strip())) + def serialize_single_font_family(x): xl = x.lower() if xl in GENERIC_FAMILIES: if xl == 'sansserif': xl = 'sans-serif' return xl - if SIMPLE_NAME_PAT.match(x) is not None: + if SIMPLE_NAME_PAT.match(x) is not None and not x.lower().startswith('and'): + # cssutils dies if a font name starts with and return x return '"%s"' % x.replace('"', r'\"') + def serialize_font_family(families): return ', '.join(map(serialize_single_font_family, families)) @@ -65,6 +70,7 @@ LEGACY_FONT_SPEC = frozenset('caption icon menu message-box small-caption status GENERIC_FAMILIES = frozenset('serif sans-serif sansserif cursive fantasy monospace'.split()) SIMPLE_NAME_PAT = re.compile(r'[a-zA-Z][a-zA-Z0-9_-]*$') + def serialize_font(font_dict): ans = [] for x in 'style variant weight stretch'.split(): @@ -83,6 +89,7 @@ def serialize_font(font_dict): ans.append(serialize_font_family(val)) return ' '.join(ans) + def parse_font(css_string): # See https://www.w3.org/TR/css-fonts-3/#font-prop style = variant = weight = stretch = size = height = None @@ -178,6 +185,7 @@ def parse_font(css_string): ans['font-family'] = families return ans + class FontFaceRule(object): at_keyword = '@font-face' @@ -192,6 +200,7 @@ class FontFaceRule(object): return ('<{0.__class__.__name__} at {0.line}:{0.column}>' .format(self)) + class CSSFonts3Parser(CSS21Parser): ''' Parse @font-face rules from the CSS 3 fonts module ''' @@ -214,4 +223,3 @@ class CSSFonts3Parser(CSS21Parser): declarations, decerrors = self.parse_declaration_list(rule.body) errors.extend(decerrors) return FontFaceRule(declarations, rule.line, rule.column) -