Skip to content

Commit 3b4aa89

Browse files
committed
It now parses every complete instanceMethod or classMethod declaration in NSString and NSObject. Added return type to output.
1 parent fada93e commit 3b4aa89

File tree

7 files changed

+229
-32
lines changed

7 files changed

+229
-32
lines changed

Rakefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@ task :spec do
1010
end
1111
end
1212

13-
task :release do
13+
task :release_stable do
1414
cmd = "cp lib/macruby-docs.js lib/macruby-docs.stable.js"
1515
puts "Running: #{cmd}"
1616
system(cmd)
1717
end
18+
19+
task :release_edge do
20+
cmd = "cp lib/macruby-docs.js lib/macruby-docs.edge.js"
21+
puts "Running: #{cmd}"
22+
system(cmd)
23+
end

lib/macruby-docs.coffee

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ class Declaration
88
@declaration.match(pattern)[1]
99

1010
methodName: ->
11-
pattern = ///
12-
.+?\)(.+?):
13-
///
11+
if @hasParameters()
12+
pattern = /.+?\)(.+?):/
13+
else
14+
pattern = /.+?\)(.+)/
15+
1416
@declaration.match(pattern)[1]
1517

1618
isInstanceMethod: ->
@@ -20,16 +22,22 @@ class Declaration
2022
!!@declaration.match(pattern)
2123

2224
parameters: ->
23-
pattern = ///
24-
.+?:(.+)
25-
///
25+
return [] unless @hasParameters()
2626

27-
# Split between parameters (not within, like with "NSString *")
28-
parameters = @declaration.match(pattern)[1].replace(new RegExp(" \\*", "g"), "#*").split(' ')
29-
parameters = (parameter.replace('#*', ' *') for parameter in parameters)
27+
# Matches:
28+
# "keyName:(type)parameter" or "(type)parameter"
29+
pattern = ///
30+
(([a-zA-Z]+?:)? # Optionally matches "keyName:" before type
31+
\(.+?\) # Matches "(some type value)"
32+
.+?\b) # Matches the parameter name upto word boundary (space between parameters or end of line)
33+
///g
3034

35+
parameters = @declaration.match(pattern)[1..-1]
3136
@mapParameter(parameter) for parameter in parameters
3237

38+
hasParameters: ->
39+
@declaration.indexOf(":") != -1
40+
3341
mapParameter: (parameter) ->
3442
# Handles "(type)value"
3543
if parameter[0] == "("
@@ -60,7 +68,7 @@ class DocRenderer
6068
str = "<div><span>#{@className}#{@separator()}#{@declaration.methodName()}</span>"
6169
str += "<span style='color: #fff'><table style='color: #000; margin-left: 20px'>"
6270
str += ("<tr><td>#{param[0]}#{@addComma((i+=1), length)}</td><td style='color: gray; padding-left: 10px;'># (#{param[1]})</td></tr>" for param in parameters).join()
63-
str += "</table></span></div>"
71+
str += "</table></span><div style='margin-top: 10px; color: gray;'>Return type: (#{@declaration.returnType()})</div> </div>"
6472
str
6573
catch err
6674
'Could not parse or render, check issues at <a href="https://github.com/joakimk/macruby-docs-js/issues">https://github.com/joakimk/macruby-docs-js/issues</a>.'
@@ -96,10 +104,11 @@ if !window.in_tests
96104
try
97105
className = jQuery("#pageTitle", window.parent.frames[0].document).html().split(" ")[0]
98106
return if jQuery(".declaration .macruby", window.parent.frames[0].document).length > 0
99-
jQuery.each jQuery(".declaration", window.parent.frames[0].document), (i, element) ->
100-
content = element.innerHTML
107+
jQuery.each jQuery(".api .declaration", window.parent.frames[0].document), (i, element) ->
108+
content = element.textContent
101109
element.innerHTML = element.innerHTML + "<h5 class='macruby' style='margin-top: 20px'>MacRuby</h5>" + new DocRenderer(className, content).render()
102110
catch err
111+
console.log("macruby-docs.user.js error:")
103112
console.log(err)
104113

105114
setInterval(check, 1000)

