markdown_ruby_documentation 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d39e3d18cd3a64d5b953bbacef111b3628327fad
4
- data.tar.gz: ab5e4c28c68bba449977477e375fac1b89db4e14
3
+ metadata.gz: 98da1a6202c25d0e20c630339f0ec5c9c6bb1898
4
+ data.tar.gz: 6af3bf690dd9f17d014ea6c5cc28eca39e975172
5
5
  SHA512:
6
- metadata.gz: afa43b83d03e03e1e97c5ae87d7e319885ae111c02b1ea7c6d6d09d31ac85b8f4beee1d8fc8b579db929e1ed29513ba25ba82a88e20e9c15488726caeb379ad5
7
- data.tar.gz: 69c1b5800e28bfc574ecc51a981679bacd06147abf46e5efaa6408f942f3d9f468fc18e6ca1081a22d01c5e12cff07eca8fc1d6eff9ad6d513cd8642fada9240
6
+ metadata.gz: 333233006d8b7304ed481d52b0b5d38b2b7605d644fae481d584be890ac59af4f9b3c43faaa8c29cc2f1e6dc3fa954fcb18d7481060640e86be4abb014188eb0
7
+ data.tar.gz: a06f239ab1f24aabf81c63e0adf2f34f35d01a4df7558d2a5f1eed1119d5393991c64a83ea6b721e4097be79846ada30dc425e349a49b514a641650e204858e1
data/README.md CHANGED
@@ -86,11 +86,29 @@ Creates a url to the file on GitHub based on the current sha or it defaults to m
86
86
  * "#instance_method_name" an instance method in the current scope.
87
87
  * `__method__` returns `#<current_method_name>`
88
88
 
89
- #### `pretty_code(ruby_source)`
90
- Convert underscore methods to more English like sentence.
89
+ #### `ruby_to_markdown`
90
+ Converts case statements and if statements to bulleted markdown
91
+ **option 1**
92
+ * param [String] ruby_source
93
+ * param [Hash] disable_processors (optional) See processors list.
94
+ *example ruby_to_markdown "def method_name\n'hello'\nend", readable_ruby_numbers: false**
95
+ **option 2 - Assumes methods source of current method**
96
+ * param [Hash] disable_processors (optional) See processors list.
97
+ *example ruby_to_markdown readable_ruby_numbers: false*
98
+
99
+ **processors**
100
+ * readable_ruby_numbers
101
+ * pretty_early_return
102
+ * convert_early_return_to_if_else
103
+ * ternary_to_if_else
104
+ * ruby_if_statement_to_md
105
+ * ruby_case_statement_to_md
106
+ * ruby_operators_to_english
107
+ * methods_as_local_links
108
+ * remove_end_keyword
109
+ * constants_with_name_and_value
110
+ * remove_memoized_vars
91
111
 
92
- #### `link_local_methods_from_pretty_code(pretty_code, include: <Optional array of matching strings>)`
93
- link_local_methods_from_pretty_code("`hello i am a method`") => "[hello i am a method](#hello-i-am-a-method)"
94
112
 
95
113
  #### `format_link`
