Пример #1
0
def match_pair(editor, direction='out', syntax=None):
    """
	Find and select HTML tag pair
	@param editor: Editor instance
	@type editor: ZenEditor
	@param direction: Direction of pair matching: 'in' or 'out'. 
	@type direction: str 
	"""
    direction = direction.lower()
    if syntax is None: syntax = editor.get_profile_name()

    range_start, range_end = editor.get_selection_range()
    cursor = range_end
    content = editor.get_content()
    rng = None

    old_open_tag = html_matcher.last_match['opening_tag']
    old_close_tag = html_matcher.last_match['closing_tag']

    if direction == 'in' and old_open_tag and range_start != range_end:
        #		user has previously selected tag and wants to move inward
        if not old_close_tag:
            #			unary tag was selected, can't move inward
            return False
        elif old_open_tag.start == range_start:
            if content[old_open_tag.end] == '<':
                #				test if the first inward tag matches the entire parent tag's content
                _r = html_matcher.find(content, old_open_tag.end + 1, syntax)
                if _r[0] == old_open_tag.end and _r[1] == old_close_tag.start:
                    rng = html_matcher.match(content, old_open_tag.end + 1,
                                             syntax)
                else:
                    rng = (old_open_tag.end, old_close_tag.start)
            else:
                rng = (old_open_tag.end, old_close_tag.start)
        else:
            new_cursor = content[0:old_close_tag.start].find(
                '<', old_open_tag.end)
            search_pos = new_cursor + 1 if new_cursor != -1 else old_open_tag.end
            rng = html_matcher.match(content, search_pos, syntax)
    else:
        rng = html_matcher.match(content, cursor, syntax)

    if rng and rng[0] is not None:
        editor.create_selection(rng[0], rng[1])
        return True
    else:
        return False
Пример #2
0
def get_zen_doctype(context, default='html'):
    '''
    Tests the document to see if it is CSS or XSL; for use with zen
    coding actions to determine type of snippets to use
    '''
    doc_type = default
    css_exts = ['css', 'less']
    xsl_exts = ['xsl', 'xslt']
    path = context.path()
    if path is not None:
        pos = path.rfind('.')
        if pos != -1:
            pos += 1
            ext = path[pos:]
            if ext in css_exts:
                doc_type = 'css'
            elif ext in xsl_exts:
                doc_type = 'xsl'
    # No luck with the extension; check for inline style tags
    if doc_type == 'html':
        range = get_range(context)
        cursor = range.location + range.length
        content = context.string()
        start, end = html_matcher.match(content, cursor)
        tag = html_matcher.last_match['opening_tag']
        if tag is not None:
            tag = tag.name
            if tag == 'style':
                doc_type = 'css'
    return doc_type
Пример #3
0
def merge_lines(editor):
    """
	Merge lines spanned by user selection. If there's no selection, tries to find
	matching tags and use them as selection
	@param editor: Editor instance
	@type editor: ZenEditor
	"""
    start, end = editor.get_selection_range()
    if start == end:
        # find matching tag
        pair = html_matcher.match(editor.get_content(), editor.get_caret_pos(),
                                  editor.get_profile_name())
        if pair and pair[0] is not None:
            start, end = pair

    if start != end:
        # got range, merge lines
        text = editor.get_content()[start:end]
        lines = map(lambda s: re.sub(r'^\s+', '', s),
                    zen_coding.split_by_lines(text))
        text = re.sub(r'\s{2,}', ' ', ''.join(lines))
        editor.replace_content(text, start, end)
        editor.create_selection(start, start + len(text))
        return True

    return False
Пример #4
0
def wrap_with_abbreviation(editor, abbr, syntax=None, profile_name=None):
	"""
	Wraps content with abbreviation
	@param editor: Editor instance
	@type editor: ZenEditor
	@param syntax: Syntax type (html, css, etc.)
	@type syntax: str
	@param profile_name: Output profile name (html, xml, xhtml)
	@type profile_name: str
	"""
	if not abbr: return None
	if syntax is None: syntax = editor.get_syntax()
	if profile_name is None: profile_name = editor.get_profile_name()
	start_offset, end_offset = editor.get_selection_range()
	content = editor.get_content()
	if start_offset == end_offset:
		# no selection, find tag pair
		rng = html_matcher.match(content, start_offset, profile_name)
		if rng[0] is None: # nothing to wrap
			return None
		else:
			start_offset, end_offset = rng
	start_offset, end_offset = narrow_to_non_space(content, start_offset, end_offset)
	line_bounds = get_line_bounds(content, start_offset)
	padding = get_line_padding(content[line_bounds[0]:line_bounds[1]])
	new_content = content[start_offset:end_offset]
	result = zen_coding.wrap_with_abbreviation(abbr, unindent_text(new_content, padding), syntax, profile_name)
	if result:
		editor.replace_content(result, start_offset, end_offset)
		return True
	return False
