Skip to content

Commit

Permalink
It now parses every complete instanceMethod or classMethod declaratio…
Browse files Browse the repository at this point in the history
…n in NSString and NSObject. Added return type to output.
  • Loading branch information
joakimk committed May 12, 2012
1 parent fada93e commit 3b4aa89
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 32 deletions.
8 changes: 7 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ task :spec do
end
end

task :release do
task :release_stable do
cmd = "cp lib/macruby-docs.js lib/macruby-docs.stable.js"
puts "Running: #{cmd}"
system(cmd)
end

task :release_edge do
cmd = "cp lib/macruby-docs.js lib/macruby-docs.edge.js"
puts "Running: #{cmd}"
system(cmd)
end
33 changes: 21 additions & 12 deletions lib/macruby-docs.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ class Declaration
@declaration.match(pattern)[1]

methodName: ->
pattern = ///
.+?\)(.+?):
///
if @hasParameters()
pattern = /.+?\)(.+?):/
else
pattern = /.+?\)(.+)/

@declaration.match(pattern)[1]

isInstanceMethod: ->
Expand All @@ -20,16 +22,22 @@ class Declaration
!!@declaration.match(pattern)

parameters: ->
pattern = ///
.+?:(.+)
///
return [] unless @hasParameters()

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

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

hasParameters: ->
@declaration.indexOf(":") != -1

mapParameter: (parameter) ->
# Handles "(type)value"
if parameter[0] == "("
Expand Down Expand Up @@ -60,7 +68,7 @@ class DocRenderer
str = "<div><span>#{@className}#{@separator()}#{@declaration.methodName()}</span>"
str += "<span style='color: #fff'><table style='color: #000; margin-left: 20px'>"
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()
str += "</table></span></div>"
str += "</table></span><div style='margin-top: 10px; color: gray;'>Return type: (#{@declaration.returnType()})</div> </div>"
str
catch err
'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>.'
Expand Down Expand Up @@ -96,10 +104,11 @@ if !window.in_tests
try
className = jQuery("#pageTitle", window.parent.frames[0].document).html().split(" ")[0]
return if jQuery(".declaration .macruby", window.parent.frames[0].document).length > 0
jQuery.each jQuery(".declaration", window.parent.frames[0].document), (i, element) ->
content = element.innerHTML
jQuery.each jQuery(".api .declaration", window.parent.frames[0].document), (i, element) ->
content = element.textContent
element.innerHTML = element.innerHTML + "<h5 class='macruby' style='margin-top: 20px'>MacRuby</h5>" + new DocRenderer(className, content).render()
catch err
console.log("macruby-docs.user.js error:")
console.log(err)

