rdoc 7.2.0 → 8.1.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +4 -7
  3. data/LICENSE.rdoc +4 -0
  4. data/README.md +43 -2
  5. data/RI.md +75 -75
  6. data/doc/markup_reference/markdown.md +104 -3
  7. data/exe/rdoc +2 -2
  8. data/lib/rdoc/code_object/alias.rb +70 -74
  9. data/lib/rdoc/code_object/any_method.rb +305 -298
  10. data/lib/rdoc/code_object/attr.rb +150 -143
  11. data/lib/rdoc/code_object/class_module.rb +801 -765
  12. data/lib/rdoc/code_object/constant.rb +178 -150
  13. data/lib/rdoc/code_object/context/section.rb +133 -160
  14. data/lib/rdoc/code_object/context.rb +925 -952
  15. data/lib/rdoc/code_object/extend.rb +7 -5
  16. data/lib/rdoc/code_object/include.rb +7 -5
  17. data/lib/rdoc/code_object/method_attr.rb +325 -324
  18. data/lib/rdoc/code_object/mixin.rb +97 -95
  19. data/lib/rdoc/code_object/normal_class.rb +77 -78
  20. data/lib/rdoc/code_object/normal_module.rb +61 -59
  21. data/lib/rdoc/code_object/require.rb +23 -39
  22. data/lib/rdoc/code_object/single_class.rb +21 -19
  23. data/lib/rdoc/code_object/top_level.rb +212 -213
  24. data/lib/rdoc/code_object.rb +305 -305
  25. data/lib/rdoc/comment.rb +274 -337
  26. data/lib/rdoc/cross_reference.rb +194 -212
  27. data/lib/rdoc/encoding.rb +105 -103
  28. data/lib/rdoc/erb_partial.rb +13 -11
  29. data/lib/rdoc/erbio.rb +29 -27
  30. data/lib/rdoc/generator/aliki.rb +165 -140
  31. data/lib/rdoc/generator/darkfish.rb +647 -631
  32. data/lib/rdoc/generator/json_index.rb +233 -229
  33. data/lib/rdoc/generator/markup.rb +165 -122
  34. data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
  35. data/lib/rdoc/generator/pot/po.rb +52 -51
  36. data/lib/rdoc/generator/pot/po_entry.rb +138 -132
  37. data/lib/rdoc/generator/pot.rb +85 -81
  38. data/lib/rdoc/generator/ri.rb +23 -19
  39. data/lib/rdoc/generator/template/aliki/DESIGN.md +538 -0
  40. data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +1 -1
  41. data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
  42. data/lib/rdoc/generator/template/aliki/_head.rhtml +11 -11
  43. data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
  44. data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +8 -6
  45. data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +8 -6
  46. data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +1 -1
  47. data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +2 -2
  48. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
  49. data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +1 -1
  50. data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +1 -1
  51. data/lib/rdoc/generator/template/aliki/class.rhtml +56 -46
  52. data/lib/rdoc/generator/template/aliki/css/rdoc.css +538 -283
  53. data/lib/rdoc/generator/template/aliki/index.rhtml +1 -1
  54. data/lib/rdoc/generator/template/aliki/js/aliki.js +80 -102
  55. data/lib/rdoc/generator/template/aliki/page.rhtml +1 -1
  56. data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +1 -1
  57. data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +2 -2
  58. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
  59. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -6
  60. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -6
  61. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +1 -1
  62. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
  63. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +1 -1
  64. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +5 -5
  65. data/lib/rdoc/generator/template/darkfish/class.rhtml +18 -21
  66. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +0 -1
  67. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +3 -3
  68. data/lib/rdoc/generator.rb +48 -46
  69. data/lib/rdoc/i18n/locale.rb +99 -95
  70. data/lib/rdoc/i18n/text.rb +109 -105
  71. data/lib/rdoc/i18n.rb +7 -5
  72. data/lib/rdoc/markdown/byte_runtime.rb +80 -0
  73. data/lib/rdoc/markdown.kpeg +30 -21
  74. data/lib/rdoc/markdown.rb +329 -151
  75. data/lib/rdoc/markup/block_quote.rb +12 -8
  76. data/lib/rdoc/markup/document.rb +127 -123
  77. data/lib/rdoc/markup/formatter.rb +215 -221
  78. data/lib/rdoc/markup/heading.rb +1 -4
  79. data/lib/rdoc/markup/include.rb +33 -29
  80. data/lib/rdoc/markup/indented_paragraph.rb +37 -33
  81. data/lib/rdoc/markup/inline_parser.rb +281 -277
  82. data/lib/rdoc/markup/list.rb +80 -88
  83. data/lib/rdoc/markup/list_item.rb +73 -85
  84. data/lib/rdoc/markup/paragraph.rb +23 -19
  85. data/lib/rdoc/markup/parser.rb +501 -497
  86. data/lib/rdoc/markup/pre_process.rb +284 -305
  87. data/lib/rdoc/markup/raw.rb +2 -2
  88. data/lib/rdoc/markup/rule.rb +16 -12
  89. data/lib/rdoc/markup/to_ansi.rb +143 -139
  90. data/lib/rdoc/markup/to_bs.rb +72 -68
  91. data/lib/rdoc/markup/to_html.rb +600 -493
  92. data/lib/rdoc/markup/to_html_crossref.rb +221 -191
  93. data/lib/rdoc/markup/to_html_snippet.rb +232 -227
  94. data/lib/rdoc/markup/to_joined_paragraph.rb +40 -41
  95. data/lib/rdoc/markup/to_label.rb +63 -59
  96. data/lib/rdoc/markup/to_markdown.rb +212 -208
  97. data/lib/rdoc/markup/to_rdoc.rb +336 -332
  98. data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
  99. data/lib/rdoc/markup/to_test.rb +60 -56
  100. data/lib/rdoc/markup/to_tt_only.rb +83 -86
  101. data/lib/rdoc/markup/verbatim.rb +62 -58
  102. data/lib/rdoc/markup.rb +198 -196
  103. data/lib/rdoc/options.rb +1063 -1076
  104. data/lib/rdoc/parser/c.rb +1039 -1036
  105. data/lib/rdoc/parser/changelog.rb +319 -315
  106. data/lib/rdoc/parser/markdown.rb +17 -13
  107. data/lib/rdoc/parser/rbs.rb +279 -0
  108. data/lib/rdoc/parser/rd.rb +17 -13
  109. data/lib/rdoc/parser/ruby.rb +1231 -2222
  110. data/lib/rdoc/parser/ruby_colorizer.rb +303 -0
  111. data/lib/rdoc/parser/simple.rb +31 -27
  112. data/lib/rdoc/parser/text.rb +12 -8
  113. data/lib/rdoc/parser.rb +230 -221
  114. data/lib/rdoc/rbs_helper.rb +186 -0
  115. data/lib/rdoc/rd/inline.rb +57 -53
  116. data/lib/rdoc/rd.rb +90 -88
  117. data/lib/rdoc/rdoc.rb +547 -366
  118. data/lib/rdoc/ri/driver.rb +1141 -1130
  119. data/lib/rdoc/ri/formatter.rb +7 -3
  120. data/lib/rdoc/ri/paths.rb +140 -136
  121. data/lib/rdoc/ri/servlet.rb +456 -0
  122. data/lib/rdoc/ri/store.rb +4 -2
  123. data/lib/rdoc/ri/task.rb +55 -51
  124. data/lib/rdoc/ri.rb +14 -11
  125. data/lib/rdoc/rubygems_hook.rb +194 -192
  126. data/lib/rdoc/server.rb +462 -0
  127. data/lib/rdoc/stats/normal.rb +46 -42
  128. data/lib/rdoc/stats/quiet.rb +39 -35
  129. data/lib/rdoc/stats/verbose.rb +35 -31
  130. data/lib/rdoc/stats.rb +363 -338
  131. data/lib/rdoc/store.rb +919 -725
  132. data/lib/rdoc/task.rb +260 -255
  133. data/lib/rdoc/text.rb +130 -245
  134. data/lib/rdoc/token_stream.rb +101 -115
  135. data/lib/rdoc/tom_doc.rb +203 -201
  136. data/lib/rdoc/version.rb +1 -1
  137. data/lib/rdoc.rb +35 -7
  138. data/lib/rubygems_plugin.rb +2 -11
  139. data/rdoc-logo.svg +43 -0
  140. data/rdoc.gemspec +6 -4
  141. metadata +36 -20
  142. data/lib/rdoc/code_object/anon_class.rb +0 -10
  143. data/lib/rdoc/code_object/ghost_method.rb +0 -6
  144. data/lib/rdoc/code_object/meta_method.rb +0 -6
  145. data/lib/rdoc/markdown/literals.kpeg +0 -21
  146. data/lib/rdoc/markdown/literals.rb +0 -454
  147. data/lib/rdoc/parser/prism_ruby.rb +0 -1112
  148. data/lib/rdoc/parser/ripper_state_lex.rb +0 -302
  149. data/lib/rdoc/parser/ruby_tools.rb +0 -163
  150. data/lib/rdoc/servlet.rb +0 -452
