Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 1b5aa30cb1caec22bb04cc2c5e3f8c55ee1b6b38 @fmarcia committed May 11, 2010
@@ -0,0 +1,39 @@
+Zen Coding for Gedit
+====================
+
+This plugin fully integrates [Zen Coding](http://code.google.com/p/zen-coding/) into [Gedit](http://projects.gnome.org/gedit/). With Zen Coding for Gedit, you can:
+
+- Expand abbreviation
+- Expand incrementally with abbreviation
+- Wrap incrementally with abbreviation
+- Balance tag inward or outward
+- Merge lines
+- Go to previous or next edit point
+- Update tag image size (needs `python-imaging`, see installation)
+- Remove tag
+- Split or join tags
+- Toggle comment
+- Create your own abbreviations and snippets
+
+These actions are available using keyboard shortcuts and menu items.
+
+Installation
+------------
+
+1. Download [zip](http://github.com/fmarcia/zen-coding-gedit/zipball/master) or [tar](http://github.com/fmarcia/zen-coding-gedit/tarball/master) source
+2. Unpack it
+3. Run `./zencoding-install.sh`
+4. In order to use "Update tag image size", install `python-imaging`, if not already done
+5. In Gedit, go to Edit > Preferences > Plugins and enable the plugin
+
+Credits
+-------
+
+- Zen Coding is written by [Sergey Chikuyonok](http://chikuyonok.ru/)
+- Zen Coding for Gedit is written by [Franck Marcia](http://github.com/fmarcia)
+
+License
+-------
+
+Zen Coding for Gedit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Zen Coding installation
+#
+
+sudo cp zencoding.png /usr/share/icons/hicolor/16x16/apps
+sudo gtk-update-icon-cache /usr/share/icons/hicolor > /dev/null 2>&1
+mkdir -p ~/.gnome2/gedit/plugins
+cp zencoding.gedit-plugin ~/.gnome2/gedit/plugins
+cp -r zencoding ~/.gnome2/gedit/plugins
+
@@ -0,0 +1,11 @@
+[Gedit Plugin]
+Loader=python
+Module=zencoding
+IAge=2
+Name=Zen Coding
+Description=Expand expressions similar to CSS selectors into HTML, CSS or XSLT code
+Description[fr]=Développe des expressions similaires à des sélecteurs CSS en code HTML, CSS ou XSLT
+Authors=Zen Coding: Sergey Chikuyonok <serge.che@gmail.com>\nGedit Plugin: Franck Marcia <franck.marcia@gmail.com>
+Copyright=Zen Coding: Sergey Chikuyonok <serge.che@gmail.com>\nGedit Plugin: Franck Marcia <franck.marcia@gmail.com>
+Website=http://code.google.com/p/zen-coding/
+
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,9 @@
+'''
+Bootstrap for Zen Coding for Gedit
+
+@author Franck Marcia (franck.marcia@gmail.com)
+@link http://github.com/fmarcia/zen-coding-gedit
+'''
+
+from plugin import ZenCodingPlugin
+
@@ -0,0 +1,23 @@
+import os.path
+import sys
+
+# import all filters
+__sub_modules = []
+__prefix = 'zencoding.filters'
+__filter_dir = os.path.dirname(__file__)
+sys.path.append(__filter_dir)
+
+filter_map = {}
+for file in os.listdir(__filter_dir):
+ name, ext = os.path.splitext(file)
+ if ext.lower() == '.py':
+ __sub_modules.append(name)
+
+__filters = __import__(__prefix, globals(), locals(), __sub_modules)
+for key in dir(__filters):
+ __module = getattr(__filters, key)
+ if hasattr(__module, '__name__') and __module.__name__.startswith(__prefix + '.') and hasattr(__module, 'process'):
+ if hasattr(__module, 'alias'):
+ filter_map[__module.alias] = __module.process
+ else:
+ filter_map[__module.__name__[len(__prefix) + 1:]] = __module.process
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Comment important tags (with 'id' and 'class' attributes)
+@author Sergey Chikuyonok (serge.che@gmail.com)
+@link http://chikuyonok.ru
+'''
+from zencoding import zen_core as zen_coding
+
+alias = 'c'
+"Filter name alias (if not defined, ZC will use module name)"
+
+def add_comments(node, i):
+
+ """
+ Add comments to tag
+ @type node: ZenNode
+ @type i: int
+ """
+ id_attr = node.get_attribute('id')
+ class_attr = node.get_attribute('class')
+ nl = zen_coding.get_newline()
+
+ if id_attr or class_attr:
+ comment_str = ''
+ padding = node.parent and node.parent.padding or ''
+ if id_attr: comment_str += '#' + id_attr
+ if class_attr: comment_str += '.' + class_attr
+
+ node.start = node.start.replace('<', '<!-- ' + comment_str + ' -->' + nl + padding + '<', 1)
+ node.end = node.end.replace('>', '>' + nl + padding + '<!-- /' + comment_str + ' -->', 1)
+
+ # replace counters
+ node.start = zen_coding.replace_counter(node.start, i + 1)
+ node.end = zen_coding.replace_counter(node.end, i + 1)
+
+def process(tree, profile):
+ if profile['tag_nl'] is False:
+ return tree
+
+ for i, item in enumerate(tree.children):
+ if item.is_block():
+ add_comments(item, i)
+ process(item, profile)
+
+ return tree
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Filter for escaping unsafe XML characters: <, >, &
+@author Sergey Chikuyonok (serge.che@gmail.com)
+@link http://chikuyonok.ru
+'''
+import re
+
+alias = 'e'
+"Filter name alias (if not defined, ZC will use module name)"
+
+char_map = {
+ '<': '&lt;',
+ '>': '&gt;',
+ '&': '&amp;'
+}
+
+re_chars = re.compile(r'[<>&]')
+
+def escape_chars(text):
+ return re_chars.sub(lambda m: char_map[m.group(0)], text)
+
+def process(tree, profile=None):
+ for item in tree.children:
+ item.start = escape_chars(item.start)
+ item.end = escape_chars(item.end)
+
+ process(item)
+
+ return tree
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Format CSS properties: add space after property name:
+padding:0; -> padding: 0;
+@author Sergey Chikuyonok (serge.che@gmail.com)
+@link http://chikuyonok.ru
+'''
+import re
+
+alias = 'fc'
+"Filter name alias (if not defined, ZC will use module name)"
+
+re_css_prop = re.compile(r'([\w\-]+\s*:)\s*')
+
+def process(tree, profile):
+ for item in tree.children:
+ # CSS properties are always snippets
+ if item.type == 'snippet':
+ item.start = re_css_prop.sub(r'\1 ', item.start)
+
+ process(item, profile)
+
+ return tree
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generic formatting filter: creates proper indentation for each tree node,
+placing "%s" placeholder where the actual output should be. You can use
+this filter to preformat tree and then replace %s placeholder to whatever you
+need. This filter should't be called directly from editor as a part
+of abbreviation.
+@author Sergey Chikuyonok (serge.che@gmail.com)
+@link http://chikuyonok.ru
+"""
+import re
+from zencoding import zen_core as zen_coding
+
+alias = '_format'
+"Filter name alias (if not defined, ZC will use module name)"
+
+child_token = '${child}'
+placeholder = '%s'
+
+def get_newline():
+ return zen_coding.get_newline()
+
+
+def get_indentation():
+ return zen_coding.get_indentation()
+
+def has_block_sibling(item):
+ """
+ Test if passed node has block-level sibling element
+ @type item: ZenNode
+ @return: bool
+ """
+ return item.parent and item.parent.has_block_children()
+
+def is_very_first_child(item):
+ """
+ Test if passed itrem is very first child of the whole tree
+ @type tree: ZenNode
+ """
+ return item.parent and not item.parent.parent and not item.previous_sibling
+
+def should_break_line(node, profile):
+ """
+ Need to add line break before element
+ @type node: ZenNode
+ @type profile: dict
+ @return: bool
+ """
+ if not profile['inline_break']:
+ return False
+
+ # find toppest non-inline sibling
+ while node.previous_sibling and node.previous_sibling.is_inline():
+ node = node.previous_sibling
+
+ if not node.is_inline():
+ return False
+
+ # calculate how many inline siblings we have
+ node_count = 1
+ node = node.next_sibling
+ while node:
+ if node.is_inline():
+ node_count += 1
+ else:
+ break
+ node = node.next_sibling
+
+ return node_count >= profile['inline_break']
+
+def should_break_child(node, profile):
+ """
+ Need to add newline because <code>item</code> has too many inline children
+ @type node: ZenNode
+ @type profile: dict
+ @return: bool
+ """
+ # we need to test only one child element, because
+ # has_block_children() method will do the rest
+ return node.children and should_break_line(node.children[0], profile)
+
+def process_snippet(item, profile, level=0):
+ """
+ Processes element with <code>snippet</code> type
+ @type item: ZenNode
+ @type profile: dict
+ @param level: Depth level
+ @type level: int
+ """
+ data = item.source.value;
+
+ if not data:
+ # snippet wasn't found, process it as tag
+ return process_tag(item, profile, level)
+
+ item.start = placeholder
+ item.end = placeholder
+
+ padding = item.parent.padding if item.parent else get_indentation() * level
+
+ if not is_very_first_child(item):
+ item.start = get_newline() + padding + item.start
+
+ # adjust item formatting according to last line of <code>start</code> property
+ parts = data.split(child_token)
+ lines = zen_coding.split_by_lines(parts[0] or '')
+ padding_delta = get_indentation()
+
+ if len(lines) > 1:
+ m = re.match(r'^(\s+)', lines[-1])
+ if m:
+ padding_delta = m.group(1)
+
+ item.padding = padding + padding_delta
+
+ return item
+
+def process_tag(item, profile, level=0):
+ """
+ Processes element with <code>tag</code> type
+ @type item: ZenNode
+ @type profile: dict
+ @param level: Depth level
+ @type level: int
+ """
+ if not item.name:
+ # looks like it's a root element
+ return item
+
+ item.start = placeholder
+ item.end = placeholder
+
+ is_unary = item.is_unary() and not item.children
+
+ # formatting output
+ if profile['tag_nl'] is not False:
+ padding = item.parent.padding if item.parent else get_indentation() * level
+ force_nl = profile['tag_nl'] is True
+ should_break = should_break_line(item, profile)
+
+ # formatting block-level elements
+ if ((item.is_block() or should_break) and item.parent) or force_nl:
+ # snippet children should take different formatting
+ if not item.parent or (item.parent.type != 'snippet' and not is_very_first_child(item)):
+ item.start = get_newline() + padding + item.start
+
+ if item.has_block_children() or should_break_child(item, profile) or (force_nl and not is_unary):
+ item.end = get_newline() + padding + item.end
+
+ if item.has_tags_in_content() or (force_nl and not item.has_children() and not is_unary):
+ item.start += get_newline() + padding + get_indentation()
+
+ elif item.is_inline() and has_block_sibling(item) and not is_very_first_child(item):
+ item.start = get_newline() + padding + item.start
+
+ item.padding = padding + get_indentation()
+
+ return item
+
+def process(tree, profile, level=0):
+ """
+ Processes simplified tree, making it suitable for output as HTML structure
+ @type item: ZenNode
+ @type profile: dict
+ @param level: Depth level
+ @type level: int
+ """
+
+ for item in tree.children:
+ if item.type == 'tag':
+ item = process_tag(item, profile, level)
+ else:
+ item = process_snippet(item, profile, level)
+
+ if item.content:
+ item.content = zen_coding.pad_string(item.content, item.padding)
+
+ process(item, profile, level + 1)
+
+ return tree
Oops, something went wrong. Retry.

0 comments on commit 1b5aa30

Please sign in to comment.