rdoc 6.3.4.1 → 8.0.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.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +195 -0
  3. data/History.rdoc +65 -63
  4. data/LEGAL.rdoc +7 -1
  5. data/LICENSE.rdoc +6 -0
  6. data/README.md +236 -0
  7. data/RI.md +842 -0
  8. data/TODO.rdoc +8 -7
  9. data/doc/markup_reference/markdown.md +659 -0
  10. data/doc/markup_reference/rdoc.rdoc +1169 -0
  11. data/exe/rdoc +0 -1
  12. data/lib/rdoc/{alias.rb → code_object/alias.rb} +4 -18
  13. data/lib/rdoc/{any_method.rb → code_object/any_method.rb} +50 -24
  14. data/lib/rdoc/{attr.rb → code_object/attr.rb} +16 -14
  15. data/lib/rdoc/{class_module.rb → code_object/class_module.rb} +225 -58
  16. data/lib/rdoc/{constant.rb → code_object/constant.rb} +44 -10
  17. data/lib/rdoc/code_object/context/section.rb +182 -0
  18. data/lib/rdoc/{context.rb → code_object/context.rb} +78 -106
  19. data/lib/rdoc/{extend.rb → code_object/extend.rb} +0 -1
  20. data/lib/rdoc/{include.rb → code_object/include.rb} +0 -1
  21. data/lib/rdoc/{method_attr.rb → code_object/method_attr.rb} +46 -48
  22. data/lib/rdoc/{mixin.rb → code_object/mixin.rb} +6 -4
  23. data/lib/rdoc/{normal_class.rb → code_object/normal_class.rb} +2 -3
  24. data/lib/rdoc/{normal_module.rb → code_object/normal_module.rb} +2 -3
  25. data/lib/rdoc/{require.rb → code_object/require.rb} +1 -2
  26. data/lib/rdoc/{single_class.rb → code_object/single_class.rb} +5 -1
  27. data/lib/rdoc/{top_level.rb → code_object/top_level.rb} +60 -63
  28. data/lib/rdoc/code_object.rb +11 -39
  29. data/lib/rdoc/code_objects.rb +1 -2
  30. data/lib/rdoc/comment.rb +202 -99
  31. data/lib/rdoc/cross_reference.rb +75 -62
  32. data/lib/rdoc/encoding.rb +8 -24
  33. data/lib/rdoc/erb_partial.rb +1 -2
  34. data/lib/rdoc/erbio.rb +3 -8
  35. data/lib/rdoc/generator/aliki.rb +200 -0
  36. data/lib/rdoc/generator/darkfish.rb +156 -122
  37. data/lib/rdoc/generator/json_index.rb +8 -24
  38. data/lib/rdoc/generator/markup.rb +70 -34
  39. data/lib/rdoc/generator/pot/message_extractor.rb +7 -7
  40. data/lib/rdoc/generator/pot/po.rb +1 -1
  41. data/lib/rdoc/generator/pot/po_entry.rb +8 -8
  42. data/lib/rdoc/generator/pot.rb +1 -5
  43. data/lib/rdoc/generator/ri.rb +1 -2
  44. data/lib/rdoc/generator/template/aliki/DESIGN.md +536 -0
  45. data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +8 -0
  46. data/lib/rdoc/generator/template/aliki/_footer.rhtml +23 -0
  47. data/lib/rdoc/generator/template/aliki/_head.rhtml +163 -0
  48. data/lib/rdoc/generator/template/aliki/_header.rhtml +56 -0
  49. data/lib/rdoc/generator/template/aliki/_icons.rhtml +208 -0
  50. data/lib/rdoc/generator/template/aliki/_sidebar_ancestors.rhtml +16 -0
  51. data/lib/rdoc/generator/template/aliki/_sidebar_classes.rhtml +15 -0
  52. data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +27 -0
  53. data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +27 -0
  54. data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +16 -0
  55. data/lib/rdoc/generator/template/aliki/_sidebar_methods.rhtml +41 -0
  56. data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +67 -0
  57. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +15 -0
  58. data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +21 -0
  59. data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +3 -0
  60. data/lib/rdoc/generator/template/aliki/class.rhtml +230 -0
  61. data/lib/rdoc/generator/template/aliki/css/rdoc.css +2181 -0
  62. data/lib/rdoc/generator/template/aliki/index.rhtml +22 -0
  63. data/lib/rdoc/generator/template/aliki/js/aliki.js +513 -0
  64. data/lib/rdoc/generator/template/aliki/js/bash_highlighter.js +167 -0
  65. data/lib/rdoc/generator/template/aliki/js/c_highlighter.js +299 -0
  66. data/lib/rdoc/generator/template/aliki/js/search_controller.js +129 -0
  67. data/lib/rdoc/generator/template/aliki/js/search_navigation.js +105 -0
  68. data/lib/rdoc/generator/template/aliki/js/search_ranker.js +239 -0
  69. data/lib/rdoc/generator/template/aliki/js/theme-toggle.js +112 -0
  70. data/lib/rdoc/generator/template/aliki/page.rhtml +18 -0
  71. data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +14 -0
  72. data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +65 -0
  73. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +3 -3
  74. data/lib/rdoc/generator/template/darkfish/_head.rhtml +35 -14
  75. data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +1 -5
  76. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +11 -9
  77. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +11 -9
  78. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +7 -6
  79. data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +20 -11
  80. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +25 -5
  81. data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +4 -9
  82. data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +2 -1
  83. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +4 -4
  84. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +28 -7
  85. data/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml +3 -0
  86. data/lib/rdoc/generator/template/darkfish/class.rhtml +138 -90
  87. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +420 -358
  88. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
  89. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
  90. data/lib/rdoc/generator/template/darkfish/index.rhtml +14 -12
  91. data/lib/rdoc/generator/template/darkfish/js/darkfish.js +59 -3
  92. data/lib/rdoc/generator/template/darkfish/js/search.js +15 -5
  93. data/lib/rdoc/generator/template/darkfish/page.rhtml +7 -6
  94. data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +12 -9
  95. data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +24 -21
  96. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +35 -21
  97. data/lib/rdoc/generator/template/json_index/js/navigation.js +8 -8
  98. data/lib/rdoc/generator/template/json_index/js/searcher.js +48 -6
  99. data/lib/rdoc/generator.rb +6 -5
  100. data/lib/rdoc/i18n/text.rb +3 -3
  101. data/lib/rdoc/i18n.rb +1 -1
  102. data/lib/rdoc/known_classes.rb +5 -4
  103. data/lib/rdoc/markdown/entities.rb +0 -1
  104. data/lib/rdoc/markdown/literals.kpeg +0 -2
  105. data/lib/rdoc/markdown/literals.rb +0 -1
  106. data/lib/rdoc/markdown.kpeg +140 -62
  107. data/lib/rdoc/markdown.rb +1015 -873
  108. data/lib/rdoc/markup/blank_line.rb +25 -24
  109. data/lib/rdoc/markup/block_quote.rb +1 -2
  110. data/lib/rdoc/markup/document.rb +10 -11
  111. data/lib/rdoc/markup/element.rb +21 -0
  112. data/lib/rdoc/markup/formatter.rb +134 -115
  113. data/lib/rdoc/markup/hard_break.rb +30 -28
  114. data/lib/rdoc/markup/heading.rb +163 -72
  115. data/lib/rdoc/markup/include.rb +3 -4
  116. data/lib/rdoc/markup/indented_paragraph.rb +4 -5
  117. data/lib/rdoc/markup/inline_parser.rb +312 -0
  118. data/lib/rdoc/markup/list.rb +6 -7
  119. data/lib/rdoc/markup/list_item.rb +6 -7
  120. data/lib/rdoc/markup/paragraph.rb +2 -3
  121. data/lib/rdoc/markup/parser.rb +29 -19
  122. data/lib/rdoc/markup/pre_process.rb +39 -18
  123. data/lib/rdoc/markup/raw.rb +52 -56
  124. data/lib/rdoc/markup/rule.rb +2 -3
  125. data/lib/rdoc/markup/table.rb +49 -32
  126. data/lib/rdoc/markup/to_ansi.rb +58 -8
  127. data/lib/rdoc/markup/to_bs.rb +47 -38
  128. data/lib/rdoc/markup/to_html.rb +343 -105
  129. data/lib/rdoc/markup/to_html_crossref.rb +143 -58
  130. data/lib/rdoc/markup/to_html_snippet.rb +78 -76
  131. data/lib/rdoc/markup/to_joined_paragraph.rb +3 -9
  132. data/lib/rdoc/markup/to_label.rb +34 -25
  133. data/lib/rdoc/markup/to_markdown.rb +74 -51
  134. data/lib/rdoc/markup/to_rdoc.rb +141 -82
  135. data/lib/rdoc/markup/to_table_of_contents.rb +4 -5
  136. data/lib/rdoc/markup/to_test.rb +10 -3
  137. data/lib/rdoc/markup/to_tt_only.rb +17 -31
  138. data/lib/rdoc/markup/verbatim.rb +5 -6
  139. data/lib/rdoc/markup.rb +59 -707
  140. data/lib/rdoc/options.rb +228 -101
  141. data/lib/rdoc/parser/c.rb +186 -184
  142. data/lib/rdoc/parser/changelog.rb +57 -13
  143. data/lib/rdoc/parser/markdown.rb +0 -2
  144. data/lib/rdoc/parser/rbs.rb +275 -0
  145. data/lib/rdoc/parser/rd.rb +0 -1
  146. data/lib/rdoc/parser/ruby.rb +963 -2024
  147. data/lib/rdoc/parser/ruby_colorizer.rb +253 -0
  148. data/lib/rdoc/parser/simple.rb +6 -23
  149. data/lib/rdoc/parser/text.rb +0 -1
  150. data/lib/rdoc/parser.rb +35 -14
  151. data/lib/rdoc/rbs_helper.rb +186 -0
  152. data/lib/rdoc/rd/block_parser.rb +659 -11
  153. data/lib/rdoc/rd/block_parser.ry +13 -9
  154. data/lib/rdoc/rd/inline.rb +4 -5
  155. data/lib/rdoc/rd/inline_parser.rb +646 -2
  156. data/lib/rdoc/rd.rb +4 -5
  157. data/lib/rdoc/rdoc.rb +234 -90
  158. data/lib/rdoc/ri/driver.rb +172 -172
  159. data/lib/rdoc/ri/paths.rb +3 -3
  160. data/lib/rdoc/{servlet.rb → ri/servlet.rb} +28 -27
  161. data/lib/rdoc/ri/store.rb +0 -1
  162. data/lib/rdoc/ri/task.rb +3 -3
  163. data/lib/rdoc/ri.rb +5 -5
  164. data/lib/rdoc/rubygems_hook.rb +106 -25
  165. data/lib/rdoc/server.rb +460 -0
  166. data/lib/rdoc/stats/normal.rb +1 -1
  167. data/lib/rdoc/stats/quiet.rb +1 -2
  168. data/lib/rdoc/stats/verbose.rb +3 -5
  169. data/lib/rdoc/stats.rb +158 -136
  170. data/lib/rdoc/store.rb +267 -48
  171. data/lib/rdoc/task.rb +54 -28
  172. data/lib/rdoc/text.rb +60 -120
  173. data/lib/rdoc/token_stream.rb +30 -45
  174. data/lib/rdoc/tom_doc.rb +9 -15
  175. data/lib/rdoc/version.rb +3 -1
  176. data/lib/rdoc.rb +90 -52
  177. data/lib/rubygems_plugin.rb +14 -0
  178. data/man/ri.1 +2 -0
  179. data/rdoc-logo.svg +43 -0
  180. data/rdoc.gemspec +25 -200
  181. metadata +120 -53
  182. data/CONTRIBUTING.rdoc +0 -220
  183. data/ExampleMarkdown.md +0 -37
  184. data/ExampleRDoc.rdoc +0 -208
  185. data/Gemfile +0 -12
  186. data/README.rdoc +0 -129
  187. data/RI.rdoc +0 -57
  188. data/Rakefile +0 -101
  189. data/bin/console +0 -7
  190. data/bin/setup +0 -6
  191. data/lib/rdoc/anon_class.rb +0 -11
  192. data/lib/rdoc/context/section.rb +0 -232
  193. data/lib/rdoc/generator/template/darkfish/.document +0 -0
  194. data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +0 -19
  195. data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +0 -9
  196. data/lib/rdoc/generator/template/json_index/.document +0 -1
  197. data/lib/rdoc/ghost_method.rb +0 -7
  198. data/lib/rdoc/markup/attr_changer.rb +0 -23
  199. data/lib/rdoc/markup/attr_span.rb +0 -36
  200. data/lib/rdoc/markup/attribute_manager.rb +0 -409
  201. data/lib/rdoc/markup/attributes.rb +0 -71
  202. data/lib/rdoc/markup/regexp_handling.rb +0 -41
  203. data/lib/rdoc/meta_method.rb +0 -7
  204. data/lib/rdoc/parser/ripper_state_lex.rb +0 -590
  205. data/lib/rdoc/parser/ruby_tools.rb +0 -167
