def get_merged_dict(settings, preprocessor=None): global hayaku_extra_dicts_cache global hayaku_extra_aliases_cache global hayaku_dict_cache global hayaku_aliases_cache cache_key = 'CSS' if preprocessor: cache_key = preprocessor result_dict, result_aliases = get_css_dict(preprocessor=preprocessor) new_dict = {} new_aliases = {} extra_scopes = ['user', 'syntax', 'project'] + settings.get('hayaku_extra_scopes', []) for scope in extra_scopes: dict_name = 'hayaku_' + scope + '_dict' alias_name = 'hayaku_' + scope + '_aliases' new_dict[dict_name] = settings.get(dict_name, {}) new_aliases[alias_name] = settings.get(alias_name, {}) # TODO: use a function for those two if-else noodles if 'CSS' in new_dict[dict_name]: if preprocessor in new_dict[dict_name]: new_dict[dict_name] = merge_dict(new_dict[dict_name].get('CSS'), new_dict[dict_name].get(preprocessor)) else: new_dict[dict_name] = new_dict[dict_name].get('CSS') elif preprocessor in new_dict[dict_name]: new_dict[dict_name] = new_dict[dict_name].get(preprocessor) if 'CSS' in new_aliases[alias_name]: if preprocessor in new_aliases[alias_name]: new_aliases[alias_name] = merge_dict(new_aliases[alias_name].get('CSS'), new_aliases[alias_name].get(preprocessor)) else: new_aliases[alias_name] = new_aliases[alias_name].get('CSS') elif preprocessor in new_aliases[alias_name]: new_aliases[alias_name] = new_aliases[alias_name].get(preprocessor) if new_dict != hayaku_extra_dicts_cache.get(cache_key): hayaku_extra_dicts_cache[cache_key] = new_dict for dict_scope in dict(hayaku_extra_dicts_cache.get(cache_key)): result_dict = merge_dict(result_dict, hayaku_extra_dicts_cache.get(cache_key).get(dict_scope)) hayaku_dict_cache[cache_key] = result_dict elif cache_key in hayaku_dict_cache: result_dict = hayaku_dict_cache[cache_key] if new_aliases != hayaku_extra_aliases_cache.get(cache_key): hayaku_extra_aliases_cache[cache_key] = new_aliases for aliases_scope in dict(hayaku_extra_aliases_cache.get(cache_key)): result_aliases = merge_aliases(result_aliases, hayaku_extra_aliases_cache.get(cache_key).get(aliases_scope)) hayaku_aliases_cache[cache_key] = result_aliases elif cache_key in hayaku_aliases_cache: result_aliases = hayaku_aliases_cache[cache_key] return result_dict, result_aliases
def get_all_properties(css_dict=None): if css_dict is None: css_dict = get_css_dict()[0] all_properties = list(css_dict) # раширить парами "свойство значение" (например "position absolute") for prop_name in all_properties: property_values = css_flat_list(prop_name, css_dict) extends_sieve = (i for i in property_values if not i[1].startswith('<')) unit_sieve = (i for i in extends_sieve if not i[1].startswith('.')) all_properties.extend('{0} {1}'.format(prop_name, v[1]) for v in unit_sieve) return all_properties
def expand_value(args, css_dict=None, options=None): if css_dict is None: css_dict = get_css_dict()[0] if 'keyword-value' in args: return args['keyword-value'] if args['property-name'] in set(p for p, v in get_flat_css(css_dict) if v == '<color_values>'): if 'color' in args and not args['color']: return '#' return color_expand(args.get('color', ''),args.get('color_alpha', 1)) elif args['property-name'] in set(p for p, v in get_flat_css(css_dict) if v.startswith('.')) and 'keyword-value' not in args: ret = length_expand(css_dict, args['property-name'], args.get('type-value', ''), args.get('type-name', ''), options) return ret elif 'type-value' in args: return str(args['type-value']) return args.get('keyword-value', '')
def expand_value(args, css_dict=None, options=None): if css_dict is None: css_dict = get_css_dict()[0] if 'keyword-value' in args: return args['keyword-value'] if args['property-name'] in set(p for p, v in get_flat_css(css_dict) if v == '<color_values>'): if 'color' in args and not args['color']: return '#' return color_expand(args.get('color', ''), args.get('color_alpha', 1)) elif args['property-name'] in set( p for p, v in get_flat_css(css_dict) if v.startswith('.')) and 'keyword-value' not in args: ret = length_expand(css_dict, args['property-name'], args.get('type-value', ''), args.get('type-name', ''), options) return ret elif 'type-value' in args: return str(args['type-value']) return args.get('keyword-value', '')
def extract(hayaku): if isinstance(hayaku, dict): s1 = hayaku.get('abbr') css_dict = hayaku.get('options').get('dict') css_aliases = hayaku.get('options').get('aliases') else: s1 = hayaku css_dict, css_aliases = get_css_dict() """В зависимости от найденных компонент в аббревиатуре применяет функцию extract""" prop_iter = [] parts = segmentation(s1) abbr_value = False if 'property-name' in parts: if parts['important']: s1 = s1[:-1] if s1[-1] != ':' and s1 != parts['property-name']: abbr_value = True if 'color' in parts: prop_iter.extend(prop for prop, val in get_flat_css(css_dict) if val == '<color_values>') if isinstance(parts.get('type-value'), int): prop_iter.extend(prop for prop, val in get_flat_css(css_dict) if val == '<integer>') if isinstance(parts.get('type-value'), float): # TODO: добавить deg, grad, time prop_iter.extend(prop for prop, val in get_flat_css(css_dict) if val in ('<length>', '<number>', 'percentage')) # TODO: проверить, всегда ли эта переменная нужна для следующих условий all_properties = get_all_properties(css_dict) if 'keyword-value' in parts and not parts['keyword-value']: prop_iter.extend(all_properties) if 'keyword-value' in parts: prop_iter.extend( prop_value(parts['property-name'], parts['keyword-value'], all_properties)) elif 'color' not in parts or 'type-value' in parts: prop_iter.extend(all_properties) if not parts or not (parts.get('property-name', '') or parts.get('property-value', '')): return abbr = ' '.join([ parts.get('property-name', '') or parts.get('property-value', ''), parts.get('keyword-value', ''), ]) abbr = abbr.strip() if not css_aliases.get(s1): abbr = css_aliases.get(abbr, abbr) if abbr[-1] == ':': abbr = abbr[:-1] starts_properties = [] # todo: переделать механизм PAIRS # надо вынести константы в css-dict # по две буквы (bd, bg, ba) pair = None for alias in css_aliases: if (alias.endswith('...')) and abbr.startswith(alias[:-3]): pair = css_aliases.get(alias) break if pair is not None: starts_properties = [ prop for prop in prop_iter if prop.startswith(pair) and sub_string(prop, abbr) ] if not starts_properties: starts_properties = [ prop for prop in prop_iter if prop[0] == abbr[0] and sub_string(prop, abbr) ] if 'type-value' in parts or ('keyword-value' in parts and parts['keyword-value'] == ''): starts_properties = [i for i in starts_properties if ' ' not in i] property_ = hayaku_extract(abbr, starts_properties, PRIORITY_PROPERTIES, string_score) property_, value = property_.split(' ') if ' ' in property_ else ( property_, None) # print property_, value if not property_: return {} parts['property-name'] = property_ if value is not None: parts['keyword-value'] = value # Проверка соответствия свойства и значения allow_values = [ val for prop, val in get_flat_css(css_dict) if prop == parts['property-name'] ] if 'color' in parts and '<color_values>' not in allow_values: del parts['color'] if 'type-value' in parts and not any( (t in allow_values) for t in ['<integer>', 'percentage', '<length>', '<number>', '<alphavalue>']): del parts['type-value'] if 'keyword-value' in parts and parts['keyword-value'] not in allow_values: del parts['keyword-value'] if all([ 'keyword-value' not in parts, 'type-value' not in parts, 'color' not in parts, ]) and abbr_value: return {} # Добавить значение по-умолчанию if parts['property-name'] in css_dict: default_value = css_defaults(parts['property-name'], css_dict) if default_value is not None: parts['default-value'] = default_value obj = css_dict[parts['property-name']] if 'prefixes' in obj: parts['prefixes'] = obj['prefixes'] if 'no-unprefixed-property' in obj: parts['no-unprefixed-property'] = obj['no-unprefixed-property'] if parts['abbr'] == parts.get('property-value'): del parts['property-value'] return parts
def extract(hayaku): if isinstance(hayaku, dict): s1 = hayaku.get('abbr') css_dict = hayaku.get('options').get('dict') css_aliases = hayaku.get('options').get('aliases') else: s1 = hayaku css_dict, css_aliases = get_css_dict() """В зависимости от найденных компонент в аббревиатуре применяет функцию extract""" prop_iter = [] parts = segmentation(s1) abbr_value = False if 'property-name' in parts: if parts['important']: s1 = s1[:-1] if s1[-1] != ':' and s1 != parts['property-name']: abbr_value = True if 'color' in parts: prop_iter.extend(prop for prop, val in get_flat_css(css_dict) if val == '<color_values>') if isinstance(parts.get('type-value'), int): prop_iter.extend(prop for prop, val in get_flat_css(css_dict) if val == '<integer>') if isinstance(parts.get('type-value'), float): # TODO: добавить deg, grad, time prop_iter.extend(prop for prop, val in get_flat_css(css_dict) if val in ('<length>', '<number>', 'percentage')) # TODO: проверить, всегда ли эта переменная нужна для следующих условий all_properties = get_all_properties(css_dict) if 'keyword-value' in parts and not parts['keyword-value']: prop_iter.extend(all_properties) if 'keyword-value' in parts: prop_iter.extend(prop_value(parts['property-name'], parts['keyword-value'], all_properties)) elif 'color' not in parts or 'type-value' in parts: prop_iter.extend(all_properties) if not parts or not (parts.get('property-name', '') or parts.get('property-value', '')): return abbr = ' '.join([ parts.get('property-name', '') or parts.get('property-value', ''), parts.get('keyword-value', ''), ]) abbr = abbr.strip() if not css_aliases.get(s1): abbr = css_aliases.get(abbr, abbr) if abbr[-1] == ':': abbr = abbr[:-1] starts_properties = [] # todo: переделать механизм PAIRS # надо вынести константы в css-dict # по две буквы (bd, bg, ba) pair = None for alias in css_aliases: if (alias.endswith('...')) and abbr.startswith(alias[:-3]): pair = css_aliases.get(alias) break if pair is not None: starts_properties = [prop for prop in prop_iter if prop.startswith(pair) and sub_string(prop, abbr)] if not starts_properties: starts_properties = [prop for prop in prop_iter if prop[0] == abbr[0] and sub_string(prop, abbr)] if 'type-value' in parts or ('keyword-value' in parts and parts['keyword-value'] == ''): starts_properties = [i for i in starts_properties if ' ' not in i] property_ = hayaku_extract(abbr, starts_properties, PRIORITY_PROPERTIES, string_score) property_, value = property_.split(' ') if ' ' in property_ else (property_, None) # print property_, value if not property_: return {} parts['property-name'] = property_ if value is not None: parts['keyword-value'] = value # Проверка соответствия свойства и значения allow_values = [val for prop, val in get_flat_css(css_dict) if prop == parts['property-name']] if 'color' in parts and '<color_values>' not in allow_values: del parts['color'] if 'type-value' in parts and not any((t in allow_values) for t in ['<integer>', 'percentage', '<length>', '<number>', '<alphavalue>']): del parts['type-value'] if 'keyword-value' in parts and parts['keyword-value'] not in allow_values: del parts['keyword-value'] if all([ 'keyword-value' not in parts, 'type-value' not in parts, 'color' not in parts, ]) and abbr_value: return {} # Добавить значение по-умолчанию if parts['property-name'] in css_dict: default_value = css_defaults(parts['property-name'], css_dict) if default_value is not None: parts['default-value'] = default_value obj = css_dict[parts['property-name']] if 'prefixes' in obj: parts['prefixes'] = obj['prefixes'] if 'no-unprefixed-property' in obj: parts['no-unprefixed-property'] = obj['no-unprefixed-property'] if parts['abbr'] == parts.get('property-value'): del parts['property-value'] return parts
def get_merged_dict(options): global hayaku_extra_dicts_cache global hayaku_extra_aliases_cache global hayaku_dict_cache global hayaku_aliases_cache settings = options.get('settings') cache_key = 'CSS' preprocessor = options.get('CSS_preprocessor') if preprocessor: cache_key = preprocessor result_dict, result_aliases = get_css_dict(preprocessor=preprocessor) new_dict = {} new_aliases = {} extra_scopes = ['user', 'syntax', 'project'] + settings.get( 'hayaku_extra_scopes', []) for scope in extra_scopes: dict_name = 'hayaku_' + scope + '_dict' alias_name = 'hayaku_' + scope + '_aliases' new_dict[dict_name] = settings.get(dict_name, {}) new_aliases[alias_name] = settings.get(alias_name, {}) # TODO: use a function for those two if-else noodles if 'CSS' in new_dict[dict_name]: if preprocessor in new_dict[dict_name]: new_dict[dict_name] = merge_dict( new_dict[dict_name].get('CSS'), new_dict[dict_name].get(preprocessor)) else: new_dict[dict_name] = new_dict[dict_name].get('CSS') elif preprocessor in new_dict[dict_name]: new_dict[dict_name] = new_dict[dict_name].get(preprocessor) if 'CSS' in new_aliases[alias_name]: if preprocessor in new_aliases[alias_name]: new_aliases[alias_name] = merge_dict( new_aliases[alias_name].get('CSS'), new_aliases[alias_name].get(preprocessor)) else: new_aliases[alias_name] = new_aliases[alias_name].get('CSS') elif preprocessor in new_aliases[alias_name]: new_aliases[alias_name] = new_aliases[alias_name].get(preprocessor) if new_dict != hayaku_extra_dicts_cache.get(cache_key): hayaku_extra_dicts_cache[cache_key] = new_dict for dict_scope in dict(hayaku_extra_dicts_cache.get(cache_key)): result_dict = merge_dict( result_dict, hayaku_extra_dicts_cache.get(cache_key).get(dict_scope)) hayaku_dict_cache[cache_key] = result_dict elif cache_key in hayaku_dict_cache: result_dict = hayaku_dict_cache[cache_key] if new_aliases != hayaku_extra_aliases_cache.get(cache_key): hayaku_extra_aliases_cache[cache_key] = new_aliases for aliases_scope in dict(hayaku_extra_aliases_cache.get(cache_key)): result_aliases = merge_aliases( result_aliases, hayaku_extra_aliases_cache.get(cache_key).get(aliases_scope)) hayaku_aliases_cache[cache_key] = result_aliases elif cache_key in hayaku_aliases_cache: result_aliases = hayaku_aliases_cache[cache_key] return result_dict, result_aliases