Пример #5
0
def match_pair(editor, direction='out', syntax=None):
	"""
	Find and select HTML tag pair
	@param editor: Editor instance
	@type editor: ZenEditor
	@param direction: Direction of pair matching: 'in' or 'out'. 
	@type direction: str 
	"""
	direction = direction.lower()
	if syntax is None: syntax = editor.get_profile_name()
	
	range_start, range_end = editor.get_selection_range()
	cursor = range_end
	content = editor.get_content()
	rng = None
	
	old_open_tag = html_matcher.last_match['opening_tag']
	old_close_tag = html_matcher.last_match['closing_tag']
	
	if direction == 'in' and old_open_tag and range_start != range_end:
#		user has previously selected tag and wants to move inward
		if not old_close_tag:
#			unary tag was selected, can't move inward
			return False
		elif old_open_tag.start == range_start:
			if content[old_open_tag.end] == '<':
#				test if the first inward tag matches the entire parent tag's content
				_r = html_matcher.find(content, old_open_tag.end + 1, syntax)
				if _r[0] == old_open_tag.end and _r[1] == old_close_tag.start:
					rng = html_matcher.match(content, old_open_tag.end + 1, syntax)
				else:
					rng = (old_open_tag.end, old_close_tag.start)
			else:
				rng = (old_open_tag.end, old_close_tag.start)
		else:
			new_cursor = content[0:old_close_tag.start].find('<', old_open_tag.end)
			search_pos = new_cursor + 1 if new_cursor != -1 else old_open_tag.end
			rng = html_matcher.match(content, search_pos, syntax)
	else:
		rng = html_matcher.match(content, cursor, syntax)
	
	if rng and rng[0] is not None:
		editor.create_selection(rng[0], rng[1])
		return True
	else:
		return False
Пример #6
0
def act(controller, bundle, options):
    context = tea.get_context(controller)
    direction = tea.get_option(options, 'direction', 'out')
    
    # Since input is always a selection of some kind, check if we have one
    
    rng = tea.get_range(context)
    cursor = rng.location + rng.length
    range_start, range_end = rng.location, rng.location + rng.length
    content = context.string()
    
    old_open_tag = html_matcher.last_match['opening_tag']
    old_close_tag = html_matcher.last_match['closing_tag']
    
    if direction.lower() == 'in' and old_open_tag and range_start != range_end:
        # user has previously selected tag and wants to move inward
        if not old_close_tag:
            # unary tag was selected, can't move inward
            return False
        elif old_open_tag.start == range_start:
            if content[old_open_tag.end] == '<':
                # test if the first inward tag matches the entire parent tag's content
                _start, _end = html_matcher.find(content, old_open_tag.end + 1)
                if _start == old_open_tag.end and _end == old_close_tag.start:
                    start, end = html_matcher.match(content, old_open_tag.end + 1)
                else:
                    start, end = old_open_tag.end, old_close_tag.start
            else:
                start, end = old_open_tag.end, old_close_tag.start
        else:
            new_cursor = content.find('<', old_open_tag.end, old_close_tag.start)
            search_pos = new_cursor != -1 and new_cursor + 1 or old_open_tag.end
            start, end = html_matcher.match(content, search_pos)
            
    else:
        start, end = html_matcher.match(content, cursor)
    
    if start is not None:
        new_range = tea.new_range(start, end - start)
        tea.set_selected_range(context, new_range)
        return True
    else:
        return False
Пример #7
0
def merge_lines(editor):
	"""
	Merge lines spanned by user selection. If there's no selection, tries to find
	matching tags and use them as selection
	@param editor: Editor instance
	@type editor: ZenEditor
	"""
	start, end = editor.get_selection_range()
	if start == end:
		# find matching tag
		pair = html_matcher.match(editor.get_content(), editor.get_caret_pos(), editor.get_profile_name())
		if pair and pair[0] is not None:
			start, end = pair
	
	if start != end:
		# got range, merge lines
		text = editor.get_content()[start:end]
		lines = map(lambda s: re.sub(r'^\s+', '', s), zen_coding.split_by_lines(text))
		text = re.sub(r'\s{2,}', ' ', ''.join(lines))
		editor.replace_content(text, start, end)
		editor.create_selection(start, start + len(text))
		return True
	
	return False
