distil 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.8.1
data/distil.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{distil}
8
- s.version = "0.8.0"
8
+ s.version = "0.8.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeff Watkins"]
12
- s.date = %q{2009-12-22}
12
+ s.date = %q{2010-01-11}
13
13
  s.default_executable = %q{distil}
14
14
  s.description = %q{A build tool for Javascript and CSS that takes advantage of best-of-breed helper applications Javascript Lint and JSDoc Toolkit}
15
15
  s.executables = ["distil"]
@@ -27,6 +27,11 @@ Gem::Specification.new do |s|
27
27
  "lib/file-types/javascript-file.rb",
28
28
  "lib/file-types/json-file.rb",
29
29
  "lib/file-types/nib-file.rb",
30
+ "lib/filter.rb",
31
+ "lib/filters/coherent-asset-filter.rb",
32
+ "lib/filters/css-filter.rb",
33
+ "lib/filters/file-reference-filter.rb",
34
+ "lib/filters/jsl-dependency-filter.rb",
30
35
  "lib/jsdoc.conf",
31
36
  "lib/jsl.conf",
32
37
  "lib/project.rb",
@@ -52,10 +57,13 @@ Gem::Specification.new do |s|
52
57
  "vendor/extconf.rb",
53
58
  "vendor/jsdoc-extras/plugins/distil-plugin.js",
54
59
  "vendor/jsdoc-extras/plugins/interface-plugin.js",
60
+ "vendor/jsdoc-extras/templates/coherent/all-classes.tmpl",
55
61
  "vendor/jsdoc-extras/templates/coherent/allclasses.tmpl",
56
62
  "vendor/jsdoc-extras/templates/coherent/allfiles.tmpl",
63
+ "vendor/jsdoc-extras/templates/coherent/class-json.tmpl",
57
64
  "vendor/jsdoc-extras/templates/coherent/class.tmpl",
58
65
  "vendor/jsdoc-extras/templates/coherent/index.tmpl",
66
+ "vendor/jsdoc-extras/templates/coherent/namespace-json.tmpl",
59
67
  "vendor/jsdoc-extras/templates/coherent/publish.js",
60
68
  "vendor/jsdoc-extras/templates/coherent/showdown.js",
61
69
  "vendor/jsdoc-extras/templates/coherent/static/code-footer.html",
data/lib/file-set.rb CHANGED
@@ -26,7 +26,7 @@ class FileSet
26
26
  if (File.exists?(full_path))
27
27
  source_file= SourceFile.from_path(full_path)
28
28
  else
29
- source_file= Target.current.find_file(file)
29
+ source_file= Project.current.find_file(file)
30
30
  return if (!source_file)
31
31
  end
32
32
 
@@ -4,71 +4,8 @@ class CssFile < SourceFile
4
4
  ".css"
5
5
  end
6
6
 