@@ -1,52 +1,54 @@
1
1
  # frozen_string_literal: true
2
- ##
3
- # RDoc uses generators to turn parsed source code in the form of an
4
- # RDoc::CodeObject tree into some form of output. RDoc comes with the HTML
5
- # generator RDoc::Generator::Darkfish and an ri data generator
6
- # RDoc::Generator::RI.
7
- #
8
- # == Registering a Generator
9
- #
10
- # Generators are registered by calling RDoc::RDoc.add_generator with the class
11
- # of the generator:
12
- #
13
- # class My::Awesome::Generator
14
- # RDoc::RDoc.add_generator self
15
- # end
16
- #
17
- # == Adding Options to +rdoc+
18
- #
19
- # Before option processing in +rdoc+, RDoc::Options will call ::setup_options
20
- # on the generator class with an RDoc::Options instance. The generator can
21
- # use RDoc::Options#option_parser to add command-line options to the +rdoc+
22
- # tool. See RDoc::Options@Custom+Options for an example and see OptionParser
23
- # for details on how to add options.
24
- #
25
- # You can extend the RDoc::Options instance with additional accessors for your
26
- # generator.
27
- #
28
- # == Generator Instantiation
29
- #
30
- # After parsing, RDoc::RDoc will instantiate a generator by calling
31
- # #initialize with an RDoc::Store instance and an RDoc::Options instance.
32
- #
33
- # The RDoc::Store instance holds documentation for parsed source code. In
34
- # RDoc 3 and earlier the RDoc::TopLevel class held this data. When upgrading
35
- # a generator from RDoc 3 and earlier you should only need to replace
36
- # RDoc::TopLevel with the store instance.
37
- #
38
- # RDoc will then call #generate on the generator instance. You can use the
39
- # various methods on RDoc::Store and in the RDoc::CodeObject tree to create
40
- # your desired output format.
2
+ module RDoc
3
+ ##
4
+ # RDoc uses generators to turn parsed source code in the form of an
5
+ # RDoc::CodeObject tree into some form of output. RDoc comes with the HTML
6
+ # generator RDoc::Generator::Darkfish and an ri data generator
7
+ # RDoc::Generator::RI.
8
+ #
9
+ # == Registering a Generator
10
+ #
11
+ # Generators are registered by calling RDoc::RDoc.add_generator with the class
12
+ # of the generator:
13
+ #
14
+ # class My::Awesome::Generator
15
+ # RDoc::RDoc.add_generator self
16
+ # end
17
+ #
18
+ # == Adding Options to +rdoc+
19
+ #
20
+ # Before option processing in +rdoc+, RDoc::Options will call ::setup_options
21
+ # on the generator class with an RDoc::Options instance. The generator can
22
+ # use RDoc::Options#option_parser to add command-line options to the +rdoc+
23
+ # tool. See RDoc::Options@Custom+Options for an example and see OptionParser
24
+ # for details on how to add options.
25
+ #
26
+ # You can extend the RDoc::Options instance with additional accessors for your
27
+ # generator.
28
+ #
29
+ # == Generator Instantiation
30
+ #
31
+ # After parsing, RDoc::RDoc will instantiate a generator by calling
32
+ # #initialize with an RDoc::Store instance and an RDoc::Options instance.
33
+ #
34
+ # The RDoc::Store instance holds documentation for parsed source code. In
35
+ # RDoc 3 and earlier the RDoc::TopLevel class held this data. When upgrading
36
+ # a generator from RDoc 3 and earlier you should only need to replace
37
+ # RDoc::TopLevel with the store instance.
38
+ #
39
+ # RDoc will then call #generate on the generator instance. You can use the
40
+ # various methods on RDoc::Store and in the RDoc::CodeObject tree to create
41
+ # your desired output format.
41
42
 
