jazzy 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: debc2610dfdacc28a580056ac62cfffdb0819402
4
- data.tar.gz: 4a2d884071430d1581dbd971bd17ca43b51fa3df
3
+ metadata.gz: 4693be658ce9c28ddc98fdc398e26db8bc48d5c8
4
+ data.tar.gz: 2fd530bafb0099d145e8c07c2c34580f086aa79f
5
5
  SHA512:
6
- metadata.gz: 4ef4bcac8aa9ec3a757ccd5c6b3c7b50fa5b29ca2b0e960e0084fa1233780af3605dc39064a51f516612afed4cca24b046e52bee09ae44bfb9bdf1865bf9ae77
7
- data.tar.gz: f4a8965fc8c61270f9e156c431d0ad6ba600fc0c91f753c3964f3f9a5b8bbc8bacc3c0961987c8a5f899f75517f8e0c0f9163f505e97aac051745c95b6720c08
6
+ metadata.gz: ad9e58a8fd88262f1671ecd3394a970cd1d3a52f4a0b66798f64f0f77a715cae87702cea614ffc6bff235a026004d243bc699e1e33a9c7405a53040aaba29e0e
7
+ data.tar.gz: ee54d025fafa17e307eb2b2a9de639cc866a70ef799ce8ba1134130a93044c7d08c1ecd0a77504227f027e1e5b7327c2685be9ad363f7b91e5f4aa270c3ec216
@@ -0,0 +1,35 @@
1
+ # Building jazzy
2
+
3
+ jazzy is composed of two parts: the parser (written in C++) and the site generator (written in ruby). This guide will allow you to build both components.
4
+
5
+ ## Requirements
6
+
7
+ * [Xcode 6 (Beta 2)](https://developer.apple.com/xcode)
8
+ * `xcode-select -p` should print Xcode 6's path. If it doesn't, run `sudo xcode-select -s /Applications/Xcode6-Beta2.app/Contents/Developer`
9
+ * [bundler](http://rubygems.org/gems/bundler)
10
+
11
+ ## Building ASTDump
12
+
13
+ Unlike many other tools built using Clang, ASTDump doesn't require building the entirety of LLVM and Clang from source. Instead, ASTDump links against libclang, so builds take seconds, not hours.
14
+
15
+ To build ASTDump, open `parser/ASTDump.xcodeproj` and hit `⌘+B`.
16
+
17
+ Then, move the resulting ASTDump binary to `bin/ASTDump`. This will make it available to the site generator portion of jazzy.
18
+
19
+ ## Building & Running jazzy
20
+
21
+ Run `bundle install` from the command line. This will install all the gems required to run jazzy.
22
+
23
+ To run jazzy locally, use the following command: `ruby -Ilib bin/jazzy`. This instructs ruby to load the local `lib` directory, which will cause jazzy to find all its necessary file dependencies.
24
+
25
+ To run jazzy on the sample input files located in `sample/`, run `ruby -Ilib bin/jazzy -i sample`. This will generate a `docs/` directory with the following structure:
26
+
27
+ ```
28
+ docs/
29
+ CSS/
30
+ Images/
31
+ JAZMusician.html
32
+ JavaScript/
33
+ ```
34
+
35
+ To run on any codebase, set the input argument (`-i`) to the directory containing your header files. i.e. `ruby -Ilib bin/jazzy -i /path/to/my/header/files`.
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem "mustache", "~> 0.99.5"
5
+ gem "activesupport", "~> 4.1.1"
6
+ gem "redcarpet", "~> 3.1.2"
7
+ gem "nokogiri", "~> 1.6.2.1"
8
+
9
+ gem "bundler", "~> 1.5"
10
+ gem "rake"
11
+ end
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (4.1.4)
5
+ i18n (~> 0.6, >= 0.6.9)
6
+ json (~> 1.7, >= 1.7.7)
7
+ minitest (~> 5.1)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 1.1)
10
+ i18n (0.6.9)
11
+ json (1.8.1)
12
+ mini_portile (0.6.0)
13
+ minitest (5.3.5)
14
+ mustache (0.99.5)
15
+ nokogiri (1.6.2.1)
16
+ mini_portile (= 0.6.0)
17
+ rake (10.3.2)
18
+ redcarpet (3.1.2)
19
+ thread_safe (0.3.4)
20
+ tzinfo (1.2.1)
21
+ thread_safe (~> 0.1)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ activesupport (~> 4.1.1)
28
+ bundler (~> 1.5)
29
+ mustache (~> 0.99.5)
30
+ nokogiri (~> 1.6.2.1)
31
+ rake
32
+ redcarpet (~> 3.1.2)
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ## jazzy <sup>♪♫</sup>
2
- **a soulful way to generate docs for Swift & Objective-C**
2
+ **a soulful way to generate docs for Swift & Objective-C** ![analytics](https://ga-beacon.appspot.com/UA-50247013-2/jazzy/README?pixel)
3
3
 
4
4
  jazzy is a command-line utility that generates documentation for your Swift or Objective-C projects.
5
5
 
@@ -7,9 +7,12 @@ Instead of parsing your source files, jazzy hooks into clang and uses the [AST][
7
7
 
8
8
  jazzy’s output matches the look & feel of Apple’s official reference documentation, post WWDC 2014.
9
9
 
10
+ ![Screenshot](screenshot.jpg)
11
+
10
12
  ### Requirements
11
13
 
12
- Jazzy requires [Xcode 6 Beta](https://developer.apple.com/xcode/) to run.
14
+ * [Xcode 6 (Beta 2)](https://developer.apple.com/xcode)
15
+ * `xcode-select -p` should print Xcode 6's path. If it doesn't, run `sudo xcode-select -s /Applications/Xcode6-Beta2.app/Contents/Developer`
13
16
 
14
17
  ### Installing
15
18
 
@@ -19,31 +22,6 @@ To install jazzy, run `[sudo] gem install jazzy` from your command line.
19
22
 
20
23
  Run `jazzy` from your command line. Run `jazzy -h` for a list of additional options.
21
24
 
22
- ### Front-End TODO
23
-
24
- - Index generation
25
- - Instance/class method distinction
26
- - Class inheritance, conforms, import, availability
27
- - Syntax Highlighting
28
- - Cross-linking
29
- - Search in page
30
- - Handle availability options
31
- - Inline code examples
32
- - Unit tests
33
- - Lists (unordered/ordered)
34
- - Generate docsets for Dash & Xcode
35
- - Pass in arbitrary Mustache templates
36
-
37
- ### Parsing TODO
38
-
39
- - Swift files
40
- - `@name`
41
- - `@warning`
42
- - `@see`
43
- - Unit tests
44
- - Enum's
45
- - Instance variables
46
-
47
25
  ### Design Goals
48
26
 
49
27
  jazzy's main design goals are:
@@ -53,10 +31,10 @@ jazzy's main design goals are:
53
31
  - High readability of source code comments
54
32
  - Leverage modern HTML templating ([Mustache](http://mustache.github.io))
55
33
  - Leverage the power and accuracy of the [Clang AST][ast]
56
- - Compatibility with [appldoc](https://github.com/tomaz/appledoc) when possible
34
+ - Compatibility with [appledoc](https://github.com/tomaz/appledoc) when possible
57
35
 
58
36
  ### License
59
37
 
60
38
  This project is under the MIT license.
61
39
 
62
- [ast]: http://clang.llvm.org/docs/IntroductionToTheClangAST.html "Introduction To The Clang AST"
40
+ [ast]: http://clang.llvm.org/docs/IntroductionToTheClangAST.html "Introduction To The Clang AST"
@@ -0,0 +1,14 @@
1
+ #!/bin/sh
2
+
3
+ # Generate temporary swift module map
4
+ header_file=$1
5
+ module_name='TempJazzyModule'
6
+ module_file='module.modulemap'
7
+ echo "module $module_name { header \"$header_file\" }" > $module_file
8
+
9
+ # Print generated Swift header
10
+ # See also -req=interface-gen
11
+ xcrun sourcekitd-test -req=doc-info -module $module_name -- -I `pwd` -sdk `xcrun --show-sdk-path`
12
+
13
+ # Remove temporary module file
14
+ rm $module_file
@@ -1,14 +1,14 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Jazzy
4
- VERSION = '0.0.3'
4
+ VERSION = '0.0.4'
5
5
  end
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = "jazzy"
9
9
  spec.version = Jazzy::VERSION
10
10
  spec.authors = ["JP Simard, Tim Anglade"]
11
- spec.email = ["jp@jpsim.com"]
11
+ spec.email = ["jp@realm.io"]
12
12
  spec.summary = %q{A soulful way to generate docs for Swift & Objective-C}
13
13
  spec.description = %q{A soulful way to generate docs for Swift & Objective-C}
14
14
  spec.homepage = "http://github.com/realm/jazzy"
@@ -24,4 +24,4 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.5"
26
26
  spec.add_development_dependency "rake"
27
- end
27
+ end
@@ -1,157 +1,150 @@
1
1
  class Jazzy
2
- def self.headers(path)
3
- paths = []
4
- Find.find(path) do |path|
5
- if (path =~ /.*\.h$/) and not (path =~ /.*private\.h$/i) and not (path =~ /test.*\//i)
6
- paths << File.expand_path(path)
7
- end
8
- end
9
- return paths
10
- end
11
-
12
- def self.document(path)
13
- bin_path = File.expand_path(File.join( File.dirname(__FILE__),'../bin'))
14
-
15
- klass = Jazzy::Klass.new
16
-
17
- string = `#{bin_path}/SwiftHeader #{path}`
18
- a = string.split(/^\[/); swift = a[0]; rawmap = "[\n"+a[-1]
19
-
20
- rawmap.gsub!(/(key.\w+):/,'"\1":')
21
- rawmap.gsub!(/(source..+),/,'"\1",')
22
-
23
-
24
- xml = `#{bin_path}/ASTDump #{path}`
25
-
26
- doc = Nokogiri::XML(xml)
27
-
28
- results = doc.xpath("//*[@file='#{path}']")
29
-
30
- #results = doc.find_all { |node| node.attribute("file") && node.attribute("file").strip.chomp == path.strip.chomp }
31
- # Fill in Overview
32
- top = results.first
33
- #next if e.attribute("file") && e.attribute("file").text != path
34
- #print top
35
- #exit
36
- klass[:name] = top.xpath("Name").text
37
- klass[:usr] = top.xpath("USR").text
38
- klass[:declaration] = {}
39
- klass[:declaration][:objc] = top.xpath("Declaration").text.strip
40
- klass[:abstract] = top.xpath("Abstract/Para").text.strip
41
- paras = []; top.xpath("./Discussion/Para").each {|p| paras << p.text.strip }
42
- klass[:discussion] = paras.join("\n\n")
43
-
44
- # Only usable if Swift Header can be correctly generated
45
- unless rawmap.include? "<<NULL>>"
46
-
47
- swiftmap = {}
48
- map = {}
49
-
50
- JSON.parse(rawmap).each do |element|
51
-
52
- next unless element["key.name"].downcase == klass[:name].downcase
53
-
54
- # more than one matching element?
55
-
56
- element["key.entities"].each do |e|
57
- swiftmap[e["key.usr"]] = {}
58
- swiftmap[e["key.usr"]]["declaration"] = swift.byteslice(e["key.offset"], e["key.length"])
59
- swiftmap[e["key.usr"]]["name"] = e["key.name"]
60
- end
61
-
62
- # Inherits
63
- klass[:inherits] = []
64
- element["key.inherits"].each { |i| klass[:inherits] << { usr: i["key.usr"], name: i["key.name"] } } unless map["key.inherits"].nil?
65
-
66
- # Conforms to
67
- klass[:conforms] = []
68
- element["key.conforms"].each { |c| klass[:conforms] << { usr: c["key.usr"], name: c["key.name"] } } unless map["key.conforms"].nil?
69
- end
70
- end
71
-
72
-
73
-
74
-
75
- # Import
76
- klass[:import] = swift.split("\n")[0].chomp.gsub('import ', '')
77
-
78
- # Fill in Properties
79
- klass[:properties] = []
80
-
81
- results[1..-1].each do |e|
82
- next unless e.name == "Other"
83
- property = {}
84
- property[:usr] = e.xpath("USR").text
85
- property[:name] = {}
86
- property[:name][:objc] = e.xpath("Name").text
87
- if !swiftmap.nil? && swiftmap[property[:usr]]
88
- property[:name][:swift] = swiftmap[property[:usr]]["name"]
89
- else
90
- property[:name][:swift] = "Could not be generated"
91
- end
92
- property[:term] = property[:usr]
93
- property[:declaration] = {}
94
- property[:declaration][:objc] = e.xpath("Declaration").text.strip
95
- if !swiftmap.nil? && swiftmap[property[:usr]]
96
- property[:declaration][:swift] = swiftmap.nil?
97
- else
98
- property[:declaration][:swift] = "Could not be generated"
99
- end
100
- property[:abstract] = e.xpath("Abstract/Para").text.strip
101
- paras = []; e.xpath("Discussion/Para").each {|p| paras << p.text.strip }
102
- property[:discussion] = paras.join("\n\n") unless paras.length == 0
103
- klass[:properties] << property
104
- end
105
-
106
- #puts klass[:properties]
107
-
108
- # Fill in Methods
109
- klass[:methods] = []
110
- results[1..-1].each do |e|
111
- next unless e.name == "Function"
112
- method = {}
113
- method[:usr] = e.xpath("USR").text
114
- method[:name] = {}
115
- method[:name][:objc] = e.xpath("Name").text
116
- if !swiftmap.nil? && swiftmap[method[:usr]]
117
- method[:name][:swift] = swiftmap[method[:usr]]["name"]
118
- else
119
- method[:name][:swift] = "Could not be generated"
120
- end
121
- next if method[:usr].include?('(py)')
122
- method[:term] = method[:usr].split(')')[-1]
123
- method[:declaration] = {}
124
- method[:declaration][:objc] = e.xpath("Declaration").text
125
- if !swiftmap.nil? && swiftmap[method[:usr]]
126
- method[:declaration][:swift] = swiftmap[method[:usr]]["declaration"]
127
- else
128
- method[:declaration][:swift] = "Could not be generated"
129
- end
130
- method[:abstract] = e.xpath("Abstract/Para").text.strip
131
- paras = []; e.xpath("Discussion/Para").each {|p| paras << p.text.strip }
132
- method[:discussion] = paras.join("\n\n") unless paras.length == 0
133
- method[:result] = e.xpath("ResultDiscussion/Para").text.strip
134
-
135
- method[:parameters] = []
136
- parameters = []; e.xpath("//Parameter").each do |p|
137
- param = {}
138
- param[:name] = p.xpath("Name").text
139
- param[:discussion] = p.xpath("Discussion/Para").text.strip
140
- method[:parameters] << param
141
- end
142
-
143
- klass[:methods] << method
144
- end
145
-
146
- klass.render
147
- end
148
-
149
- def self.assets(dir)
150
- Dir.mkdir(File.join(dir,'CSS'))
151
- Dir.mkdir(File.join(dir,'JavaScript'))
152
- Dir.mkdir(File.join(dir,'Images'))
153
- FileUtils.cp_r(Dir[File.expand_path(File.join( File.dirname(__FILE__),'assets/*'))],dir)
154
- end
2
+
3
+ def self.headers(path)
4
+ paths = []
5
+ Find.find(path) do |path|
6
+ if (path =~ /.*\.h$/) && !(path =~ /.*private\.h$/i) && !(path =~ /test.*\//i)
7
+ paths << File.expand_path(path)
8
+ end
9
+ end
10
+ paths
11
+ end
12
+
13
+ def self.document(path)
14
+ bin_path = File.expand_path(File.join(File.dirname(__FILE__), '../bin'))
15
+
16
+ klass = Jazzy::Klass.new
17
+
18
+ string = `#{bin_path}/generate_swift_header.sh #{path}`
19
+ a = string.split(/^\[/); swift = a[0]; rawmap = "[\n"+a[-1]
20
+
21
+ rawmap.gsub!(/(key.\w+):/,'"\1":')
22
+ rawmap.gsub!(/(source..+),/,'"\1",')
23
+
24
+ xml = `#{bin_path}/ASTDump #{path}`
25
+
26
+ doc = Nokogiri::XML(xml)
27
+
28
+ results = doc.xpath("//*[@file='#{path}']")
29
+
30
+ # Fill in Overview
31
+ top = results.first
32
+
33
+ klass[:name] = top.xpath("Name").text
34
+ klass[:usr] = top.xpath("USR").text
35
+ klass[:declaration] = {}
36
+ klass[:declaration][:objc] = top.xpath("Declaration").text.strip
37
+ klass[:abstract] = top.xpath("Abstract/Para").text.strip
38
+ paras = []; top.xpath("./Discussion/Para").each {|p| paras << p.text.strip }
39
+ klass[:discussion] = paras.join("\n\n")
40
+
41
+ # Only usable if Swift Header can be correctly generated
42
+ unless rawmap.include? "<<NULL>>"
43
+
44
+ swiftmap = {}
45
+ map = {}
46
+
47
+ JSON.parse(rawmap).each do |element|
48
+
49
+ next unless element["key.name"].downcase == klass[:name].downcase
50
+
51
+ # More than one matching element?
52
+ element["key.entities"].each do |e|
53
+ swiftmap[e["key.usr"]] = {}
54
+ swiftmap[e["key.usr"]]["declaration"] = swift.byteslice(e["key.offset"], e["key.length"])
55
+ swiftmap[e["key.usr"]]["name"] = e["key.name"]
56
+ end
57
+
58
+ # Inherits
59
+ klass[:inherits] = []
60
+ element["key.inherits"].each { |i| klass[:inherits] << { usr: i["key.usr"], name: i["key.name"] } } unless map["key.inherits"].nil?
61
+
62
+ # Conforms to
63
+ klass[:conforms] = []
64
+ element["key.conforms"].each { |c| klass[:conforms] << { usr: c["key.usr"], name: c["key.name"] } } unless map["key.conforms"].nil?
65
+ end
66
+ end
67
+
68
+ # Import
69
+ klass[:import] = swift.split("\n")[0].chomp.gsub('import ', '')
70
+
71
+ # Fill in Properties
72
+ klass[:properties] = []
73
+
74
+ results[1..-1].each do |e|
75
+ next unless e.name == "Other"
76
+ property = {}
77
+ property[:usr] = e.xpath("USR").text
78
+ property[:name] = {}
79
+ property[:name][:objc] = e.xpath("Name").text
80
+ if !swiftmap.nil? && swiftmap[property[:usr]]
81
+ property[:name][:swift] = swiftmap[property[:usr]]["name"]
82
+ else
83
+ property[:name][:swift] = "Could not be generated"
84
+ end
85
+ property[:term] = property[:usr]
86
+ property[:declaration] = {}
87
+ property[:declaration][:objc] = e.xpath("Declaration").text.strip
88
+ if !swiftmap.nil? && swiftmap[property[:usr]]
89
+ property[:declaration][:swift] = swiftmap.nil?
90
+ else
91
+ property[:declaration][:swift] = "Could not be generated"
92
+ end
93
+ property[:abstract] = e.xpath("Abstract/Para").text.strip
94
+ paras = []; e.xpath("Discussion/Para").each {|p| paras << p.text.strip }
95
+ property[:discussion] = paras.join("\n\n") unless paras.length == 0
96
+ klass[:properties] << property
97
+ end
98
+
99
+ #puts klass[:properties]
100
+
101
+ # Fill in Methods
102
+ klass[:methods] = []
103
+ results[1..-1].each do |e|
104
+ next unless e.name == "Function"
105
+ method = {}
106
+ method[:usr] = e.xpath("USR").text
107
+ method[:name] = {}
108
+ method[:name][:objc] = e.xpath("Name").text
109
+ if !swiftmap.nil? && swiftmap[method[:usr]]
110
+ method[:name][:swift] = swiftmap[method[:usr]]["name"]
111
+ else
112
+ method[:name][:swift] = "Could not be generated"
113
+ end
114
+ next if method[:usr].include?('(py)')
115
+ method[:term] = method[:usr].split(')')[-1]
116
+ method[:declaration] = {}
117
+ method[:declaration][:objc] = e.xpath("Declaration").text
118
+ if !swiftmap.nil? && swiftmap[method[:usr]]
119
+ method[:declaration][:swift] = swiftmap[method[:usr]]["declaration"]
120
+ else
121
+ method[:declaration][:swift] = "Could not be generated"
122
+ end
123
+ method[:abstract] = e.xpath("Abstract/Para").text.strip
124
+ paras = []; e.xpath("Discussion/Para").each {|p| paras << p.text.strip }
125
+ method[:discussion] = paras.join("\n\n") unless paras.length == 0
126
+ method[:result] = e.xpath("ResultDiscussion/Para").text.strip
127
+
128
+ method[:parameters] = []
129
+ parameters = []; e.xpath("//Parameter").each do |p|
130
+ param = {}
131
+ param[:name] = p.xpath("Name").text
132
+ param[:discussion] = p.xpath("Discussion/Para").text.strip
133
+ method[:parameters] << param
134
+ end
135
+
136
+ klass[:methods] << method
137
+ end
138
+
139
+ klass.render
140
+ end
141
+
142
+ def self.assets(dir)
143
+ Dir.mkdir(File.join(dir,'CSS'))
144
+ Dir.mkdir(File.join(dir,'JavaScript'))
145
+ Dir.mkdir(File.join(dir,'Images'))
146
+ FileUtils.cp_r(Dir[File.expand_path(File.join( File.dirname(__FILE__),'assets/*'))],dir)
147
+ end
155
148
 
156
149
  end
157
150