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 +4 -4
- data/DEV_README.md +35 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +32 -0
- data/README.md +7 -29
- data/bin/generate_swift_header.sh +14 -0
- data/jazzy.gemspec +3 -3
- data/lib/jazzy.rb +146 -153
- data/lib/jazzy/klass.mustache +137 -312
- data/lib/jazzy/klass.rb +0 -4
- data/lib/jazzy/partials/klass-method.mustache +68 -82
- data/lib/jazzy/partials/klass-overview.mustache +2 -2
- data/lib/jazzy/partials/klass-property.mustache +40 -51
- data/parser/ASTDump.xcodeproj/project.pbxproj +21 -8
- data/parser/clang-c/Index.h +17 -1
- data/{parser/ASTDump → sample}/JAZMusician.h +1 -1
- data/{parser/ASTDump → sample}/JAZMusician.m +0 -0
- data/sample/Musician.swift +37 -0
- data/screenshot.jpg +0 -0
- metadata +13 -7
- data/bin/SwiftHeader +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4693be658ce9c28ddc98fdc398e26db8bc48d5c8
|
4
|
+
data.tar.gz: 2fd530bafb0099d145e8c07c2c34580f086aa79f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad9e58a8fd88262f1671ecd3394a970cd1d3a52f4a0b66798f64f0f77a715cae87702cea614ffc6bff235a026004d243bc699e1e33a9c7405a53040aaba29e0e
|
7
|
+
data.tar.gz: ee54d025fafa17e307eb2b2a9de639cc866a70ef799ce8ba1134130a93044c7d08c1ecd0a77504227f027e1e5b7327c2685be9ad363f7b91e5f4aa270c3ec216
|
data/DEV_README.md
ADDED
@@ -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
data/Gemfile.lock
ADDED
@@ -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
|
-
|
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 [
|
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
|
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
|
data/jazzy.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
module Jazzy
|
4
|
-
VERSION = '0.0.
|
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@
|
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
|
data/lib/jazzy.rb
CHANGED
@@ -1,157 +1,150 @@
|
|
1
1
|
class Jazzy
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
|