erbeautifier 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ pkg/
@@ -0,0 +1,4 @@
1
+ == 0.1.0 2007-09-02
2
+
3
+ * 1 major enhancement:
4
+ * Initial release as a RubyGem
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Paul Battley/Revieworld Ltd.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/htmlbeautifier
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ lib/htmlbeautifier.rb
10
+ lib/htmlbeautifier/beautifier.rb
11
+ lib/htmlbeautifier/parser.rb
12
+ lib/htmlbeautifier/version.rb
13
+ log/debug.log
14
+ script/destroy
15
+ script/generate
16
+ setup.rb
17
+ tasks/deployment.rake
18
+ tasks/environment.rake
19
+ tasks/website.rake
20
+ test/html_beautifier_test_utilities.rb
21
+ test/test_helper.rb
22
+ test/test_html_beautifier_integration.rb
23
+ test/test_html_beautifier_regression.rb
24
+ test/test_parser.rb
@@ -0,0 +1,16 @@
1
+ = HTML Beautifier
2
+
3
+ A normaliser/beautifier for HTML that also understands embedded Ruby. Ideal for tidying up Rails templates.
4
+
5
+ == What it does
6
+
7
+ * Normalises hard tabs to spaces
8
+ * Removes trailing spaces
9
+ * Indents after opening HTML elements
10
+ * Outdents before closing elements
11
+ * Collapses multiple whitespace
12
+ * Indents after block-opening embedded Ruby (if, do etc.)
13
+ * Outdents before closing Ruby blocks
14
+ * Outdents elsif and then indents again
15
+ * Indents the left-hand margin of JavaScript and CSS blocks to match the indentation level of the code
16
+
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "erbeautifier"
8
+ gemspec.summary = %q{Beautifies your HTML erb templates. Midwire's fork of Ho-Sheng Hsiao's code. Bug fixes, etc.}
9
+ gemspec.description = %q{A normaliser/beautifier for HTML that also understands embedded Ruby. Ideal for tidying up Rails templates.}
10
+ gemspec.email = %q{midwire@midwiretech.com}
11
+ gemspec.homepage = %q{http://github.com/midwire/htmlbeautifier}
12
+ gemspec.authors = ["Ho-Sheng Hsiao", "Midwire"]
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler not available. Install it with: gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/test_*.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+ task :test => :check_dependencies
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "erbeautifier #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,4 @@
1
+ #! /usr/bin/ruby18
2
+ require 'htmlbeautifier/beautifier'
3
+ HtmlBeautifier::Beautifier.new($stdout).scan($stdin.read)
4
+ $stdout << "\n"
@@ -0,0 +1,70 @@
1
+ require 'htmlbeautifier/version'
2
+
3
+ AUTHOR = 'Paul Battley' # can also be an array of Authors
4
+ EMAIL = "pbattley@gmail.com"
5
+ DESCRIPTION = "A normaliser/beautifier for HTML that also understands embedded Ruby. Ideal for tidying up Rails templates."
6
+ GEM_NAME = 'htmlbeautifier' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'htmlbeautifier' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+
11
+ @config_file = "~/.rubyforge/user-config.yml"
12
+ @config = nil
13
+ RUBYFORGE_USERNAME = "unknown"
14
+ def rubyforge_username
15
+ unless @config
16
+ begin
17
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
18
+ rescue
19
+ puts <<-EOS
20
+ ERROR: No rubyforge config file found: #{@config_file}"
21
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
22
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
23
+ EOS
24
+ exit
25
+ end
26
+ end
27
+ RUBYFORGE_USERNAME.replace @config["username"]
28
+ end
29
+
30
+
31
+ REV = nil
32
+ # UNCOMMENT IF REQUIRED:
33
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
34
+ VERS = HtmlBeautifier::VERSION::STRING + (REV ? ".#{REV}" : "")
35
+ RDOC_OPTS = ['--quiet', '--title', 'htmlbeautifier documentation',
36
+ "--opname", "index.html",
37
+ "--line-numbers",
38
+ "--main", "README",
39
+ "--inline-source"]
40
+
41
+ class Hoe
42
+ def extra_deps
43
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
44
+ @extra_deps
45
+ end
46
+ end
47
+
48
+ # Generate all the Rake tasks
49
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
50
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
51
+ p.author = AUTHOR
52
+ p.description = DESCRIPTION
53
+ p.email = EMAIL
54
+ p.summary = DESCRIPTION
55
+ p.url = HOMEPATH
56
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
57
+ p.test_globs = ["test/**/test_*.rb"]
58
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
59
+
60
+ # == Optional
61
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\\n\\n")
62
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
63
+
64
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
65
+
66
+ end
67
+
68
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
69
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
70
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
@@ -0,0 +1,3 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
2
+
3
+ require 'htmlbeautifier'
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{erbeautifier}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ho-Sheng Hsiao", "Midwire"]
12
+ s.date = %q{2010-02-05}
13
+ s.default_executable = %q{htmlbeautifier}
14
+ s.description = %q{A normaliser/beautifier for HTML that also understands embedded Ruby. Ideal for tidying up Rails templates.}
15
+ s.email = %q{midwire@midwiretech.com}
16
+ s.executables = ["htmlbeautifier"]
17
+ s.extra_rdoc_files = [
18
+ "README.txt"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "History.txt",
23
+ "License.txt",
24
+ "Manifest.txt",
25
+ "README.txt",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/htmlbeautifier",
29
+ "config/hoe.rb",
30
+ "config/requirements.rb",
31
+ "erbeautifier.gemspec",
32
+ "lib/htmlbeautifier.rb",
33
+ "lib/htmlbeautifier/beautifier.rb",
34
+ "lib/htmlbeautifier/parser.rb",
35
+ "lib/htmlbeautifier/version.rb",
36
+ "script/destroy",
37
+ "script/generate",
38
+ "setup.rb",
39
+ "tasks/deployment.rake",
40
+ "tasks/environment.rake",
41
+ "tasks/website.rake",
42
+ "test/html_beautifier_test_utilities.rb",
43
+ "test/test_helper.rb",
44
+ "test/test_html_beautifier_integration.rb",
45
+ "test/test_html_beautifier_regression.rb",
46
+ "test/test_parser.rb"
47
+ ]
48
+ s.homepage = %q{http://github.com/midwire/htmlbeautifier}
49
+ s.rdoc_options = ["--charset=UTF-8"]
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = %q{1.3.5}
52
+ s.summary = %q{Beautifies your HTML erb templates. Midwire's fork of Ho-Sheng Hsiao's code. Bug fixes, etc.}
53
+ s.test_files = [
54
+ "test/html_beautifier_test_utilities.rb",
55
+ "test/test_helper.rb",
56
+ "test/test_html_beautifier_integration.rb",
57
+ "test/test_html_beautifier_regression.rb",
58
+ "test/test_parser.rb"
59
+ ]
60
+
61
+ if s.respond_to? :specification_version then
62
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
63
+ s.specification_version = 3
64
+
65
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
66
+ else
67
+ end
68
+ else
69
+ end
70
+ end
71
+
@@ -0,0 +1,5 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ module HtmlBeautifier
4
+
5
+ end
@@ -0,0 +1,119 @@
1
+ require 'htmlbeautifier/parser'
2
+
3
+ module HtmlBeautifier
4
+ class Beautifier
5
+
6
+ RUBY_INDENT =
7
+ %r{ ^ ( if | unless | while | begin | elsif )\b
8
+ | \b ( do | \{ ) ( \s* \| [^\|]+ \| )? $
9
+ }x
10
+ RUBY_OUTDENT =
11
+ %r{ ^ ( end | elsif |\} ) \b
12
+ }x
13
+ ELEMENT_CONTENT = %r{ (?:[^<>]|<%.*?%>)* }mx
14
+
15
+ def initialize(output)
16
+ @level = 0
17
+ @new_line = true
18
+ self.tab_stops = 2
19
+ @output = output
20
+ end
21
+
22
+ def tab_stops=(n)
23
+ @tab = ' ' * n
24
+ end
25
+
26
+ def indent
27
+ @level += 1
28
+ end
29
+
30
+ def outdent
31
+ @level -= 1
32
+ raise "Outdented too far" if @level < 0
33
+ end
34
+
35
+ def emit(s)
36
+ if (@new_line)
37
+ @output << (@tab * @level)
38
+ end
39
+ @output << s
40
+ @new_line = false
41
+ end
42
+
43
+ def whitespace(*x)
44
+ emit "\n"
45
+ @new_line = true
46
+ end
47
+
48
+ def embed(opening, code, closing)
49
+ lines = code.split(/\n/).map{ |l| l.strip }
50
+ outdent if lines.first =~ RUBY_OUTDENT
51
+ emit opening + code + closing
52
+ indent if lines.last =~ RUBY_INDENT
53
+ end
54
+
55
+ def foreign_block(opening, code, closing)
56
+ emit opening
57
+ begin
58
+ unless code.empty?
59
+ indent
60
+
61
+ lines = code.split(/\n/)
62
+ lines.shift while lines.first.strip.empty?
63
+ lines.pop while lines.last.strip.empty?
64
+ indentation = lines.first[/^ +/]
65
+
66
+ whitespace
67
+ lines.each do |line|
68
+ emit line.rstrip.sub(/^#{indentation}/, '')
69
+ whitespace
70
+ end
71
+
72
+ outdent
73
+ end
74
+ rescue
75
+ # Ignore empty script blocks
76
+ end
77
+ emit closing
78
+ end
79
+
80
+ def standalone_element(e)
81
+ emit e
82
+ end
83
+
84
+ def close_element(e)
85
+ outdent
86
+ emit e
87
+ end
88
+
89
+ def open_element(e)
90
+ emit e
91
+ indent
92
+ end
93
+
94
+ def text(t)
95
+ emit(t.strip)
96
+ whitespace if t =~ /\s$/
97
+ end
98
+
99
+ def scan(html)
100
+ html = html.strip.gsub(/\t/, @tab)
101
+ parser = Parser.new do
102
+ map %r{(<%=?)(.*?)(-?%>)}m, :embed
103
+ map %r{<!--\[.*?\]>}m, :open_element
104
+ map %r{<!\[.*?\]-->}m, :close_element
105
+ map %r{<!--.*?-->}m, :standalone_element
106
+ map %r{<!.*?>}m, :standalone_element
107
+ map %r{(<script#{ELEMENT_CONTENT}>)(.*?)(</script>)}m, :foreign_block
108
+ map %r{(<style#{ELEMENT_CONTENT}>)(.*?)(</style>)}m, :foreign_block
109
+ map %r{<#{ELEMENT_CONTENT}/>}m, :standalone_element
110
+ map %r{</#{ELEMENT_CONTENT}>}m, :close_element
111
+ map %r{<#{ELEMENT_CONTENT}>}m, :open_element
112
+ map %r{\s+}, :whitespace
113
+ map %r{[^<]+}, :text
114
+ end
115
+ parser.scan(html, self)
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,53 @@
1
+ require 'strscan'
2
+
3
+ module HtmlBeautifier
4
+ class Parser
5
+
6
+ def self.debug_block(&blk)
7
+ @debug_block = blk
8
+ end
9
+
10
+ def self.debug(match, method)
11
+ if defined? @debug_block
12
+ @debug_block.call(match, method)
13
+ end
14
+ end
15
+
16
+ def initialize(&blk)
17
+ @maps = []
18
+ if block_given?
19
+ self.instance_eval(&blk)
20
+ end
21
+ end
22
+
23
+ def map(pattern, method)
24
+ @maps << [pattern, method]
25
+ end
26
+
27
+ def scan(subject, receiver)
28
+ scanner = StringScanner.new(subject)
29
+ until scanner.eos?
30
+ dispatch(scanner, receiver)
31
+ end
32
+ end
33
+
34
+ def dispatch(scanner, receiver)
35
+ @maps.each do |pattern, method|
36
+ if scanner.scan(pattern)
37
+ params = []
38
+ i = 1
39
+ while scanner[i]
40
+ params << scanner[i]
41
+ i += 1
42
+ end
43
+ params = [scanner[0]] if params.empty?
44
+ self.class.debug(scanner[0], method)
45
+ receiver.__send__(method, *params)
46
+ return
47
+ end
48
+ end
49
+ raise "Unmatched sequence #{match.inspect}"
50
+ end
51
+
52
+ end
53
+ end