lib/macruby-docs.edge.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
var Declaration, DocRenderer, addJQuery, main;
2+
Declaration = (function() {
3+
function Declaration(declaration) {
4+
this.declaration = declaration;
5+
}
6+
Declaration.prototype.returnType = function() {
7+
var pattern;
8+
pattern = /.\((.+?)\)/;
9+
return this.declaration.match(pattern)[1];
10+
};
11+
Declaration.prototype.methodName = function() {
12+
var pattern;
13+
if (this.hasParameters()) {
14+
pattern = /.+?\)(.+?):/;
15+
} else {
16+
pattern = /.+?\)(.+)/;
17+
}
18+
return this.declaration.match(pattern)[1];
19+
};
20+
Declaration.prototype.isInstanceMethod = function() {
21+
var pattern;
22+
pattern = /-.+/;
23+
return !!this.declaration.match(pattern);
24+
};
25+
Declaration.prototype.parameters = function() {
26+
var parameter, parameters, pattern, _i, _len, _results;
27+
if (!this.hasParameters()) {
28+
return [];
29+
}
30+
pattern = /(([a-zA-Z]+?:)?\(.+?\).+?\b)/g;
31+
parameters = this.declaration.match(pattern).slice(1);
32+
_results = [];
33+
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
34+
parameter = parameters[_i];
35+
_results.push(this.mapParameter(parameter));
36+
}
37+
return _results;
38+
};
39+
Declaration.prototype.hasParameters = function() {
40+
return this.declaration.indexOf(":") !== -1;
41+
};
42+
Declaration.prototype.mapParameter = function(parameter) {
43+
var arg, key, pattern, type, value, _ref, _ref2;
44+
if (parameter[0] === "(") {
45+
pattern = /\((.+?)\)(.+)/;
46+
return parameter.match(pattern).slice(1, 3).reverse();
47+
} else {
48+
pattern = /\((.+?)\)(.+)/;
49+
_ref = parameter.split(':'), key = _ref[0], arg = _ref[1];
50+
_ref2 = arg.match(pattern).slice(1, 3).reverse(), value = _ref2[0], type = _ref2[1];
51+
return ["" + key + ": " + value, type];
52+
}
53+
};
54+
return Declaration;
55+
})();
56+
DocRenderer = (function() {
57+
function DocRenderer(className, declarationText) {
58+
this.className = className;
59+
this.declarationText = declarationText;
60+
}
61+
DocRenderer.prototype.render = function() {
62+
var i, length, param, parameters, str;
63+
try {
64+
this.declaration = new Declaration(this.declarationText);
65+
parameters = this.declaration.parameters();
66+
length = parameters.length;
67+
i = 0;
68+
str = "<div><span>" + this.className + (this.separator()) + (this.declaration.methodName()) + "</span>";
69+
str += "<span style='color: #fff'><table style='color: #000; margin-left: 20px'>";
70+
str += ((function() {
71+
var _i, _len, _results;
72+
_results = [];
73+
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
74+
param = parameters[_i];
75+
_results.push("<tr><td>" + param[0] + (this.addComma((i += 1), length)) + "</td><td style='color: gray; padding-left: 10px;'># (" + param[1] + ")</td></tr>");
76+
}
77+
return _results;
78+
}).call(this)).join();
79+
str += "</table></span><div style='margin-top: 10px; color: gray;'>Return type: (" + (this.declaration.returnType()) + ")</div> </div>";
80+
return str;
81+
} catch (err) {
82+
return 'Could not parse or render, check issues at <a href="https://github.com/joakimk/macruby-docs-js/issues">https://github.com/joakimk/macruby-docs-js/issues</a>.';
83+
}
84+
};
85+
DocRenderer.prototype.separator = function() {
86+
if (this.declaration.isInstanceMethod()) {
87+
return "#";
88+
} else {
89+
return ".";
90+
}
91+
};
92+
DocRenderer.prototype.addComma = function(i, length) {
93+
if (length !== i) {
94+
return ',';
95+
} else {
96+
return '';
97+
}
98+
};
99+
return DocRenderer;
100+
})();
101+
if (!window.in_tests) {
102+
addJQuery = function(callback) {
103+
var addScriptToPage, script;
104+
script = document.createElement("script");
105+
script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js");
106+
addScriptToPage = function() {
107+
script = document.createElement("script");
108+
script.textContent = "(" + callback.toString() + ")();";
109+
return document.body.appendChild(script);
110+
};
111+
script.addEventListener('load', addScriptToPage, false);
112+
return document.body.appendChild(script);
113+
};
114+
main = function() {
115+
var check;
116+
$.noConflict();
117+
check = function() {
118+
var className;
119+
try {
120+
className = jQuery("#pageTitle", window.parent.frames[0].document).html().split(" ")[0];
121+
if (jQuery(".declaration .macruby", window.parent.frames[0].document).length > 0) {
122+
return;
123+
}
124+
return jQuery.each(jQuery(".api .declaration", window.parent.frames[0].document), function(i, element) {
125+
var content;
126+
content = element.textContent;
127+
return element.innerHTML = element.innerHTML + "<h5 class='macruby' style='margin-top: 20px'>MacRuby</h5>" + new DocRenderer(className, content).render();
128+
});
129+
} catch (err) {
130+
console.log("macruby-docs.user.js error:");
131+
return console.log(err);
132+
}
133+
};
134+
return setInterval(check, 1000);
135+
};
136+
addJQuery(main);
137+
}

