forked from victorporof/Sublime-HTMLPrettify
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sam Anderson
committed
Jan 26, 2012
1 parent
9360791
commit 98a4286
Showing
5 changed files
with
250 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
HTMLPrettify.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1 @@ | ||
# HTML, CSS and Javascript code formatter for Sublime Text editor via node.js | ||
#### [Sublime Text 2](http://www.sublimetext.com/2) | ||
#### [JSBeautifier](http://jsbeautifier.org/) | ||
#### [Node.js download](http://nodejs.org/#download) | ||
|
||
## About | ||
This is a Sublime Text 2 plugin and build system allowing you to format your HTML, CSS and JavaScript code. It uses a set of nice beautifier libs made by Einar Lielmanis and Noah Kantrowitz. The formatters are written in JavaScript, so you'll need something (node.js) to interpret JavaScript code outside the browser. | ||
|
||
This will work with both HTML, CSS and JavaScript files. | ||
|
||
## Installation | ||
First of all, be sure you have [node.js](http://nodejs.org/#download) installed in order to run the beautifier. After you've installed node.js, you will need to setup this plugin. | ||
Each OS has a different `Packages` folder required by Sublime Text. Open it via Preferences -> Browse Packages, and copy this repository contents to the `HTMLPrettify` folder there. | ||
|
||
The shorter way of doing this is: | ||
#### Mac | ||
`git clone git://github.com/victorporof/Sublime-HTMLPrettify.git ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/HTMLPrettify` | ||
|
||
#### Windows | ||
`git clone git://github.com/victorporof/Sublime-HTMLPrettify.git %APPDATA%\Sublime Text 2\Packages\HTMLPrettify` | ||
|
||
## Usage | ||
Open a HTML or JavaScript file, pop out the console in Sublime Text from View -> Show Console, and type `view.run_command("htmlprettify")`. | ||
|
||
Writing commands in the console is ugly. Set up your own key combo for this, by going to Preferences -> Key Bindings - Default, and adding a command in that huge array: `{ "keys": ["super+shift+h"], "command": "htmlprettify" }`. You can use any other command you want, thought most of them are already taken. | ||
|
||
## Customize | ||
The `HTMLPrettify.py` script has some predefined settings regarding the indentation size, indentation character, maximum chars per line and brace styling. Customize these settings by modifying the script with your desired values (see the [JSBeautifier options](https://github.com/einars/js-beautify/blob/master/beautify-html.js)). | ||
|
||
Have fun! | ||
Beginnings of a Python port of [Sublime-HTMLPrettify](https://github.com/victorporof/Sublime-HTMLPrettify). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import commands | ||
import os | ||
import re | ||
import sublime | ||
import sublime_plugin | ||
from .lib import * | ||
|
||
|
||
class WebBeautifyCommand(sublime_plugin.TextCommand): | ||
|
||
def run(self, edit): | ||
self.save() | ||
self.beautify(edit) | ||
|
||
def save(self): | ||
self.view.run_command("save") | ||
|
||
def prettify(self, edit): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from cssbeautify import css_beautifier |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
import re | ||
import string | ||
|
||
|
||
class CssBeautify(object): | ||
|
||
def __init__(self): | ||
self.comment = False | ||
self.depth = 0 | ||
self.formatted = '' | ||
self.index = 0 | ||
self.open_brace_suffix = True | ||
self.options = { | ||
'indent': '\t' | ||
} | ||
self.quote = None | ||
self.state = { | ||
'start': 0, | ||
'at_rule': 1, | ||
'block': 2, | ||
'selector': 3, | ||
'ruleset': 4, | ||
'property': 5, | ||
'separator': 6, | ||
'expression': 7 | ||
} | ||
|
||
def __call__(self, css, options={}, *args): | ||
|
||
self.index = 0 | ||
self.formatted = '' | ||
|
||
for k, v in self.options.iteritems(): | ||
if options[k]: | ||
self.options[k] = options[k] | ||
|
||
length = len(css) | ||
state = self.state.start | ||
|
||
# Goodbye CRLF | ||
re.sub(r'\r\n', '\n', css) | ||
|
||
while self.index < length: | ||
ch = css[self.index] | ||
ch2 = css[self.index + 1] | ||
self.index += 1 | ||
|
||
# Inside a string literal? | ||
if self.is_quote(self.quote): | ||
self.formatted += ch | ||
if ch == self.quote: | ||
quote = None | ||
if ch == '\\' and ch2 == quote: | ||
# Don't treat escaped character as the closing quote | ||
self.formatted += ch2 | ||
self.index += 1 | ||
continue | ||
|
||
# Starting a string literal? | ||
if self.is_quote(ch): | ||
self.formatted += ch | ||
self.quote = ch | ||
continue | ||
|
||
if self.comment: | ||
self.formatted += ch | ||
if ch == '*' and ch2 == '/': | ||
self.comment = False | ||
self.formatted += ch2 | ||
self.index += 1 | ||
continue | ||
else: | ||
if ch == '/' and ch2 == '*': | ||
self.comment = True | ||
self.formatted += ch | ||
self.formatted += ch2 | ||
self.index += 1 | ||
continue | ||
|
||
if state == self.state.start: | ||
|
||
# Copy white spaces and control characters | ||
if ch <= ' ' or ord(ch) >= 128: | ||
state = self.state.start | ||
self.formatted += ch | ||
continue | ||
|
||
# Selector or at_rule | ||
if self.is_name(ch) or ch == '@': | ||
|
||
# Clear trailing whitespaces and linefeeds | ||
self.formatted.rstrip() | ||
|
||
# After finishing a ruleset or directive statement, | ||
# there should be one blank line | ||
if (str[-1] == '}') or str[-1] == ';': | ||
self.formatted = str + '\n\n' | ||
else: | ||
# After block comment, keep all the linfeeds but start | ||
# from the first column (remove whitespaces prefix). | ||
while True: | ||
ch2 = self.formatted[-1] | ||
if ch2 != ' ' and ord(ch2) != 9: | ||
break | ||
self.formatted = self.formatted[0:-1] | ||
|
||
self.formatted += ch | ||
state = self.state.at_rule if ch == '@' else self.state.selector | ||
continue | ||
|
||
if state == self.state.at_rule: | ||
|
||
# ; terminates a statement | ||
if ch == ';': | ||
self.formatted += ch | ||
state = self.state.start | ||
continue | ||
|
||
# '{' starts a block | ||
if ch == '{': | ||
self.open_block() | ||
state = self.state.block | ||
continue | ||
|
||
self.formatted += ch | ||
continue | ||
|
||
if state == self.state.block: | ||
if self.is_name(ch): | ||
|
||
# Clear trailing whitespace and linefeeds | ||
str = self.formatted.rstrip() | ||
|
||
# Insert blank line if necessary | ||
if str[-1] == '}': | ||
self.formatted = str + '\n\n' | ||
else: | ||
while True: | ||
ch2 = self.formatted[-1] | ||
if ch2 != ' ' and ord(ch2) != 9: | ||
break | ||
self.formatted = self.formatted[0:-1] | ||
|
||
self.append_indent() | ||
self.formatted += ch | ||
state = self.state.selector | ||
continue | ||
|
||
if ch == '}': | ||
self.close_block() | ||
state = self.state.start | ||
continue | ||
|
||
self.formatted += ch | ||
continue | ||
|
||
if state = self.state.selector: | ||
|
||
# '{' starts the ruleset | ||
if ch == '{': | ||
self.open_block() | ||
state = self.state.ruleset | ||
continue | ||
|
||
# '}' resets the state | ||
if ch == '}': | ||
self.close_block() | ||
state = self.state.start | ||
continue | ||
|
||
self.formatted += ch | ||
continue | ||
|
||
if state == self.state.ruleset: | ||
if ch == '}': | ||
self.close_block() | ||
state = self.state.start | ||
if self.depth > 0: | ||
state = self.state.block | ||
continue | ||
|
||
if ch == '\n': | ||
self.formatted += '\n' | ||
continue | ||
|
||
if not self.is_whitespace(ch): | ||
self.formatted += '\n' | ||
self.append_indent | ||
|
||
self.formatted += ch | ||
|
||
def is_name(self, c): | ||
return ch in string.letters or | ||
ch in string.digits or | ||
ch in '-_*.:#' | ||
|
||
def is_whitespace(self, c): | ||
return c in string.whitespace | ||
|
||
def is_quote(self, c): | ||
return c in '\'"' | ||
|
||
def append_indent(self): | ||
self.formatted += (self.options.indent * self.depth) | ||
|
||
def open_block(self): | ||
self.formatted = self.formatted.rstrip() | ||
|
||
if self.open_brace_suffix: | ||
self.formatted += ' {' | ||
else: | ||
self.formatted += '\n' | ||
self.append_indent | ||
self.formatted += '{' | ||
|
||
if ch2 != '\n': | ||
self.formatted += '\n' | ||
|
||
self.depth += 1 | ||
|
||
def close_block(self): | ||
self.depth -= 1 | ||
self.formatted = self.formatted.rstrip() | ||
self.formatted += '\n' | ||
self.append_indent() | ||
self.formatted += '}' | ||
|
||
css_beautifier = CssBeautify() |
98a4286
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is cool!
98a4286
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, thanks for the comment, Victor. Now I just need to get off my butt and finish the rest of it.