42
- module RDoc::Generator
43
+ module Generator
43
44
 
44
- autoload :Markup, "#{__dir__}/generator/markup"
45
+ autoload :Markup, "#{__dir__}/generator/markup"
45
46
 
46
- autoload :Aliki, "#{__dir__}/generator/aliki"
47
- autoload :Darkfish, "#{__dir__}/generator/darkfish"
48
- autoload :JsonIndex, "#{__dir__}/generator/json_index"
49
- autoload :RI, "#{__dir__}/generator/ri"
50
- autoload :POT, "#{__dir__}/generator/pot"
47
+ autoload :Aliki, "#{__dir__}/generator/aliki"
48
+ autoload :Darkfish, "#{__dir__}/generator/darkfish"
49
+ autoload :JsonIndex, "#{__dir__}/generator/json_index"
50
+ autoload :RI, "#{__dir__}/generator/ri"
51
+ autoload :POT, "#{__dir__}/generator/pot"
51
52
 
53
+ end
52
54
  end
@@ -1,102 +1,106 @@
1
1
  # frozen_string_literal: true
2
- ##
3
- # A message container for a locale.
4
- #
5
- # This object provides the following two features:
6
- #
7
- # * Loads translated messages from .po file.
8
- # * Translates a message into the locale.
9
-
10
- class RDoc::I18n::Locale
11
-
12
- @@locales = {} # :nodoc:
13
-
14
- class << self
15
-
2
+ module RDoc
3
+ module I18n
16
4
  ##