@@ -2,5 +2,4 @@
2
2
  # This file was used to load all the RDoc::CodeObject subclasses at once. Now
3
3
  # autoload handles this.
4
4
 
5
- require 'rdoc'
6
-
5
+ require_relative '../rdoc'
data/lib/rdoc/comment.rb CHANGED
@@ -6,8 +6,8 @@
6
6
  # Each comment may have a different markup format set by #format=. By default
7
7
  # 'rdoc' is used. The :markup: directive tells RDoc which format to use.
8
8
  #
9
- # See RDoc::Markup@Other+directives for instructions on adding an alternate
10
- # format.
9
+ # See {RDoc Markup Reference}[rdoc-ref:doc/markup_reference/rdoc.rdoc@Directive+for+Specifying+RDoc+Source+Format].
10
+
11
11
 
12
12
  class RDoc::Comment
13
13
 
@@ -53,7 +53,7 @@ class RDoc::Comment
53
53
  # Creates a new comment with +text+ that is found in the RDoc::TopLevel
54
54
  # +location+.
55
55
 
56
- def initialize text = nil, location = nil, language = nil
56
+ def initialize(text = nil, location = nil, language = nil)
57
57
  @location = location
58
58
  @text = text.nil? ? nil : text.dup
59
59
  @language = language
