cocoadex 1.4 → 1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/cdex_completion +7 -0
- data/bin/cocoadex +5 -3
- data/changelog.md +5 -0
- data/lib/cocoadex/docset_helper.rb +8 -4
- data/lib/cocoadex/extensions.rb +4 -0
- data/lib/cocoadex/keyword.rb +30 -103
- data/lib/cocoadex/model.rb +56 -0
- data/lib/cocoadex/models/callback.rb +12 -0
- data/lib/cocoadex/models/class.rb +2 -2
- data/lib/cocoadex/models/constant.rb +41 -0
- data/lib/cocoadex/models/data_type.rb +47 -0
- data/lib/cocoadex/models/element.rb +14 -1
- data/lib/cocoadex/models/entity.rb +6 -0
- data/lib/cocoadex/models/function.rb +28 -0
- data/lib/cocoadex/models/generic_ref.rb +88 -0
- data/lib/cocoadex/models/method.rb +21 -70
- data/lib/cocoadex/models/nested_node_element.rb +17 -0
- data/lib/cocoadex/models/parameter.rb +20 -0
- data/lib/cocoadex/models/property.rb +3 -18
- data/lib/cocoadex/models/result_code.rb +17 -0
- data/lib/cocoadex/models/seq_node_element.rb +53 -0
- data/lib/cocoadex/parser.rb +22 -18
- data/lib/cocoadex/serializer.rb +18 -8
- data/lib/cocoadex/tokenizer.rb +123 -0
- data/lib/cocoadex/tools/completion_helper.rb +84 -0
- data/lib/cocoadex/version.rb +1 -1
- data/lib/cocoadex.rb +12 -10
- data/lib/ext/nil.rb +3 -0
- data/lib/ext/string.rb +9 -0
- data/lib/ext/template_helpers.rb +20 -0
- data/lib/ext/xml_element.rb +10 -0
- data/readme.md +36 -8
- data/views/class.erb +35 -0
- data/views/constant.erb +10 -0
- data/views/constant_group.erb +28 -0
- data/views/data_type.erb +47 -0
- data/views/generic_ref.erb +28 -0
- data/views/method.erb +34 -0
- data/views/multiple.erb +4 -0
- data/views/property.erb +14 -0
- data/views/result_code.erb +7 -0
- metadata +50 -10
- data/bin/cocoadex_completion.sh +0 -36
- data/lib/cocoadex/templates.rb +0 -114
data/bin/cdex_completion
ADDED
data/bin/cocoadex
CHANGED
@@ -18,15 +18,15 @@ main do |query|
|
|
18
18
|
end
|
19
19
|
if options[:configure]
|
20
20
|
DocSetHelper.search_and_index
|
21
|
+
elsif options[:'generate-tags']
|
22
|
+
CompletionHelper.generate_tags!
|
21
23
|
elsif options[:'load-docset']
|
22
24
|
paths = options[:'load-docset'].map do |p|
|
23
25
|
File.expand_path(p)
|
24
26
|
end.uniq
|
25
27
|
DocSetHelper.search_and_index(paths)
|
26
28
|
elsif query
|
27
|
-
if
|
28
|
-
logger.debug "Loading index..."
|
29
|
-
Keyword.read
|
29
|
+
if Tokenizer.loaded?
|
30
30
|
Cocoadex.search(query, options[:first])
|
31
31
|
else
|
32
32
|
puts "No DocSets loaded. Run `cocodex --configure` to search for existing DocSets."
|
@@ -43,6 +43,8 @@ arg :query, :optional
|
|
43
43
|
|
44
44
|
on("--verbose","Be verbose")
|
45
45
|
|
46
|
+
on("--generate-tags","Generate a tags file from indexed docsets and exit")
|
47
|
+
|
46
48
|
on("--configure","Index all DocSets in default locations")
|
47
49
|
|
48
50
|
on("--first","Load first result when multiple matches exist")
|
data/changelog.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.5
|
4
|
+
|
5
|
+
- Searching for constants, functions, data types, callbacks, and result codes are now supported!
|
6
|
+
- Added smart completion; `Class-method`, `Class+method`, and `Class.property` can now be tab-completed
|
7
|
+
|
3
8
|
## 1.4
|
4
9
|
|
5
10
|
- Fixed parsing error on non-ASCII characters. Patch submitted by farcaller.
|
@@ -1,5 +1,7 @@
|
|
1
1
|
|
2
2
|
module Cocoadex
|
3
|
+
|
4
|
+
# Helper for finding and indexing DocSets
|
3
5
|
class DocSetHelper
|
4
6
|
|
5
7
|
ROOT_PATHS = [
|
@@ -15,7 +17,9 @@ module Cocoadex
|
|
15
17
|
|
16
18
|
def self.docset_paths
|
17
19
|
@paths ||= begin
|
18
|
-
ROOT_PATHS.map
|
20
|
+
ROOT_PATHS.map do |path|
|
21
|
+
Dir.glob(File.expand_path(path)+'/*/')
|
22
|
+
end.flatten
|
19
23
|
end
|
20
24
|
end
|
21
25
|
|
@@ -28,8 +32,8 @@ module Cocoadex
|
|
28
32
|
end
|
29
33
|
|
30
34
|
if docsets.size > 0
|
31
|
-
|
32
|
-
|
35
|
+
Tokenizer.persist
|
36
|
+
CompletionHelper.generate_tags!
|
33
37
|
write(docsets)
|
34
38
|
end
|
35
39
|
logger.info "Done! #{docsets.size} DocSet#{docsets.size == 1 ? '':'s'} indexed."
|
@@ -45,7 +49,7 @@ module Cocoadex
|
|
45
49
|
|
46
50
|
def self.write docsets
|
47
51
|
@docsets = docsets
|
48
|
-
Serializer.
|
52
|
+
Serializer.write_array(data_path, docsets, :overwrite)
|
49
53
|
end
|
50
54
|
end
|
51
55
|
end
|
data/lib/cocoadex/keyword.rb
CHANGED
@@ -11,41 +11,45 @@ module Cocoadex
|
|
11
11
|
CLASS_PROP_DELIM = '.'
|
12
12
|
SCOPE_CHARS = [CLASS_PROP_DELIM,CLASS_METHOD_DELIM,INST_METHOD_DELIM]
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
# Search the cache for matching text
|
15
|
+
def self.find text
|
16
|
+
logger.debug "Searching tokens for #{text}"
|
17
|
+
if scope = Keyword.get_scope(text)
|
18
|
+
class_name, term = text.split(scope)
|
19
|
+
find_with_scope(scope, class_name, term)
|
20
|
+
else
|
21
|
+
keys = Tokenizer.fuzzy_match(text)
|
22
|
+
keys.map {|k| k.to_element }
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
Cocoadex.config_file("data/store.blob")
|
26
|
+
def self.get_scope text
|
27
|
+
SCOPE_CHARS.detect {|c| text.include? c}
|
21
28
|
end
|
22
29
|
|
23
|
-
def
|
24
|
-
|
30
|
+
def initialize term, type, docset, url
|
31
|
+
@term, @type, @docset, @url = term, type, docset, url
|
25
32
|
end
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
if scope = SCOPE_CHARS.detect {|c| text.include? c }
|
30
|
-
class_name, term = text.split(scope)
|
31
|
-
logger.debug "Searching scope: #{scope}, #{class_name}, #{term}"
|
32
|
-
find_with_scope scope, class_name, term
|
33
|
-
else
|
34
|
-
logger.debug "Searching Keyword datastore (#{datastore.size}): #{text}"
|
35
|
-
keys = datastore.select {|k| k.term.start_with? text }
|
36
|
-
logger.debug "#{keys.size} keys found"
|
37
|
-
if key = keys.detect {|k| k.term == text }
|
38
|
-
keys = [key]
|
39
|
-
logger.debug "Exact match!"
|
40
|
-
end
|
41
|
-
untokenize(keys)
|
42
|
-
end
|
34
|
+
def to_element
|
35
|
+
Tokenizer.untokenize([self]).first
|
43
36
|
end
|
44
37
|
|
38
|
+
def inspect
|
39
|
+
"<Keyword:#{type} @term=\"#{term}\">"
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
"#{type} => #{term}"
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
45
48
|
# Find matches for term within a given class
|
46
49
|
def self.find_with_scope scope, class_name, term
|
47
|
-
if class_key =
|
48
|
-
|
50
|
+
if class_key = Tokenizer.match(class_name)
|
51
|
+
return [] unless class_key.type == :class
|
52
|
+
klass = class_key.to_element
|
49
53
|
list = case scope
|
50
54
|
when CLASS_PROP_DELIM
|
51
55
|
klass.methods + klass.properties
|
@@ -59,82 +63,5 @@ module Cocoadex
|
|
59
63
|
[]
|
60
64
|
end
|
61
65
|
end
|
62
|
-
|
63
|
-
# Are any docsets loaded into the cache?
|
64
|
-
def self.loaded?
|
65
|
-
File.exists? data_path
|
66
|
-
end
|
67
|
-
|
68
|
-
# Read a serialized cache file into an Array
|
69
|
-
def self.read
|
70
|
-
@store = Serializer.read(data_path)
|
71
|
-
logger.debug "Loaded #{datastore.size} tokens"
|
72
|
-
end
|
73
|
-
|
74
|
-
# Write a cache Array as a serialized file
|
75
|
-
def self.write style
|
76
|
-
Serializer.write(data_path, datastore, style)
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.tags
|
80
|
-
@tags ||= begin
|
81
|
-
if File.exists? tags_path
|
82
|
-
IO.read(tags_path).split('\n')
|
83
|
-
else
|
84
|
-
[]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# Build a tags file from existing kewords
|
90
|
-
def self.generate_tags!
|
91
|
-
text = datastore.map {|k| k.term }.join('\n')
|
92
|
-
Serializer.write_text tags_path, text
|
93
|
-
end
|
94
|
-
|
95
|
-
# Create Cocoadex model objects for Keyword references
|
96
|
-
def self.untokenize keys
|
97
|
-
keys.map do |key|
|
98
|
-
case key.type
|
99
|
-
when :class
|
100
|
-
Cocoadex::Class.new(key.url)
|
101
|
-
when :method, :property
|
102
|
-
if class_key = datastore.detect {|k| k.id == key.fk}
|
103
|
-
klass = Cocoadex::Class.new(class_key.url)
|
104
|
-
logger.debug "Searching #{key.type} list of #{klass.name}"
|
105
|
-
list = key.type == :method ? klass.methods : klass.properties
|
106
|
-
list.detect {|m| m.name == key.term}
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Find all searchable keywords in a class and add to cache
|
113
|
-
def self.tokenize_class docset, path, id
|
114
|
-
klass = Cocoadex::Class.new(path)
|
115
|
-
class_key = Keyword.new(klass.name, :class, docset, path)
|
116
|
-
class_key.id = id
|
117
|
-
datastore << class_key
|
118
|
-
|
119
|
-
{:method => klass.methods, :property => klass.properties}.each do |type,list|
|
120
|
-
list.each do |item|
|
121
|
-
item_key = Keyword.new(item.name, type, docset, path)
|
122
|
-
item_key.fk = id
|
123
|
-
datastore << item_key
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def initialize term, type, docset, url
|
129
|
-
@term, @type, @docset, @url = term, type, docset, url
|
130
|
-
end
|
131
|
-
|
132
|
-
def inspect
|
133
|
-
"<Keyword#{type} @term=#{term}>"
|
134
|
-
end
|
135
|
-
|
136
|
-
def to_s
|
137
|
-
"#{type} => #{term}"
|
138
|
-
end
|
139
66
|
end
|
140
|
-
end
|
67
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'cocoadex/models/docset'
|
2
|
+
require 'cocoadex/models/element'
|
3
|
+
require 'cocoadex/models/seq_node_element'
|
4
|
+
require 'cocoadex/models/nested_node_element'
|
5
|
+
require 'cocoadex/models/entity'
|
6
|
+
require 'cocoadex/models/constant'
|
7
|
+
require 'cocoadex/models/parameter'
|
8
|
+
require 'cocoadex/models/function'
|
9
|
+
require 'cocoadex/models/callback'
|
10
|
+
require 'cocoadex/models/result_code'
|
11
|
+
require 'cocoadex/models/data_type'
|
12
|
+
require 'cocoadex/models/generic_ref'
|
13
|
+
require 'cocoadex/models/method'
|
14
|
+
require 'cocoadex/models/property'
|
15
|
+
require 'cocoadex/models/class'
|
16
|
+
|
17
|
+
# Class Structure -------------
|
18
|
+
#
|
19
|
+
# DocSet
|
20
|
+
# Element
|
21
|
+
# Entity
|
22
|
+
# Class
|
23
|
+
# GenericRef
|
24
|
+
# NestedNodeElement
|
25
|
+
# Method
|
26
|
+
# Property
|
27
|
+
# SequentialNodeElement
|
28
|
+
# Callback
|
29
|
+
# ConstantGroup
|
30
|
+
# DataType
|
31
|
+
# Function
|
32
|
+
# Constant
|
33
|
+
# Parameter
|
34
|
+
# ResultCode
|
35
|
+
#
|
36
|
+
# Relationship Tree -----------
|
37
|
+
# Class
|
38
|
+
# Method
|
39
|
+
# Parameter
|
40
|
+
# Property
|
41
|
+
#
|
42
|
+
# GenericRef
|
43
|
+
# Callback
|
44
|
+
# Parameter
|
45
|
+
# ConstantGroup
|
46
|
+
# Constant
|
47
|
+
# DataType
|
48
|
+
# Parameter
|
49
|
+
# Function
|
50
|
+
# Parameter
|
51
|
+
#
|
52
|
+
#
|
53
|
+
module Cocoadex
|
54
|
+
class Model
|
55
|
+
end
|
56
|
+
end
|
@@ -4,7 +4,7 @@ require 'set'
|
|
4
4
|
module Cocoadex
|
5
5
|
# A model of a Cocoa API class or protocol
|
6
6
|
class Class < Entity
|
7
|
-
|
7
|
+
TEMPLATE_NAME=:class
|
8
8
|
|
9
9
|
attr_reader :description, :overview
|
10
10
|
|
@@ -48,7 +48,7 @@ module Cocoadex
|
|
48
48
|
@parents = doc.css("div.zSharedSpecBoxHeadList").first.css('a').map {|node| node.text}
|
49
49
|
|
50
50
|
parse_properties(doc)
|
51
|
-
parse_tasks(doc)
|
51
|
+
# parse_tasks(doc)
|
52
52
|
parse_methods(doc)
|
53
53
|
end
|
54
54
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class ConstantGroup < SequentialNodeElement
|
4
|
+
TEMPLATE_NAME=:constant_group
|
5
|
+
|
6
|
+
attr_reader :abstract, :declaration,
|
7
|
+
:discussion, :declared_in
|
8
|
+
|
9
|
+
def constants
|
10
|
+
@constants ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def handle_node node
|
14
|
+
if node.classes.include? "termdef"
|
15
|
+
node.css("dt").each do |field_title_node|
|
16
|
+
source = "#{@origin} > #{@name}"
|
17
|
+
field_name = field_title_node.css("code").text
|
18
|
+
description = field_title_node.next.css("p").map {|p| p.text}.join("\n")
|
19
|
+
constants << Constant.new(source,field_name, description)
|
20
|
+
end
|
21
|
+
elsif node.name == "p" and node.classes.empty?
|
22
|
+
@abstract = node.text
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Constant < Element
|
28
|
+
TEMPLATE_NAME=:constant
|
29
|
+
|
30
|
+
attr_reader :description
|
31
|
+
|
32
|
+
def initialize origin, name, description
|
33
|
+
@origin = origin
|
34
|
+
@name, @description = name, description
|
35
|
+
end
|
36
|
+
|
37
|
+
def origin
|
38
|
+
@origin
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
|
4
|
+
class DataType < SequentialNodeElement
|
5
|
+
TEMPLATE_NAME=:data_type
|
6
|
+
|
7
|
+
class Field < Parameter;end
|
8
|
+
|
9
|
+
attr_reader :abstract, :declaration, :declared_in,
|
10
|
+
:discussion, :availability, :considerations
|
11
|
+
attr_accessor :next_termdef
|
12
|
+
|
13
|
+
def fields
|
14
|
+
@fields ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def constants
|
18
|
+
@constants ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def origin
|
22
|
+
@origin
|
23
|
+
end
|
24
|
+
|
25
|
+
def handle_node node
|
26
|
+
if ["Fields","Constants"].include? node.text
|
27
|
+
next_termdef = node.text
|
28
|
+
elsif node.classes.include? "termdef" and not next_termdef.nil?
|
29
|
+
if list = termdef_to_properties(next_termdef)
|
30
|
+
node.css("dt").each do |field_title_node|
|
31
|
+
field_name = field_title_node.css("code").text
|
32
|
+
description = field_title_node.next.text
|
33
|
+
list << Field.new(field_name, description)
|
34
|
+
end
|
35
|
+
next_termdef = ""
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def termdef_to_properties termdef
|
41
|
+
case termdef
|
42
|
+
when "Fields" then fields
|
43
|
+
when "Constants" then constants
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -12,7 +12,9 @@ module Cocoadex
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def print
|
15
|
-
|
15
|
+
template_name = self.class.const_get("TEMPLATE_NAME")
|
16
|
+
path = Cocoadex.view_path(template_name)
|
17
|
+
template = IO.read(path, :mode => 'rb')
|
16
18
|
ERB.new(template, nil, '<>').result(binding)
|
17
19
|
end
|
18
20
|
|
@@ -27,5 +29,16 @@ module Cocoadex
|
|
27
29
|
def type
|
28
30
|
raise "#{self.class}#type is not defined"
|
29
31
|
end
|
32
|
+
|
33
|
+
def parse_parameters node
|
34
|
+
node.css("dt").each do |param|
|
35
|
+
name_nodes = param.css("em")
|
36
|
+
if name_nodes.size > 0
|
37
|
+
name = param.css("em").first.text
|
38
|
+
description = param.next.css("p").first.text
|
39
|
+
parameters << Parameter.new(name, description)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
30
43
|
end
|
31
44
|
end
|
@@ -2,8 +2,10 @@ module Cocoadex
|
|
2
2
|
# A top level element, roughly equivalent to one
|
3
3
|
# page of documentation
|
4
4
|
class Entity < Element
|
5
|
+
attr_reader :path
|
5
6
|
|
6
7
|
def initialize path
|
8
|
+
@path = path
|
7
9
|
text = clean(IO.read(path, :mode => 'rb'))
|
8
10
|
document = Nokogiri::HTML(text)
|
9
11
|
parse(document)
|
@@ -18,5 +20,9 @@ module Cocoadex
|
|
18
20
|
def strip text
|
19
21
|
text.gsub("  ","")
|
20
22
|
end
|
23
|
+
|
24
|
+
def section_by_title doc, title
|
25
|
+
doc.css("section").to_a.detect {|s| s.css("h2.jump").text == title }
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
class Function < SequentialNodeElement
|
4
|
+
attr_reader :abstract, :declaration, :declared_in,
|
5
|
+
:availability, :return_value
|
6
|
+
TEMPLATE_NAME=:method
|
7
|
+
|
8
|
+
def parameters
|
9
|
+
@parameters ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def discussion
|
13
|
+
""
|
14
|
+
end
|
15
|
+
|
16
|
+
def handle_node node
|
17
|
+
if node.classes.include? "parameters"
|
18
|
+
parse_parameters(node)
|
19
|
+
else
|
20
|
+
logger.debug("Unhandled function property: #{node.classes} => #{node.text}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def type
|
25
|
+
"Function"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
|
2
|
+
module Cocoadex
|
3
|
+
# A non-class reference document containing functions,
|
4
|
+
# constants, callbacks, result codes, and data types
|
5
|
+
class GenericRef < Entity
|
6
|
+
attr_reader :specs, :data_types, :overview,
|
7
|
+
:result_codes, :const_groups, :functions,
|
8
|
+
:callbacks
|
9
|
+
TEMPLATE_NAME=:generic_ref
|
10
|
+
|
11
|
+
def parse doc
|
12
|
+
@name = doc.title.sub("Reference","").strip
|
13
|
+
@specs = {}
|
14
|
+
|
15
|
+
parse_specbox(doc)
|
16
|
+
parse_overview(doc)
|
17
|
+
parse_data_types(doc)
|
18
|
+
parse_result_codes(doc)
|
19
|
+
parse_constants(doc)
|
20
|
+
parse_functions(doc)
|
21
|
+
parse_callbacks(doc)
|
22
|
+
end
|
23
|
+
|
24
|
+
def constants
|
25
|
+
@const_groups.map {|g| g.constants}.flatten
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_overview doc
|
29
|
+
if section = section_by_title(doc, "Overview")
|
30
|
+
@overview = section.text.sub("Overview","")
|
31
|
+
else
|
32
|
+
@overview = ""
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_specbox doc
|
37
|
+
specbox = doc.css(".specbox")
|
38
|
+
return if specbox.to_a.empty?
|
39
|
+
specbox.first.css("tr").each do |row|
|
40
|
+
title = row.css("td").first.css("strong").text
|
41
|
+
value = row.css("td").to_a[1].text.strip
|
42
|
+
@specs[title] = value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_callbacks doc
|
47
|
+
@callbacks = []
|
48
|
+
parse_section(doc, @callbacks, "Callbacks", Callback)
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_functions doc
|
52
|
+
@functions = []
|
53
|
+
parse_section(doc, @functions, "Functions", Function)
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_data_types doc
|
57
|
+
@data_types = []
|
58
|
+
parse_section(doc, @data_types, "Data Types", DataType)
|
59
|
+
end
|
60
|
+
|
61
|
+
def parse_constants doc
|
62
|
+
@const_groups = []
|
63
|
+
parse_section(doc, @const_groups, "Constants",ConstantGroup)
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_section doc, list, title, klass
|
67
|
+
if section = section_by_title(doc, title)
|
68
|
+
section.css("h3").each do |type_title|
|
69
|
+
list << klass.new(@name, type_title)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse_result_codes doc
|
75
|
+
@result_codes = []
|
76
|
+
if section = section_by_title(doc, "Result Codes")
|
77
|
+
table = section.css("table").first
|
78
|
+
table.css("tr").each do |row|
|
79
|
+
if cells = row.css("td") and cells.size > 0
|
80
|
+
value = cells[1].text
|
81
|
+
description = cells[2].css("p").map {|p| p.text}.join("\n\n")
|
82
|
+
@result_codes << ResultCode.new(@name, cells.first.text, value, description)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,81 +1,32 @@
|
|
1
1
|
|
2
2
|
module Cocoadex
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
TEMPLATE=Cocoadex::Templates::METHOD_DESCRIPTION
|
3
|
+
# A model of a method in a Cocoa class
|
4
|
+
class Method < NestedNodeElement
|
5
|
+
TEMPLATE_NAME=:method
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
attr_reader :abstract, :declaration, :discussion,
|
8
|
+
:declared_in, :availability, :parameters,
|
9
|
+
:return_value, :scope, :parent
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
attr_reader :name, :description
|
16
|
-
|
17
|
-
def initialize name, description
|
18
|
-
@name, @description = name, description
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
"#{name} - #{description}"
|
23
|
-
end
|
24
|
-
|
25
|
-
def <=> other
|
26
|
-
name <=> other.name if other.respond_to? :name
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def parameters
|
31
|
-
@parameters ||= []
|
32
|
-
end
|
33
|
-
|
34
|
-
def initialize parent_class, type, node
|
35
|
-
@parent = parent_class
|
36
|
-
@scope = type
|
37
|
-
@name = node.css("h3.#{type}Method").first.text
|
38
|
-
logger.debug("parsing #{@type} method #{@name}")
|
39
|
-
|
40
|
-
@abstract = node.css(".abstract").first.text
|
41
|
-
@declaration = node.css(".declaration").first.text
|
42
|
-
|
43
|
-
decl_nodes = node.css(".declaredIn code.HeaderFile")
|
44
|
-
@declared_in = decl_nodes.first.text if decl_nodes.size > 0
|
45
|
-
|
46
|
-
discussion_node = node.css(".discussion > p")
|
47
|
-
@discussion = discussion_node.first.text if discussion_node.length > 0
|
48
|
-
|
49
|
-
return_nodes = node.css(".return_value p")
|
50
|
-
@return_value = return_nodes.first.text if return_nodes.size > 0
|
51
|
-
|
52
|
-
ava_nodes = node.css(".availability > ul > li")
|
53
|
-
@availability = ava_nodes.first.text if ava_nodes.size > 0
|
11
|
+
def parameters
|
12
|
+
@parameters ||= []
|
13
|
+
end
|
54
14
|
|
55
|
-
|
56
|
-
|
15
|
+
def initialize parent_class, type, node
|
16
|
+
@parent = parent_class
|
17
|
+
@scope = type
|
18
|
+
@name = node.css("h3.#{type}Method").first.text
|
57
19
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
parameters.first.css("dt").each do |param|
|
62
|
-
name_nodes = param.css("em")
|
63
|
-
if name_nodes.size > 0
|
64
|
-
name = param.css("em").first.text
|
65
|
-
description = param.next.css("p").first.text
|
66
|
-
@parameters << Parameter.new(name, description)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
20
|
+
parse_properties(node)
|
21
|
+
parse_parameters(node.css(".parameters").first)
|
22
|
+
end
|
71
23
|
|
72
|
-
|
73
|
-
|
74
|
-
|
24
|
+
def type
|
25
|
+
"#{scope.to_s.capitalize} Method"
|
26
|
+
end
|
75
27
|
|
76
|
-
|
77
|
-
|
78
|
-
end
|
28
|
+
def origin
|
29
|
+
parent.to_s
|
79
30
|
end
|
80
31
|
end
|
81
32
|
end
|