17
- # Returns the locale object for +locale_name+.
18
-
19
- def [](locale_name)
20
- @@locales[locale_name] ||= new(locale_name)
21
- end
22
-
23
- ##
24
- # Sets the locale object for +locale_name+.
5
+ # A message container for a locale.
25
6
  #
26
- # Normally, this method is not used. This method is useful for
27
- # testing.
28
-
29
- def []=(locale_name, locale)
30
- @@locales[locale_name] = locale
31
- end
32
-
33
- end
34
-
35
- ##
36
- # The name of the locale. It uses IETF language tag format
37
- # +[language[_territory][.codeset][@modifier]]+.
38
- #
39
- # See also {BCP 47 - Tags for Identifying
40
- # Languages}[http://tools.ietf.org/rfc/bcp/bcp47.txt].
41
-
42
- attr_reader :name
43
-
44
- ##
45
- # Creates a new locale object for +name+ locale. +name+ must
46
- # follow IETF language tag format.
47
-
48
- def initialize(name)
49
- @name = name
50
- @messages = {}
51
- end
7
+ # This object provides the following two features:
8
+ #
9
+ # * Loads translated messages from .po file.
10
+ # * Translates a message into the locale.
11
+
12
+ class Locale
13
+
14
+ @@locales = {} # :nodoc:
15
+
16
+ class << self
17
+
18
+ ##
19
+ # Returns the locale object for +locale_name+.
20
+
21
+ def [](locale_name)
22
+ @@locales[locale_name] ||= new(locale_name)
23
+ end
24
+
25
+ ##
26
+ # Sets the locale object for +locale_name+.
27
+ #
28
+ # Normally, this method is not used. This method is useful for
29
+ # testing.
30
+
31
+ def []=(locale_name, locale)
32
+ @@locales[locale_name] = locale
33
+ end
34
+
35
+ end
36
+
37
+ ##
38
+ # The name of the locale. It uses IETF language tag format
39
+ # +[language[_territory][.codeset][@modifier]]+.
40
+ #
41
+ # See also {BCP 47 - Tags for Identifying
42
+ # Languages}[http://tools.ietf.org/rfc/bcp/bcp47.txt].
43
+
44
+ attr_reader :name
45
+
46
+ ##
47
+ # Creates a new locale object for +name+ locale. +name+ must
48
+ # follow IETF language tag format.
49
+
50
+ def initialize(name)
51
+ @name = name
52
+ @messages = {}
53
+ end
54
+
55
+ ##
56
+ # Loads translation messages from +locale_directory+/+@name+/rdoc.po
57
+ # or +locale_directory+/+@name+.po. The former has high priority.
58
+ #
59
+ # This method requires gettext gem for parsing .po file. If you
60
+ # don't have gettext gem, this method doesn't load .po file. This
61
+ # method warns and returns +false+.
62
+ #
63
+ # Returns +true+ if succeeded, +false+ otherwise.
64
+
65
+ def load(locale_directory)
66
+ return false if @name.nil?
67
+
68
+ po_file_candidates = [
69
+ File.join(locale_directory, @name, 'rdoc.po'),
70
+ File.join(locale_directory, "#{@name}.po"),
71
+ ]
72
+ po_file = po_file_candidates.find do |po_file_candidate|
73
+ File.exist?(po_file_candidate)
74
+ end
75
+ return false unless po_file
76
+
77
+ begin
78
+ require 'gettext/po_parser'
79
+ require 'gettext/mo'
80
+ rescue LoadError
81
+ warn('Need gettext gem for i18n feature:')
82
+ warn(' gem install gettext')
83
+ return false
84
+ end
85
+
86
+ po_parser = GetText::POParser.new
87
+ messages = GetText::MO.new
88
+ po_parser.report_warning = false
89
+ po_parser.parse_file(po_file, messages)
90
+
91
+ @messages.merge!(messages)
92
+
93
+ true
94
+ end
95
+
96
+ ##
97
+ # Translates the +message+ into locale. If there is no translation
98
+ # messages for +message+ in locale, +message+ itself is returned.
99
+
100
+ def translate(message)
101
+ @messages[message] || message
102
+ end
52
103
 