Пример #8
0
	def testXhtml(self):
		self.assertEqual((11, 16), html_matcher.match(xhtml_string, 12));
		self.assertEqual((3, 25), html_matcher.match(xhtml_string, 8));
		self.assertEqual((32, 38), html_matcher.match(xhtml_string, 36));
		self.assertEqual((46, 85), html_matcher.match(xhtml_string, 70));
		self.assertEqual((3, 113), html_matcher.match(xhtml_string, 43));
		self.assertEqual((89, 105), html_matcher.match(xhtml_string, 99));
		
		self.assertEqual((12, 52), html_matcher.match(xhtml_string2, 39));
		self.assertEqual((6, 59), html_matcher.match(xhtml_string2, 52));
		self.assertEqual((6, 59), html_matcher.match(xhtml_string2, 57));
		self.assertEqual((0, 66), html_matcher.match(xhtml_string2, 3));
		self.assertEqual((39, 52), html_matcher.match(xhtml_string2, 45));
		self.assertEqual((66, 97), html_matcher.match(xhtml_string2, 95));

		self.assertEqual((23, 52), html_matcher.match(xsl_string, 32));
		self.assertEqual((62, 91), html_matcher.match(xsl_string, 76));
		
		self.assertEqual((3, 105), html_matcher.match(xhtml_string3, 77));
		self.assertEqual((25, 56), html_matcher.match(xhtml_string3, 49));
Пример #9
0
    def testXhtml(self):
        self.assertEqual((11, 16), html_matcher.match(xhtml_string, 12))
        self.assertEqual((3, 25), html_matcher.match(xhtml_string, 8))
        self.assertEqual((32, 38), html_matcher.match(xhtml_string, 36))
        self.assertEqual((46, 85), html_matcher.match(xhtml_string, 70))
        self.assertEqual((3, 113), html_matcher.match(xhtml_string, 43))
        self.assertEqual((89, 105), html_matcher.match(xhtml_string, 99))

        self.assertEqual((12, 52), html_matcher.match(xhtml_string2, 39))
        self.assertEqual((6, 59), html_matcher.match(xhtml_string2, 52))
        self.assertEqual((6, 59), html_matcher.match(xhtml_string2, 57))
        self.assertEqual((0, 66), html_matcher.match(xhtml_string2, 3))
        self.assertEqual((39, 52), html_matcher.match(xhtml_string2, 45))
        self.assertEqual((66, 97), html_matcher.match(xhtml_string2, 95))

        self.assertEqual((23, 52), html_matcher.match(xsl_string, 32))
        self.assertEqual((62, 91), html_matcher.match(xsl_string, 76))

        self.assertEqual((3, 105), html_matcher.match(xhtml_string3, 77))
        self.assertEqual((25, 56), html_matcher.match(xhtml_string3, 49))
 def wrap(self, context, abbr, profile_name='xhtml'):
     # Set up the config variables
     zen_settings = settings_loader.load_settings()
     zen.update_settings(zen_settings)
     zen.newline = self.safe_str(tea.get_line_ending(context))
     zen_settings['variables']['indentation'] = self.safe_str(tea.get_indentation_string(context))
     
     # This allows us to use smart incrementing tab stops in zen snippets
     point_ix = [0]
     def place_ins_point(text):
         if not point_ix[0]:
             point_ix[0] += 1
             return '$0'
         else:
             return ''
     zen.insertion_point = place_ins_point
     
     text, rng = tea.selection_and_range(context)
     if not text:
         # no selection, find matching tag
         content = context.string()
         start, end = html_matcher.match(content, rng.location)
         if start is None:
             # nothing to wrap
             return False
         
         def is_space(char):
             return char.isspace() or char in r'\n\r'
         
         # narrow down selection until first non-space character
         while start < end:
             if not is_space(content[start]):
                 break
             start += 1
         
         while end > start:
             end -= 1
             if not is_space(content[end]):
                 end += 1
                 break
         
         rng = tea.new_range(start, end - start)
         text = tea.get_selection(context, rng)
         
     # Fetch the doctype based on file extension
     doc_type = tea.get_zen_doctype(context)
     
     text = self.unindent(context, text)
     
     # Damn Python's encodings! Have to convert string to ascii before wrapping 
     # and then back to utf-8
     result = zen.wrap_with_abbreviation(self.safe_str(abbr), self.safe_str(text), doc_type, profile_name)
     result = unicode(result, 'utf-8')
     
     result = tea.indent_snippet(context, result, rng)
     result = tea.clean_line_endings(context, result)
     
     cursor_loc = result.find('$0')
     if cursor_loc != -1:
         select_range = tea.new_range(cursor_loc + rng.location, 0)
         result = result.replace('$0', '')
         tea.insert_text_and_select(context, result, rng, select_range)
     else:
         tea.insert_text(context, result, rng)