distil 0.8.0 → 0.8.1

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.
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