53
- ##
54
- # Loads translation messages from +locale_directory+/+@name+/rdoc.po
55
- # or +locale_directory+/+@name+.po. The former has high priority.
56
- #
57
- # This method requires gettext gem for parsing .po file. If you
58
- # don't have gettext gem, this method doesn't load .po file. This
59
- # method warns and returns +false+.
60
- #
61
- # Returns +true+ if succeeded, +false+ otherwise.
62
-
63
- def load(locale_directory)
64
- return false if @name.nil?
65
-
66
- po_file_candidates = [
67
- File.join(locale_directory, @name, 'rdoc.po'),
68
- File.join(locale_directory, "#{@name}.po"),
69
- ]
70
- po_file = po_file_candidates.find do |po_file_candidate|
71
- File.exist?(po_file_candidate)
72
- end
73
- return false unless po_file
74
-
75
- begin
76
- require 'gettext/po_parser'
77
- require 'gettext/mo'
78
- rescue LoadError
79
- warn('Need gettext gem for i18n feature:')
80
- warn(' gem install gettext')
81
- return false
82
104
  end
83
-
84
- po_parser = GetText::POParser.new
85
- messages = GetText::MO.new
86
- po_parser.report_warning = false
87
- po_parser.parse_file(po_file, messages)
88
-
89
- @messages.merge!(messages)
90
-
91
- true
92
- end
93
-
94
- ##
95
- # Translates the +message+ into locale. If there is no translation
96
- # messages for +message+ in locale, +message+ itself is returned.
97
-
98
- def translate(message)
99
- @messages[message] || message
100
105
  end
101
-
102
106
  end
@@ -1,126 +1,130 @@
1
1
  # frozen_string_literal: true
2
- ##
3
- # An i18n supported text.
4
- #
5
- # This object provides the following two features:
6
- #
7
- # * Extracts translation messages from wrapped raw text.
8
- # * Translates wrapped raw text in specified locale.
9
- #
10
- # Wrapped raw text is one of String, RDoc::Comment or Array of them.
2
+ module RDoc
3
+ module I18n
4
+ ##
5
+ # An i18n supported text.
6
+ #
7
+ # This object provides the following two features:
8
+ #
9
+ # * Extracts translation messages from wrapped raw text.
10
+ # * Translates wrapped raw text in specified locale.
11
+ #
12
+ # Wrapped raw text is one of String, RDoc::Comment or Array of them.
11
13
 
12
- class RDoc::I18n::Text
14
+ class Text
13
15
 
14
- ##
15
- # Creates a new i18n supported text for +raw+ text.
16
+ ##
17
+ # Creates a new i18n supported text for +raw+ text.
16
18
 
17
- def initialize(raw)
18
- @raw = raw
19
- end
19
+ def initialize(raw)
20
+ @raw = raw
21
+ end
20
22
 
21
- ##
22
- # Extracts translation target messages and yields each message.
23
- #
24
- # Each yielded message is a Hash. It consists of the followings:
25
- #
26
- # :type :: :paragraph
27
- # :paragraph :: String (The translation target message itself.)
28
- # :line_no :: Integer (The line number of the :paragraph is started.)
29
- #
30
- # The above content may be added in the future.
23
+ ##
24
+ # Extracts translation target messages and yields each message.
25
+ #
26
+ # Each yielded message is a Hash. It consists of the followings:
27
+ #
28
+ # :type :: :paragraph
29
+ # :paragraph :: String (The translation target message itself.)
30
+ # :line_no :: Integer (The line number of the :paragraph is started.)
31
+ #
32
+ # The above content may be added in the future.
31
33
 