7
- def can_embed_as_content
8
- true
9
- end
10
-
11
- def minify_content_type
12
- "css"
13
- end
14
-
15
- def content
16
- return @content if (@content && @root_folder==@@root_folder)
17
-
18
- # Remember the value of the class root_folder variable, because it changes
19
- # where files are generated relative to.
20
- @root_folder= @@root_folder
21
-
22
- buffer= File.read(@full_path)
23
- # Replace all ' (single quotes) with " (double quotes) in
24
- # order to fix a problem with the background url regexp
25
- buffer.gsub!(/\'/,'"')
26
- # Force a newline after a rule terminating ; (semi-colon)
27
- # in order to fix a problem with the background url regexp
28
- buffer.gsub!(/;(\n|\r)*/, ";\n")
29
-
30
- # Rewrites the 'url("...")' rules to a relative path
31
- # based on the location of the new concatenated CSS file.
32
- line_num=0
33
-
34
- lines= buffer.split("\n")
35
-
36
- lines.each { |line|
37
-
38
- line_num+=1
39
-
40
- line.gsub!(/@import\s+url\("?(.*\.css)"?\)/) { |match|
41
- css_file= File.join(@parent_folder, $1)
42
-
43
- if (!File.exists?(css_file))
44
- error "imported CSS file not found: #{$1}", line_num
45
- # leave the @import rule in place
46
- match
47
- else
48
- dependency= SourceFile.from_path(css_file)
49
- @dependencies << dependency
50
- end
51
- }
52
-
53
- line.gsub!(/url\("?(.*\.(jpg|png|gif))"?\)/) { |match|
54
- image_file= File.join(@parent_folder, $1)
55
-
56
- if (!File.exists?(image_file))
57
- warning "resource not found: #{$1} (#{image_file})", line_num
58
- "url(\"#{$1}\")"
59
- else
60
- asset= SourceFile.from_path(image_file)
61
- @assets << asset
62
- # dependency.dependencies
63
- "url(\"{{FILEREF(#{asset})}}\")"
64
- end
65
- }
66
- }
67
-
68
- @content= lines.join("\n")
69
- end
70
-
71
- def debug_content_relative_to_destination(destination)
7
+ def debug_content(options)
8
+ destination= File.expand_path(options.remove_prefix||"")
72
9
  "@import url(\"#{self.relative_to_folder(destination)}\");\n"
73
10
  end
74
11
 
@@ -4,8 +4,8 @@ class HtmlFile < SourceFile
4
4
  ".html"
5
5
  end
6
6
 
7
- def can_embed_as_content
8
- true
7
+ def minify_content(source)
8
+ source.gsub(/>\s+</, "><")
9
9
  end
10
-
10
+
11
11
  end
@@ -7,90 +7,16 @@ class JavascriptFile < SourceFile
7
7
  ".js"
8
8
  end
9
9
 
10
- def can_embed_as_content
11
- true
10
+ def can_embed_as_content(file)
11
+ [".css", ".html", ".json"].include?(file.extension)
12
12
  end
13
13
 
14
- def minify_content_type
15
- "js"
16
- end
17
-
18
- def content
19
- return @content if (@content && @root_folder==@@root_folder)
20
-
21
- # Remember the value of the class root_folder variable, because it changes
22
- # where files are generated relative to.
23
- @root_folder= @@root_folder
24
-
25
- @dependencies= []
26
- content= File.read(@full_path).split("\n")
27
-
28
- line_num=0
29
-
30
- content.each { |line|
31
-
32
- line_num+=1
33
-
34
- # handle dependencies
35
- line.gsub!($jsl_import_regex) { |match|
36
-
37
- import_file= File.expand_path(File.join(@parent_folder, $1))
38
-
39
- if (File.exists?(import_file))
40
- dependency= SourceFile.from_path(import_file)
41
- @dependencies << dependency
42
- else
43
- dependency= Target.current.find_file($1)
44
- if (dependency)
45
- @dependencies << dependency
46
- else
47
- error "Missing import file: #{$1}", line_num
48
- end
49
- end
50
-
51
- # replace jsl import with empty string
52
- ""
53
-
54
- }
55
-
56
- line.gsub!($include_regex) { |match|
57
-
58
- import_file= File.expand_path(File.join(@parent_folder, $1))
59
-
60
- if (!File.exists?(import_file))
61
- error "Missing import file: #{$1}", line_num
62
- "NIB.asset('#{$1}')"
63
- else
64
- asset= SourceFile.from_path(import_file)
65
- @assets << asset
66
- if (asset.can_embed_as_content)
67
- "NIB.asset('{{FILEREF(#{asset})}}','{{CONTENTREF(#{asset})}}')"
68
- else
69
- "NIB.asset('{{FILEREF(#{asset})}}')"
70
- # include_content= asset.content.gsub("\\", "\\\\").gsub(/>\s+</, "><").gsub("\n", "\\n").gsub("\"", "\\\"").gsub("'", "\\\\'")
71
- # "INC('{{FILEREF(#{asset})}}','{{CONTENTREF(#{asset})}}')"
72
- end
73
- end
74
-
75
- }
76
-
77
- }
78
-
79
- # return the array of dependencies
80
- @content= content.join("\n") + "\n"
81
- end
82
-
83
- def content_relative_to_destination(destination)
84
- relative= super(destination)
85
- relative.gsub(/\{\{CONTENTREF\(([^)]*)\)\}\}/) { |match|
86
- file= SourceFile.from_path($1)
87
- included_content= file.content_relative_to_destination(destination)
88
- included_content= file.minify_content(included_content)
89
- included_content.gsub("\\", "\\\\").gsub(/>\s+</, "><").gsub("\n", "\\n").gsub("\"", "\\\"").gsub("'", "\\\\'")
90
- }
14
+ def escape_embeded_content(content)
15
+ content.gsub("\\", "\\\\").gsub("\n", "\\n").gsub("\"", "\\\"").gsub("'", "\\\\'")
91
16
  end
92
17
 
93
- def debug_content_relative_to_destination(destination)
18
+ def debug_content(options)
19
+ destination= File.expand_path(options.remove_prefix||"")
94
20
  path= @file_path ? @file_path : self.relative_to_folder(destination)
95
21
  "loadScript(\"#{path}\");\n"
96
22
  end
@@ -8,7 +8,6 @@ class JsonFile < JavascriptFile
8
8
 
9
9
  def minify_content(source)
10
10
  super("(#{source})")[1..-3]
11
-
12
11
  end
13
12
 
14
13
  end
@@ -6,4 +6,8 @@ class NibFile < JavascriptFile
6
6
  ".jsnib"
7
7
  end
8
8
 
9
+ def content_type
10
+ "js"
11
+ end
12
+
9
13
  end