setInterval(check, 1000)
Expand Down
137 changes: 137 additions & 0 deletions lib/macruby-docs.edge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
var Declaration, DocRenderer, addJQuery, main;
Declaration = (function() {
function Declaration(declaration) {
this.declaration = declaration;
}
Declaration.prototype.returnType = function() {
var pattern;
pattern = /.\((.+?)\)/;
return this.declaration.match(pattern)[1];
};
Declaration.prototype.methodName = function() {
var pattern;
if (this.hasParameters()) {
pattern = /.+?\)(.+?):/;
} else {
pattern = /.+?\)(.+)/;
}
return this.declaration.match(pattern)[1];
};
Declaration.prototype.isInstanceMethod = function() {
var pattern;
pattern = /-.+/;
return !!this.declaration.match(pattern);
};
Declaration.prototype.parameters = function() {
var parameter, parameters, pattern, _i, _len, _results;
if (!this.hasParameters()) {
return [];
}
pattern = /(([a-zA-Z]+?:)?\(.+?\).+?\b)/g;
parameters = this.declaration.match(pattern).slice(1);
_results = [];
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
parameter = parameters[_i];
_results.push(this.mapParameter(parameter));
}
return _results;
};
Declaration.prototype.hasParameters = function() {
return this.declaration.indexOf(":") !== -1;
};
Declaration.prototype.mapParameter = function(parameter) {
var arg, key, pattern, type, value, _ref, _ref2;
if (parameter[0] === "(") {
pattern = /\((.+?)\)(.+)/;
return parameter.match(pattern).slice(1, 3).reverse();
} else {
pattern = /\((.+?)\)(.+)/;
_ref = parameter.split(':'), key = _ref[0], arg = _ref[1];
_ref2 = arg.match(pattern).slice(1, 3).reverse(), value = _ref2[0], type = _ref2[1];
return ["" + key + ": " + value, type];
}
};
return Declaration;
})();
DocRenderer = (function() {
function DocRenderer(className, declarationText) {
this.className = className;
this.declarationText = declarationText;
}
DocRenderer.prototype.render = function() {
var i, length, param, parameters, str;
try {
this.declaration = new Declaration(this.declarationText);
parameters = this.declaration.parameters();
length = parameters.length;
i = 0;
str = "<div><span>" + this.className + (this.separator()) + (this.declaration.methodName()) + "</span>";
str += "<span style='color: #fff'><table style='color: #000; margin-left: 20px'>";
str += ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
param = parameters[_i];
_results.push("<tr><td>" + param[0] + (this.addComma((i += 1), length)) + "</td><td style='color: gray; padding-left: 10px;'># (" + param[1] + ")</td></tr>");
}
return _results;
}).call(this)).join();
str += "</table></span><div style='margin-top: 10px; color: gray;'>Return type: (" + (this.declaration.returnType()) + ")</div> </div>";
return str;
} catch (err) {
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>.';
}
};
DocRenderer.prototype.separator = function() {
if (this.declaration.isInstanceMethod()) {
return "#";
} else {
return ".";
}
};
DocRenderer.prototype.addComma = function(i, length) {
if (length !== i) {
return ',';
} else {
return '';
}
};
return DocRenderer;
})();
if (!window.in_tests) {
addJQuery = function(callback) {
var addScriptToPage, script;
script = document.createElement("script");
script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js");
addScriptToPage = function() {
script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
return document.body.appendChild(script);
};
script.addEventListener('load', addScriptToPage, false);
return document.body.appendChild(script);
};
main = function() {
var check;
$.noConflict();
check = function() {
var className;
try {
className = jQuery("#pageTitle", window.parent.frames[0].document).html().split(" ")[0];
if (jQuery(".declaration .macruby", window.parent.frames[0].document).length > 0) {
return;
}
return jQuery.each(jQuery(".api .declaration", window.parent.frames[0].document), function(i, element) {
var content;
content = element.textContent;
return element.innerHTML = element.innerHTML + "<h5 class='macruby' style='margin-top: 20px'>MacRuby</h5>" + new DocRenderer(className, content).render();
});
} catch (err) {
console.log("macruby-docs.user.js error:");
return console.log(err);
}
};
return setInterval(check, 1000);
};
addJQuery(main);
}
32 changes: 17 additions & 15 deletions lib/macruby-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ Declaration = (function() {
};
Declaration.prototype.methodName = function() {
var pattern;
pattern = /.+?\)(.+?):/;
if (this.hasParameters()) {
pattern = /.+?\)(.+?):/;
} else {
pattern = /.+?\)(.+)/;
}
return this.declaration.match(pattern)[1];
};
Declaration.prototype.isInstanceMethod = function() {
Expand All @@ -20,24 +24,21 @@ Declaration = (function() {
};
Declaration.prototype.parameters = function() {
var parameter, parameters, pattern, _i, _len, _results;
pattern = /.+?:(.+)/;
parameters = this.declaration.match(pattern)[1].replace(new RegExp(" \\*", "g"), "#*").split(' ');
parameters = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
parameter = parameters[_i];
_results.push(parameter.replace('#*', ' *'));
}
return _results;
})();
if (!this.hasParameters()) {
return [];
}
pattern = /(([a-zA-Z]+?:)?\(.+?\).+?\b)/g;
parameters = this.declaration.match(pattern).slice(1);
_results = [];
for (_i = 0, _len = parameters.length; _i < _len; _i++) {
parameter = parameters[_i];
_results.push(this.mapParameter(parameter));
}
return _results;
};
Declaration.prototype.hasParameters = function() {
return this.declaration.indexOf(":") !== -1;
};
Declaration.prototype.mapParameter = function(parameter) {
var arg, key, pattern, type, value, _ref, _ref2;
if (parameter[0] === "(") {
Expand Down Expand Up @@ -75,7 +76,7 @@ DocRenderer = (function() {
}
return _results;
}).call(this)).join();
str += "</table></span></div>";
str += "</table></span><div style='margin-top: 10px; color: gray;'>Return type: (" + (this.declaration.returnType()) + ")</div> </div>";
return str;
} catch (err) {
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>.';
Expand Down Expand Up @@ -120,12 +121,13 @@ if (!window.in_tests) {
if (jQuery(".declaration .macruby", window.parent.frames[0].document).length > 0) {
return;
}
return jQuery.each(jQuery(".declaration", window.parent.frames[0].document), function(i, element) {
return jQuery.each(jQuery(".api .declaration", window.parent.frames[0].document), function(i, element) {
var content;
content = element.innerHTML;
content = element.textContent;
return element.innerHTML = element.innerHTML + "<h5 class='macruby' style='margin-top: 20px'>MacRuby</h5>" + new DocRenderer(className, content).render();
});
} catch (err) {
console.log("macruby-docs.user.js error:");
return console.log(err);
}
};
Expand Down
12 changes: 9 additions & 3 deletions spec/macruby-docs_spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ describe "Declaration", ->
expect(parameters[3]).toEqual([ "orthography: orthography", "NSOrthography *" ])
expect(parameters[4]).toEqual([ "tokenRanges: tokenRanges", "NSArray **" ])

# it "can handle multiple spaces within a type", ->
# dec = new Declaration("- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding")
# expect(dec.parameters()).toEqual([ [ "nullTerminatedCString", "const char *" ], [ "encoding: encoding", "NSStringEncoding" ] ])
it "can handle multiple spaces within a type", ->
dec = new Declaration("- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding")
expect(dec.parameters()).toEqual([ [ "nullTerminatedCString", "const char *" ], [ "encoding: encoding", "NSStringEncoding" ] ])

it "can parse methods without parameters", ->
dec = new Declaration("+ (id)string")
expect(dec.parameters()).toEqual([])
expect(dec.methodName()).toEqual("string")
expect(dec.returnType()).toEqual("id")

describe "DocRenderer", ->
it "can render docs", ->
Expand Down
14 changes: 13 additions & 1 deletion spec/macruby-docs_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("Declaration", function() {
dec = new Declaration("- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)flag");
return expect(dec.parameters()).toEqual([["encoding", "NSStringEncoding"], ["allowLossyConversion: flag", "BOOL"]]);
});
return it("can parse more complex parameters", function() {
it("can parse more complex parameters", function() {
var dec, parameters;
dec = new Declaration("- (NSArray *)linguisticTagsInRange:(NSRange)range scheme:(NSString *)tagScheme options:(NSLinguisticTaggerOptions)opts orthography:(NSOrthography *)orthography tokenRanges:(NSArray **)tokenRanges");
parameters = dec.parameters();
Expand All @@ -32,6 +32,18 @@ describe("Declaration", function() {
expect(parameters[3]).toEqual(["orthography: orthography", "NSOrthography *"]);
return expect(parameters[4]).toEqual(["tokenRanges: tokenRanges", "NSArray **"]);
});
it("can handle multiple spaces within a type", function() {
var dec;
dec = new Declaration("- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding");
return expect(dec.parameters()).toEqual([["nullTerminatedCString", "const char *"], ["encoding: encoding", "NSStringEncoding"]]);
});
return it("can parse methods without parameters", function() {
var dec;
dec = new Declaration("+ (id)string");
expect(dec.parameters()).toEqual([]);
expect(dec.methodName()).toEqual("string");
return expect(dec.returnType()).toEqual("id");
});
});
describe("DocRenderer", function() {
it("can render docs", function() {
Expand Down
25 changes: 25 additions & 0 deletions tools/macruby-docs-edge.user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ==UserScript==
// @name (edge version) MacRuby Docs JS - Adds MacRuby/RubyMotion syntax to Apple's Objective-C/Cocoa docs.
// @namespace http://twitter.com/joakimk
// @description Adds MacRuby/RubyMotion syntax to Apple's Objective-C/Cocoa docs.
// @include http://developer.apple.com/library/mac/*
// @include https://developer.apple.com/library/mac/*
// @version 1.0
// ==/UserScript==

(function() {
var head = document.getElementsByTagName("head")[0];

var require = function(src) {
var script = document.createElement("script");
script.setAttribute("language", "javascript");
script.setAttribute("src", src);
head.appendChild(script);
};

var load_latest = function() {
require("https://raw.github.com/joakimk/macruby-docs-js/master/lib/macruby-docs.edge.js");
};

load_latest();
})();

0 comments on commit 3b4aa89

Please sign in to comment.