32
- def extract_messages
33
- parse do |part|
34
- case part[:type]
35
- when :empty_line
36
- # ignore
37
- when :paragraph
38
- yield(part)
34
+ def extract_messages
35
+ parse do |part|
36
+ case part[:type]
37
+ when :empty_line
38
+ # ignore
39
+ when :paragraph
40
+ yield(part)
41
+ end
42
+ end
39
43
  end
40
- end
41
- end
42
44
 
43
- # Translates raw text into +locale+.
44
- def translate(locale)
45
- translated_text = ''
46
- parse do |part|
47
- case part[:type]
48
- when :paragraph
49
- translated_text += locale.translate(part[:paragraph])
50
- when :empty_line
51
- translated_text += part[:line]
52
- else
53
- raise "should not reach here: unexpected type: #{type}"
45
+ # Translates raw text into +locale+.
46
+ def translate(locale)
47
+ translated_text = ''
48
+ parse do |part|
49
+ case part[:type]
50
+ when :paragraph
51
+ translated_text += locale.translate(part[:paragraph])
52
+ when :empty_line
53
+ translated_text += part[:line]
54
+ else
55
+ raise "should not reach here: unexpected type: #{type}"
56
+ end
57
+ end
58
+ translated_text
54
59
  end
55
- end
56
- translated_text
57
- end
58
60
 
59
- private
60
- def parse(&block)
61
- paragraph = ''
62
- paragraph_start_line = 0
63
- line_no = 0
61
+ private
62
+ def parse(&block)
63
+ paragraph = ''
64
+ paragraph_start_line = 0
65
+ line_no = 0
64
66
 
65
- each_line(@raw) do |line|
66
- line_no += 1
67
- case line
68
- when /\A\s*\z/
69
- if paragraph.empty?
70
- emit_empty_line_event(line, line_no, &block)
71
- else
72
- paragraph += line
73
- emit_paragraph_event(paragraph, paragraph_start_line, line_no,
74
- &block)
75
- paragraph = ''
67
+ each_line(@raw) do |line|
68
+ line_no += 1
69
+ case line
70
+ when /\A\s*\z/
71
+ if paragraph.empty?
72
+ emit_empty_line_event(line, line_no, &block)
73
+ else
74
+ paragraph += line
75
+ emit_paragraph_event(paragraph, paragraph_start_line, line_no,
76
+ &block)
77
+ paragraph = ''
78
+ end
79
+ else
80
+ paragraph_start_line = line_no if paragraph.empty?
81
+ paragraph += line
82
+ end
83
+ end
84
+
85
+ unless paragraph.empty?
86
+ emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
76
87
  end
77
- else
78
- paragraph_start_line = line_no if paragraph.empty?
79
- paragraph += line
80
88
  end
81
- end
82
89
 
83
- unless paragraph.empty?
84
- emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
85
- end
86
- end
90
+ def each_line(raw, &block)
91
+ case raw
92
+ when Comment
93
+ raw.text.each_line(&block)
94
+ when Hash
95
+ raw.each_value do |comments|
96
+ comments.each { |comment| each_line(comment, &block) }
97
+ end
98
+ else
99
+ raw.each_line(&block)
100
+ end
101
+ end
87
102
 
88
- def each_line(raw, &block)
89
- case raw
90
- when RDoc::Comment
91
- raw.text.each_line(&block)
92
- when Array
93
- raw.each do |comment, location|
94
- each_line(comment, &block)
103
+ def emit_empty_line_event(line, line_no)
104
+ part = {
105
+ :type => :empty_line,
106
+ :line => line,
107
+ :line_no => line_no,
108
+ }
109
+ yield(part)
95
110
  end
96
- else
97
- raw.each_line(&block)
98
- end
99
- end
100
111
 