data/lib/filter.rb ADDED
@@ -0,0 +1,41 @@
1
+ # require "#{$script_dir}/configurable"
2
+
3
+ class Filter
4
+
5
+ @@filters= []
6
+ def self.inherited(subclass)
7
+ @@filters << subclass.new
8
+ end
9
+
10
+ def self.abstract
11
+ false
12
+ end
13
+
14
+ def self.each
15
+ @@filters.each { |f|
16
+ yield f
17
+ }
18
+ end
19
+
20
+ def self.defined
21
+ @@filters
22
+ end
23
+
24
+ def handles_file(file)
25
+ false
26
+ end
27
+
28
+ def preprocess_content(file, content)
29
+ content
30
+ end
31
+
32
+ def filter_content(file, content, options={})
33
+ content
34
+ end
35
+
36
+ end
37
+
38
+ # load all the other file types
39
+ Dir.glob("#{$script_dir}/filters/*-filter.rb") { |file|
40
+ require file
41
+ }
@@ -0,0 +1,65 @@
1
+ require "#{$script_dir}/filters/file-reference-filter"
2
+
3
+ $include_regex= /NIB\.asset\(['"]([^)]+)['"]\)/
4
+ $include_regex_old= /INC\(['"]([^)]+)['"]\)/
5
+
6
+ class CoherentAssetFilter < FileReferenceFilter
7
+
8
+ def handles_file(file)
9
+ return [".js"].include?(file.extension)
10
+ end
11
+
12
+ def preprocess_content(file, content)
13
+ content= content.split("\n")
14
+
15
+ line_num=0
16
+
17
+ content.each { |line|
18
+
19
+ line_num+=1
20
+
21
+ line.gsub!($include_regex) { |match|
22
+
23
+ import_file= File.expand_path(File.join(file.parent_folder, $1))
24
+
25
+ if (!File.exists?(import_file))
26
+ file.error "Missing import file: #{$1}", line_num
27
+ "NIB.asset('#{$1}')"
28
+ else
29
+ asset= SourceFile.from_path(import_file)
30
+ file.add_asset(asset);
31
+ if (file.can_embed_as_content(asset))
32
+ "NIB.asset('#{file_reference(asset)}','#{content_reference(asset)}')"
33
+ else
34
+ "NIB.asset('#{file_reference(asset)}')"
35
+ end
36
+ end
37
+
38
+ }
39
+
40
+ line.gsub!($include_regex_old) { |match|
41
+
42
+ import_file= File.expand_path(File.join(file.parent_folder, $1))
43
+
44
+ if (!File.exists?(import_file))
45
+ file.error "Missing import file: #{$1}", line_num
46
+ "INC('#{$1}')"
47
+ else
48
+ asset= SourceFile.from_path(import_file)
49
+ file.add_asset(asset);
50
+ if (file.can_embed_as_content(asset))
51
+ "INC('#{file_reference(asset)}','#{content_reference(asset)}')"
52
+ else
53
+ "INC('#{file_reference(asset)}')"
54
+ end
55
+ end
56
+
57
+ }
58
+
59
+ }
60
+
61
+ content.join("\n")
62
+ end
63
+
64
+ end
65
+
@@ -0,0 +1,58 @@
1
+ require "#{$script_dir}/filters/file-reference-filter"
2
+
3
+ $jsl_import_regex= /\/\*jsl:import\s+([^\*]*)\*\//
4
+
5
+ class CssDependencyFilter < FileReferenceFilter
6
+
7
+ def handles_file(file)
8
+ return [".css"].include?(file.extension)
9
+ end
10
+
11
+ def preprocess_content(file, content)
12
+ # Replace all ' (single quotes) with " (double quotes) in
13
+ # order to fix a problem with the background url regexp
14
+ content.gsub!(/\'/,'"')
15
+ # Force a newline after a rule terminating ; (semi-colon)
16
+ # in order to fix a problem with the background url regexp
17
+ content.gsub!(/;(\n|\r)*/, ";\n")
18
+
19
+ # Rewrites the 'url("...")' rules to a relative path
20
+ # based on the location of the new concatenated CSS file.
21
+ line_num=0
22
+
23
+ lines= content.split("\n")
24
+
25
+ lines.each { |line|
26
+
27
+ line_num+=1
28
+
29
+ line.gsub!(/@import\s+url\("?(.*\.css)"?\)/) { |match|
30
+ css_file= File.join(file.parent_folder, $1)
31
+
32
+ if (!File.exists?(css_file))
33
+ file.error "imported CSS file not found: #{$1}", line_num
34
+ # leave the @import rule in place
35
+ match
36
+ else
37
+ file.add_dependency(SourceFile.from_path(css_file))
38
+ end
39
+ }
40
+
41
+ line.gsub!(/url\("?(.*\.(jpg|png|gif))"?\)/) { |match|
42
+ image_file= File.join(file.parent_folder, $1)
43
+
44
+ if (!File.exists?(image_file))
45
+ file.warning "resource not found: #{$1} (#{image_file})", line_num
46
+ "url(\"#{$1}\")"
47
+ else
48
+ asset= SourceFile.from_path(image_file)
49
+ file.add_asset(asset)
50
+ "url(\"#{file_reference(asset)}\")"
51
+ end
52
+ }
53
+ }
54
+
55
+ lines.join("\n")
56
+ end
57
+
58
+ end
@@ -0,0 +1,30 @@
1
+ class FileReferenceFilter < Filter
2
+
3
+ def file_reference(file)
4
+ "{{FILEREF(#{file})}}"
5
+ end
6
+
7
+ def content_reference(file)
8
+ "{{CONTENTREF(#{file})}}"
9
+ end
10
+
11
+ def filter_content(file, content, options)
12
+ destination= File.expand_path(options.remove_prefix||"")
13
+
14
+ content.gsub!(/\{\{FILEREF\(([^)]*)\)\}\}/) { |match|
15
+ include_file= SourceFile.from_path($1)
16
+ include_file.relative_to_folder(destination)
17
+ }
18
+
19
+ content.gsub!(/\{\{CONTENTREF\(([^)]*)\)\}\}/) { |match|
20
+ include_file= SourceFile.from_path($1)
21
+ included_content= include_file.filtered_content(options)
22
+ included_content= include_file.minify_content(included_content)
23
+ file.escape_embeded_content(included_content)
24
+ }
25
+
26
+ content
27
+ end
28
+
29
+
30
+ end
@@ -0,0 +1,44 @@
1
+ $jsl_import_regex= /\/\*jsl:import\s+([^\*]*)\*\//
2
+
3
+ class JslDependencyFilter < Filter
4
+
5
+ def handles_file(file)
6
+ return [".js"].include?(file.extension)
7
+ end
8
+
9
+ def preprocess_content(file, content)
10
+
11
+ content= content.split("\n")
12
+
13
+ line_num=0
14
+
15
+ content.each { |line|
16
+
17
+ line_num+=1
18
+
19
+ # handle dependencies
20
+ line.gsub!($jsl_import_regex) { |match|
21
+
22
+ import_file= File.expand_path(File.join(file.parent_folder, $1))
23
+ if (File.exists?(import_file))
24
+ file.add_dependency SourceFile.from_path(import_file)
25
+ else
26
+ dependency= Project.current.find_file($1)
27
+ if (dependency)
28
+ file.add_dependency SourceFile.from_path(import_file)
29
+ else
30
+ file.error "Missing import file: #{$1}", line_num
31
+ end
32
+ end
33
+
34
+ # replace jsl import with empty string
35
+ ""
36
+
37
+ }
38
+
39
+ }
40
+
41
+ content.join("\n")
42
+ end
43
+
44
+ end
data/lib/project.rb CHANGED
@@ -20,6 +20,7 @@ class Project < Configurable
20
20
  option :external_projects
21
21
 
22
22
  def initialize(project_file, settings)
23
+ @@current= self
23
24
  @project_file= File.expand_path(project_file)
24
25
  Dir.chdir(File.dirname(@project_file))
25
26
 
@@ -27,7 +28,26 @@ class Project < Configurable
27
28
  settings.merge!(project_info)
28
29
  super(settings)
29
30
  end
30
-
31
+
32
+ @@current=nil
33
+ def self.current
34
+ @@current
35
+ end
36
+
37
+ def find_file(file)
38
+ return nil if external_projects.nil?
39
+
40
+ external_projects.each { |project|
41
+ path= File.expand_path(File.join(project["include"], file))
42
+ if (File.exists?(path))
43
+ source_file= SourceFile.from_path(path)
44
+ source_file.file_path= file
45
+ return source_file
46
+ end
47
+ }
48
+ nil
49
+ end
50
+
31
51
  def build_external_projects
32
52
  projects= external_projects
33
53
  if (projects.nil?)
@@ -94,8 +114,6 @@ class Project < Configurable
94
114
  }
95
115
 
96
116
  @options.external_projects= projects
97
-
98
- puts "external_projects=#{external_projects.inspect}"
99
117
  end
100
118
 
101
119
  def build_targets
data/lib/source-file.rb CHANGED
@@ -9,8 +9,8 @@ class SourceFile
9
9
  @full_path= File.expand_path(filepath)
10
10
 
11
11
  @parent_folder= File.dirname(@full_path)
12
- @dependencies= Array.new
13
- @assets= Array.new
12
+ @dependencies= []
13
+ @assets= []
14
14
 
15
15
  @@file_cache[@full_path]= self
16
16
  end
@@ -31,11 +31,14 @@ class SourceFile
31
31
  self.class.extension
32
32
  end
33
33
 
34
- def can_embed_as_content
34
+ def can_embed_as_content(file)
35
35
  false
36
36
  end
37
37
 
38
- def minify_content_type
38
+ def content_type
39
+ ext= self.extension
40
+ return if !ext
41
+ ext[1..-1]
39
42
  end
40
43
 
41
44
  @@file_types= []
@@ -81,21 +84,39 @@ class SourceFile
81
84
  end
82
85
 
83
86
  def file_path
84
- @file_path || self.relative_to_folder(@@root_folder)
87
+ @file_path
85
88
  end
86
89
 
87
90
  def file_path=(path)
88
91
  @file_path=path
89
92
  end
90
93
 
91
- def has_file_path
92
- @file_path
94
+ def load_content
95
+ content= File.read(@full_path)
96
+ Filter.each { |f|
97
+ next if !f.handles_file(self)
98
+ content= f.preprocess_content(self, content)
99
+ }
100
+ content
101
+ end
102
+
103
+ def escape_embeded_content(content)
104
+ content
93
105
  end
94
106
 
95
107
  def content
96
- @content ||= File.read(@full_path)
108
+ @content ||= load_content
97
109
  end
98
110
 
111
+ def filtered_content(options)
112
+ c= content || ""
113
+ Filter.each { |f|
114
+ next if !f.handles_file(self)
115
+ c= f.filter_content(self, c, options)
116
+ }
117
+ "#{c}\n"
118
+ end
119
+
99
120
  def content_relative_to_destination(destination)
100
121
  content.gsub(/\{\{FILEREF\(([^)]*)\)\}\}/) { |match|
101
122
  file= SourceFile.from_path($1)
@@ -103,23 +124,23 @@ class SourceFile
103
124
  }
104
125
  end
105
126
 
106
- def debug_content_relative_to_destination(destination)
107
- self.content_relative_to_destination(destination)
127
+ def debug_content(options)
128
+ self.filtered_content(options)
108
129
  end
109
130
 
110
131
  def minify_content(source)
111
132
  # Run the Y!UI Compressor
112
- return source if !minify_content_type
133
+ return source if !content_type
113
134
  buffer= ""
114
135
 
115
- IO.popen("java -jar #{$compressor} --type #{minify_content_type}", "r+") { |pipe|
136
+ IO.popen("java -jar #{$compressor} --type #{content_type}", "r+") { |pipe|
116
137
  pipe.puts(source)
117
138
  pipe.close_write
118
139
  buffer= pipe.read
119
140
  }
120
141
 
121
142
  # buffer = `java -jar #{$compressor} --type #{type} #{working_file}`
122
- if ('css'==minify_content_type)
143
+ if ('css'==content_type)
123
144
  # puts each rule on its own line, and deletes @import statements
124
145
  return buffer.gsub(/\}/,"}\n").gsub(/.*@import url\(\".*\"\);/,'')
125
146
  else
@@ -154,19 +175,26 @@ class SourceFile
154
175
  end
155
176
 
156
177
  def dependencies
157
- # make certain the content is loaded
158
- self.content
178
+ content
159
179
  @dependencies
160
180
  end
161
181
 
182
+ def add_dependency(file)
183
+ return if @dependencies.include?(file)
184
+ @dependencies << file
185
+ end
186
+
162
187
  def assets
163
- # make certain the content is loaded
164
- self.content
188
+ content
165
189
  @assets
166
190
  end
167
191
 
168
- def copy_to(folder)
169
- file_path= self.file_path
192
+ def add_asset(file)
193
+ @assets << file
194
+ end
195
+
196
+ def copy_to(folder, prefix)
197
+ file_path= self.file_path || relative_to_folder(prefix||"")
170
198
  final_target_folder= File.join(folder, File.dirname(file_path))
171
199
  FileUtils.mkdir_p final_target_folder
172
200
  FileUtils.cp self.full_path, final_target_folder
data/lib/target.rb CHANGED
@@ -8,10 +8,10 @@ class Target < Configurable
8
8
 
9
9
  def initialize(name, settings, project)
10
10
  super(settings, project)
11
-
11
+
12
+ @@current= self
12
13
  @project= project
13
14
  @target_name= name
14
- @@current= self
15
15
 
16
16
  @tasks= []
17
17
 
@@ -25,6 +25,7 @@ class Target < Configurable
25
25
  @error_count=0
26
26
  end
27
27
 
28
+ @@current=nil
28
29
  def self.current
29
30
  @@current
30
31
  end
@@ -56,18 +57,6 @@ class Target < Configurable
56
57
  products
57
58
  end
58
59
 
59
- def find_file(file)
60
- external_projects.each { |project|
61
- path= File.expand_path(File.join(project["include"], file))
62
- if (File.exists?(path))
63
- source_file= SourceFile.from_path(path)
64
- source_file.file_path= file
65
- return source_file
66
- end
67
- }
68
- nil
69
- end
70
-
71
60
  def process_files
72
61
  @tasks.each { |t|
73
62
  t.find_files
data/lib/task.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require "#{$script_dir}/filter"
1
2
  require "#{$script_dir}/source-file"
2
3
  require "#{$script_dir}/file-set"
3
4
  require 'set'
@@ -96,6 +97,10 @@ class Task < Configurable
96
97
  @probed= Set.new
97
98
  @included_files= []
98
99
  @files_to_include.each { |i| include_file(i) }
100
+
101
+ files= @included_files.map { |f|
102
+ f.to_s
103
+ }
99
104
  end
100
105
 
101
106
  def products
@@ -104,7 +109,7 @@ class Task < Configurable
104
109
 
105
110
  def need_to_build
106
111
  return @need_to_build if !@need_to_build.nil?
107
-
112
+
108
113
  product_modification_times= products.map { |p|
109
114
  p=File.expand_path(p)
110
115
  return (@need_to_build=true) if !File.exists?(p)
@@ -138,13 +143,13 @@ class Task < Configurable
138
143
  folders= []
139
144
 
140
145
  assets.each { |a|
141
- path= a.has_file_path ? a.file_path : a.relative_to_folder(full_root_path)
146
+ path= a.file_path || a.relative_to_folder(full_root_path)
142
147
 
143
148
  parts= File.dirname(path).split(File::SEPARATOR)
144
149
  if ('.'==parts[0])
145
150
  target_path= File.join(output_folder, path)
146
151
  FileUtils.rm target_path if File.exists? target_path
147
- File.symlink a.full_path, target_path
152
+ File.symlink a.relative_to_folder(output_folder), target_path
148
153
  next
149
154
  end
150
155
 
@@ -161,9 +166,11 @@ class Task < Configurable
161
166
  folders.each { |f|
162
167
  # puts "#{File.join(remove_prefix, f)} => #{File.join(output_folder, f)}"
163
168
  src_folder= remove_prefix ? File.join(remove_prefix, f) : f
169
+ src_folder= SourceFile.path_relative_to_folder(File.expand_path(src_folder), output_folder)
170
+
164
171
  target_folder= File.expand_path(File.join(output_folder, f))
165
172
  next if File.exists?(target_folder)
166
- File.symlink File.expand_path(src_folder), target_folder
173
+ File.symlink src_folder, target_folder
167
174
  }
168
175
 
169
176
  # puts "#{task_name}: folder=#{folders.inspect}"
@@ -171,7 +178,7 @@ class Task < Configurable
171
178
 
172
179
  def copy_assets
173
180
  assets.each { |a|
174
- a.copy_to(output_folder)
181
+ a.copy_to(output_folder, remove_prefix)
175
182
  }
176
183
  end
177
184
 
@@ -23,6 +23,14 @@ class JavascriptTask < SingleOutputTask
23
23
  "js"
24
24
  end
25
25
 
26
+ def initialize(target, options)
27
+ super(target, options)
28
+
29
+ if (generate_docs)
30
+ @products << File.join(doc_folder, "index.html")
31
+ end
32
+ end
33
+
26
34
  # JsTask handles files that end in .js
27
35
  def handles_file?(file_name)
28
36
  "#{file_name}"[/\.js$/]
@@ -82,7 +90,7 @@ class JavascriptTask < SingleOutputTask
82
90
 
83
91
  def document_files()
84
92
 
85
- return if (!@options.generate_docs)
93
+ return if (!generate_docs)
86
94
  return if (!File.exists?($jsdoc_command))
87
95
 
88
96
  tmp= Tempfile.new("jsdoc.conf")
@@ -92,9 +100,9 @@ class JavascriptTask < SingleOutputTask
92
100
 
93
101
  conf= replace_tokens(template, {
94
102
  "DOC_FILES"=>doc_files.join(",\n"),
95
- "DOC_OUTPUT_DIR"=>@options.doc_folder,
96
- "DOC_TEMPLATE_DIR"=>@options.jsdoc_template,
97
- "DOC_PLUGINS_DIR"=>@options.jsdoc_plugins
103
+ "DOC_OUTPUT_DIR"=>doc_folder,
104
+ "DOC_TEMPLATE_DIR"=>jsdoc_template,
105
+ "DOC_PLUGINS_DIR"=>jsdoc_plugins
98
106
  })
99
107
 
100
108
  tmp << conf
@@ -48,18 +48,16 @@ class MultipleOutputTask < OutputTask
48
48
  concat= ""
49
49
  debug= ""
50
50
 
51
- destination= File.expand_path(remove_prefix||"")
52
-
53
51
  file.dependencies.each { |depend|
54
52
  next if !@files_to_include.include?(depend)
55
53
  next if @files_to_exclude.include?(depend)
56
54
 
57
- concat << depend.content_relative_to_destination(destination)
58
- debug << depend.debug_content_relative_to_destination(destination)
55
+ concat << depend.filtered_content(options)
56
+ debug << depend.debug_content(options)
59
57
  }
60
58
 
61
- concat << file.content_relative_to_destination(destination)
62
- debug << file.debug_content_relative_to_destination(destination)
59
+ concat << file.filtered_content(options)
60
+ debug << file.debug_content(options)
63
61
 
64
62
  @concat[file]= concat
65
63
  @debug[file]= debug
@@ -1,4 +1,4 @@
1
- require "#{$script_dir}/tasks/output-task.rb"
1
+ require "#{$script_dir}/tasks/multiple-output-task.rb"
2
2
  require "#{$script_dir}/tasks/javascript-task.rb"
3
3
 
4
4
  class NibTask < MultipleOutputTask
@@ -29,10 +29,9 @@ class SingleOutputTask < OutputTask
29
29
  end
30
30
 
31
31
  def process_files
32
- destination= File.expand_path(remove_prefix||"")
33
32
  @included_files.each { |f|
34
- @concat << f.content_relative_to_destination(destination)
35
- @debug << f.debug_content_relative_to_destination(destination)
33
+ @concat << f.filtered_content(options)
34
+ @debug << f.debug_content(options)
36
35
  }
37
36
  end
38
37
 
@@ -50,7 +49,7 @@ class SingleOutputTask < OutputTask
50
49
  params= {
51
50
  "VERSION"=>@options.version
52
51
  }
53
-
52
+
54
53
  concat= replace_tokens(@concat, params)
55
54
 
56
55
  File.open(@name_concat, "w") { |f|
@@ -1,3 +1,4 @@
1
+ /*jsl:declare JSDOC*/
1
2
  JSDOC.PluginManager.registerPlugin("DistilPlugin", {
2
3
 
3
4
  onFunctionCall: function (functionCall)
@@ -5,6 +6,7 @@ JSDOC.PluginManager.registerPlugin("DistilPlugin", {
5
6
  switch (functionCall.name)
6
7
  {
7
8
  case 'Class.create':
9
+ case 'Class._create':
8
10
  this.onClassCreate(functionCall);
9
11
  break;
10
12
 
@@ -136,6 +138,7 @@ JSDOC.PluginManager.registerPlugin("DistilPlugin", {
136
138
  tag.desc= tag.nibbleType(tag.desc);
137
139
  tag.desc= tag.nibbleName(tag.desc);
138
140
  break;
141
+
139
142
  }
140
143
  }
141
144
 
@@ -0,0 +1,16 @@
1
+ {+data.node.link+}
2
+ <if test="data.node.namespaces && data.node.namespaces.length">
3
+ <ul class="namespaces">
4
+ <for each="namespace" in="data.node.namespaces">
5
+ <li>{+publishClassListNamespace(data, namespace)+}</li>
6
+ </for>
7
+ </ul>
8
+ </if>
9
+
10
+ <if test="data.node.symbols && data.node.symbols.length">
11
+ <ul class="classes">
12
+ <for each="symbol" in="data.node.symbols">
13
+ <li>{+symbol.link+}</li>
14
+ </for>
15
+ </ul>
16
+ </if>
@@ -0,0 +1,4 @@
1
+ {
2
+ name: "{+data.node.name+}",
3
+ link: "{+data.node.linkHref+}"
4
+ }
@@ -0,0 +1,20 @@
1
+ <if test="data.node">
2
+ {
3
+ name: "{+data.node.name+}",
4
+ link: "{+data.node.linkHref+}"
5
+ <if test="data.node.symbols && data.node.symbols.length">
6
+ symbols: [
7
+ <for each="symbol" in="data.node.symbols">
8
+ {+publishJsonSymbol(data, symbol)+},
9
+ </for>
10
+ ],
11
+ </if>
12
+ <if test="data.node.namespaces && data.node.namespaces.length">
13
+ namespaces: [
14
+ <for each="namespace" in="data.node.namespaces">
15
+ {+publishJsonSymbol(data, namespace)+},
16
+ </for>
17
+ ]
18
+ </if>
19
+ }
20
+ </if>
@@ -69,7 +69,14 @@ function publish(symbolSet) {
69
69
 
70
70
  // create a class index, displayed in the left-hand column of every class page
71
71
  Link.base = "../";
72
- publish.classesIndex = classesTemplate.process(classes); // kept in memory
72
+
73
+ var summary= generateJsonSummary(symbols);
74
+
75
+ // publish.classesIndex = classesTemplate.process(classes); // kept in memory
76
+ publish.classesIndex = publishClassListSummary(summary); // kept in memory
77
+
78
+ var classesJson= publishJsonSummary(summary);
79
+ IO.saveFile(publish.conf.outDir, "all-classes.json", classesJson);
73
80
 
74
81
  // create each of the class pages
75
82
  for (i = 0, l = classes.length; i < l; i++) {
@@ -240,3 +247,117 @@ function copyFile(file, destFolder)
240
247
 
241
248
  IO.copyFile(file, destFolder);
242
249
  }
250
+
251
+ function generateJsonSummary(symbols)
252
+ {
253
+ var namespaces= {};
254
+
255
+ var global;
256
+ var hrefRegex= /href="([^"]*)"/;
257
+
258
+ symbols.forEach(function(symbol) {
259
+ var parentNamespace= namespaces[symbol.memberOf || "_global_"];
260
+ if (!symbol.isNamespace && !symbol.is("CONSTRUCTOR"))
261
+ return;
262
+ var link= new Link().toClass(symbol.alias).withText(symbol.name).toString();
263
+ var linkHref= link.match(hrefRegex)[1];
264
+
265
+ if (!symbol.isNamespace)
266
+ {
267
+ var classInfo= {
268
+ name: symbol.name,
269
+ isa: "CLASS",
270
+ linkHref: linkHref,
271
+ link: link
272
+ };
273
+ // if (!parentNamespace)
274
+ // print("missing parent namespace: " + (symbol.memberOf || "_global_"));
275
+ if (parentNamespace)
276
+ parentNamespace.symbols.push(classInfo);
277
+ return;
278
+ }
279
+
280
+ var namespace= namespaces[symbol.alias]= {
281
+ name: symbol.name,
282
+ isa: "NAMESPACE",
283
+ linkHref: linkHref,
284
+ link: link,
285
+
286
+ // symbol: symbol,
287
+ namespaces: [],
288
+ symbols: []
289
+ };
290
+
291
+ if ('_global_'===symbol.name)
292
+ global= namespace;
293
+
294
+ // Link to parent
295
+ // if (!parentNamespace)
296
+ // print("missing parent namespace: " + (symbol.memberOf || "_global_"));
297
+ if (parentNamespace)
298
+ parentNamespace.namespaces.push(namespace);
299
+ });
300
+
301
+ // sort the namespaces and symbols
302
+ var sorter=makeSortby("name");
303
+
304
+ for (var name in namespaces)
305
+ {
306
+ namespace= namespaces[name];
307
+ namespace.symbols= namespace.symbols.sort(sorter);
308
+ namespace.namespaces= namespace.namespaces.sort(sorter);
309
+ }
310
+
311
+ return global;
312
+ }
313
+
314
+ function publishJsonSummary(summary)
315
+ {
316
+ var namespaceTemplate= new JSDOC.JsPlate(publish.conf.templatesDir+"namespace-json.tmpl");
317
+ var classTemplate= new JSDOC.JsPlate(publish.conf.templatesDir+"class-json.tmpl");
318
+
319
+ var data= {
320
+ namespaceTemplate: namespaceTemplate,
321
+ classTemplate: classTemplate,
322
+ symbolTemplate: classTemplate,
323
+ node: summary
324
+ };
325
+
326
+ return namespaceTemplate.process(data);
327
+ }
328
+
329
+ function publishJsonSymbol(data, node)
330
+ {
331
+ var newData= {};
332
+ for (var p in data)
333
+ newData[p]= data[p];
334
+ newData.node= node;
335
+ if ("NAMESPACE"===node.isa)
336
+ return data.namespaceTemplate.process(newData);
337
+ else
338
+ return data.symbolTemplate.process(newData);
339
+ }
340
+
341
+ function publishClassListSummary(summary)
342
+ {
343
+ var namespaceTemplate= new JSDOC.JsPlate(publish.conf.templatesDir+"all-classes.tmpl");
344
+
345
+ var data= {
346
+ namespaceTemplate: namespaceTemplate,
347
+ node: summary
348
+ };
349
+
350
+ return namespaceTemplate.process(data);
351
+ }
352
+
353
+ function publishClassListNamespace(data, node)
354
+ {
355
+ var newData= {};
356
+ for (var p in data)
357
+ newData[p]= data[p];
358
+ newData.node= node;
359
+ if ("NAMESPACE"===node.isa)
360
+ return data.namespaceTemplate.process(newData);
361
+ else
362
+ return data.symbolTemplate.process(newData);
363
+ }
@@ -131,6 +131,16 @@ pre.code
131
131
  margin: 20px 0 0 0;
132
132
  }
133
133
 
134
+ #index ul
135
+ {
136
+ margin-left: 10px;
137
+ }
138
+
139
+ #index ul.namespaces + ul.classes
140
+ {
141
+ margin-top: 20px;
142
+ }
143
+
134
144
  #content
135
145
  {
136
146
  margin-left: 300px;
@@ -94,6 +94,8 @@ JSDOC.JsPlate.prototype.process = function(data, compact) {
94
94
  if (e.lineNumber-2 >= 0) print("line "+(e.lineNumber-1)+": "+lines[e.lineNumber-2]);
95
95
  print("line "+e.lineNumber+": "+lines[e.lineNumber-1]);
96
96
  print("");
97
+
98
+ print(this.code);
97
99
  }
98
100
 
99
101
  if (compact) { // patch by mcbain.asm
@@ -406,7 +406,7 @@ JSDOC.Walker.prototype.step = function() {
406
406
 
407
407
  name = "$anonymous";
408
408
  name = this.namescope.last().alias+"-"+name
409
-
409
+
410
410
  params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
411
411
 
412
412
  symbol = new JSDOC.Symbol(name, params, "FUNCTION", doc);
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env sh
2
2
 
3
3
  # launcher script for jsdoc
4
4
  # Author: Avi Deitcher
@@ -48,6 +48,5 @@ else
48
48
  fi
49
49
 
50
50
  CMD="java $_DOCDIR $_TDIR -jar $_BASEDIR/jsrun.jar $_APPDIR/run.js $@"
51
- echo $CMD
52
51
  $CMD
53
52
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: distil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Watkins
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-22 00:00:00 -08:00
12
+ date: 2010-01-11 00:00:00 -08:00
13
13
  default_executable: distil
14
14
  dependencies: []
15
15
 
@@ -34,6 +34,11 @@ files:
34
34
  - lib/file-types/javascript-file.rb
35
35
  - lib/file-types/json-file.rb
36
36
  - lib/file-types/nib-file.rb
37
+ - lib/filter.rb
38
+ - lib/filters/coherent-asset-filter.rb
39
+ - lib/filters/css-filter.rb
40
+ - lib/filters/file-reference-filter.rb
41
+ - lib/filters/jsl-dependency-filter.rb
37
42
  - lib/jsdoc.conf
38
43
  - lib/jsl.conf
39
44
  - lib/project.rb
@@ -59,10 +64,13 @@ files:
59
64
  - vendor/extconf.rb
60
65
  - vendor/jsdoc-extras/plugins/distil-plugin.js
61
66
  - vendor/jsdoc-extras/plugins/interface-plugin.js
67
+ - vendor/jsdoc-extras/templates/coherent/all-classes.tmpl
62
68
  - vendor/jsdoc-extras/templates/coherent/allclasses.tmpl
63
69
  - vendor/jsdoc-extras/templates/coherent/allfiles.tmpl
70
+ - vendor/jsdoc-extras/templates/coherent/class-json.tmpl
64
71
  - vendor/jsdoc-extras/templates/coherent/class.tmpl
65
72
  - vendor/jsdoc-extras/templates/coherent/index.tmpl
73
+ - vendor/jsdoc-extras/templates/coherent/namespace-json.tmpl
66
74
  - vendor/jsdoc-extras/templates/coherent/publish.js
67
75
  - vendor/jsdoc-extras/templates/coherent/showdown.js
68
76
  - vendor/jsdoc-extras/templates/coherent/static/code-footer.html