<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
Created on Jan 21, 2011

@author: sergey
'''
import zencoding.parser.utils as parser_utils
import re
import math
from zencoding.utils import prettify_number

def reflect_css_value(editor):
	"""
	Reflect CSS value: takes rule's value under caret and pastes it for the same 
	rules with vendor prefixes
	@param editor: ZenEditor
	"""
	if editor.get_syntax() != 'css':
		return False
	
	content = editor.get_content()
	caret_pos = editor.get_caret_pos()
	sel_start, sel_end = editor.get_selection_range()
	css = parser_utils.extract_css_rule(content, caret_pos)
		
	if not css or caret_pos < css[0] or caret_pos > css[1]:
		# no matching CSS rule or caret outside rule bounds
		return False
		
	tokens = parser_utils.parse_css(content[css[0]:css[1]], css[0])
	token_ix = find_token_from_position(tokens, caret_pos, 'identifier')
	
	if token_ix != -1:
		cur_prop = tokens[token_ix]['content']
		value_token = find_value_token(tokens, token_ix + 1)
		base_name = get_base_css_name(cur_prop)
		re_name = re.compile('^(?:\\-\\w+\\-)?' + base_name + '$')
		re_name = get_reflected_css_name(base_name)
		values = []
			
		if not value_token:
			return False
			
		# search for all vendor-prefixed properties
		for i, token in enumerate(tokens):
			if token['type'] == 'identifier' and re.search(re_name, token['content']) and token['content'] != cur_prop:
				v = find_value_token(tokens, i + 1)
				if v:
					values.append({'name': token, 'value': v})
		
		# some editors do not provide easy way to replace multiple code 
		# fragments so we have to squash all replace operations into one
		if values:
			data = content[values[0]['value']['start']:values[-1]['value']['end']]
			offset = values[0]['value']['start']
			value = value_token['content']
				
			for v in values:
				data = replace_substring(data, v['value']['start'] - offset, v['value']['end'] - offset, 
					get_reflected_value(cur_prop, value, v['name']['content'], v['value']['content']))
					
				# also calculate new caret position
				if v['value']['start'] < caret_pos:
					caret_pos += len(value) - v['value']['end'] + v['value']['start']
				
			editor.replace_content(data, offset, values[-1]['value']['end'], True)
			editor.create_selection(caret_pos, caret_pos + sel_end - sel_start)
			
			return True
	
	return False

def get_base_css_name(name):
	"""
    Removes vendor prefix from CSS property
    @param name: CSS property
    @type name: str
    @return: str
	"""
	return re.sub(r'^\s*\-\w+\-', '', name)

def get_reflected_css_name(name):
	"""
    Returns regexp that should match reflected CSS property names
    @param name: Current CSS property name
    @type name: str
    @return: RegExp
	"""
	name = get_base_css_name(name)
	vendor_prefix = '^(?:\\-\\w+\\-)?'
	
	if name == 'opacity' or name == 'filter':
		return re.compile(vendor_prefix + '(?:opacity|filter)$')
	
	m = re.match(r'^border-radius-(top|bottom)(left|right)')
	if m:
		# Mozilla-style border radius
		return re.compile(vendor_prefix + '(?:%s|border-%s-%s-radius)$' % (name, m.group(1), m.group(2)) )
	
	m = re.match(r'^border-(top|bottom)-(left|right)-radius')
	if m: 
		return re.compile(vendor_prefix + '(?:%s|border-radius-%s%s)$'  % (name, m.group(1), m.group(2)) );
	
	return re.compile(vendor_prefix + name + '$')

def get_reflected_value(cur_name, cur_value, ref_name, ref_value):
	"""<commit_msg>Bugfixes in Reflect CSS Value action<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
Created on Jan 21, 2011

@author: sergey
'''
import zencoding.parser.utils as parser_utils
import re
import math
from zencoding.utils import prettify_number
import zencoding

@zencoding.action
def reflect_css_value(editor):
	"""
	Reflect CSS value: takes rule's value under caret and pastes it for the same 
	rules with vendor prefixes
	@param editor: ZenEditor
	"""
	if editor.get_syntax() != 'css':
		return False
	
	content = editor.get_content()
	caret_pos = editor.get_caret_pos()
	sel_start, sel_end = editor.get_selection_range()
	css = parser_utils.extract_css_rule(content, caret_pos)
		
	if not css or caret_pos < css[0] or caret_pos > css[1]:
		# no matching CSS rule or caret outside rule bounds
		return False
		
	tokens = parser_utils.parse_css(content[css[0]:css[1]], css[0])
	token_ix = find_token_from_position(tokens, caret_pos, 'identifier')
	
	if token_ix != -1:
		cur_prop = tokens[token_ix]['content']
		value_token = find_value_token(tokens, token_ix + 1)
		base_name = get_base_css_name(cur_prop)
		re_name = re.compile('^(?:\\-\\w+\\-)?' + base_name + '$')
		re_name = get_reflected_css_name(base_name)
		values = []
			
		if not value_token:
			return False
			
		# search for all vendor-prefixed properties
		for i, token in enumerate(tokens):
			if token['type'] == 'identifier' and re.search(re_name, token['content']) and token['content'] != cur_prop:
				v = find_value_token(tokens, i + 1)
				if v:
					values.append({'name': token, 'value': v})
		
		# some editors do not provide easy way to replace multiple code 
		# fragments so we have to squash all replace operations into one
		if values:
			data = content[values[0]['value']['start']:values[-1]['value']['end']]
			offset = values[0]['value']['start']
			value = value_token['content']
				
			for v in values:
				data = replace_substring(data, v['value']['start'] - offset, v['value']['end'] - offset, 
					get_reflected_value(cur_prop, value, v['name']['content'], v['value']['content']))
					
				# also calculate new caret position
				if v['value']['start'] < caret_pos:
					caret_pos += len(value) - v['value']['end'] + v['value']['start']
				
			editor.replace_content(data, offset, values[-1]['value']['end'], True)
			editor.create_selection(caret_pos, caret_pos + sel_end - sel_start)
			
			return True
	
	return False

def get_base_css_name(name):
	"""
    Removes vendor prefix from CSS property
    @param name: CSS property
    @type name: str
    @return: str
	"""
	return re.sub(r'^\s*\-\w+\-', '', name)

def get_reflected_css_name(name):
	"""
    Returns regexp that should match reflected CSS property names
    @param name: Current CSS property name
    @type name: str
    @return: RegExp
	"""
	name = get_base_css_name(name)
	vendor_prefix = '^(?:\\-\\w+\\-)?'
	
	if name == 'opacity' or name == 'filter':
		return re.compile(vendor_prefix + '(?:opacity|filter)$')
	
	m = re.match(r'^border-radius-(top|bottom)(left|right)', name)
	if m:
		# Mozilla-style border radius
		return re.compile(vendor_prefix + '(?:%s|border-%s-%s-radius)$' % (name, m.group(1), m.group(2)) )
	
	m = re.match(r'^border-(top|bottom)-(left|right)-radius', name)
	if m: 
		return re.compile(vendor_prefix + '(?:%s|border-radius-%s%s)$'  % (name, m.group(1), m.group(2)) );
	
	return re.compile(vendor_prefix + name + '$')

def get_reflected_value(cur_name, cur_value, ref_name, ref_value):
	"""
{'fraction_non_alphanumeric': 0.15745296671490594, 'fraction_numerical': 0.0066570188133140374, 'mean_word_length': 4.180659670164918, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5899369', 'n_tokens_mistral': 2589, 'n_tokens_neox': 2313, 'n_words': 596}