101
- def emit_empty_line_event(line, line_no)
102
- part = {
103
- :type => :empty_line,
104
- :line => line,
105
- :line_no => line_no,
106
- }
107
- yield(part)
108
- end
112
+ def emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
113
+ paragraph_part = {
114
+ :type => :paragraph,
115
+ :line_no => paragraph_start_line,
116
+ }
117
+ match_data = /(\s*)\z/.match(paragraph)
118
+ if match_data
119
+ paragraph_part[:paragraph] = match_data.pre_match
120
+ yield(paragraph_part)
121
+ emit_empty_line_event(match_data[1], line_no, &block)
122
+ else
123
+ paragraph_part[:paragraph] = paragraph
124
+ yield(paragraph_part)
125
+ end
126
+ end
109
127
 
110
- def emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
111
- paragraph_part = {
112
- :type => :paragraph,
113
- :line_no => paragraph_start_line,
114
- }
115
- match_data = /(\s*)\z/.match(paragraph)
116
- if match_data
117
- paragraph_part[:paragraph] = match_data.pre_match
118
- yield(paragraph_part)
119
- emit_empty_line_event(match_data[1], line_no, &block)
120
- else
121
- paragraph_part[:paragraph] = paragraph
122
- yield(paragraph_part)
123
128
  end
124
129
  end
125
-
126
130
  end
data/lib/rdoc/i18n.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
- ##
3
- # This module provides i18n related features.
2
+ module RDoc
3
+ ##
4
+ # This module provides i18n related features.
4
5
 
5
- module RDoc::I18n
6
+ module I18n
6
7
 
7
- autoload :Locale, "#{__dir__}/i18n/locale"
8
- require_relative 'i18n/text'
8
+ autoload :Locale, "#{__dir__}/i18n/locale"
9
+ require_relative 'i18n/text'
9
10
 
11
+ end
10
12
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'strscan'
4
+
5
+ module RDoc
6
+ class Markdown
7
+
8
+ ##
9
+ # Byte-offset replacements for the position helpers of the kpeg-generated
10
+ # parser runtime.
11
+ #
12
+ # The generated runtime addresses +@string+ by character index, which makes
13
+ # every position lookup scan the string from its beginning when the input
14
+ # contains non-ASCII characters, so parse time becomes quadratic in the
15
+ # input size. Generated rule bodies only save and restore +pos+ without
16
+ # inspecting it, so replacing these helpers is enough to switch the whole
17
+ # parser to byte offsets.
18
+ #
19
+ # get_byte (the grammar's `.`) consumes one character and returns its
20
+ # codepoint, exactly like the character-index runtime, so positions always
21
+ # stay on character boundaries and the only observable difference is the
22
+ # position values themselves. The input must be validly encoded in an
23
+ # ASCII-compatible encoding.
24
+ #
25
+ # The error-reporting helpers of the generated runtime (+current_line+,
26
+ # +current_column+, ...) are left as-is and would misreport locations when
27
+ # given byte offsets. They are unreachable: markdown is deliberately
28
+ # designed to parse any input somehow rather than fail (the root rule
29
+ # `Doc = Block*` cannot fail), so a parse failure means a bug in the
30
+ # grammar itself, and nothing in RDoc invokes +raise_error+ or
31
+ # +show_error+. Make these helpers byte-aware before using them for
32
+ # anything.
33
+
34
+ module ByteRuntime
35
+ def set_string(string, pos)
36
+ @string = string
37
+ @string_size = string ? string.bytesize : 0
38
+ @pos = pos
39
+ @position_line_offsets = nil
40
+ @scanner = string ? StringScanner.new(string) : nil
41
+ end
42
+
43
+ def scan(reg)
44
+ @scanner.pos = @pos
45
+ if @scanner.skip(reg)
46
+ @pos = @scanner.pos
47
+ true
48
+ end
49
+ end
50
+
51
+ def match_string(str)
52
+ len = str.bytesize
53
+ if @string.byteslice(@pos, len) == str
54
+ @pos += len
55
+ str
56
+ end
57
+ end
58
+
59
+ def get_byte
60
+ byte = @string.getbyte(@pos)
61
+ return nil unless byte
62
+
63
+ if byte < 0x80
64
+ @pos += 1
65
+ byte
66
+ else
67
+ @scanner.pos = @pos
68
+ # /./ interprets the character in the string's own encoding
69
+ char = @scanner.scan(/./m)
70
+ @pos = @scanner.pos
71
+ char.ord
72
+ end
73
+ end
74
+
75
+ def get_text(start)
76
+ @string.byteslice(start, @pos - start)
77
+ end
78
+ end
79
+ end
80
+ end