@@ -67,101 +67,34 @@ class RDoc::Comment
67
67
  #--
68
68
  # TODO deep copy @document
69
69
 
70
- def initialize_copy copy # :nodoc:
70
+ def initialize_copy(copy) # :nodoc:
71
71
  @text = copy.text.dup
72
72
  end
73
73
 
74
- def == other # :nodoc:
74
+ def ==(other) # :nodoc:
75
75
  self.class === other and
76
76
  other.text == @text and other.location == @location
77
77
  end
78
78
 
79
- ##
80
- # Look for a 'call-seq' in the comment to override the normal parameter
81
- # handling. The :call-seq: is indented from the baseline. All lines of the
82
- # same indentation level and prefix are consumed.
83
- #
84
- # For example, all of the following will be used as the :call-seq:
85
- #
86
- # # :call-seq:
87
- # # ARGF.readlines(sep=$/) -> array
88
- # # ARGF.readlines(limit) -> array
89
- # # ARGF.readlines(sep, limit) -> array
90
- # #
91
- # # ARGF.to_a(sep=$/) -> array
92
- # # ARGF.to_a(limit) -> array
93
- # # ARGF.to_a(sep, limit) -> array
94
-
95
- def extract_call_seq method
96
- # we must handle situations like the above followed by an unindented first
97
- # comment. The difficulty is to make sure not to match lines starting
98
- # with ARGF at the same indent, but that are after the first description
99
- # paragraph.
100
- if @text =~ /^\s*:?call-seq:(.*?(?:\S).*?)^\s*$/m then
101
- all_start, all_stop = $~.offset(0)
102
- seq_start, seq_stop = $~.offset(1)
103
-
104
- # we get the following lines that start with the leading word at the
105
- # same indent, even if they have blank lines before
106
- if $1 =~ /(^\s*\n)+^(\s*\w+)/m then
107
- leading = $2 # ' * ARGF' in the example above
108
- re = %r%
109
- \A(
110
- (^\s*\n)+
111
- (^#{Regexp.escape leading}.*?\n)+
112
- )+
113
- ^\s*$
114
- %xm
115
-
116
- if @text[seq_stop..-1] =~ re then
117
- all_stop = seq_stop + $~.offset(0).last
118
- seq_stop = seq_stop + $~.offset(1).last
119
- end
120
- end
121
-
122
- seq = @text[seq_start..seq_stop]
123
- seq.gsub!(/^\s*(\S|\n)/m, '\1')
124
- @text.slice! all_start...all_stop
125
-
126
- method.call_seq = seq.chomp
127
-
128
- else
129
- regexp = /^\s*:?call-seq:(.*?)(^\s*$|\z)/m
130
- if regexp =~ @text then
131
- @text = @text.sub(regexp, '')
132
- seq = $1
133
- seq.gsub!(/^\s*/, '')
134
- method.call_seq = seq
135
- end
136
- end
137
-
138
- method
139
- end
140
-
141
79
  ##
142
80
  # A comment is empty if its text String is empty.
143
81
 
144
82
  def empty?
145
- @text.empty?
83
+ @text.empty? && (@document.nil? || @document.empty?)
146
84
  end
147
85
 
148
86
  ##
149
87
  # HACK dubious
150
88
 
151
- def encode! encoding
152
- # TODO: Remove this condition after Ruby 2.2 EOL
153
- if RUBY_VERSION < '2.3.0'
154
- @text = @text.force_encoding encoding
155
- else
156
- @text = String.new @text, encoding: encoding
157
- end
89
+ def encode!(encoding)
90
+ @text = String.new @text, encoding: encoding
158
91
  self
159
92
  end
160
93
 
161
94
  ##
162
95
  # Sets the format of this comment and resets any parsed document
163
96
 
164
- def format= format
97
+ def format=(format)
165
98
  @format = format
166
99
  @document = nil
167
100
  end
@@ -186,6 +119,12 @@ class RDoc::Comment
186
119
  self
187
120
  end
188
121
 
122
+ # Change normalized, when creating already normalized comment.
123
+
124
+ def normalized=(value)
125
+ @normalized = value
126
+ end
127
+
189
128
  ##
190
129
  # Was this text normalized?
191
130
 
@@ -205,34 +144,12 @@ class RDoc::Comment
205
144
  @document
206
145
  end
207
146
 
208
- ##
209
- # Removes private sections from this comment. Private sections are flush to
210
- # the comment marker and start with <tt>--</tt> and end with <tt>++</tt>.
211
- # For C-style comments, a private marker may not start at the opening of the
212
- # comment.
213
- #
214
- # /*
215
- # *--
216
- # * private
217
- # *++
218
- # * public
219
- # */
220
-
221
- def remove_private
222
- # Workaround for gsub encoding for Ruby 1.9.2 and earlier
223
- empty = ''
224
- empty = RDoc::Encoding.change_encoding empty, @text.encoding
225
-
226
- @text = @text.gsub(%r%^\s*([#*]?)--.*?^\s*(\1)\+\+\n?%m, empty)
227
- @text = @text.sub(%r%^\s*[#*]?--.*%m, '')
228
- end
229
-
230
147
  ##
231
148
  # Replaces this comment's text with +text+ and resets the parsed document.
232
149
  #
233
150
  # An error is raised if the comment contains a document but no text.
234
151
 
235
- def text= text
152
+ def text=(text)
236
153
  raise RDoc::Error, 'replacing document-only comment is not allowed' if
237
154
  @text.nil? and @document
238
155
 
@@ -247,4 +164,190 @@ class RDoc::Comment
247
164
  @format == 'tomdoc'
248
165
  end
249
166
 
167
+ MULTILINE_DIRECTIVES = %w[call-seq].freeze # :nodoc:
168
+
169
+ # There are more, but already handled by RDoc::Parser::C
170
+ COLON_LESS_DIRECTIVES = %w[call-seq Document-method].freeze # :nodoc:
171
+
172
+ DIRECTIVE_OR_ESCAPED_DIRECTIV_REGEXP = /\A(?<colon>\\?:|:?)(?<directive>[\w-]+):(?<param>.*)/
173
+
174
+ private_constant :MULTILINE_DIRECTIVES, :COLON_LESS_DIRECTIVES, :DIRECTIVE_OR_ESCAPED_DIRECTIV_REGEXP
175
+
176
+ class << self
177
+
178
+ ##
179
+ # Create a new parsed comment from a document
180
+
181
+ def from_document(document) # :nodoc:
182
+ comment = RDoc::Comment.new('')
183
+ comment.document = document
184
+ comment.location = RDoc::TopLevel.new(document.file) if document.file
185
+ comment
186
+ end
187
+
188
+ # Parse comment, collect directives as an attribute and return [normalized_comment_text, directives_hash]
189
+ # This method expands include and removes everything not needed in the document text, such as
190
+ # private section, directive line, comment characters `# /* * */` and indent spaces.
191
+ #
192
+ # RDoc comment consists of include, directive, multiline directive, private section and comment text.
193
+ #
194
+ # Include
195
+ # # :include: filename
196
+ #
197
+ # Directive
198
+ # # :directive-without-value:
199
+ # # :directive-with-value: value
200
+ #
201
+ # Multiline directive (only :call-seq:)
202
+ # # :multiline-directive:
203
+ # # value1
204
+ # # value2
205
+ #
206
+ # Private section
207
+ # #--
208
+ # # private comment
209
+ # #++
210
+
211
+ def parse(text, filename, line_no, type, &include_callback)
212
+ case type
213
+ when :ruby
214
+ text = text.gsub(/^#+/, '') if text.start_with?('#')
215
+ private_start_regexp = /^-{2,}$/
216
+ private_end_regexp = /^\+{2}$/
217
+ indent_regexp = /^\s*/
218
+ when :c
219
+ private_start_regexp = /^(\s*\*)?-{2,}$/
220
+ private_end_regexp = /^(\s*\*)?\+{2}$/
221
+ indent_regexp = /^\s*(\/\*+|\*)?\s*/
222
+ text = text.gsub(/\s*\*+\/\s*\z/, '')
223
+ when :simple
224
+ # Unlike other types, this implementation only looks for two dashes at
225
+ # the beginning of the line. Three or more dashes are considered to be
226
+ # a rule and ignored.
227
+ private_start_regexp = /^-{2}$/
228
+ private_end_regexp = /^\+{2}$/
229
+ indent_regexp = /^\s*/
230
+ end
231
+
232
+ directives = {}
233
+ lines = text.split("\n")
234
+ in_private = false
235
+ comment_lines = []
236
+ until lines.empty?
237
+ line = lines.shift
238
+ read_lines = 1
239
+ if in_private
240
+ # If `++` appears in a private section that starts with `--`, private section ends.
241
+ in_private = false if line.match?(private_end_regexp)
242
+ line_no += read_lines
243
+ next
244
+ elsif line.match?(private_start_regexp)
245
+ # If `--` appears in a line, private section starts.
246
+ in_private = true
247
+ line_no += read_lines
248
+ next
249
+ end
250
+
251
+ prefix = line[indent_regexp]
252
+ prefix_indent = ' ' * prefix.size
253
+ line = line.byteslice(prefix.bytesize..)
254
+
255
+ if (directive_match = DIRECTIVE_OR_ESCAPED_DIRECTIV_REGEXP.match(line))
256
+ colon = directive_match[:colon]
257
+ directive = directive_match[:directive]
258
+ raw_param = directive_match[:param]
259
+ param = raw_param.strip
260
+ else
261
+ colon = directive = raw_param = param = nil
262
+ end
263
+
264
+ if !directive
265
+ comment_lines << prefix_indent + line
266
+ elsif colon == '\\:'
267
+ # If directive is escaped, unescape it
268
+ comment_lines << prefix_indent + line.sub('\\:', ':')
269
+ elsif raw_param.start_with?(':') || (colon.empty? && !COLON_LESS_DIRECTIVES.include?(directive))
270
+ # Something like `:toto::` is not a directive
271
+ # Only few directives allows to start without a colon
272
+ comment_lines << prefix_indent + line
273
+ elsif directive == 'include'
274
+ filename_to_include = param
275
+ include_callback.call(filename_to_include, prefix_indent).lines.each { |l| comment_lines << l.chomp }
276
+ elsif MULTILINE_DIRECTIVES.include?(directive)
277
+ value_lines = take_multiline_directive_value_lines(directive, filename, line_no, lines, prefix_indent.size, indent_regexp, !param.empty?)
278
+ read_lines += value_lines.size
279
+ lines.shift(value_lines.size)
280
+ unless param.empty?
281
+ # Accept `:call-seq: first-line\n second-line` for now
282
+ value_lines.unshift(param)
283
+ end
284
+ value = value_lines.join("\n")
285
+ directives[directive] = [value.empty? ? nil : value, line_no]
286
+ else
287
+ directives[directive] = [param.empty? ? nil : param, line_no]
288
+ end
289
+ line_no += read_lines
290
+ end
291
+
292
+ normalized_comment = String.new(encoding: text.encoding) << normalize_comment_lines(comment_lines).join("\n")
293
+ [normalized_comment, directives]
294
+ end
295
+
296
+ # Remove preceding indent spaces and blank lines from the comment lines
297
+
298
+ private def normalize_comment_lines(lines)
299
+ blank_line_regexp = /\A\s*\z/
300
+ lines = lines.dup
301
+ lines.shift while lines.first&.match?(blank_line_regexp)
302
+ lines.pop while lines.last&.match?(blank_line_regexp)
303
+
304
+ min_spaces = lines.map do |l|
305
+ l.match(/\A *(?=\S)/)&.end(0)
306
+ end.compact.min
307
+ if min_spaces && min_spaces > 0
308
+ lines.map { |l| l[min_spaces..] || '' }
309
+ else
310
+ lines
311
+ end
312
+ end
313
+
314
+ # Take value lines of multiline directive
315
+
316
+ private def take_multiline_directive_value_lines(directive, filename, line_no, lines, base_indent_size, indent_regexp, has_param)
317
+ return [] if lines.empty?
318
+
319
+ first_indent_size = lines.first.match(indent_regexp).end(0)
320
+
321
+ # Blank line or unindented line is not part of multiline-directive value
322
+ return [] if first_indent_size <= base_indent_size
323
+
324
+ if has_param
325
+ # :multiline-directive: line1
326
+ # line2
327
+ # line3
328
+ #
329
+ value_lines = lines.take_while do |l|
330
+ l.rstrip.match(indent_regexp).end(0) > base_indent_size
331
+ end
332
+ min_indent = value_lines.map { |l| l.match(indent_regexp).end(0) }.min
333
+ value_lines.map { |l| l[min_indent..] }
334
+ else
335
+ # Take indented lines accepting blank lines between them
336
+ value_lines = lines.take_while do |l|
337
+ l = l.rstrip
338
+ indent = l[indent_regexp]
339
+ if indent == l || indent.size >= first_indent_size
340
+ true
341
+ end
342
+ end
343
+ value_lines.map! { |l| (l[first_indent_size..] || '').chomp }
344
+
345
+ if value_lines.size != lines.size && !value_lines.last.empty?
346
+ warn "#{filename}:#{line_no} Multiline directive :#{directive}: should end with a blank line."
347
+ end
348
+ value_lines.pop while value_lines.last&.empty?
349
+ value_lines
350
+ end
351
+ end
352
+ end
250
353
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  ##
3
4
  # RDoc::CrossReference is a reusable way to create cross references for names.
4
5
 
@@ -14,12 +15,25 @@ class RDoc::CrossReference
14
15
 
15
16
  CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)'
16
17
 
18
+ ##
19
+ # Regular expression to match a single method argument.
20
+
21
+ METHOD_ARG_REGEXP_STR = '[\w.+*/=<>-]+'
22
+
23
+ ##
24
+ # Regular expression to match method arguments.
25
+
26
+ METHOD_ARGS_REGEXP_STR = /(?:\((?:#{METHOD_ARG_REGEXP_STR}(?:,\s*#{METHOD_ARG_REGEXP_STR})*)?\))?/.source
27
+
17
28
  ##
18
29
  # Regular expression to match method references.
19
30
  #
20
31
  # See CLASS_REGEXP_STR
21
32
 
22
- METHOD_REGEXP_STR = '([a-z]\w*[!?=]?|%|===|\[\]=?|<<|>>|\+@|-@|-|\+|\*)(?:\([\w.+*/=<>-]*\))?'
33
+ METHOD_REGEXP_STR = /(
34
+ (?!\d)[\w]+[!?=]?|
35
+ %|=(?:==?|~)|![=~]|\[\]=?|<(?:<|=>?)?|>[>=]?|[-+!]@?|\*\*?|[\/%\`|&^~]
36
+ )#{METHOD_ARGS_REGEXP_STR}/.source.delete("\n ").freeze
23
37
 
24
38
  ##
25
39
  # Regular expressions matching text that should potentially have
@@ -34,12 +48,6 @@ class RDoc::CrossReference
34
48
  # A::B::C.meth
35
49
  #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
36
50
 
37
- # Stand-alone method (preceded by a #)
38
- | \\?\##{METHOD_REGEXP_STR}
39
-
40
- # Stand-alone method (preceded by ::)
41
- | ::#{METHOD_REGEXP_STR}
42
-
43
51
  # A::B::C
44
52
  # The stuff after CLASS_REGEXP_STR is a
45
53
  # nasty hack. CLASS_REGEXP_STR unfortunately matches
@@ -56,6 +64,12 @@ class RDoc::CrossReference
56
64
  # marker.
57
65
  | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)
58
66
 
67
+ # Stand-alone method (preceded by a #)
68
+ | \\?\##{METHOD_REGEXP_STR}
69
+
70
+ # Stand-alone method (preceded by ::)
71
+ | ::#{METHOD_REGEXP_STR}
72
+
59
73
  # Things that look like filenames
60
74
  # The key thing is that there must be at least
61
75
  # one special character (period, slash, or
@@ -82,12 +96,12 @@ class RDoc::CrossReference
82
96
  # A::B::C.meth
83
97
  #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
84
98
 
85
- # Stand-alone method
86
- | \\?#{METHOD_REGEXP_STR}
87
-
88
99
  # A::B::C
89
100
  | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)
90
101
 
102
+ # Stand-alone method
103
+ | \\?#{METHOD_REGEXP_STR}
104
+
91
105
  # Things that look like filenames
92
106
  | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+
93
107
 
@@ -108,7 +122,7 @@ class RDoc::CrossReference
108
122
  # Allows cross-references to be created based on the given +context+
109
123
  # (RDoc::Context).
110
124
 
111
- def initialize context
125
+ def initialize(context)
112
126
  @context = context
113
127
  @store = context.store
114
128
 
@@ -116,87 +130,86 @@ class RDoc::CrossReference
116
130
  end
117
131
 
118
132
  ##
119
- # Returns a reference to +name+.
133
+ # Returns a method, attribute or constant reference to +name+
134
+ # if it exists in the containing context object. It returns
135
+ # nil otherwise.
120
136
  #
121
- # If the reference is found and +name+ is not documented +text+ will be
122
- # returned. If +name+ is escaped +name+ is returned. If +name+ is not
123
- # found +text+ is returned.
124
-
125
- def resolve name, text
126
- return @seen[name] if @seen.include? name
127
-
128
- if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then
137
+ # For example, this method would decompose name = 'A::CONSTANT' into a
138
+ # container object A and a symbol 'CONSTANT', and it would try to find
139
+ # 'CONSTANT' in A.
140
+
141
+ def resolve_local_symbol(name)
142
+ ref = nil
143
+ type = nil
144
+ container = nil
145
+
146
+ case name
147
+ when /#{CLASS_REGEXP_STR}::([A-Z]\w*)\z/o then
148
+ symbol = $2
149
+ container = @context.find_symbol_module($1)
150
+ when /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o then
129
151
  type = $2
130
152
  if '.' == type # will find either #method or ::method
131
- method = $3
153
+ symbol = $3
132
154
  else
133
- method = "#{type}#{$3}"
155
+ symbol = "#{type}#{$3}"
134
156
  end
135
157
  container = @context.find_symbol_module($1)
136
- elsif /^([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then
158
+ when /^([.#]|::)#{METHOD_REGEXP_STR}/o then
137
159
  type = $1
138
160
  if '.' == type
139
- method = $2
161
+ symbol = $2
140
162
  else
141
- method = "#{type}#{$2}"
163
+ symbol = "#{type}#{$2}"
142
164
  end
143
165
  container = @context
144
- else
145
- type = nil
146
- container = nil
147
166
  end
148
167
 
149
168
  if container then
150
169
  unless RDoc::TopLevel === container then
151
170
  if '.' == type then
152
- if 'new' == method then # AnyClassName.new will be class method
153
- ref = container.find_local_symbol method
154
- ref = container.find_ancestor_local_symbol method unless ref
171
+ if 'new' == symbol then # AnyClassName.new will be class method
172
+ ref = container.find_local_symbol symbol
173
+ ref = container.find_ancestor_local_symbol symbol unless ref
155
174
  else
156
- ref = container.find_local_symbol "::#{method}"
157
- ref = container.find_ancestor_local_symbol "::#{method}" unless ref
158
- ref = container.find_local_symbol "##{method}" unless ref
159
- ref = container.find_ancestor_local_symbol "##{method}" unless ref
175
+ ref = container.find_local_symbol "::#{symbol}"
176
+ ref = container.find_ancestor_local_symbol "::#{symbol}" unless ref
177
+ ref = container.find_local_symbol "##{symbol}" unless ref
178
+ ref = container.find_ancestor_local_symbol "##{symbol}" unless ref
160
179
  end
161
180
  else
162
- ref = container.find_local_symbol method
163
- ref = container.find_ancestor_local_symbol method unless ref
181
+ ref = container.find_local_symbol symbol
182
+ ref = container.find_ancestor_local_symbol symbol unless ref
164
183
  end
165
184
  end
166
185
  end
167
186
 
168
- ref = case name
169
- when /^\\(#{CLASS_REGEXP_STR})$/o then
170
- @context.find_symbol $1
171
- else
172
- @context.find_symbol name
173
- end unless ref
187
+ ref
188
+ end
189
+
190
+ ##
191
+ # Returns a reference to +name+.
192
+ #
193
+ # If the reference is found and +name+ is not documented +nil+ will be
194
+ # returned. If +name+ is not found +nil+ is returned.
195
+
196
+ def resolve(name)
197
+ return @seen[name] if @seen.include? name
198
+
199
+ ref = @context.find_symbol name
200
+
201
+ ref = resolve_local_symbol name unless ref
174
202
 
175
203
  # Try a page name
176
- ref = @store.page name if not ref and name =~ /^[\w.]+$/
204
+ ref = @store.page name if not ref and name =~ /^[\w.\/]+$/
177
205
 
178
206
  ref = nil if RDoc::Alias === ref # external alias, can't link to it
179
207
 
180
- out = if name == '\\' then
181
- name
182
- elsif name =~ /^\\/ then
183
- # we remove the \ only in front of what we know:
184
- # other backslashes are treated later, only outside of <tt>
185
- ref ? $' : name
186
- elsif ref then
187
- if ref.display? then
188
- ref
189
- else
190
- text
191
- end
192
- else
193
- text
194
- end
208
+ ref = nil unless ref&.display?
195
209
 
196
- @seen[name] = out
210
+ @seen[name] = ref
197
211
 
198
- out
212
+ ref
199
213
  end
200
214
 
201
215
  end
202
-
data/lib/rdoc/encoding.rb CHANGED
@@ -7,13 +7,13 @@
7
7
 
8
8
  module RDoc::Encoding
9
9
 
10
- HEADER_REGEXP = /^
10
+ HEADER_REGEXP = /\A
11
11
  (?:
12
- \A\#!.*\n
12
+ \#!.*\n
13
13
  |
14
14
  ^\#\s+frozen[-_]string[-_]literal[=:].+\n
15
15
  |
16
- ^\#[^\n]+\b(?:en)?coding[=:]\s*(?<name>[^\s;]+).*\n
16
+ ^\#\s*(?:-\*-\s*(?:[^;\n]*;\s*)*)?(?:en)?coding[=:]\s*(?<name>[^:\s;]+).*\n
17
17
  |
18
18
  <\?xml[^?]*encoding=(?<quote>["'])(?<name>.*?)\k<quote>.*\n
19
19
  )+
@@ -29,7 +29,7 @@ module RDoc::Encoding
29
29
  # If +force_transcode+ is true the document will be transcoded and any
30
30
  # unknown character in the target encoding will be replaced with '?'
31
31
 
32
- def self.read_file filename, encoding, force_transcode = false
32
+ def self.read_file(filename, encoding, force_transcode = false)
33
33
  content = File.open filename, "rb" do |f| f.read end
34
34
  content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/
35
35
 
@@ -86,21 +86,10 @@ module RDoc::Encoding
86
86
  nil
87
87
  end
88
88
 
89
- def self.remove_frozen_string_literal string
90
- string =~ /\A(?:#!.*\n)?(.*\n)/
91
- first_line = $1
92
-
93
- if first_line =~ /\A# +frozen[-_]string[-_]literal[=:].+$/i
94
- string = string.sub first_line, ''
95
- end
96
-
97
- string
98
- end
99
-
100
89
  ##
101
90
  # Detects the encoding of +string+ based on the magic comment
102
91
 
103
- def self.detect_encoding string
92
+ def self.detect_encoding(string)
104
93
  result = HEADER_REGEXP.match string
105
94
  name = result && result[:name]
106
95
 
@@ -110,7 +99,7 @@ module RDoc::Encoding
110
99
  ##
111
100
  # Removes magic comments and shebang
112
101
 
113
- def self.remove_magic_comment string
102
+ def self.remove_magic_comment(string)
114
103
  string.sub HEADER_REGEXP do |s|
115
104
  s.gsub(/[^\n]/, '')
116
105
  end
@@ -120,16 +109,11 @@ module RDoc::Encoding
120
109
  # Changes encoding based on +encoding+ without converting and returns new
121
110
  # string
122
111
 
123
- def self.change_encoding text, encoding
112
+ def self.change_encoding(text, encoding)
124
113
  if text.kind_of? RDoc::Comment
125
114
  text.encode! encoding
126
115
  else
127
- # TODO: Remove this condition after Ruby 2.2 EOL
128
- if RUBY_VERSION < '2.3.0'
129
- text.force_encoding encoding
130
- else
131
- String.new text, encoding: encoding
132
- end
116
+ String.new text, encoding: encoding
133
117
  end
134
118
  end
135
119
 
@@ -9,11 +9,10 @@ class RDoc::ERBPartial < ERB
9
9
  # Overrides +compiler+ startup to set the +eoutvar+ to an empty string only
10
10
  # if it isn't already set.
11
11
 
12
- def set_eoutvar compiler, eoutvar = '_erbout'
12
+ def set_eoutvar(compiler, eoutvar = '_erbout')
13
13
  super
14
14
 
15
15
  compiler.pre_cmd = ["#{eoutvar} ||= +''"]
16
16
  end
17
17
 
18
18
  end
19
-