markdown_ruby_documentation 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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