几个 Editplus 实用用户工具集

1、CSS自动完成文件

将下面的保存为 CSS.ACP,然后在设置里面指定即可,我只加了自己常用的一些属性,你可以自行扩展。

 

代码
#TITLE=Css
; EditPlus Auto-completion file v1.0 written by matin0728@gmail.com, QQ 5364241 沙加 - 博客园
; This file
is provided as a default auto-completion file for Java and C#.

#CASE=y

#T=b
background:^!;
#T=bi
background-image:^!;
#T=bp
background-position"^!;
#T=bc
background-color:^!;
#T=fl
float:left;
#T=fr
float:right;
#T=of
overflow:hidden;
#T=z
zoom:1;
#T=d
display:^!;
#T=db
display:block;
#T=dn
display:none;
#T=fw
font-weight:^!;
#T=fs
font-size:^!;
#T=h
height:^!;
#T=w
width:^!;
#T=lh
line-height:^!;
#T=c
color:^!;
#T=fs
font-size:^!;
#T=p
padding:^!;
#T=pt
padding-top:^!;
#T=pb
padding-bottom:^!;
#T=pl
padding-left:^!;
#T=pr
padding-right:^!;
#T=m
margin:^!;
#T=mt
margin-top:^!;
#T=ml
margin-left:^!;
#T=mr
margin-right:^!;
#T=mb
margin-bottom:^!;
#T=rbt
-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px;-webkit-border-radius-topleft:5px;-webkit-border-radius-topright:5px;
#T=rbb
-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-webkit-border-radius-bottomleft:5px;-webkit-border-radius-bottomright:5px;
#T=rb
-moz-border-radius:5px;-webkit-border-radius:5px;
#T=ta
text-align:^!;
#T=tal
text-align:left;
#T=tar
text-align:right;
#T=tac
text-align:center;
#T=ti
text-indent:^!;
#T=v
visibility:hidden;
#T=ps
position:^!;
#T=psr
position:relative;
#T=psa
position:absolute;
#

 

 

2、Sparkup 的Editplus  移植版

如果你不知道 Sparkup 用来做什么,可以去看看 Zencoding

使用这个工具需要本机安装Python的执行环境,注意还需要修改环境变量把python.exe的目录加到PATH里面去,并导入win32的剪帖板包,具体可以看这里 

 

相对于原始的那个 sparkup, 我略作了修改,好让它在console  里面使用参数调用,将下面这个保存到 spark.py 文件

 

 

代码
#!/usr/bin/env python
#
-*- coding: utf-8 -*-
version = "0.1.3"

import os
import fileinput
import getopt
import sys
import re
import win32clipboard, win32con

# ===============================================================================

class Dialect:
shortcuts
= {}
synonyms
= {}
required
= {}
short_tags
= ()

