fuse 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ require 'thin'
3
3
 
4
4
  module Fuse
5
5
 
6
- VERSION = '0.1.5'
6
+ VERSION = '0.1.6'
7
7
 
8
8
  LOG_COLOURS = {
9
9
  info: 6, # cyan
@@ -42,6 +42,10 @@ require 'fuse/exceptions'
42
42
  require 'fuse/server'
43
43
  require 'fuse/document'
44
44
  require 'fuse/document/asset'
45
+ require 'fuse/document/asset/has_dependents'
46
+ require 'fuse/document/asset/style_sheet'
47
+ require 'fuse/document/asset/java_script'
48
+ require 'fuse/document/asset/font'
45
49
  require 'fuse/document/asset_types'
46
50
  require 'fuse/document/asset_collection'
47
51
 
@@ -13,24 +13,29 @@ class Fuse::Document
13
13
  end
14
14
 
15
15
  def to_s
16
- result.to_html encoding: @options[:encoding]
16
+ ret = result.to_html encoding: @options[:encoding], indent: 0
17
+ ret.gsub!(/(\s)\s+/, '\\1') unless @options[:preserve_white]
18
+ ret
17
19
  end
18
20
 
19
21
  def result
20
22
 
21
- #todo find a way to transform Nokogiri XML to HTML without serializing
22
-
23
23
  document = if xsl_path
24
- Nokogiri::HTML(Nokogiri::XSLT(File.read xsl_path).transform(Nokogiri::XML(File.read source_path)).to_html encoding: @options[:encoding])
24
+ Nokogiri::XSLT(File.read xsl_path).transform(Nokogiri(File.read source_path))
25
25
  else
26
26
  Nokogiri::HTML(File.read source_path)
27
27
  end
28
28
 
29
- html = document.css('> html').first
29
+ while (html = document.css('> html').first).nil?
30
+ document = Nokogiri::HTML(document.to_html encoding: @options[:encoding])
31
+ end
30
32
  body = html.css('> body').first
31
33
  head = html.css('> head').first || body.add_previous_sibling(Nokogiri::XML::Node.new 'head', document)
32
34
 
33
- document.title = @options[:title] unless @options[:title].nil?
35
+ unless @options[:title].nil?
36
+ title = head.css('> title').first || head.add_child(Nokogiri::XML::Node.new('title', document))
37
+ title.children = Nokogiri::XML::Text.new(@options[:title], document)
38
+ end
34
39
 
35
40
  #attach stylesheets and scripts
36
41
  [Fuse::Document::Asset::StyleSheet, Fuse::Document::Asset::JavaScript].each do |klass|
@@ -0,0 +1,32 @@
1
+ class Fuse::Document::Asset
2
+ class Font < self
3
+ CSS_FORMATS = [
4
+ { extension: :woff, format: 'woff' },
5
+ { extension: :ttf, format: 'truetype' },
6
+ { extension: :otf, format: 'opentype' }
7
+ ]
8
+ MIME_TYPES = {
9
+ otf: 'application/x-font-opentype',
10
+ ttf: 'application/x-font-truetype',
11
+ woff: 'application/x-font-woff'
12
+ }
13
+ VARIANT_PATTERN = %r`([^/]+?)(?:[-_ ](normal|bold|bolder|lighter|[1-9]00))?(?:[-_ ](normal|italic|oblique))?\.[a-z]+$`
14
+ def family; @family ||= variant[:family] end
15
+ def weight; @weight ||= variant[:weight] end
16
+ def style; @style ||= variant[:style] end
17
+ def variant
18
+ @variant ||= begin
19
+ match = VARIANT_PATTERN.match(path)
20
+ {
21
+ family: match[1],
22
+ weight: match[2] || 'normal',
23
+ style: match[3] || 'normal'
24
+ }
25
+ end
26
+ end
27
+ def face; @face ||= [family, weight, style].join('-') end
28
+ def type
29
+ MIME_TYPES[extension.to_sym] || super
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module Fuse::Document::Asset::HasDependents
2
+
3
+ COMMENT_PATTERN = %r`^\s*(/\*[\s\S]*?\*/|(\s*//.*\s+)+)`
4
+ REQUIRE_PATTERN = %r`^\s*(?:\*|//)=\s+(require|require_glob)\s+(.+?)\s*$`
5
+
6
+ def dependents
7
+ ret = Fuse::Document::AssetCollection.new
8
+ local_root = File.dirname(full_path)
9
+ if (comments = raw[COMMENT_PATTERN])
10
+ comments.lines.each do |line|
11
+ if (match = REQUIRE_PATTERN.match(line))
12
+ case match[1]
13
+ when 'require'
14
+ [File.join(local_root, match[2])]
15
+ when 'require_glob'
16
+ Dir[File.join(local_root, match[2])]
17
+ else
18
+ []
19
+ end.map do |p|
20
+ Fuse::Document::Asset.for(p[@root.length..-1], @root)
21
+ end.reject do |p|
22
+ p.nil?
23
+ end.each do |p|
24
+ ret << p
25
+ end
26
+ end
27
+ end
28
+ end
29
+ ret
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ class Fuse::Document::Asset
2
+ class JavaScript < self
3
+ EMBED_WITH = 'script'
4
+ JOIN_WITH = ';'
5
+ include HasDependents
6
+ def reference_with
7
+ {
8
+ tag_name: 'script',
9
+ attributes: {
10
+ type: type,
11
+ src: relative_path
12
+ }
13
+ }
14
+ end
15
+ def compress
16
+ original = filtered
17
+ compressed = Uglifier.compile original
18
+ Fuse.log "Uglifier: Compressed #{path} from #{original.bytesize} bytes to #{compressed.bytesize} bytes", :success
19
+ compressed
20
+ end
21
+ def type; 'text/javascript' end
22
+ class Coffee < self
23
+ def filter
24
+ original = raw
25
+ compiled = CoffeeScript.compile original
26
+ Fuse.log "CoffeeScript: Compiled #{path} from #{original.bytesize} bytes to #{compiled.bytesize} bytes", :success
27
+ compiled
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,36 @@
1
+ class Fuse::Document::Asset
2
+ class StyleSheet < self
3
+ EMBED_WITH = 'style'
4
+ JOIN_WITH = ''
5
+ MEDIA_PATTERN = /\(([a-z]+(?:,\s*[a-z]+)*)\)\.[a-z]+$/i
6
+ include HasDependents
7
+ def reference_with
8
+ {
9
+ tag_name: 'link',
10
+ attributes: {
11
+ rel: 'stylesheet',
12
+ href: relative_path,
13
+ media: media
14
+ }
15
+ }
16
+ end
17
+ def media
18
+ @media ||= (match = MEDIA_PATTERN.match(path)) && match[1].split(/,\s*/).sort.join(', ')
19
+ end
20
+ def compress
21
+ original = raw
22
+ compressed = ::Sass.compile original, style: :compressed
23
+ Fuse.log "SASS: Compressed #{path} from #{original.bytesize} bytes to #{compressed.bytesize} bytes", :success
24
+ compressed
25
+ end
26
+ def type; 'text/css' end
27
+ class Sass < self
28
+ def filter
29
+ original = raw
30
+ compiled = ::Sass.compile original, style: :expanded
31
+ Fuse.log "SASS: Compiled #{path} from #{original.bytesize} bytes to #{compiled.bytesize} bytes", :success
32
+ compiled
33
+ end
34
+ end
35
+ end
36
+ end
@@ -4,136 +4,9 @@ require 'uglifier'
4
4
 
5
5
  class Fuse::Document::Asset
6
6
 
7
- module HasDependents
8
- COMMENT_PATTERN = %r`^\s*(/\*[\s\S]*?\*/|(\s*//.*\s+)+)`
9
- REQUIRE_PATTERN = %r`^\s*(?:\*|//)=\s+(require|require_glob)\s+(.+?)\s*$`
10
-
11
- def dependents
12
- ret = Fuse::Document::AssetCollection.new
13
- local_root = File.dirname(full_path)
14
- if (comments = raw[COMMENT_PATTERN])
15
- comments.lines.each do |line|
16
- if (match = REQUIRE_PATTERN.match(line))
17
- case match[1]
18
- when 'require'
19
- [File.join(local_root, match[2])]
20
- when 'require_glob'
21
- Dir[File.join(local_root, match[2])]
22
- else
23
- []
24
- end.map do |p|
25
- Fuse::Document::Asset.for(p[@root.length..-1], @root)
26
- end.reject do |p|
27
- p.nil?
28
- end.each do |p|
29
- ret << p
30
- end
31
- end
32
- end
33
- end
34
- ret
35
- end
36
- end
37
-
38
- class StyleSheet < self
39
- EMBED_WITH = 'style'
40
- JOIN_WITH = ''
41
- MEDIA_PATTERN = /\(([a-z]+(?:,\s*[a-z]+)*)\)\.[a-z]+$/i
42
- include HasDependents
43
- def reference_with
44
- {
45
- tag_name: 'link',
46
- attributes: {
47
- rel: 'stylesheet',
48
- href: relative_path,
49
- media: media
50
- }
51
- }
52
- end
53
- def media
54
- @media ||= (match = MEDIA_PATTERN.match(path)) && match[1].split(/,\s*/).sort.join(', ')
55
- end
56
- def compress
57
- original = raw
58
- compressed = ::Sass.compile original, style: :compressed
59
- Fuse.log "SASS: Compressed #{path} from #{original.length} bytes to #{compressed.length} bytes", :success
60
- compressed
61
- end
62
- def type; 'text/css' end
63
- class Sass < self
64
- def filter
65
- original = raw
66
- compiled = ::Sass.compile original, style: :expanded
67
- Fuse.log "SASS: Compiled #{path} from #{original.length} bytes to #{compiled.length} bytes", :success
68
- compiled
69
- end
70
- end
71
- end
72
-
73
- class JavaScript < self
74
- EMBED_WITH = 'script'
75
- JOIN_WITH = ';'
76
- include HasDependents
77
- def reference_with
78
- {
79
- tag_name: 'script',
80
- attributes: {
81
- type: type,
82
- src: relative_path
83
- }
84
- }
85
- end
86
- def compress
87
- original = filtered
88
- compressed = Uglifier.compile original
89
- Fuse.log "Uglifier: Compressed #{path} from #{original.length} bytes to #{compressed.length} bytes", :success
90
- compressed
91
- end
92
- def type; 'text/javascript' end
93
- class Coffee < self
94
- def filter
95
- original = raw
96
- compiled = CoffeeScript.compile original
97
- Fuse.log "CoffeeScript: Compiled #{path} from #{original.length} bytes to #{compiled.length} bytes", :success
98
- compiled
99
- end
100
- end
101
- end
102
-
103
7
  class Image < self
104
8
  end
105
9
 
106
- class Font < self
107
- CSS_FORMATS = [
108
- { extension: :woff, format: 'woff' },
109
- { extension: :ttf, format: 'truetype' },
110
- { extension: :otf, format: 'opentype' }
111
- ]
112
- MIME_TYPES = {
113
- otf: 'application/x-font-opentype',
114
- ttf: 'application/x-font-truetype',
115
- woff: 'application/x-font-woff'
116
- }
117
- VARIANT_PATTERN = %r`([^/]+?)(?:[-_ ](normal|bold|bolder|lighter|[1-9]00))?(?:[-_ ](normal|italic|oblique))?\.[a-z]+$`
118
- def family; @family ||= variant[:family] end
119
- def weight; @weight ||= variant[:weight] end
120
- def style; @style ||= variant[:style] end
121
- def variant
122
- @variant ||= begin
123
- match = VARIANT_PATTERN.match(path)
124
- {
125
- family: match[1],
126
- weight: match[2] || 'normal',
127
- style: match[3] || 'normal'
128
- }
129
- end
130
- end
131
- def face; @face ||= [family, weight, style].join('-') end
132
- def type
133
- MIME_TYPES[extension.to_sym] || super
134
- end
135
- end
136
-
137
10
  class Xml < self
138
11
  end
139
12
 
@@ -6,7 +6,8 @@ module Fuse
6
6
  DEFAULTS = {
7
7
  common: {
8
8
  source: '.',
9
- encoding: 'UTF-8'
9
+ encoding: 'UTF-8',
10
+ preserve_white: true
10
11
  },
11
12
  server: {
12
13
  addr: '127.0.0.1',
@@ -30,7 +31,7 @@ module Fuse
30
31
 
31
32
  "
32
33
 
33
- Usage: #{$0} [command] [options]
34
+ Usage: #{$0} command [options]
34
35
 
35
36
  Commands:
36
37
  server : Run a local testing server
@@ -95,6 +96,11 @@ Options:
95
96
  'Show Fuse version.'
96
97
  ) { abort Fuse::VERSION }
97
98
 
99
+ opts.on('-w',
100
+ '--[no-]preserve-white',
101
+ wrap("Preserve all white space in HTML. Default is #{DEFAULTS[:common][:preserve_white]}.")
102
+ ) { |w| options[:preserve_white] = w }
103
+
98
104
  opts.on('-x',
99
105
  '--xsl FILE',
100
106
  wrap('XSL transformation stylesheet. Default is current directory.')
@@ -123,8 +129,9 @@ Options:
123
129
  begin
124
130
  doc = Document.new(options)
125
131
  log "Compiling #{doc.source_path}"
126
- print doc.to_s
127
- log 'Done.', :success
132
+ out = doc.to_s
133
+ print out
134
+ log "Wrote #{out.bytesize} byte(s) to STDOUT.", :success
128
135
  rescue Exception::SourceUnknown::TooManySources
129
136
  log "Found more than one potential #{$!.option_name} document. Please specify one with --#{$!.option_name}.", :notice
130
137
  log $!.options.join "\n"
@@ -4,6 +4,7 @@ class Fuse::Server
4
4
 
5
5
  def initialize(options)
6
6
  @options = options
7
+ Fuse.log "Starting Fuse Server v#{Fuse::VERSION}", :success
7
8
  end
8
9
 
9
10
  def call(env)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fuse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-07 00:00:00.000000000 Z
12
+ date: 2013-03-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thin
@@ -134,6 +134,10 @@ extensions: []
134
134
  extra_rdoc_files: []
135
135
  files:
136
136
  - bin/fuse
137
+ - lib/fuse/document/asset/font.rb
138
+ - lib/fuse/document/asset/has_dependents.rb
139
+ - lib/fuse/document/asset/java_script.rb
140
+ - lib/fuse/document/asset/style_sheet.rb
137
141
  - lib/fuse/document/asset.rb
138
142
  - lib/fuse/document/asset_collection.rb
139
143
  - lib/fuse/document/asset_types.rb