Skip to content
Browse files

Introduce 'Toggle between image url and data'

  • Loading branch information...
1 parent 5a055ea commit 5bc97fc6dbf9c79fa2f475413ccde2fdc9c47ce1 @fmarcia committed May 12, 2010
Showing with 149 additions and 24 deletions.
  1. +1 −0 README.md
  2. +19 −14 zencoding/plugin.py
  3. +105 −2 zencoding/zen_actions.py
  4. +4 −1 zencoding/zen_dialog.py
  5. +13 −4 zencoding/zen_editor.py
  6. +7 −3 zencoding/zen_file.py
View
1 README.md
@@ -10,6 +10,7 @@ This plugin fully integrates [Zen Coding](http://code.google.com/p/zen-coding/)
- Merge lines
- Go to previous or next edit point
- Update tag image size
+- Toggle between image url and data
- Remove tag
- Split or join tags
- Toggle comment
View
33 zencoding/plugin.py
@@ -44,6 +44,7 @@
<menuitem name="ZenCodingNext" action="ZenCodingNextAction"/>
<separator/>
<menuitem name="ZenCodingSize" action="ZenCodingSizeAction"/>
+ <menuitem name="ZenCodingData" action="ZenCodingDataAction"/>
<separator/>
<menuitem name="ZenCodingRemove" action="ZenCodingRemoveAction"/>
<menuitem name="ZenCodingSplit" action="ZenCodingSplitAction"/>
@@ -62,20 +63,21 @@ class ZenCodingPlugin(gedit.Plugin):
def activate(self, window):
actions = [
- ('ZenCodingMenuAction', None, '_Zen Coding', None, "Zen Coding tools", None),
- ('ZenCodingExpandAction', None, '_Expand abbreviation', '<Ctrl>E', "Expand abbreviation to raw HTML/CSS", self.expand_abbreviation),
- ('ZenCodingExpandWAction', None, 'E_xpand with abbreviation...', '<Ctrl><Alt>E', "Type in an abbreviation to expand", self.expand_with_abbreviation),
- ('ZenCodingWrapAction', None, '_Wrap with abbreviation...', '<Ctrl><Shift>E', "Wrap with code expanded from abbreviation", self.wrap_with_abbreviation),
- ('ZenCodingInwardAction', None, 'Balance tag _inward', '<Ctrl><Alt>I', "Select inner tag's content", self.match_pair_inward),
- ('ZenCodingOutwardAction', None, 'Balance tag _outward', '<Ctrl><Alt>O', "Select outer tag's content", self.match_pair_outward),
- ('ZenCodingMergeAction', None, '_Merge lines', '<Ctrl><Alt>M', "Merge all lines of the current selection", self.merge_lines),
- ('ZenCodingPrevAction', None, '_Previous edit point', '<Alt>Left', "Place the cursor at the previous edit point", self.prev_edit_point),
- ('ZenCodingNextAction', None, '_Next edit point', '<Alt>Right', "Place the cursor at the next edit point", self.next_edit_point),
- ('ZenCodingSizeAction', None, 'Update image _size', '<Ctrl><Alt>S', "Update image size tag from file", self.update_image_size),
- ('ZenCodingRemoveAction', None, '_Remove tag', '<Ctrl><Alt>R', "Remove a tag", self.remove_tag),
- ('ZenCodingSplitAction', None, 'Split or _join tag', '<Ctrl><Alt>J', "Toggle between single and double tag", self.split_join_tag),
- ('ZenCodingCommentAction', None, 'Toggle _comment', '<Ctrl><Alt>C', "Toggle an XML or HTML comment", self.toggle_comment),
- ('ZenCodingSettingsAction', None, 'E_dit settings...', None, "Customize snippets and abbreviations", self.edit_settings)
+ ('ZenCodingMenuAction', None, '_Zen Coding', None, "Zen Coding tools", None),
+ ('ZenCodingExpandAction', None, '_Expand abbreviation', '<Ctrl>E', "Expand abbreviation to raw HTML/CSS", self.expand_abbreviation),
+ ('ZenCodingExpandWAction', None, 'E_xpand with abbreviation...', '<Ctrl><Alt>E', "Type in an abbreviation to expand", self.expand_with_abbreviation),
+ ('ZenCodingWrapAction', None, '_Wrap with abbreviation...', '<Ctrl><Shift>E', "Wrap with code expanded from abbreviation", self.wrap_with_abbreviation),
+ ('ZenCodingInwardAction', None, 'Balance tag _inward', '<Ctrl><Alt>I', "Select inner tag's content", self.match_pair_inward),
+ ('ZenCodingOutwardAction', None, 'Balance tag _outward', '<Ctrl><Alt>O', "Select outer tag's content", self.match_pair_outward),
+ ('ZenCodingMergeAction', None, '_Merge lines', '<Ctrl><Alt>M', "Merge all lines of the current selection", self.merge_lines),
+ ('ZenCodingPrevAction', None, '_Previous edit point', '<Alt>Left', "Place the cursor at the previous edit point", self.prev_edit_point),
+ ('ZenCodingNextAction', None, '_Next edit point', '<Alt>Right', "Place the cursor at the next edit point", self.next_edit_point),
+ ('ZenCodingSizeAction', None, 'Update image _size', '<Ctrl><Alt>S', "Update image size tag from file", self.update_image_size),
+ ('ZenCodingDataAction', None, 'Toggle image url/da_ta', '<Ctrl><Alt>A', "Toggle between image url and data", self.encode_decode_base64),
+ ('ZenCodingRemoveAction', None, '_Remove tag', '<Ctrl><Alt>R', "Remove a tag", self.remove_tag),
+ ('ZenCodingSplitAction', None, 'Split or _join tag', '<Ctrl><Alt>J', "Toggle between single and double tag", self.split_join_tag),
+ ('ZenCodingCommentAction', None, 'Toggle _comment', '<Ctrl><Alt>C', "Toggle an XML or HTML comment", self.toggle_comment),
+ ('ZenCodingSettingsAction', None, 'E_dit settings...', None, "Customize snippets and abbreviations", self.edit_settings)
]
windowdata = dict()
window.set_data("ZenCodingPluginDataKey", windowdata)
@@ -135,6 +137,9 @@ def next_edit_point(self, action, window):
def update_image_size(self, action, window):
self.editor.update_image_size(window)
+ def encode_decode_base64(self, action, window):
+ self.editor.encode_decode_base64(window)
+
def remove_tag(self, action, window):
self.editor.remove_tag(window)
View
107 zencoding/zen_actions.py
@@ -10,8 +10,9 @@
"""
from zencoding import zen_core as zen_coding
from zencoding import html_matcher
-import re
+import re, base64
from zen_core import char_at
+import zen_file
def find_abbreviation(editor):
"""
@@ -335,7 +336,7 @@ def select_line(editor):
@param editor: Editor instance
@type editor: ZenEditor
"""
- start, end = editor.get_current_line_range();
+ start, end = editor.get_current_line_range()
editor.create_selection(start, end)
return True
@@ -644,3 +645,105 @@ def remove_tag(editor):
return True
else:
return False
+
+def encode_decode_base64(editor):
+ """
+ Encodes/decodes image under cursor to/from base64
+ @param {zen_editor} editor
+ @since 0.65
+ """
+ data = editor.get_selection()
+ caret_pos, not_used = editor.get_selection_range()
+
+ if not data:
+ # no selection, try to find image bounds from current caret position
+ text = editor.get_content()
+ while caret_pos >= 0:
+ if text.startswith('src=', caret_pos): # found <img src="">
+ m = re.match(r'^(src=(["\'])?)([^\'"<>\s]+)\1?', text[caret_pos:])
+ if m:
+ data = m.group(3)
+ caret_pos += len(m.group(1))
+ break
+ elif text.startswith('url(', caret_pos): # found CSS url() pattern
+ m = re.match(r'^(url\(([\'"])?)([^\'"\)\s]+)\1?/', text[caret_pos:])
+ if m:
+ data = m.group(3)
+ caret_pos += len(m.group(1))
+ break
+ elif text[caret_pos] == '>':
+ return False
+ caret_pos -= 1
+
+ if data:
+ if data.startswith('data:'):
+ return decode_from_base64(editor, data, caret_pos)
+ else:
+ return encode_to_base64(editor, data, caret_pos)
+ else:
+ return False
+
+def encode_to_base64(editor, img_path, pos):
+ """
+ Encodes image to base64
+ @requires zen_file
+ @param {zen_editor} editor
+ @param {String} img_path Path to image
+ @param {Number} pos Caret position where image is located in the editor
+ @return {Boolean}
+ """
+
+ editor_file = editor.get_file_path()
+ default_mime_type = 'application/octet-stream'
+
+ if not editor_file:
+ raise Exception("You should save your file before using this action")
+
+ # locate real image path
+ real_img_path = zen_file.locate_file(editor_file, img_path)
+ if not real_img_path:
+ raise Exception("Can't find " + img_path + ' file')
+
+ b64 = base64.b64encode(zen_file.read(real_img_path))
+ if not b64:
+ raise Exception("Can't encode file content to base64")
+
+ mime_types = {
+ 'gif': 'image/gif',
+ 'png': 'image/png',
+ 'jpg': 'image/jpeg',
+ 'jpeg': 'image/jpeg',
+ 'svg': 'image/svg+xml',
+ 'html': 'text/html',
+ 'htm': 'text/html'
+ }
+
+ ext = zen_file.get_ext(real_img_path)
+ b64 = 'data:' + (ext if ext in mime_types else default_mime_type) + ';base64,' + b64
+
+ editor.replace_content(b64, pos, pos + len(img_path))
+ return True
+
+def decode_from_base64(editor, data, pos):
+ """
+ Decodes base64 string back to file.
+ @requires zen_editor.prompt
+ @requires zen_file
+ @param {zen_editor} editor
+ @param {String} data Base64-encoded file content
+ @param {Number} pos Caret position where image is located in the editor
+ """
+ # ask user to enter path to file
+ file_path = editor.prompt('Enter path to file (absolute or relative)')
+ if not file_path:
+ return False
+
+ abs_path = zen_file.create_path(editor.get_file_path(), file_path)
+ if not abs_path:
+ raise Exception("Can't save file")
+
+ if zen_file.save(abs_path, base64.b64decode(re.sub(r'^data\:.+?;.+?,', '', data))):
+ editor.replace_content(file_path, pos, pos + len(data))
+ return True
+
+ return False
View
5 zencoding/zen_dialog.py
@@ -98,5 +98,8 @@ def main(editor, window, callback, text=""):
editor.view.set_cursor_visible(True)
# return exit status and abbreviation
- return my_zen_dialog.done and my_zen_dialog.exit, my_zen_dialog.abbreviation
+ if callback:
+ return my_zen_dialog.done and my_zen_dialog.exit, my_zen_dialog.abbreviation
+ else:
+ return my_zen_dialog.exit, my_zen_dialog.abbreviation
View
17 zencoding/zen_editor.py
@@ -165,6 +165,7 @@ def replace_content(self, value, offset_start=None, offset_end=None):
iter_end = self.buffer.get_iter_at_offset(offset_end)
self.buffer.delete(iter_start, iter_end)
+ self.set_caret_pos(offset_start)
self.insertion_start = self.get_insert_offset()
padding = zen_actions.get_current_line_padding(self)
@@ -207,12 +208,12 @@ def prompt(self, title):
@return {String} Entered data
@since 0.65
"""
- done, result = zen_dialog.main(self, window, None, '')
+ done, result = zen_dialog.main(self, self.context, None, title)
if done:
return result
return ''
- def getSelection(self):
+ def get_selection(self):
"""
Returns current selection
@return {String}
@@ -223,13 +224,13 @@ def getSelection(self):
iter_end = self.buffer.get_iter_at_offset(offset_end)
return self.buffer.get_text(iter_start, iter_end).decode('UTF-8')
- def getFilePath(self):
+ def get_file_path(self):
"""
Returns current editor's file path
@return {String}
@since 0.65
"""
- return self.document.get_uri()
+ return re.sub('^file://', '', self.document.get_uri())
#---------------------------------------------------------------------------------------
@@ -369,6 +370,14 @@ def update_image_size(self, window):
update_image_size(self)
self.buffer.end_user_action()
+ def encode_decode_base64(self, window):
+ self.set_context(window)
+ self.buffer.begin_user_action()
+ zen_actions.encode_decode_base64(self)
+ self.buffer.end_user_action()
+
+ #---------------------------------------------------------------------------------------
+
def remove_tag(self, window):
self.set_context(window)
self.buffer.begin_user_action()
View
10 zencoding/zen_file.py
@@ -66,9 +66,13 @@ def save(file, content):
@param content: File content
@type content: str
"""
- fp = open(file, 'wb')
- fp.write(content)
- fp.close()
+ try:
+ fp = open(file, 'wb')
+ fp.write(content)
+ fp.close()
+ return True
+ except:
+ return False
def get_ext(file):
"""

0 comments on commit 5bc97fc

Please sign in to comment.
Something went wrong with that request. Please try again.