class HtmlDialect(Dialect):
shortcuts
= {
'cc:ie': {
'opening_tag': '<!--[if IE]>',
'closing_tag': '<![endif]-->'},
'cc:ie6': {
'opening_tag': '<!--[if lte IE 6]>',
'closing_tag': '<![endif]-->'},
'cc:ie7': {
'opening_tag': '<!--[if lte IE 7]>',
'closing_tag': '<![endif]-->'},
'cc:noie': {
'opening_tag': '<!--[if !IE]><!-->',
'closing_tag': '<!--<![endif]-->'},
'html:4t': {
'expand': True,
'opening_tag':
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n' +
'<html lang="en">\n' +
'<head>\n' +
' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
' ' + '<title></title>\n' +
'</head>\n' +
'<body>',
'closing_tag':
'</body>\n' +
'</html>'},
'html:4s': {
'expand': True,
'opening_tag':
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n' +
'<html lang="en">\n' +
'<head>\n' +
' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
' ' + '<title></title>\n' +
'</head>\n' +
'<body>',
'closing_tag':
'</body>\n' +
'</html>'},
'html:xt': {
'expand': True,
'opening_tag':
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' +
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n' +
'<head>\n' +
' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
' ' + '<title></title>\n' +
'</head>\n' +
'<body>',
'closing_tag':
'</body>\n' +
'</html>'},
'html:xs': {
'expand': True,
'opening_tag':
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n' +
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n' +
'<head>\n' +
' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
' ' + '<title></title>\n' +
'</head>\n' +
'<body>',
'closing_tag':
'</body>\n' +
'</html>'},
'html:xxs': {
'expand': True,
'opening_tag':
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n' +
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n' +
'<head>\n' +
' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
' ' + '<title></title>\n' +
'</head>\n' +
'<body>',
'closing_tag':
'</body>\n' +
'</html>'},
'html:5': {
'expand': True,
'opening_tag':
'<!DOCTYPE html>\n' +
'<html lang="en">\n' +
'<head>\n' +
' ' + '<meta charset="UTF-8" />\n' +
' ' + '<title></title>\n' +
'</head>\n' +
'<body>',
'closing_tag':
'</body>\n' +
'</html>'},
'input:button': {
'name': 'input',
'attributes': { 'class': 'button', 'type': 'button', 'name': '', 'value': '' }
},
'input:password': {
'name': 'input',
'attributes': { 'class': 'text password', 'type': 'password', 'name': '', 'value': '' }
},
'input:radio': {
'name': 'input',
'attributes': { 'class': 'radio', 'type': 'radio', 'name': '', 'value': '' }
},
'input:checkbox': {
'name': 'input',
'attributes': { 'class': 'checkbox', 'type': 'checkbox', 'name': '', 'value': '' }
},
'input:file': {
'name': 'input',
'attributes': { 'class': 'file', 'type': 'file', 'name': '', 'value': '' }
},
'input:text': {
'name': 'input',
'attributes': { 'class': 'text', 'type': 'text', 'name': '', 'value': '' }
},
'input:submit': {
'name': 'input',
'attributes': { 'class': 'submit', 'type': 'submit', 'value': '' }
},
'input:hidden': {
'name': 'input',
'attributes': { 'type': 'hidden', 'name': '', 'value': '' }
},
'script:src': {
'name': 'script',
'attributes': { 'src': '' }
},
'script:jquery': {
'name': 'script',
'attributes': { 'src': 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' }
},
'script:jsapi': {
'name': 'script',
'attributes': { 'src': 'http://www.google.com/jsapi' }
},
'script:jsapix': {
'name': 'script',
'text': '\n google.load("jquery", "1.3.2");\n google.setOnLoadCallback(function() {\n \n });\n'
},
'link:css': {
'name': 'link',
'attributes': { 'rel': 'stylesheet', 'type': 'text/css', 'href': '', 'media': 'all' },
},
'link:print': {
'name': 'link',
'attributes': { 'rel': 'stylesheet', 'type': 'text/css', 'href': '', 'media': 'print' },
},
'link:favicon': {
'name': 'link',
'attributes': { 'rel': 'shortcut icon', 'type': 'image/x-icon', 'href': '' },
},
'link:touch': {
'name': 'link',
'attributes': { 'rel': 'apple-touch-icon', 'href': '' },
},
'link:rss': {
'name': 'link',
'attributes': { 'rel': 'alternate', 'type': 'application/rss+xml', 'title': 'RSS', 'href': '' },
},
'link:atom': {
'name': 'link',
'attributes': { 'rel': 'alternate', 'type': 'application/atom+xml', 'title': 'Atom', 'href': '' },
},
'meta:ie7': {
'name': 'meta',
'attributes': { 'http-equiv': 'X-UA-Compatible', 'content': 'IE=7' },
},
'meta:ie8': {
'name': 'meta',
'attributes': { 'http-equiv': 'X-UA-Compatible', 'content': 'IE=8' },
},
'form:get': {
'name': 'form',
'attributes': { 'method': 'get' },
},
'form:g': {
'name': 'form',
'attributes': { 'method': 'get' },
},
'form:post': {
'name': 'form',
'attributes': { 'method': 'post' },
},
'form:p': {
'name': 'form',
'attributes': { 'method': 'post' },
},
}
synonyms
= {
'checkbox': 'input:checkbox',
'check': 'input:checkbox',
'input:c': 'input:checkbox',
'button': 'input:button',
'input:b': 'input:button',
'input:h': 'input:hidden',
'hidden': 'input:hidden',
'submit': 'input:submit',
'input:s': 'input:submit',
'radio': 'input:radio',
'input:r': 'input:radio',
'text': 'input:text',
'passwd': 'input:password',
'password': 'input:password',
'pw': 'input:password',
'input:t': 'input:text',
'linkcss': 'link:css',
'scriptsrc': 'script:src',
'jquery': 'script:jquery',
'jsapi': 'script:jsapi',
'html5': 'html:5',
'html4': 'html:4s',
'html4s': 'html:4s',
'html4t': 'html:4t',
'xhtml': 'html:xxs',
'xhtmlt': 'html:xt',
'xhtmls': 'html:xs',
'xhtml11': 'html:xxs',
'opt': 'option',
'st': 'strong',
'css': 'style',
'csss': 'link:css',
'css:src': 'link:css',
'csssrc': 'link:css',
'js': 'script',
'jss': 'script:src',
'js:src': 'script:src',
'jssrc': 'script:src',
}
short_tags
= (
'area', 'base', 'basefont', 'br', 'embed', 'hr', \
'input', 'img', 'link', 'param', 'meta')
required
= {
'a': {'href':''},
'base': {'href':''},
'abbr': {'title': ''},
'acronym':{'title': ''},
'bdo': {'dir': ''},
'link': {'rel': 'stylesheet', 'href': ''},
'style': {'type': 'text/css'},
'script': {'type': 'text/javascript'},
'img': {'src':'', 'alt':''},
'iframe': {'src': '', 'frameborder': '0'},
'embed': {'src': '', 'type': ''},
'object': {'data': '', 'type': ''},
'param': {'name': '', 'value': ''},
'form': {'action': '', 'method': 'post'},
'table': {'cellspacing': '0'},
'input': {'type': '', 'name': '', 'value': ''},
'base': {'href': ''},
'area': {'shape': '', 'coords': '', 'href': '', 'alt': ''},
'select': {'name': ''},
'option': {'value': ''},
'textarea':{'name': ''},
'meta': {'content': ''},
}

class Parser:
"""The parser.
"""

# Constructor
# ---------------------------------------------------------------------------

def __init__(self, options=None, str='', dialect=HtmlDialect()):
"""Constructor.
"""

self.tokens
= []
self.str
= str
self.options
= options
self.dialect
= dialect
self.root
= Element(parser=self)
self.caret
= []
self.caret.append(self.root)
self._last
= []

# Methods
# ---------------------------------------------------------------------------

def load_string(self, str):
"""Loads a string to parse.
"""

self.str
= str
self._tokenize()
self._parse()

def render(self):
"""Renders.
Called by [[Router]].
"""

# Get the initial render of the root node
output = self.root.render()

# Indent by whatever the input is indented with
indent = re.findall("^[\r\n]*(\s*)", self.str)[0]
output
= indent + output.replace("\n", "\n" + indent)

# Strip newline if not needed
if self.options.has("no-last-newline") \
or self.prefix or self.suffix:
output
= re.sub(r'\n\s*$', '', output)

# TextMate mode
if self.options.has("textmate"):
output
= self._textmatify(output)

return output

# Protected methods
# ---------------------------------------------------------------------------

def _textmatify(self, output):
"""Returns a version of the output with TextMate placeholders in it.
"""

matches
= re.findall(r'(></)|("")|(\n\s+)\n|(.|\s)', output)
output
= ''
n
= 1
for i in matches:
if i[0]:
output
+= '>$%i</' % n
n
+= 1
elif i[1]:
output
+= '"$%i"' % n
n
+= 1
elif i[2]:
output
+= i[2] + '$%i\n' % n
n
+= 1
elif i[3]:
output
+= i[3]
output
+= "$0"
return output

def _tokenize(self):
"""Tokenizes.
Initializes [[self.tokens]].
"""

str
= self.str.strip()

# Find prefix/suffix
while True:
match
= re.match(r"^(\s*<[^>]+>\s*)", str)
if match is None: break
if self.prefix is None: self.prefix = ''
self.prefix
+= match.group(0)
str
= str[len(match.group(0)):]

while True:
match
= re.findall(r"(\s*<[^>]+>[\s\n\r]*)$", str)
if not match: break
if self.suffix is None: self.suffix = ''
self.suffix
= match[0] + self.suffix
str
= str[:-len(match[0])]

# Split by the element separators
for token in re.split('(<|>|\+(?!\\s*\+|$))', str):
if token.strip() != '':
self.tokens.append(Token(token, parser
=self))

def _parse(self):
"""Takes the tokens and does its thing.
Populates [[self.root]].
"""

# Carry it over to the root node.
if self.prefix or self.suffix:
self.root.prefix
= self.prefix
self.root.suffix
= self.suffix
self.root.depth
+= 1

for token in self.tokens:
if token.type == Token.ELEMENT:
# Reset the "last elements added" list. We will
# repopulate this with the new elements added now.
self._last[:] = []

# Create [[Element]]s from a [[Token]].
# They will be created as many as the multiplier specifies,
# multiplied by how many carets we have
count = 0
for caret in self.caret:
local_count
= 0
for i in range(token.multiplier):
count
+= 1
local_count
+= 1
new
= Element(token, caret,
count
= count,
local_count
= local_count,
parser
= self)
self._last.append(new)
caret.append(new)

# For >
elif token.type == Token.CHILD:
# The last children added.
self.caret[:] = self._last

# For <
elif token.type == Token.PARENT:
# If we're the root node, don't do anything
parent = self.caret[0].parent
if parent is not None:
self.caret[:]
= [parent]
return

# Properties
# ---------------------------------------------------------------------------

# Property: dialect
# The dialect of XML
dialect = None

# Property: str
# The string
str = ''

# Property: tokens
# The list of tokens
tokens = []

# Property: options
# Reference to the [[Options]] instance
options = None

# Property: root
# The root [[Element]] node.
root = None

# Property: caret
# The current insertion point.
caret = None

# Property: _last
# List of the last appended stuff
_last = None

# Property: indent
# Yeah
indent = ''

# Property: prefix
# (String) The trailing tag in the beginning.
#
# Description:
# For instance, in `<div>ul>li</div>`, the `prefix` is `<div>`.
prefix = ''

# Property: suffix
# (string) The trailing tag at the end.
suffix = ''
pass

# ===============================================================================

class Element:
"""An element.
"""

def __init__(self, token=None, parent=None, count=None, local_count=None, \
parser
=None, opening_tag=None, closing_tag=None, \
attributes
=None, name=None, text=None):
"""Constructor.

This is called by ???.

Description:
All parameters are optional.

token - (Token) The token (required)
parent - (Element) Parent element; `None` if root
count - (Int) The number to substitute for `&` (e.g., in `li.item-$`)
local_count - (Int) The number to substitute for `$` (e.g., in `li.item-&`)
parser - (Parser) The parser

attributes - ...
name - ...
text - ...
"""

self.children
= []
self.attributes
= {}
self.parser
= parser

if token is not None:
# Assumption is that token is of type [[Token]] and is
# a [[Token.ELEMENT]].
self.name = token.name
self.attributes
= token.attributes.copy()
self.text
= token.text
self.populate
= token.populate
self.expand
= token.expand
self.opening_tag
= token.opening_tag
self.closing_tag
= token.closing_tag

# `count` can be given. This will substitude & in classname and ID
if count is not None:
for key in self.attributes:
attrib
= self.attributes[key]
attrib
= attrib.replace('&', ("%i" % count))
if local_count is not None:
attrib
= attrib.replace('$', ("%i" % local_count))
self.attributes[key]
= attrib

# Copy over from parameters
if attributes: self.attributes = attribues
if name: self.name = name
if text: self.text = text

self._fill_attributes()

self.parent
= parent
if parent is not None:
self.depth
= parent.depth + 1

if self.populate: self._populate()

def render(self):
"""Renders the element, along with it's subelements, into HTML code.

[Grouped under "Rendering methods"]
"""

output
= ""
try: spaces_count = int(self.parser.options.options['indent-spaces'])
except: spaces_count = 4
spaces
= ' ' * spaces_count
indent
= self.depth * spaces

prefix, suffix
= ('', '')
if self.prefix: prefix = self.prefix + "\n"
if self.suffix: suffix = self.suffix

# Make the guide from the ID (/#header), or the class if there's no ID (/.item)
# This is for the start-guide, end-guide and post-tag-guides
guide_str = ''
if 'id' in self.attributes:
guide_str
+= "#%s" % self.attributes['id']
elif 'class' in self.attributes:
guide_str
+= ".%s" % self.attributes['class'].replace(' ', '.')

# Build the post-tag guide (e.g., </div><!-- /#header -->),
# the start guide, and the end guide.
guide = ''
start_guide
= ''
end_guide
= ''
if ((self.name == 'div') and \
((
'id' in self.attributes) or ('class' in self.attributes))):

if (self.parser.options.has('post-tag-guides')):
guide
= "<!-- /%s -->" % guide_str

if (self.parser.options.has('start-guide-format')):
format
= self.parser.options.get('start-guide-format')
try: start_guide = format % guide_str
except: start_guide = (format + " " + guide_str).strip()
start_guide
= "%s<!-- %s -->\n" % (indent, start_guide)

if (self.parser.options.has('end-guide-format')):
format
= self.parser.options.get('end-guide-format')
try: end_guide = format % guide_str
except: end_guide = (format + " " + guide_str).strip()
end_guide
= "\n%s<!-- %s -->" % (indent, end_guide)

# Short, self-closing tags (<br />)
short_tags = self.parser.dialect.short_tags

# When it should be expanded..
# (That is, <div>\n...\n</div> or similar -- wherein something must go
# inside the opening/closing tags)
if len(self.children) > 0 \
or self.expand \
or prefix or suffix \
or (self.parser.options.has('expand-divs') and self.name == 'div'):

for child in self.children:
output
+= child.render()

# For expand divs: if there are no children (that is, `output`
# is still blank despite above), fill it with a blank line.
if (output == ''): output = indent + spaces + "\n"

# If we're a root node and we have a prefix or suffix...
# (Only the root node can have a prefix or suffix.)
if prefix or suffix:
output
= "%s%s%s%s%s\n" % \
(indent, prefix, output, suffix, guide)

# Uh..
elif self.name != '' or \
self.opening_tag
is not None or \
self.closing_tag
is not None:
output
= start_guide + \
indent
+ self.get_opening_tag() + "\n" + \
output
+ \
indent
+ self.get_closing_tag() + \
guide
+ end_guide + "\n"


# Short, self-closing tags (<br />)
elif self.name in short_tags:
output
= "%s<%s />\n" % (indent, self.get_default_tag())

# Tags with text, possibly
elif self.name != '' or \
self.opening_tag
is not None or \
self.closing_tag
is not None:
output
= "%s%s%s%s%s%s%s%s" % \
(start_guide, indent, self.get_opening_tag(), \
self.text, \
self.get_closing_tag(), \
guide, end_guide,
"\n")

# Else, it's an empty-named element (like the root). Pass.
else: pass


return output

def get_default_tag(self):
"""Returns the opening tag (without brackets).

Usage:
element.get_default_tag()

[Grouped under "Rendering methods"]
"""

output
= '%s' % (self.name)
for key, value in self.attributes.iteritems():
output
+= ' %s="%s"' % (key, value)
return output

def get_opening_tag(self):
if self.opening_tag is None:
return "<%s>" % self.get_default_tag()
else:
return self.opening_tag

def get_closing_tag(self):
if self.closing_tag is None:
return "</%s>" % self.name
else:
return self.closing_tag

def append(self, object):
"""Registers an element as a child of this element.

Usage:
element.append(child)

Description:
Adds a given element `child` to the children list of this element. It
will be rendered when [[render()]] is called on the element.

See also:
- [[get_last_child()]]

[Grouped under "Traversion methods"]
"""

self.children.append(object)

def get_last_child(self):
"""Returns the last child element which was [[append()]]ed to this element.

Usage:
element.get_last_child()

Description:
This is the same as using `element.children[-1]`.

[Grouped under "Traversion methods"]
"""

return self.children[-1]

def _populate(self):
"""Expands with default items.

This is called when the [[populate]] flag is turned on.
"""

if self.name == 'ul':
elements
= [Element(name='li', parent=self, parser=self.parser)]

elif self.name == 'dl':
elements
= [
Element(name
='dt', parent=self, parser=self.parser),
Element(name
='dd', parent=self, parser=self.parser)]

elif self.name == 'table':
tr
= Element(name='tr', parent=self, parser=self.parser)
td
= Element(name='td', parent=tr, parser=self.parser)
tr.children.append(td)
elements
= [tr]

else:
elements
= []

for el in elements:
self.children.append(el)

def _fill_attributes(self):
"""Fills default attributes for certain elements.

Description:
This is called by the constructor.

[Protected, grouped under "Protected methods"]
"""

# Make sure <a>'s have a href, <img>'s have an src, etc.
required = self.parser.dialect.required

for element, attribs in required.iteritems():
if self.name == element:
for attrib in attribs:
if attrib not in self.attributes:
self.attributes[attrib]
= attribs[attrib]

# ---------------------------------------------------------------------------

# Property: last_child
# [Read-only]
last_child = property(get_last_child)

# ---------------------------------------------------------------------------

# Property: parent
# (Element) The parent element.
parent = None

# Property: name
# (String) The name of the element (e.g., `div`)
name = ''

# Property: attributes
# (Dict) The dictionary of attributes (e.g., `{'src': 'image.jpg'}`)
attributes = None

# Property: children
# (List of Elements) The children
children = None

# Property: opening_tag
# (String or None) The opening tag. Optional; will use `name` and
# `attributes` if this is not given.
opening_tag = None

# Property: closing_tag
# (String or None) The closing tag
closing_tag = None

text
= ''
depth
= -1
expand
= False
populate
= False
parser
= None

# Property: prefix
# Only the root note can have this.
prefix = None
suffix
= None

# ===============================================================================

class Token:
def __init__(self, str, parser=None):
"""Token.

Description:
str - The string to parse

In the string `div > ul`, there are 3 tokens. (`div`, `>`, and `ul`)

For `>`, it will be a `Token` with `type` set to `Token.CHILD`
"""

self.str
= str.strip()
self.attributes
= {}
self.parser
= parser

# Set the type.
if self.str == '<':
self.type
= Token.PARENT
elif self.str == '>':
self.type
= Token.CHILD
elif self.str == '+':
self.type
= Token.SIBLING
else:
self.type
= Token.ELEMENT
self._init_element()

def _init_element(self):
"""Initializes. Only called if the token is an element token.
[Private]
"""

# Get the tag name. Default to DIV if none given.
name = re.findall('^([\w\-:]*)', self.str)[0]
name
= name.lower().replace('-', ':')

# Find synonyms through this thesaurus
synonyms = self.parser.dialect.synonyms
if name in synonyms.keys():
name
= synonyms[name]

if ':' in name:
try: spaces_count = int(self.parser.options.get('indent-spaces'))
except: spaces_count = 4
indent
= ' ' * spaces_count

shortcuts
= self.parser.dialect.shortcuts
if name in shortcuts.keys():
for key, value in shortcuts[name].iteritems():
setattr(self, key, value)
if 'html' in name:
return
else:
self.name
= name

elif (name == ''): self.name = 'div'
else: self.name = name

# Look for attributes
attribs = []
for attrib in re.findall('\[([^\]]*)\]', self.str):
attribs.append(attrib)
self.str
= self.str.replace("[" + attrib + "]", "")
if len(attribs) > 0:
for attrib in attribs:
try: key, value = attrib.split('=', 1)
except: key, value = attrib, ''
self.attributes[key]
= value

# Try looking for text
text = None
for text in re.findall('\{([^\}]*)\}', self.str):
self.str
= self.str.replace("{" + text + "}", "")
if text is not None:
self.text
= text

# Get the class names
classes = []
for classname in re.findall('\.([\$a-zA-Z0-9_\-\&]+)', self.str):
classes.append(classname)
if len(classes) > 0:
try: self.attributes['class']
except: self.attributes['class'] = ''
self.attributes[
'class'] += ' ' + ' '.join(classes)
self.attributes[
'class'] = self.attributes['class'].strip()

# Get the ID
id = None
for id in re.findall('#([\$a-zA-Z0-9_\-\&]+)', self.str): pass
if id is not None:
self.attributes[
'id'] = id

# See if there's a multiplier (e.g., "li*3")
multiplier = None
for multiplier in re.findall('\*\s*([0-9]+)', self.str): pass
if multiplier is not None:
self.multiplier
= int(multiplier)

# Populate flag (e.g., ul+)
flags = None
for flags in re.findall('[\+\!]+$', self.str): pass
if flags is not None:
if '+' in flags: self.populate = True
if '!' in flags: self.expand = True

def __str__(self):
return self.str

str
= ''
parser
= None

# For elements
# See the properties of `Element` for description on these.
name = ''
attributes
= None
multiplier
= 1
expand
= False
populate
= False
text
= ''
opening_tag
= None
closing_tag
= None

# Type
type = 0
ELEMENT
= 2
CHILD
= 4
PARENT
= 8
SIBLING
= 16

# ===============================================================================

class Router:
"""The router.
"""

# Constructor
# ---------------------------------------------------------------------------

def __init__(self):
pass

# Methods
# ---------------------------------------------------------------------------

def start(self, options=None, str=None, ret=None):
if (options):
self.options
= Options(router=self, options=options, argv=None)
else:
self.options
= Options(router=self, argv=sys.argv[1:], options=None)

if (self.options.has('help')):
return self.help()

elif (self.options.has('version')):
return self.version()

else:
return self.parse(str=str, ret=ret)

def help(self):
print "Usage: %s [OPTIONS]" % sys.argv[0]
print "Expands input into HTML."
print ""
for short, long, info in self.options.cmdline_keys:
if "Deprecated" in info: continue
if not short == '': short = '-%s,' % short
if not long == '': long = '--%s' % long.replace("=", "=XXX")

print "%6s %-25s %s" % (short, long, info)
print ""
print "\n".join(self.help_content)

def version(self):
print "Uhm, yeah."

def parse(self, str=None, ret=None):
self.parser
= Parser(self.options)

try:
# Read the files
# for line in fileinput.input(): lines.append(line.rstrip(os.linesep))
if str is not None:
lines
= str
else:
lines
= sys.stdin.readline()
#lines = [sys.stdin.read()]
#lines = " ".join(lines)

except KeyboardInterrupt:
pass

except:
sys.stderr.write(
"Reading failed.\n")
return

try:
self.parser.load_string(lines)
output
= self.parser.render()
if ret: return output
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(output)
win32clipboard.CloseClipboard()
#sys.stdout.write(output)

except:
sys.stderr.write(
"Parse error. Check your input.\n")
print sys.exc_info()[0]
print sys.exc_info()[1]

def exit(self):
sys.exit()

help_content
= [
"Please refer to the manual for more information.",
]

# ===============================================================================

class Options:
def __init__(self, router, argv, options=None):
# Init self
self.router = router

# `options` can be given as a dict of stuff to preload
if options:
for k, v in options.iteritems():
self.options[k]
= v
return

# Prepare for getopt()
short_keys, long_keys = "", []
for short, long, info in self.cmdline_keys: # 'v', 'version'
short_keys += short
long_keys.append(long)

try:
getoptions, arguments
= getopt.getopt(argv, short_keys, long_keys)

except getopt.GetoptError:
err
= sys.exc_info()[1]
sys.stderr.write(
"Options error: %s\n" % err)
sys.stderr.write(
"Try --help for a list of arguments.\n")
return router.exit()

# Sort them out into options
options = {}
i
= 0
for option in getoptions:
key, value
= option # '--version', ''
if (value == ''): value = True

# If the key is long, write it
if key[0:2] == '--':
clean_key
= key[2:]
options[clean_key]
= value

# If the key is short, look for the long version of it
elif key[0:1] == '-':
for short, long, info in self.cmdline_keys:
if short == key[1:]:
print long
options[long]
= True

# Done
for k, v in options.iteritems():
self.options[k]
= v

def __getattr__(self, attr):
return self.get(attr)

def get(self, attr):
try: return self.options[attr]
except: return None

def has(self, attr):
try: return self.options.has_key(attr)
except: return False

options
= {
'indent-spaces': 4
}
cmdline_keys
= [
(
'h', 'help', 'Shows help'),
(
'v', 'version', 'Shows the version'),
(
'', 'no-guides', 'Deprecated'),
(
'', 'post-tag-guides', 'Adds comments at the end of DIV tags'),
(
'', 'textmate', 'Adds snippet info (textmate mode)'),
(
'', 'indent-spaces=', 'Indent spaces'),
(
'', 'expand-divs', 'Automatically expand divs'),
(
'', 'no-last-newline', 'Skip the trailing newline'),
(
'', 'start-guide-format=', 'To be documented'),
(
'', 'end-guide-format=', 'To be documented'),
]

# Property: router
# Router
router = 1

# ===============================================================================

if __name__ == "__main__":
if len(sys.argv) > 1:
s
= sys.argv[1]
else:
s
= None
z
= Router()
z.start(str
=s)

 

 

然后配置用户工具,指定刚才保存的python脚本位置:

 

配置好了以后就可以呼出这个用工具,在弹出框中输入比如:   div#header > ul > li*3 > a > span   它帮你生成如下内容的html:

 

代码
<div id="header">
<ul>
<li>
<a href="">
<span></span>
</a>
</li>
<li>
<a href="">
<span></span>
</a>
</li>
<li>
<a href="">
<span></span>
</a>
</li>
</ul>
</div>

 

 

按两次回车,再按 Ctrl+v 就可以把生成的代码从剪帖板上粘到文档中了,还是挺方便,你也可以将 Argument 调置为 Selection, 这样就可以先在文档中书写 简写码,再选中它执行这个用户工具,具体就看个人喜好了。

 

3、格式化HTML

一直想着Editplus有象VS那样的酷的代码格式化功能,现在可以使用HTB这个工具来实现,但现在直接指定输入和输出文件为同一个文件好象不正常,不得已只有先输出到一个临时文件里面再用手动拷贝过来,其实也可以写一个Python脚本将生成后的文件内容读取到剪粘板中再粘,就象上一例里面一样,有兴趣的朋友可以自行尝试。

 

上面的那个 for.htm 就是输出的临时文件, 最后一个参数是 错误输出文件 f:\error.txt ,请自行指定。

 

4、格式化 PHP 代码

 

其中的 Argument:   --space-after-if --optimize-eol --space-after-switch --space-after-while --space-before-start-angle-bracket --space-after-end-angle-bracket --extra-padding-for-case-statement --glue-amperscore --change-shell-comment-to-double-slashes-comment --indent-with-tab --force-large-php-code-tag --force-true-false-null-contant-lowercase --comment-rendering-style PEAR --equal-align-position 50 --padding-char-count 1 "$(FilePath)"

 

用到了phpCB.exe (和上面的那个HTB.exe) ,在这里下载

5、其它的

原来还弄过的两个小工具,格式化js 和 css的看这里

 

其实都不难,放在这里方便懒人同志,使用中有什么疑问可以发信到 matin0728(AT)gmail.com,  QQ5364241,如果你有其它的好东西也可以发给我放在这里跟大家一起分享。谢谢。

posted on 2010-03-31 13:43  沙加  阅读(3884)  评论(0编辑  收藏  举报

导航