lib/macruby-docs.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ Declaration = (function() {
1010
};
1111
Declaration.prototype.methodName = function() {
1212
var pattern;
13-
pattern = /.+?\)(.+?):/;
13+
if (this.hasParameters()) {
14+
pattern = /.+?\)(.+?):/;
15+
} else {
16+
pattern = /.+?\)(.+)/;
17+
}
1418
return this.declaration.match(pattern)[1];
1519
};
1620
Declaration.prototype.isInstanceMethod = function() {
@@ -20,24 +24,21 @@ Declaration = (function() {
2024
};
2125
Declaration.prototype.parameters = function() {
2226
var parameter, parameters, pattern, _i, _len, _results;
23-
pattern = /.+?:(.+)/;
24-
parameters = this.declaration.match(pattern)[1].replace(new RegExp(" \\*", "g"), "#*").split(' ');
25-
parameters = (function() {
26-
var _i, _len, _results;
27-
_results = [];
28-
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
29-
parameter = parameters[_i];
30-
_results.push(parameter.replace('#*', ' *'));
31-
}
32-
return _results;
33-
})();
27+
if (!this.hasParameters()) {
28+
return [];
29+
}
30+
pattern = /(([a-zA-Z]+?:)?\(.+?\).+?\b)/g;
31+
parameters = this.declaration.match(pattern).slice(1);
3432
_results = [];
3533
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
3634
parameter = parameters[_i];
3735
_results.push(this.mapParameter(parameter));
3836
}
3937
return _results;
4038
};
39+
Declaration.prototype.hasParameters = function() {
40+
return this.declaration.indexOf(":") !== -1;
41+
};
4142
Declaration.prototype.mapParameter = function(parameter) {
4243
var arg, key, pattern, type, value, _ref, _ref2;
4344
if (parameter[0] === "(") {
@@ -75,7 +76,7 @@ DocRenderer = (function() {
7576
}
7677
return _results;
7778
}).call(this)).join();
78-
str += "</table></span></div>";
79+
str += "</table></span><div style='margin-top: 10px; color: gray;'>Return type: (" + (this.declaration.returnType()) + ")</div> </div>";
7980
return str;
8081
} catch (err) {
8182
return 'Could not parse or render, check issues at <a href="https://github.com/joakimk/macruby-docs-js/issues">https://github.com/joakimk/macruby-docs-js/issues</a>.';
@@ -120,12 +121,13 @@ if (!window.in_tests) {
120121
if (jQuery(".declaration .macruby", window.parent.frames[0].document).length > 0) {
121122
return;
122123
}
123-
return jQuery.each(jQuery(".declaration", window.parent.frames[0].document), function(i, element) {
124+
return jQuery.each(jQuery(".api .declaration", window.parent.frames[0].document), function(i, element) {
124125
var content;
125-
content = element.innerHTML;
126+
content = element.textContent;
126127
return element.innerHTML = element.innerHTML + "<h5 class='macruby' style='margin-top: 20px'>MacRuby</h5>" + new DocRenderer(className, content).render();
127128
});
128129
} catch (err) {
130+
console.log("macruby-docs.user.js error:");
129131
return console.log(err);
130132
}
131133
};

spec/macruby-docs_spec.coffee

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,15 @@ describe "Declaration", ->
2828
expect(parameters[3]).toEqual([ "orthography: orthography", "NSOrthography *" ])
2929
expect(parameters[4]).toEqual([ "tokenRanges: tokenRanges", "NSArray **" ])
3030

31-
# it "can handle multiple spaces within a type", ->
32-
# dec = new Declaration("- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding")
33-
# expect(dec.parameters()).toEqual([ [ "nullTerminatedCString", "const char *" ], [ "encoding: encoding", "NSStringEncoding" ] ])
31+
it "can handle multiple spaces within a type", ->
32+
dec = new Declaration("- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding")
33+
expect(dec.parameters()).toEqual([ [ "nullTerminatedCString", "const char *" ], [ "encoding: encoding", "NSStringEncoding" ] ])
34+
35+
it "can parse methods without parameters", ->
36+
dec = new Declaration("+ (id)string")
37+
expect(dec.parameters()).toEqual([])
38+
expect(dec.methodName()).toEqual("string")
39+
expect(dec.returnType()).toEqual("id")
3440

3541
describe "DocRenderer", ->
3642
it "can render docs", ->

spec/macruby-docs_spec.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe("Declaration", function() {
2121
dec = new Declaration("- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)flag");
2222
return expect(dec.parameters()).toEqual([["encoding", "NSStringEncoding"], ["allowLossyConversion: flag", "BOOL"]]);
2323
});
24-
return it("can parse more complex parameters", function() {
24+
it("can parse more complex parameters", function() {
2525
var dec, parameters;
2626
dec = new Declaration("- (NSArray *)linguisticTagsInRange:(NSRange)range scheme:(NSString *)tagScheme options:(NSLinguisticTaggerOptions)opts orthography:(NSOrthography *)orthography tokenRanges:(NSArray **)tokenRanges");
2727
parameters = dec.parameters();
@@ -32,6 +32,18 @@ describe("Declaration", function() {
3232
expect(parameters[3]).toEqual(["orthography: orthography", "NSOrthography *"]);
3333
return expect(parameters[4]).toEqual(["tokenRanges: tokenRanges", "NSArray **"]);
3434
});
35+
it("can handle multiple spaces within a type", function() {
36+
var dec;
37+
dec = new Declaration("- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding");
38+
return expect(dec.parameters()).toEqual([["nullTerminatedCString", "const char *"], ["encoding: encoding", "NSStringEncoding"]]);
39+
});
40+
return it("can parse methods without parameters", function() {
41+
var dec;
42+
dec = new Declaration("+ (id)string");
43+
expect(dec.parameters()).toEqual([]);
44+
expect(dec.methodName()).toEqual("string");
45+
return expect(dec.returnType()).toEqual("id");
46+
});
3547
});
3648
describe("DocRenderer", function() {
3749
it("can render docs", function() {

tools/macruby-docs-edge.user.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// ==UserScript==
2+
// @name (edge version) MacRuby Docs JS - Adds MacRuby/RubyMotion syntax to Apple's Objective-C/Cocoa docs.
3+
// @namespace http://twitter.com/joakimk
4+
// @description Adds MacRuby/RubyMotion syntax to Apple's Objective-C/Cocoa docs.
5+
// @include http://developer.apple.com/library/mac/*
6+
// @include https://developer.apple.com/library/mac/*
7+
// @version 1.0
8+
// ==/UserScript==
9+
10+
(function() {
11+
var head = document.getElementsByTagName("head")[0];
12+
13+
var require = function(src) {
14+
var script = document.createElement("script");
15+
script.setAttribute("language", "javascript");
16+
script.setAttribute("src", src);
17+
head.appendChild(script);
18+
};
19+
20+
var load_latest = function() {
21+
require("https://raw.github.com/joakimk/macruby-docs-js/master/lib/macruby-docs.edge.js");
22+
};
23+
24+
load_latest();
25+
})();

0 commit comments

Comments
 (0)