96
114
  format_link "#i_do_other_things" => [I do other things](#i-do-other-things)
@@ -98,18 +116,12 @@ format_link "The method 10", "#i_do_other_things" => [The method 10](#i-do-other
98
116
 
99
117
  Instance method that call other methods will results in an error.
100
118
 
101
- #### `method_as_local_links`
102
- method_as_local_links("i_return_one + i_return_two") => "^`i_return_one` + ^`i_return_two`"
119
+ #### `methods_as_local_links`
120
+ methods_as_local_links("i_return_one + i_return_two") => "^`i_return_one` + ^`i_return_two`"
103
121
 
104
122
  #### `constants_with_name_and_value`
105
123
  constants_with_name_and_value("SOME_CONST_VALUE") => "`SOME_CONST_VALUE => "1"`"
106
124
 
107
- #### `quoted_strings_as_local_links(text, include: <Optional array of matching strings>)`
108
- quoted_strings_as_local_links('"this is Bob"') => "^`the_is_bob`"
109
-
110
- #### `ruby_to_markdown`
111
- Converts case statements and if statements to bulleted markdown
112
-
113
125
  #### `readable_ruby_numbers`
114
126
  Add commas to any ruby numbers. To provide additional formatting it yields a block given the number object.
115
127
 
@@ -1,7 +1,9 @@
1
1
  require "markdown_ruby_documentation/version"
2
2
  require "markdown_ruby_documentation/summary"
3
- require "markdown_ruby_documentation/instance_to_class_methods"
4
- require "markdown_ruby_documentation/print_method_source"
3
+ require "markdown_ruby_documentation/template_parser/parsing"
4
+ require "markdown_ruby_documentation/template_parser/any_args"
5
+ require "markdown_ruby_documentation/template_parser/instance_to_class_methods"
6
+ require "markdown_ruby_documentation/template_parser/print_method_source"
5
7
  require "markdown_ruby_documentation/template_parser"
6
8
  require "markdown_ruby_documentation/markdown_presenter"
7
9
  require "markdown_ruby_documentation/generate"
@@ -14,16 +14,7 @@ module MarkdownRubyDocumentation
14
14
  interface
15
15
  end
16
16
 
17
- private
18
-
19
- def constants
20
- subject.constants.each_with_object({}) do |v, const|
21
- c = subject.const_get(v)
22
- const[v] = format(c) unless c.class == Module || c.class == Class
23
- end
24
- end
25
-
26
- def format(value)
17
+ def self.format(value)
27
18
  case value
28
19
  when Fixnum
29
20
  ActiveSupport::NumberHelper.number_to_delimited(value)
@@ -34,5 +25,13 @@ module MarkdownRubyDocumentation
34
25
  end
35
26
  end
36
27
 
28
+ private
29
+
30
+ def constants
31
+ subject.constants.each_with_object({}) do |v, const|
32
+ c = subject.const_get(v)
33
+ const[v] = self.class.format(c) unless c.class == Module || c.class == Class
34
+ end
35
+ end
37
36
  end
38
37
  end
@@ -1,5 +1,6 @@
1
1
  module MarkdownRubyDocumentation
2
2
  class Method
3
+ InvalidMethodReference = Class.new(StandardError)
3
4
  attr_reader :method_reference
4
5
  protected :method_reference
5
6
 
@@ -15,6 +16,7 @@ module MarkdownRubyDocumentation
15
16
  # "SomeClass#instance_method_name" an instance method on a specific constant.
16
17
  # "#instance_method_name" an instance method in the current scope.
17
18
  def self.create(method_reference, null_method: false, context: Kernel)
19
+ return method_reference if method_reference.is_a?(Method)
18
20
  case method_reference
19
21
  when InstanceMethod
20
22
  InstanceMethod.new(method_reference, context: context)
@@ -24,7 +26,7 @@ module MarkdownRubyDocumentation
24
26
  if null_method
25
27
  NullMethod.new(method_reference, context: context)
26
28
  else
27
- raise ArgumentError, "method_reference is formatted incorrectly: '#{method_reference}'"
29
+ raise InvalidMethodReference, "method_reference is formatted incorrectly: '#{method_reference}'"
28
30
  end
29
31
  end
30
32
  end
@@ -41,7 +43,7 @@ module MarkdownRubyDocumentation
41
43
 
42
44
  def self.===(value)
43
45
  if value.is_a?(String)
44
- value.include?(type_symbol)
46
+ value.include?(type_symbol) && !!/\A[:A-Za-z_0-9!?#{type_symbol}]+\z/.match(value)
45
47
  else
46
48
  super
47
49
  end
@@ -44,14 +44,16 @@ module MarkdownRubyDocumentation
44
44
  using
45
45
  )
46
46
 
47
- attr_reader :ruby_class, :methods, :erb_methods_class
47
+ attr_reader :ruby_class, :methods, :erb_methods_class, :current_method
48
48
 
49
49
  def parser
50
50
  @parser ||= methods.each_with_object({}) do |method, hash|
51
51
  begin
52
- value = parse_erb(insert_method_name(strip_comment_hash(extract_dsl_comment_from_method(method)), method), method)
52
+ @current_method = method
53
+ value = parse_erb(insert_method_name(strip_comment_hash(extract_dsl_comment_from_method(method)), method), method)
53
54
  rescue MethodSource::SourceNotFoundError => e
54
- value = false
55
+ @current_method = nil
56
+ value = false
55
57
  puts e.message unless IGNORE_METHODS.any? { |im| e.message.include? im }
56
58
  end
57
59
  if value
@@ -61,6 +63,8 @@ module MarkdownRubyDocumentation
61
63
  end
62
64
 
63
65
  module CommentMacros
66
+ include Parsing
67
+
64
68
  # @param [String] str
65
69
  # @example
66
70
  # @return [String] of any comments proceeding a method def
@@ -79,7 +83,7 @@ module MarkdownRubyDocumentation
79
83
  # @param [String] str
80
84
  # @example
81
85
  # @return [Object] anything that the evaluated method would return.
82
- def eval_method(str)
86
+ def eval_method(str=current_method)
83
87
  case (method = Method.create(str, context: ruby_class))
84
88
  when ClassMethod
85
89
  method.context.public_send(method.name)
@@ -88,58 +92,99 @@ module MarkdownRubyDocumentation
88
92
  end
89
93
  end
90
94
 
91
- # @param [String] input
95
+ # @param [String] method_reference
92
96
  # @return [String] the source of a method block is returned as text.
93
- def print_method_source(input)
94
- method = Method.create(input.dup, context: ruby_class)
97
+ def print_method_source(method_reference=current_method)
98
+ method = Method.create(method_reference.dup, context: ruby_class)
95
99
  PrintMethodSource.new(method: method).print
96
100
  end
97
101
 
98
- def git_hub_method_url(input)
99
- method = Method.create(input.dup, context: ruby_class)
102
+
103
+ # @param [String] method_reference
104
+ def git_hub_method_url(method_reference=current_method)
105
+ method = Method.create(method_reference.dup, context: ruby_class)
100
106
  GitHubLink::MethodUrl.new(subject: method.context, method_object: method)
101
107
  end
102
108
 
103
- def git_hub_file_url(file_path)
104
- if file_path.include?("/")
105
- GitHubLink::FileUrl.new(file_path: file_path)
109
+ def git_hub_file_url(file_path_or_const)
110
+ if file_path_or_const.include?("/")
111
+ GitHubLink::FileUrl.new(file_path: file_path_or_const)
106
112
  else
107
- const = Object.const_get(file_path)
113
+ const = Object.const_get(file_path_or_const)
108
114
  a_method = const.public_instance_methods.first
109
- git_hub_method_url("#{file_path}##{a_method}")
115
+ git_hub_method_url("#{file_path_or_const}##{a_method}")
110
116
  end
111
117
  end
112
118
 
113
- def pretty_code(source_code, humanize: true)
114
- source_code = ternary_to_if_else(source_code)
115
- source_code = pretty_early_return(source_code)
116
- source_code.gsub!(/@[a-z][a-z0-9_]+ \|\|=?\s/, "") # @memoized_vars ||=
117
- source_code.gsub!(":", '')
118
- source_code.gsub!("&&", "and")
119
- source_code.gsub!(">=", "is greater than or equal to")
120
- source_code.gsub!("<=", "is less than or equal to")
121
- source_code.gsub!(" < ", " is less than ")
122
- source_code.gsub!(" > ", " is greater than ")
123
- source_code.gsub!(" == ", " Equal to ")
124
- source_code.gsub!("nil?", "is missing?")
125
- source_code.gsub!("elsif", "else if")
126
- source_code.gsub!("||", "or")
127
- source_code.gsub!(/([0-9][0-9_]+[0-9]+)/) do |match|
128
- match.gsub("_", ",")
129
- end
130
- if humanize
131
- source_code.gsub!(/["']?[a-z_A-Z?!0-9]*["']?/) do |s|
132
- if s.include?("_") && !(/["'][a-z_A-Z?!0-9]*["']/ =~ s)
133
- "'#{s.humanize}'"
134
- else
135
- s.humanize(capitalize: false)
136
- end
137
- end
119
+ RUBY_TO_MARKDOWN_PROCESSORS = [
120
+ :readable_ruby_numbers,
121
+ :pretty_early_return,
122
+ :convert_early_return_to_if_else,
123
+ :ternary_to_if_else,
124
+ :ruby_if_statement_to_md,
125
+ :ruby_case_statement_to_md,
126
+ :ruby_operators_to_english,
127
+ :nil_check_readable,
128
+ :question_mark_method_format,
129
+ :methods_as_local_links,
130
+ :remove_end_keyword,
131
+ :constants_with_name_and_value,
132
+ :remove_memoized_vars,
133
+ ]
134
+
135
+ def ruby_to_markdown(*args)
136
+ any_args = AnyArgs.new(args: args,
137
+ print_method_source: method(:print_method_source),
138
+ caller: caller,
139
+ for_method: __method__,
140
+ method_creator: method(:create_method_with_ruby_class))
141
+ disable_processors = any_args.disable_processors
142
+ ruby_source = any_args.source_code
143
+
144
+ RUBY_TO_MARKDOWN_PROCESSORS.each do |processor|
145
+ options = disable_processors.fetch(processor, {})
146
+ ruby_source = send(processor, ruby_source, options) if options
138
147
  end
139
- source_code
148
+ ruby_source
149
+ end
150
+
151
+ def remove_memoized_vars(source_code=print_method_source, *)
152
+ source_code.gsub(/@[a-z][a-z0-9_]+ \|\|=?\s/, "") # @memoized_vars ||=
153
+ end
154
+
155
+ def nil_check_readable(source_code, proc: false)
156
+ conversions = {
157
+ ".nil?" => " is missing?"
158
+ }
159
+ gsub_replacement(source_code, conversions, proc: proc)
160
+ end
161
+
162
+ def elsif_to_else_if(source_code, proc: false)
163
+ conversions = {
164
+ "elsif" => "else if"
165
+ }
166
+ gsub_replacement(source_code, conversions, proc: proc)
167
+ end
168
+
169
+ def remove_colons(source_code)
170
+ source_code.gsub(":", '')
140
171
  end
141
172
 
142
- def readable_ruby_numbers(source_code, &block)
173
+ def ruby_operators_to_english(source_code, proc: false)
174
+ conversions = {
175
+ "&&" => "and",
176
+ ">=" => "is greater than or equal to",
177
+ "<=" => "is less than or equal to",
178
+ " < " => " is less than ",
179
+ " > " => " is greater than ",
180
+ " == " => " Equal to ",
181
+ "||" => "or"
182
+ }
183
+
184
+ gsub_replacement(source_code, conversions, proc: proc)
185
+ end
186
+
187
+ def readable_ruby_numbers(source_code, *, &block)
143
188
  source_code.gsub(/([0-9][0-9_]+[0-9]+)/) do |match|
144
189
  value = eval(match)
145
190
  if block_given?
@@ -150,14 +195,6 @@ module MarkdownRubyDocumentation
150
195
  end
151
196
  end
152
197
 
153
- def link_local_methods_from_pretty_code(pretty_code, include: nil)
154
- pretty_code.gsub(/([`][a-zA-Z_0-9!?\s]+[`])/) do |match|
155
- include_code(include, match) do
156
- variables_as_local_links match.underscore.gsub(" ", "_").gsub(/`/, "")
157
- end
158
- end
159
- end
160
-
161
198
  def include_code(include, text, &do_action)
162
199
  if include.nil? || (include.present? && include.include?(remove_quotes(text)))
163
200
  do_action.call(text)
@@ -168,24 +205,32 @@ module MarkdownRubyDocumentation
168
205
 
169
206
  private :include_code
170
207
 
171
- def convert_early_return_to_if_else(source_code)
172
- source_code.gsub(/(.+) if (.+)/, "if \\2\n\\1\nend")
208
+ def convert_early_return_to_if_else(source_code, *)
209
+ source_code = source_code.gsub(/(.+) if (.+)/, "if \\2\n\\1\nend")
210
+ source_code.gsub(/(.+) unless (.+)/, "unless \\2\n\\1\nend")
173
211
  end
174
212
 
175
- def pretty_early_return(source_code)
213
+ def pretty_early_return(source_code, *)
176
214
  source_code.gsub(/return (unless|if)/, 'return nothing \1')
177
215
  end
178
216
 
179
- def ternary_to_if_else(ternary)
217
+ def ternary_to_if_else(ternary, *)
180
218
  ternary.gsub(/(.*) \? (.*) \: (.*)/, "if \\1\n\\2\nelse\n\\3\nend")
181
219
  end
182
220
 
221
+ # @param [String] title the name of the link
222
+ # @param [String] link_ref the url with method anchor
223
+ # @example format_link("MyLink", "path/to/it#method_name?")
224
+ # #=> "[MyLink](#path/to/it#method-name)"
183
225
  def format_link(title, link_ref)
184
226
  path, anchor = *link_ref.to_s.split("#")
185
227
  formatted_path = [path, anchor.try!(:dasherize).try!(:delete, "?")].compact.join("#")
186
228
  "[#{title}](#{formatted_path})"
187
229
  end
188
230
 
231
+ # @param [String] link_ref the url with method anchor
232
+ # @example title_from_link"path/to/it#method_name?")
233
+ # #=> "[Method Name](#path/to/it#method-name)"
189
234
  def title_from_link(link_ref)
190
235
  [link_ref.split("/").last.split("#").last.to_s.humanize, link_ref]
191
236
  end
@@ -195,56 +240,60 @@ module MarkdownRubyDocumentation
195
240
  raise "Client needs to define MarkdownRubyDocumentation::TemplateParser::CommentMacros#link_to_markdown"
196
241
  end
197
242
 
198
- def method_as_local_links(ruby_source)
243
+ def methods_as_local_links(ruby_source,
244
+ call_on_title: :titleize,
245
+ proc: -> (match, anchor) { "[#{match}](#{anchor})" })
199
246
  ruby_source.gsub(/(\b(?<!['"])[a-z_][a-z_0-9?!]*(?!['"]))/) do |match|
200
- is_a_method_on_ruby_class?(match) ? "^`#{match}`" : match
201
- end
202
- end
203
-
204
- alias_method(:variables_as_local_links, :method_as_local_links)
205
-
206
- def quoted_strings_as_local_links(text, include: nil)
207
- text.gsub(/(['|"][a-zA-Z_0-9!?\s]+['|"])/) do |match|
208
- include_code(include, match) do
209
- "^`#{remove_quotes(match).underscore.gsub(" ", "_")}`"
247
+ if is_a_method_on_ruby_class?(match)
248
+
249
+ title = if call_on_title
250
+ call_on_title = [*call_on_title].compact
251
+ match.public_send(call_on_title.first, *call_on_title[1..-1])
252
+ else
253
+ match
254
+ end
255
+ proc.call(title, "##{match.downcase.dasherize.delete(" ").delete('?')}")
256
+ else
257
+ match
210
258
  end
211
259
  end
212
260
  end
213
261
 
214
- def constants_with_name_and_value(ruby_source)
262
+ def constants_with_name_and_value(ruby_source, *)
215
263
  ruby_source.gsub(/([A-Z]+[A-Z_0-9]+)/) do |match|
216
264
  value = ruby_class.const_get(match)
217
- "`#{match} => #{value.inspect}`"
265
+ "[#{ConstantsPresenter.format(value)}](##{match.dasherize.downcase})"
218
266
  end
219
267
  end
220
268
 
221
- def ruby_to_markdown(ruby_source)
222
- ruby_source = readable_ruby_numbers(ruby_source)
223
- ruby_source = pretty_early_return(ruby_source)
224
- ruby_source = convert_early_return_to_if_else(ruby_source)
225
- ruby_source = ternary_to_if_else(ruby_source)
226
- ruby_source = ruby_if_statement_to_md(ruby_source)
227
- ruby_source = ruby_case_statement_to_md(ruby_source)
228
- remove_end_keyword(ruby_source)
269
+ def question_mark_method_format(ruby_source, *)
270
+ ruby_source.gsub(/(\b(?<!['"])\.[a-z_][a-z_0-9]+\?(?!['"]))/) do |match|
271
+ " is #{match}".sub(".", "")
272
+ end
229
273
  end
230
274
 
231
- def remove_end_keyword(ruby_source)
232
- ruby_source.gsub!(/^[\s]*end\n?/, "")
275
+ def remove_end_keyword(ruby_source, *)
276
+ ruby_source.gsub(/^[\s]*end\n?/, "")
233
277
  end
234
278
 
235
- def ruby_if_statement_to_md(ruby_source)
236
- ruby_source.gsub!(/else if(.*)/, "* __ElseIf__\\1\n__Then__")
237
- ruby_source.gsub!(/elsif(.*)/, "* __ElseIf__\\1\n__Then__")
238
- ruby_source.gsub!(/if(.*)/, "* __If__\\1\n__Then__")
239
- ruby_source.gsub!("else", "* __Else__")
240
- ruby_source
279
+ def ruby_if_statement_to_md(ruby_source, proc: false)
280
+ conversions = {
281
+ /else if(.*)/ => "* __ElseIf__\\1\n__Then__",
282
+ /elsif(.*)/ => "* __ElseIf__\\1\n__Then__",
283
+ /if(.*)/ => "* __If__\\1\n__Then__",
284
+ /unless(.*)/ => "* __Unless__\\1\n__Then__",
285
+ "else" => "* __Else__"
286
+ }
287
+ gsub_replacement(ruby_source, conversions, proc: proc)
241
288
  end
242
289
 
243
- def ruby_case_statement_to_md(ruby_source)
244
- ruby_source.gsub!(/case(.*)/, "* __Given__\\1")
245
- ruby_source.gsub!(/when(.*)/, "* __When__\\1\n__Then__")
246
- ruby_source.gsub!("else", "* __Else__")
247
- ruby_source
290
+ def ruby_case_statement_to_md(ruby_source, proc: false)
291
+ conversions = {
292
+ /case(.*)/ => "* __Given__\\1",
293
+ /when(.*)/ => "* __When__\\1\n__Then__",
294
+ "else" => "* __Else__"
295
+ }
296
+ gsub_replacement(ruby_source, conversions, proc: proc)
248
297
  end
249
298
 
250
299
  def hash_to_markdown_table(hash, key_name:, value_name:)
@@ -273,76 +322,53 @@ module MarkdownRubyDocumentation
273
322
 
274
323
  private
275
324
 
276
- def is_a_method_on_ruby_class?(method)
277
- [*ruby_class.public_instance_methods, *ruby_class.private_instance_methods].include?(remove_quotes(method).to_sym)
278
- end
279
-
280
- def remove_quotes(string)
281
- string.gsub(/['|"]/, "")
325
+ def fetch_strings(source_code, &block)
326
+ source_code.gsub(/["']?[a-z_A-Z?!0-9]*["']?/, &block)
282
327
  end
283
328
 
284
- def insert_method_name(string, method)
285
- string.gsub("__method__", "'#{method.to_s}'")
329
+ def fetch_strings_that_contain_codes(source_code, &block)
330
+ source_code.gsub(/["']?[a-z_A-Z?!0-9]*["']?/, &block)
286
331
  end
287
332
 
288
- def parse_erb(str, method)
289
- filename, lineno = ruby_class_meth_source_location(method)
290
-
291
- ruby_class.module_eval(<<-RUBY, __FILE__, __LINE__+1)
292
- def self.get_binding
293
- self.send(:binding)
333
+ def fetch_methods(source_code, &block)
334
+ source_code.gsub(/(\b(?<!['"])[a-z_][a-z_0-9?!]*(?!['"]))/) do |match|
335
+ block.call(match) if is_a_method_on_ruby_class?(match)
294
336
  end
295
- RUBY
296
- ruby_class.extend(CommentMacros)
297
- erb = ERB.new(str, nil, "-")
298
- erb.result(ruby_class.get_binding)
299
- rescue => e
300
- raise e.class, e.message, ["#{filename}:#{lineno}:in `#{method.name}'", *e.backtrace]
301
- end
302
-
303
- def strip_comment_hash(str)
304
- str.gsub(/^#[\s]?/, "")
305
- end
306
-
307
- def ruby_class_meth_comment(method)
308
- method.context.public_send(method.type, method.name).comment
309
-
310
- rescue MethodSource::SourceNotFoundError => e
311
- raise e.class, "#{ method.context}#{method.type_symbol}#{method.name}, \n#{e.message}"
312
337
  end
313
338
 
314
- def ruby_class_meth_source_location(method)
315
- method.context.public_send(method.type, method.name).source_location
339
+ def fetch_symbols(source_code, &block)
340
+ source_code = source_code.gsub(/:[a-z_?!0-9]+/, &block)
341
+ source_code = source_code.gsub(/[a-z_?!0-9]+:/, &block)
316
342
  end
317
343
 
318
- def extract_dsl_comment(comment_string)
319
- if (v = when_start_and_end(comment_string))
320
- v
321
- elsif (x = when_only_start(comment_string))
322
- x << "[//]: # (This method has no mark_end)"
323
- else
324
- ""
325
- end
344
+ def is_a_method_on_ruby_class?(method)
345
+ [*ruby_class.public_instance_methods, *ruby_class.private_instance_methods].include?(remove_quotes(method).to_sym)
326
346
  end
327
347
 
328
- def when_start_and_end(comment_string)
329
- v = /#{START_TOKEN}\n((.|\n)*)#{END_TOKEN}/.match(comment_string)
330
- v.try!(:captures).try!(:first)
348
+ def remove_quotes(string)
349
+ string.gsub(/['|"]/, "")
331
350
  end
332
351
 
333
- def when_only_start(comment_string)
334
- v = /#{START_TOKEN}\n((.|\n)*)/.match(comment_string)
335
- v.try!(:captures).try!(:first)
352
+ def ruby_class
353
+ @ruby_class || self
336
354
  end
337
355
 
338
- def extract_dsl_comment_from_method(method)
339
- extract_dsl_comment strip_comment_hash(ruby_class_meth_comment(method))
356
+ def create_method_with_ruby_class(method_reference)
357
+ Method.create(method_reference, context: ruby_class)
340
358
  end
341
359
 
342
- def ruby_class
343
- @ruby_class || self
360
+ def gsub_replacement(source_code, conversions, proc: false)
361
+ conversions.each do |symbol, replacement|
362
+ source_code = if proc
363
+ source_code.gsub(symbol, &proc.curry[replacement])
364
+ else
365
+ source_code.gsub(symbol, replacement)
366
+ end
367
+ end
368
+ source_code
344
369
  end
345
370
  end
371
+
346
372
  include CommentMacros
347
373
  end
348
374
  end
@@ -0,0 +1,49 @@
1
+ module MarkdownRubyDocumentation
2
+ class AnyArgs
3
+ attr_reader :disable_processors, :source_code
4
+
5
+ def initialize(args:, print_method_source:, caller:, for_method:, method_creator:)
6
+ @args = args
7
+ @print_method_source = print_method_source
8
+ @caller = caller
9
+ @for_method = for_method
10
+ @method_creator = method_creator
11
+ call
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :args, :print_method_source, :caller, :for_method, :method_creator
17
+
18
+ def call
19
+ if args.first.is_a?(Hash)
20
+ when_hash_first(args.first)
21
+ elsif args.first.is_a?(String)
22
+ when_string_first(args)
23
+ elsif args.empty?
24
+ when_no_args
25
+ else
26
+ raise ArgumentError, "Incorrect arguments given: #{for_method}(#{args})", caller
27
+ end
28
+ end
29
+
30
+ def when_hash_first(options)
31
+ @disable_processors = options
32
+ if options.has_key?(:method_reference)
33
+ @source_code = print_method_source.call(method_creator.call(options[:method_reference]))
34
+ else
35
+ @source_code = print_method_source.call
36
+ end
37
+ end
38
+
39
+ def when_string_first(args)
40
+ @source_code = args.first
41
+ @disable_processors = args[1] || {}
42
+ end
43
+
44
+ def when_no_args
45
+ @disable_processors = {}
46
+ @source_code = print_method_source.call
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,71 @@
1
+ module MarkdownRubyDocumentation
2
+ class TemplateParser
3
+ module Parsing
4
+ def parse_erb(str, method)
5
+ filename, lineno = ruby_class_meth_source_location(method)
6
+ adjusted_lineno = (lineno - ruby_class_meth_comment(method).split("\n").count-1)
7
+ ruby_class.module_eval(<<-RUBY, __FILE__, __LINE__+1)
8
+ def self.get_binding
9
+ self.send(:binding)
10
+ end
11
+ RUBY
12
+ ruby_class.send(:define_singleton_method, :current_method) do
13
+ method
14
+ end
15
+
16
+ ruby_class.extend(CommentMacros)
17
+
18
+ erb = ERB.new(str, nil, "-")
19
+
20
+ erb.lineno = adjusted_lineno if erb.respond_to?(:lineno)
21
+ erb.filename = filename if erb.respond_to?(:filename)
22
+ erb.result(ruby_class.get_binding)
23
+ rescue => e
24
+ raise e.class, e.message, ["#{filename}:#{adjusted_lineno}:in `#{method.name}'", *e.backtrace]
25
+ end
26
+
27
+ def insert_method_name(string, method)
28
+ string.gsub("__method__", "'#{method.to_s}'")
29
+ end
30
+
31
+ def strip_comment_hash(str)
32
+ str.gsub(/^#[\s]?/, "")
33
+ end
34
+
35
+ def ruby_class_meth_comment(method)
36
+ method.context.public_send(method.type, method.name).comment
37
+
38
+ rescue MethodSource::SourceNotFoundError => e
39
+ raise e.class, "#{ method.context}#{method.type_symbol}#{method.name}, \n#{e.message}"
40
+ end
41
+
42
+ def ruby_class_meth_source_location(method)
43
+ method.context.public_send(method.type, method.name).source_location
44
+ end
45
+
46
+ def extract_dsl_comment(comment_string)
47
+ if (v = when_start_and_end(comment_string))
48
+ v
49
+ elsif (x = when_only_start(comment_string))
50
+ x << "[//]: # (This method has no mark_end)"
51
+ else
52
+ ""
53
+ end
54
+ end
55
+
56
+ def when_start_and_end(comment_string)
57
+ v = /#{START_TOKEN}\n((.|\n)*)#{END_TOKEN}/.match(comment_string)
58
+ v.try!(:captures).try!(:first)
59
+ end
60
+
61
+ def when_only_start(comment_string)
62
+ v = /#{START_TOKEN}\n((.|\n)*)/.match(comment_string)
63
+ v.try!(:captures).try!(:first)
64
+ end
65
+
66
+ def extract_dsl_comment_from_method(method)
67
+ extract_dsl_comment strip_comment_hash(ruby_class_meth_comment(method))
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,3 +1,3 @@
1
1
  module MarkdownRubyDocumentation
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_ruby_documentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dustin Zeisler
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-25 00:00:00.000000000 Z
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: method_source
@@ -120,17 +120,19 @@ files:
120
120
  - lib/markdown_ruby_documentation/generate.rb
121
121
  - lib/markdown_ruby_documentation/git_hub_link.rb
122
122
  - lib/markdown_ruby_documentation/git_hub_project.rb
123
- - lib/markdown_ruby_documentation/instance_to_class_methods.rb
124
123
  - lib/markdown_ruby_documentation/markdown_presenter.rb
125
124
  - lib/markdown_ruby_documentation/method.rb
126
125
  - lib/markdown_ruby_documentation/method/class_method.rb
127
126
  - lib/markdown_ruby_documentation/method/instance_method.rb
128
127
  - lib/markdown_ruby_documentation/method/null_method.rb
129
128
  - lib/markdown_ruby_documentation/method_linker.rb
130
- - lib/markdown_ruby_documentation/print_method_source.rb
131
129
  - lib/markdown_ruby_documentation/reject_blank_methods.rb
132
130
  - lib/markdown_ruby_documentation/summary.rb
133
131
  - lib/markdown_ruby_documentation/template_parser.rb
132
+ - lib/markdown_ruby_documentation/template_parser/any_args.rb
133
+ - lib/markdown_ruby_documentation/template_parser/instance_to_class_methods.rb
134
+ - lib/markdown_ruby_documentation/template_parser/parsing.rb
135
+ - lib/markdown_ruby_documentation/template_parser/print_method_source.rb
134
136
  - lib/markdown_ruby_documentation/version.rb
135
137
  - lib/markdown_ruby_documentation/write_markdown_to_disk.rb
136
138
  - markdown_ruby_documenation.gemspec