cocoadex 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +7 -0
- data/bin/cocoadex +67 -0
- data/cocoadex.gemspec +25 -0
- data/data/_store +0 -0
- data/lib/cocoadex/keyword.rb +94 -0
- data/lib/cocoadex/models/class.rb +97 -0
- data/lib/cocoadex/models/docset.rb +34 -0
- data/lib/cocoadex/models/entity.rb +23 -0
- data/lib/cocoadex/models/method.rb +86 -0
- data/lib/cocoadex/models/property.rb +44 -0
- data/lib/cocoadex/parser.rb +53 -0
- data/lib/cocoadex/version.rb +3 -0
- data/lib/cocoadex.rb +15 -0
- data/lib/ext/nil.rb +18 -0
- data/readme.md +34 -0
- metadata +131 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Delisa Mason
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2012 Delisa Mason
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/cocoadex
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'methadone'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'cocoadex'
|
6
|
+
|
7
|
+
include Methadone::Main
|
8
|
+
include Methadone::CLILogging
|
9
|
+
include Cocoadex
|
10
|
+
|
11
|
+
logger.error_level = Logger::ERROR
|
12
|
+
|
13
|
+
main do |arg|
|
14
|
+
if options[:verbose]
|
15
|
+
logger.error_level = Logger::DEBUG
|
16
|
+
end
|
17
|
+
|
18
|
+
if options[:docset] and path = File.expand_path(options[:docset].first)
|
19
|
+
Parser.parse(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
if options[:search] and text = options[:search].first
|
24
|
+
if Keyword.loaded?
|
25
|
+
logger.debug "Loading index..."
|
26
|
+
Keyword.read
|
27
|
+
search(text)
|
28
|
+
else
|
29
|
+
puts "No DocSets loaded"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def search term
|
35
|
+
if term and not term.strip.empty?
|
36
|
+
objects = Keyword.find(term.strip)
|
37
|
+
if objects.size == 0
|
38
|
+
puts "No matches found"
|
39
|
+
elsif objects.size == 1
|
40
|
+
objects.first.print
|
41
|
+
else
|
42
|
+
objects.each_with_index do |obj, index|
|
43
|
+
puts "#{index} #{obj}"
|
44
|
+
end
|
45
|
+
puts "Select:"
|
46
|
+
which = gets
|
47
|
+
begin
|
48
|
+
index = [[which.to_i,0].max,objects.size - 1].min
|
49
|
+
objects[index].print
|
50
|
+
rescue Exception => e
|
51
|
+
puts ":("
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
version Cocoadex::VERSION
|
58
|
+
description 'A Class Reference Utility for Cocoa APIs'
|
59
|
+
|
60
|
+
on("--verbose","Be verbose")
|
61
|
+
|
62
|
+
on("-d DOCSET","--docset","DocSet",/^(.*)$/)
|
63
|
+
on("-s QUERY","--search","Search",/^(.*)$/)
|
64
|
+
|
65
|
+
# todo: support --platform, --platform-version, --language, --first, --force
|
66
|
+
|
67
|
+
go!
|
data/cocoadex.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/cocoadex/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Delisa Mason"]
|
6
|
+
gem.email = ["iskanamagus@gmail.com"]
|
7
|
+
gem.description = %q{A reference utility for Cocoa APIs}
|
8
|
+
gem.summary = %q{A command-line reference utility for Cocoa APIs.}
|
9
|
+
gem.homepage = "https://kattrali.github.com/cocoadex"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "cocoadex"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Cocoadex::VERSION
|
17
|
+
gem.add_development_dependency('bacon')
|
18
|
+
gem.add_development_dependency('rdoc')
|
19
|
+
gem.add_development_dependency('aruba')
|
20
|
+
gem.add_development_dependency('rake','~> 0.9.2')
|
21
|
+
gem.add_dependency('methadone', '~>1.2.1')
|
22
|
+
# gem.add_dependency('term-ansicolor')
|
23
|
+
# gem.add_dependency('sqlite3')
|
24
|
+
gem.add_dependency('nokogiri')
|
25
|
+
end
|
data/data/_store
ADDED
File without changes
|
@@ -0,0 +1,94 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class Keyword
|
4
|
+
attr_reader :term, :type, :docset, :url
|
5
|
+
attr_accessor :fk, :id
|
6
|
+
|
7
|
+
DATA_PATH = File.join(File.dirname(__FILE__),"..","..","data","store.yaml")
|
8
|
+
|
9
|
+
def self.datastore
|
10
|
+
@store ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find text
|
14
|
+
keys = datastore.select {|k| k.term.start_with? text }
|
15
|
+
if key = keys.detect {|k| k.term == text}
|
16
|
+
keys = [key]
|
17
|
+
end
|
18
|
+
untokenize(keys)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.loaded?
|
22
|
+
File.exists? DATA_PATH
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.read
|
26
|
+
$/="\n\n"
|
27
|
+
File.open(DATA_PATH, "r").each do |object|
|
28
|
+
datastore << YAML::load(object)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.write
|
33
|
+
File.open(DATA_PATH, "w") do |file|
|
34
|
+
datastore.each do |keyword|
|
35
|
+
file.puts(YAML.dump(keyword))
|
36
|
+
file.puts
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.untokenize keys
|
42
|
+
keys.map do |key|
|
43
|
+
case key.type
|
44
|
+
when :class
|
45
|
+
Cocoadex::Class.new(key.url)
|
46
|
+
when :method, :property
|
47
|
+
if class_key = datastore.detect {|k| k.id == key.fk}
|
48
|
+
klass = Cocoadex::Class.new(class_key.url)
|
49
|
+
case key.type
|
50
|
+
when :method
|
51
|
+
entity = klass.methods.detect {|m| m.name == key.term}
|
52
|
+
when :property
|
53
|
+
entity = klass.properties.detect {|m| m.name == key.term}
|
54
|
+
end
|
55
|
+
|
56
|
+
entity.class_name = klass.name
|
57
|
+
entity
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.tokenize_class docset, path, id
|
64
|
+
klass = Cocoadex::Class.new(path)
|
65
|
+
class_key = Keyword.new(klass.name, :class, docset, path)
|
66
|
+
class_key.id = id
|
67
|
+
datastore << class_key
|
68
|
+
|
69
|
+
klass.methods.each do |m|
|
70
|
+
mkey = Keyword.new(m.name, :method, docset, path)
|
71
|
+
mkey.fk = id
|
72
|
+
datastore << mkey
|
73
|
+
end
|
74
|
+
|
75
|
+
klass.properties.each do |p|
|
76
|
+
pkey = Keyword.new(p.name, :property, docset, path)
|
77
|
+
pkey.fk = id
|
78
|
+
datastore << pkey
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize term, type, docset, url
|
83
|
+
@term, @type, @docset, @url = term, type, docset, url
|
84
|
+
end
|
85
|
+
|
86
|
+
def inspect
|
87
|
+
"<Keyword#{type} @term=#{term}>"
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_s
|
91
|
+
"#{type} => #{term}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Cocoadex
|
5
|
+
class Class < Entity
|
6
|
+
attr_reader :name, :description, :overview
|
7
|
+
|
8
|
+
def properties
|
9
|
+
@properties ||=[]
|
10
|
+
end
|
11
|
+
|
12
|
+
def tasks
|
13
|
+
@tasks ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
def methods
|
17
|
+
@methods ||= ::Set.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def parents
|
21
|
+
@parents ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"Class #{name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def print
|
29
|
+
puts <<-INFO
|
30
|
+
Class: #{name}
|
31
|
+
|
32
|
+
#{description}
|
33
|
+
|
34
|
+
Inherits From: #{parents.join(' > ')}
|
35
|
+
|
36
|
+
Overview:
|
37
|
+
|
38
|
+
#{overview}
|
39
|
+
|
40
|
+
Properties:
|
41
|
+
|
42
|
+
INFO
|
43
|
+
properties.each do |prop|
|
44
|
+
prop.print
|
45
|
+
end
|
46
|
+
puts <<-INFO
|
47
|
+
Methods:
|
48
|
+
INFO
|
49
|
+
methods.each do |m|
|
50
|
+
m.print
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse doc
|
55
|
+
@name = doc.css('body a').first['title']
|
56
|
+
@description = doc.css('meta#description').first['content']
|
57
|
+
# @overview = doc.css(".zClassDescription p.abstract").first.text
|
58
|
+
@overview = doc.css(".zClassDescription").first.text.sub("Overview","")
|
59
|
+
@parents = doc.css("div.zSharedSpecBoxHeadList").first.css('a').map {|node| node.text}
|
60
|
+
|
61
|
+
parse_properties(doc)
|
62
|
+
parse_tasks(doc)
|
63
|
+
parse_methods(doc)
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_methods doc
|
67
|
+
[:class, :instance].each do |selector|
|
68
|
+
nodes = doc.css("div.#{selector}Method")
|
69
|
+
# logger.debug(nodes.inspect)
|
70
|
+
unless nodes.empty?
|
71
|
+
methods.merge(nodes.map {|n| Method.new(selector, n)})
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_properties doc
|
77
|
+
@properties = doc.css("div.propertyObjC").map do |prop|
|
78
|
+
Property.new(prop)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_tasks doc
|
83
|
+
@tasks = {}
|
84
|
+
doc.css('ul.tooltip').each do |list|
|
85
|
+
key = list.previous.text
|
86
|
+
@tasks[key] = []
|
87
|
+
list.css('li span.tooltip').each do |prop|
|
88
|
+
@tasks[key] << {
|
89
|
+
:name => strip(prop.css('a').first.text),
|
90
|
+
:abstract => prop.css('.tooltipicon').first['data-abstract']
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
@tasks
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class DocSet
|
4
|
+
attr_reader :platform, :version, :name, :description, :path
|
5
|
+
|
6
|
+
def initialize plist_path
|
7
|
+
@doc = Nokogiri::HTML(IO.read(plist_path))
|
8
|
+
@path = plist_path
|
9
|
+
@name = plist_value 'CFBundleName'
|
10
|
+
@platform = plist_value "DocSetPlatformFamily"
|
11
|
+
@version = plist_value "DocSetPlatformVersion"
|
12
|
+
@description = plist_value "DocSetDescription"
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
"<DocSet #{name} @description=#{description} @path=#{path}>"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def plist_value key
|
22
|
+
key_node = @doc.css("dict key").detect do |node|
|
23
|
+
node.text == key
|
24
|
+
end
|
25
|
+
|
26
|
+
if key_node
|
27
|
+
key_node.next.text
|
28
|
+
else
|
29
|
+
logger.iwarn "Node not found: #{key}"
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class Entity
|
4
|
+
|
5
|
+
def initialize path
|
6
|
+
text = clean(IO.read(path))
|
7
|
+
document = Nokogiri::HTML(text)
|
8
|
+
parse(document)
|
9
|
+
end
|
10
|
+
|
11
|
+
def print
|
12
|
+
raise "print() not defined for #{self.class}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def clean text
|
16
|
+
text.gsub(/(\n|\t|\r)/, ' ').gsub(/>\s*</, '><').squeeze(' ')
|
17
|
+
end
|
18
|
+
|
19
|
+
def strip text
|
20
|
+
text.gsub("  ","")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class Class < Entity
|
4
|
+
class Method
|
5
|
+
attr_reader :name, :abstract, :declaration, :scope,
|
6
|
+
:discussion, :declared_in, :availability, :parameters,
|
7
|
+
:return_value
|
8
|
+
|
9
|
+
attr_accessor :class_name
|
10
|
+
|
11
|
+
class Parameter
|
12
|
+
attr_reader :name, :description
|
13
|
+
|
14
|
+
def initialize name, description
|
15
|
+
@name, @description = name, description
|
16
|
+
end
|
17
|
+
|
18
|
+
def print
|
19
|
+
puts "#{name} - #{description}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def parameters
|
24
|
+
@parameters ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize type, node
|
28
|
+
@type = type
|
29
|
+
@name = node.css("h3.#{type}Method").first.text
|
30
|
+
logger.debug("parsing #{@type} method #{@name}")
|
31
|
+
@abstract = node.css(".abstract").first.text
|
32
|
+
@declaration = node.css(".declaration").first.text
|
33
|
+
|
34
|
+
decl_nodes = node.css(".declaredIn code.HeaderFile")
|
35
|
+
if decl_nodes.size > 0
|
36
|
+
@declared_in = decl_nodes.first.text
|
37
|
+
end
|
38
|
+
|
39
|
+
if discussion_node = node.css(".discussion > p") and discussion_node.length > 0
|
40
|
+
@discussion = discussion_node.first.text
|
41
|
+
end
|
42
|
+
|
43
|
+
if return_nodes = node.css(".return_value p") and return_nodes.size > 0
|
44
|
+
@return_value = return_nodes.first.text
|
45
|
+
end
|
46
|
+
|
47
|
+
ava_nodes = node.css(".availability > ul > li")
|
48
|
+
if ava_nodes.size > 0
|
49
|
+
@availability = ava_nodes.first.text
|
50
|
+
end
|
51
|
+
|
52
|
+
if parameters = node.css(".parameters") and parameters.length > 0
|
53
|
+
@parameters = []
|
54
|
+
parameters.first.css("dt").each do |param|
|
55
|
+
name_nodes = param.css("em")
|
56
|
+
if name_nodes.size > 0
|
57
|
+
name = param.css("em").first.text
|
58
|
+
description = param.next.css("p").first.text
|
59
|
+
@parameters << Parameter.new(name, description)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
"Method #{name}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def print
|
70
|
+
puts <<-PRINT
|
71
|
+
Declared in: #{declared_in}
|
72
|
+
|
73
|
+
#{declaration}
|
74
|
+
#{print_parameters}
|
75
|
+
Returns: #{return_value}
|
76
|
+
#{abstract}
|
77
|
+
#{availability}
|
78
|
+
PRINT
|
79
|
+
end
|
80
|
+
|
81
|
+
def print_parameters
|
82
|
+
parameters.map {|pm| pm.print}.join("\n ") if parameters
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class Property
|
4
|
+
attr_reader :name, :abstract, :declaration, :discussion, :availability
|
5
|
+
|
6
|
+
attr_accessor :class_name
|
7
|
+
|
8
|
+
def initialize node
|
9
|
+
@name = node.css("h3.method_property").first.text
|
10
|
+
logger.debug("Adding property: #{@name}")
|
11
|
+
|
12
|
+
if abs = node.css(".abstract") and abs.length > 0
|
13
|
+
@abstract = abs.first.text
|
14
|
+
end
|
15
|
+
|
16
|
+
if decl = node.css(".declaration") and decl.length > 0
|
17
|
+
@declaration = decl.first.text
|
18
|
+
end
|
19
|
+
|
20
|
+
if disc = node.css(".discussion > p") and disc.length > 0
|
21
|
+
@discussion = disc.first.text
|
22
|
+
end
|
23
|
+
|
24
|
+
if ava_nodes = node.css(".availability > ul > li") and ava_nodes.size > 0
|
25
|
+
@availability = ava_nodes.first.text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"Property #{name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def print
|
34
|
+
puts <<-PRINT
|
35
|
+
Declared in: #{class_name || ''}
|
36
|
+
|
37
|
+
#{name}
|
38
|
+
#{abstract}
|
39
|
+
#{availability}
|
40
|
+
|
41
|
+
PRINT
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class Parser
|
4
|
+
|
5
|
+
IGNORED_DIRS = [
|
6
|
+
'codinghowtos', 'qa',
|
7
|
+
'featuredarticles','navigation',
|
8
|
+
'recipes','releasenotes',
|
9
|
+
'samplecode','Conceptual',
|
10
|
+
'technotes','History',
|
11
|
+
'Introduction','GettingStarted'
|
12
|
+
]
|
13
|
+
|
14
|
+
IGNORED_FILES = [
|
15
|
+
'RevisionHistory','Introduction'
|
16
|
+
]
|
17
|
+
|
18
|
+
def self.ignored? path
|
19
|
+
(path.split('/') & IGNORED_DIRS).size > 0 or
|
20
|
+
IGNORED_FILES.include?(File.basename(path).sub('.html','')) or
|
21
|
+
(File.basename(path) == 'index.html' && File.exist?(File.join(File.dirname(path),'Reference')))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse docset_path
|
25
|
+
logger.debug "Parsing docset..."
|
26
|
+
plist = File.join(docset_path,"Contents", "Info.plist")
|
27
|
+
if File.exist? plist
|
28
|
+
docset = DocSet.new(plist)
|
29
|
+
logger.info docset.inspect
|
30
|
+
files = Dir.glob(docset_path+"/**/*.html")
|
31
|
+
files.reject! {|f| ignored?(f) }
|
32
|
+
|
33
|
+
files.each_with_index do |f,index|
|
34
|
+
logger.debug " Parsing path: #{f}"
|
35
|
+
doc = Nokogiri::HTML(IO.read(f))
|
36
|
+
title_nodes = doc.css("#IndexTitle")
|
37
|
+
unless title_nodes.size == 0
|
38
|
+
title = title_nodes.first['content']
|
39
|
+
if title.include? "Deprecated"
|
40
|
+
next
|
41
|
+
elsif title.include? "Class Reference" or title.include? "Protocol Reference"
|
42
|
+
logger.info " Creating #{title}"
|
43
|
+
Keyword.tokenize_class docset.name, f, index
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
logger.info "Tokens Indexed: #{Keyword.datastore.size}"
|
49
|
+
Keyword.write
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/cocoadex.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
require 'cocoadex/version'
|
3
|
+
require 'cocoadex/models/docset'
|
4
|
+
require 'cocoadex/models/entity'
|
5
|
+
require 'cocoadex/models/method'
|
6
|
+
require 'cocoadex/models/property'
|
7
|
+
require 'cocoadex/models/class'
|
8
|
+
require 'cocoadex/parser'
|
9
|
+
require 'cocoadex/keyword'
|
10
|
+
require 'ext/nil'
|
11
|
+
require 'nokogiri'
|
12
|
+
|
13
|
+
module Cocoadex
|
14
|
+
|
15
|
+
end
|
data/lib/ext/nil.rb
ADDED
data/readme.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# THE COCOADEX
|
2
|
+
|
3
|
+
Spartan documentation lookup for Cocoa APIs
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
gem install cocoadex
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
- **View Options:** `cocoadex --help`
|
13
|
+
- **Loading a DocSet:** `cocoadex --docset [path]` (Try `~/Library/Developer/DocSets/[docset name]`)
|
14
|
+
- **Look up:** `cocoadex --search [query]`
|
15
|
+
- Valid search terms are Class, method, and property names
|
16
|
+
- Example:
|
17
|
+
|
18
|
+
$ cocoadex -s tableView:didSelectRow
|
19
|
+
Declared in: UITableView.h
|
20
|
+
|
21
|
+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
22
|
+
tableView - A table-view object informing the delegate about the new row selection.
|
23
|
+
indexPath - An index path locating the new selected row in tableView.
|
24
|
+
Returns:
|
25
|
+
Tells the delegate that the specified row is now selected.
|
26
|
+
Available in iOS 2.0 and later.
|
27
|
+
|
28
|
+
|
29
|
+
## Todo
|
30
|
+
|
31
|
+
- Improve UX: Some tasteful usage of text formatting wouldn't hurt
|
32
|
+
- Support `--first`, for returning the first result of multiple matches
|
33
|
+
- Support auto-loading DocSets from common locations
|
34
|
+
- Persist object model/datastore using AR
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cocoadex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Delisa Mason
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-19 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bacon
|
17
|
+
requirement: &19750080 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *19750080
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rdoc
|
28
|
+
requirement: &19749520 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *19749520
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: aruba
|
39
|
+
requirement: &19749100 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *19749100
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rake
|
50
|
+
requirement: &19733880 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.9.2
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *19733880
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: methadone
|
61
|
+
requirement: &19733280 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.2.1
|
67
|
+
type: :runtime
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *19733280
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: nokogiri
|
72
|
+
requirement: &19732840 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :runtime
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *19732840
|
81
|
+
description: A reference utility for Cocoa APIs
|
82
|
+
email:
|
83
|
+
- iskanamagus@gmail.com
|
84
|
+
executables:
|
85
|
+
- cocoadex
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- Gemfile
|
90
|
+
- LICENSE
|
91
|
+
- LICENSE.txt
|
92
|
+
- bin/cocoadex
|
93
|
+
- cocoadex.gemspec
|
94
|
+
- data/_store
|
95
|
+
- lib/cocoadex.rb
|
96
|
+
- lib/cocoadex/keyword.rb
|
97
|
+
- lib/cocoadex/models/class.rb
|
98
|
+
- lib/cocoadex/models/docset.rb
|
99
|
+
- lib/cocoadex/models/entity.rb
|
100
|
+
- lib/cocoadex/models/method.rb
|
101
|
+
- lib/cocoadex/models/property.rb
|
102
|
+
- lib/cocoadex/parser.rb
|
103
|
+
- lib/cocoadex/version.rb
|
104
|
+
- lib/ext/nil.rb
|
105
|
+
- readme.md
|
106
|
+
has_rdoc: true
|
107
|
+
homepage: https://kattrali.github.com/cocoadex
|
108
|
+
licenses: []
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 1.6.2
|
128
|
+
signing_key:
|
129
|
+
specification_version: 3
|
130
|
+
summary: A command-line reference utility for Cocoa APIs.
|
131
|
+
test_files: []
|