rdoc 8.0.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -3
  3. data/RI.md +75 -75
  4. data/exe/rdoc +2 -2
  5. data/lib/rdoc/code_object/alias.rb +71 -69
  6. data/lib/rdoc/code_object/any_method.rb +305 -303
  7. data/lib/rdoc/code_object/attr.rb +150 -148
  8. data/lib/rdoc/code_object/class_module.rb +798 -792
  9. data/lib/rdoc/code_object/constant.rb +175 -173
  10. data/lib/rdoc/code_object/context/section.rb +142 -138
  11. data/lib/rdoc/code_object/context.rb +926 -958
  12. data/lib/rdoc/code_object/extend.rb +7 -5
  13. data/lib/rdoc/code_object/include.rb +7 -5
  14. data/lib/rdoc/code_object/method_attr.rb +326 -319
  15. data/lib/rdoc/code_object/mixin.rb +97 -95
  16. data/lib/rdoc/code_object/normal_class.rb +77 -78
  17. data/lib/rdoc/code_object/normal_module.rb +61 -59
  18. data/lib/rdoc/code_object/require.rb +23 -39
  19. data/lib/rdoc/code_object/single_class.rb +21 -19
  20. data/lib/rdoc/code_object/top_level.rb +212 -219
  21. data/lib/rdoc/code_object.rb +305 -303
  22. data/lib/rdoc/comment.rb +275 -273
  23. data/lib/rdoc/cross_reference.rb +192 -190
  24. data/lib/rdoc/encoding.rb +105 -103
  25. data/lib/rdoc/erb_partial.rb +13 -11
  26. data/lib/rdoc/erbio.rb +29 -27
  27. data/lib/rdoc/generator/aliki.rb +161 -153
  28. data/lib/rdoc/generator/darkfish.rb +645 -635
  29. data/lib/rdoc/generator/json_index.rb +233 -229
  30. data/lib/rdoc/generator/markup.rb +164 -146
  31. data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
  32. data/lib/rdoc/generator/pot/po.rb +52 -51
  33. data/lib/rdoc/generator/pot/po_entry.rb +138 -132
  34. data/lib/rdoc/generator/pot.rb +85 -81
  35. data/lib/rdoc/generator/ri.rb +23 -19
  36. data/lib/rdoc/generator/template/aliki/DESIGN.md +6 -4
  37. data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
  38. data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
  39. data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
  40. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
  41. data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
  42. data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
  43. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
  44. data/lib/rdoc/generator.rb +48 -46
  45. data/lib/rdoc/i18n/locale.rb +99 -95
  46. data/lib/rdoc/i18n/text.rb +109 -105
  47. data/lib/rdoc/i18n.rb +7 -5
  48. data/lib/rdoc/markdown/byte_runtime.rb +80 -0
  49. data/lib/rdoc/markdown.kpeg +15 -11
  50. data/lib/rdoc/markdown.rb +40 -47
  51. data/lib/rdoc/markup/block_quote.rb +12 -8
  52. data/lib/rdoc/markup/document.rb +127 -123
  53. data/lib/rdoc/markup/formatter.rb +219 -215
  54. data/lib/rdoc/markup/include.rb +33 -29
  55. data/lib/rdoc/markup/indented_paragraph.rb +37 -33
  56. data/lib/rdoc/markup/inline_parser.rb +281 -277
  57. data/lib/rdoc/markup/list.rb +80 -88
  58. data/lib/rdoc/markup/list_item.rb +73 -85
  59. data/lib/rdoc/markup/paragraph.rb +23 -19
  60. data/lib/rdoc/markup/parser.rb +501 -497
  61. data/lib/rdoc/markup/pre_process.rb +283 -279
  62. data/lib/rdoc/markup/raw.rb +2 -2
  63. data/lib/rdoc/markup/rule.rb +16 -12
  64. data/lib/rdoc/markup/to_ansi.rb +143 -139
  65. data/lib/rdoc/markup/to_bs.rb +72 -68
  66. data/lib/rdoc/markup/to_html.rb +594 -565
  67. data/lib/rdoc/markup/to_html_crossref.rb +234 -230
  68. data/lib/rdoc/markup/to_html_snippet.rb +232 -227
  69. data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
  70. data/lib/rdoc/markup/to_label.rb +63 -59
  71. data/lib/rdoc/markup/to_markdown.rb +212 -208
  72. data/lib/rdoc/markup/to_rdoc.rb +336 -332
  73. data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
  74. data/lib/rdoc/markup/to_test.rb +60 -56
  75. data/lib/rdoc/markup/to_tt_only.rb +84 -80
  76. data/lib/rdoc/markup/verbatim.rb +62 -58
  77. data/lib/rdoc/markup.rb +198 -196
  78. data/lib/rdoc/options.rb +1063 -1061
  79. data/lib/rdoc/parser/c.rb +1039 -1037
  80. data/lib/rdoc/parser/changelog.rb +319 -315
  81. data/lib/rdoc/parser/markdown.rb +17 -13
  82. data/lib/rdoc/parser/rbs.rb +239 -235
  83. data/lib/rdoc/parser/rd.rb +17 -13
  84. data/lib/rdoc/parser/ruby.rb +1245 -1124
  85. data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
  86. data/lib/rdoc/parser/simple.rb +31 -27
  87. data/lib/rdoc/parser/text.rb +12 -8
  88. data/lib/rdoc/parser.rb +228 -220
  89. data/lib/rdoc/rbs_helper.rb +1 -1
  90. data/lib/rdoc/rd/inline.rb +57 -53
  91. data/lib/rdoc/rd.rb +90 -88
  92. data/lib/rdoc/rdoc.rb +500 -491
  93. data/lib/rdoc/ri/driver.rb +1140 -1135
  94. data/lib/rdoc/ri/formatter.rb +7 -3
  95. data/lib/rdoc/ri/paths.rb +140 -136
  96. data/lib/rdoc/ri/servlet.rb +354 -350
  97. data/lib/rdoc/ri/store.rb +4 -2
  98. data/lib/rdoc/ri/task.rb +55 -51
  99. data/lib/rdoc/ri.rb +14 -12
  100. data/lib/rdoc/rubygems_hook.rb +183 -181
  101. data/lib/rdoc/server.rb +349 -347
  102. data/lib/rdoc/stats/normal.rb +46 -42
  103. data/lib/rdoc/stats/quiet.rb +39 -35
  104. data/lib/rdoc/stats/verbose.rb +35 -31
  105. data/lib/rdoc/stats.rb +365 -363
  106. data/lib/rdoc/store.rb +888 -902
  107. data/lib/rdoc/task.rb +260 -256
  108. data/lib/rdoc/text.rb +135 -133
  109. data/lib/rdoc/token_stream.rb +101 -93
  110. data/lib/rdoc/tom_doc.rb +203 -201
  111. data/lib/rdoc/version.rb +1 -1
  112. metadata +4 -5
  113. data/lib/rdoc/markdown/literals.kpeg +0 -21
  114. data/lib/rdoc/markdown/literals.rb +0 -454
@@ -1,215 +1,217 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ##
4
- # RDoc::CrossReference is a reusable way to create cross references for names.
5
-
6
- class RDoc::CrossReference
7
-
8
- ##
9
- # Regular expression to match class references
10
- #
11
- # 1. There can be a '\\' in front of text to suppress the cross-reference
12
- # 2. There can be a '::' in front of class names to reference from the
13
- # top-level namespace.
14
- # 3. The method can be followed by parenthesis (not recommended)
15
-
16
- CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)'
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
-
28
- ##
29
- # Regular expression to match method references.
30
- #
31
- # See CLASS_REGEXP_STR
32
-
33
- METHOD_REGEXP_STR = /(
34
- (?!\d)[\w]+[!?=]?|
35
- %|=(?:==?|~)|![=~]|\[\]=?|<(?:<|=>?)?|>[>=]?|[-+!]@?|\*\*?|[\/%\`|&^~]
36
- )#{METHOD_ARGS_REGEXP_STR}/.source.delete("\n ").freeze
37
-
38
- ##
39
- # Regular expressions matching text that should potentially have
40
- # cross-reference links generated are passed to add_regexp_handling. Note
41
- # that these expressions are meant to pick up text for which cross-references
42
- # have been suppressed, since the suppression characters are removed by the
43
- # code that is triggered.
44
-
45
- CROSSREF_REGEXP = /(?:^|[\s()])
46
- (
47
- (?:
48
- # A::B::C.meth
49
- #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
50
-
51
- # A::B::C
52
- # The stuff after CLASS_REGEXP_STR is a
53
- # nasty hack. CLASS_REGEXP_STR unfortunately matches
54
- # words like dog and cat (these are legal "class"
55
- # names in Fortran 95). When a word is flagged as a
56
- # potential cross-reference, limitations in the markup
57
- # engine suppress other processing, such as typesetting.
58
- # This is particularly noticeable for contractions.
59
- # In order that words like "can't" not
60
- # be flagged as potential cross-references, only
61
- # flag potential class cross-references if the character
62
- # after the cross-reference is a space, sentence
63
- # punctuation, tag start character, or attribute
64
- # marker.
65
- | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)
66
-
67
- # Stand-alone method (preceded by a #)
68
- | \\?\##{METHOD_REGEXP_STR}
69
-
70
- # Stand-alone method (preceded by ::)
71
- | ::#{METHOD_REGEXP_STR}
72
-
73
- # Things that look like filenames
74
- # The key thing is that there must be at least
75
- # one special character (period, slash, or
76
- # underscore).
77
- | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+
78
-
79
- # Things that have markup suppressed
80
- # Don't process things like '\<' in \<tt>, though.
81
- # TODO: including < is a hack, not very satisfying.
82
- | \\[^\s<]
83
- )
84
-
85
- # labels for headings
86
- (?:@[\w+%-]+(?:\.[\w|%-]+)?)?
87
- )/x
88
-
89
- ##
90
- # Version of CROSSREF_REGEXP used when <tt>--hyperlink-all</tt> is specified.
91
-
92
- ALL_CROSSREF_REGEXP = /
93
- (?:^|[\s()])
94
- (
95
- (?:
96
- # A::B::C.meth
97
- #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
98
-
99
- # A::B::C
100
- | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)
101
-
102
- # Stand-alone method
103
- | \\?#{METHOD_REGEXP_STR}
104
-
105
- # Things that look like filenames
106
- | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+
107
-
108
- # Things that have markup suppressed
109
- | \\[^\s<]
110
- )
111
-
112
- # labels for headings
113
- (?:@[\w+%-]+)?
114
- )/x
115
-
116
- ##
117
- # Hash of references that have been looked-up to their replacements
118
-
119
- attr_accessor :seen
120
-
3
+ module RDoc
121
4
  ##
122
- # Allows cross-references to be created based on the given +context+
123
- # (RDoc::Context).
124
-
125
- def initialize(context)
126
- @context = context
127
- @store = context.store
128
-
129
- @seen = {}
130
- end
5
+ # RDoc::CrossReference is a reusable way to create cross references for names.
6
+
7
+ class CrossReference
8
+
9
+ ##
10
+ # Regular expression to match class references
11
+ #
12
+ # 1. There can be a '\\' in front of text to suppress the cross-reference
13
+ # 2. There can be a '::' in front of class names to reference from the
14
+ # top-level namespace.
15
+ # 3. The method can be followed by parenthesis (not recommended)
16
+
17
+ CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)'
18
+
19
+ ##
20
+ # Regular expression to match a single method argument.
21
+
22
+ METHOD_ARG_REGEXP_STR = '[\w.+*/=<>-]+'
23
+
24
+ ##
25
+ # Regular expression to match method arguments.
26
+
27
+ METHOD_ARGS_REGEXP_STR = /(?:\((?:#{METHOD_ARG_REGEXP_STR}(?:,\s*#{METHOD_ARG_REGEXP_STR})*)?\))?/.source
28
+
29
+ ##
30
+ # Regular expression to match method references.
31
+ #
32
+ # See CLASS_REGEXP_STR
33
+
34
+ METHOD_REGEXP_STR = /(
35
+ (?!\d)[\w]+[!?=]?|
36
+ %|=(?:==?|~)|![=~]|\[\]=?|<(?:<|=>?)?|>[>=]?|[-+!]@?|\*\*?|[\/%\`|&^~]
37
+ )#{METHOD_ARGS_REGEXP_STR}/.source.delete("\n ").freeze
38
+
39
+ ##
40
+ # Regular expressions matching text that should potentially have
41
+ # cross-reference links generated are passed to add_regexp_handling. Note
42
+ # that these expressions are meant to pick up text for which cross-references
43
+ # have been suppressed, since the suppression characters are removed by the
44
+ # code that is triggered.
45
+
46
+ CROSSREF_REGEXP = /(?:^|[\s()])
47
+ (
48
+ (?:
49
+ # A::B::C.meth
50
+ #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
51
+
52
+ # A::B::C
53
+ # The stuff after CLASS_REGEXP_STR is a
54
+ # nasty hack. CLASS_REGEXP_STR unfortunately matches
55
+ # words like dog and cat (these are legal "class"
56
+ # names in Fortran 95). When a word is flagged as a
57
+ # potential cross-reference, limitations in the markup
58
+ # engine suppress other processing, such as typesetting.
59
+ # This is particularly noticeable for contractions.
60
+ # In order that words like "can't" not
61
+ # be flagged as potential cross-references, only
62
+ # flag potential class cross-references if the character
63
+ # after the cross-reference is a space, sentence
64
+ # punctuation, tag start character, or attribute
65
+ # marker.
66
+ | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)
67
+
68
+ # Stand-alone method (preceded by a #)
69
+ | \\?\##{METHOD_REGEXP_STR}
70
+
71
+ # Stand-alone method (preceded by ::)
72
+ | ::#{METHOD_REGEXP_STR}
73
+
74
+ # Things that look like filenames
75
+ # The key thing is that there must be at least
76
+ # one special character (period, slash, or
77
+ # underscore).
78
+ | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+
79
+
80
+ # Things that have markup suppressed
81
+ # Don't process things like '\<' in \<tt>, though.
82
+ # TODO: including < is a hack, not very satisfying.
83
+ | \\[^\s<]
84
+ )
85
+
86
+ # labels for headings
87
+ (?:@[\w+%-]+(?:\.[\w|%-]+)?)?
88
+ )/x
89
+
90
+ ##
91
+ # Version of CROSSREF_REGEXP used when <tt>--hyperlink-all</tt> is specified.
92
+
93
+ ALL_CROSSREF_REGEXP = /
94
+ (?:^|[\s()])
95
+ (
96
+ (?:
97
+ # A::B::C.meth
98
+ #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
99
+
100
+ # A::B::C
101
+ | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)
102
+
103
+ # Stand-alone method
104
+ | \\?#{METHOD_REGEXP_STR}
105
+
106
+ # Things that look like filenames
107
+ | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+
108
+
109
+ # Things that have markup suppressed
110
+ | \\[^\s<]
111
+ )
112
+
113
+ # labels for headings
114
+ (?:@[\w+%-]+)?
115
+ )/x
116
+
117
+ ##
118
+ # Hash of references that have been looked-up to their replacements
119
+
120
+ attr_accessor :seen
121
+
122
+ ##
123
+ # Allows cross-references to be created based on the given +context+
124
+ # (RDoc::Context).
125
+
126
+ def initialize(context)
127
+ @context = context
128
+ @store = context.store
129
+
130
+ @seen = {}
131
+ end
131
132
 
132
- ##
133
- # Returns a method, attribute or constant reference to +name+
134
- # if it exists in the containing context object. It returns
135
- # nil otherwise.
136
- #
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
151
- type = $2
152
- if '.' == type # will find either #method or ::method
153
- symbol = $3
154
- else
155
- symbol = "#{type}#{$3}"
156
- end
157
- container = @context.find_symbol_module($1)
158
- when /^([.#]|::)#{METHOD_REGEXP_STR}/o then
159
- type = $1
160
- if '.' == type
133
+ ##
134
+ # Returns a method, attribute or constant reference to +name+
135
+ # if it exists in the containing context object. It returns
136
+ # nil otherwise.
137
+ #
138
+ # For example, this method would decompose name = 'A::CONSTANT' into a
139
+ # container object A and a symbol 'CONSTANT', and it would try to find
140
+ # 'CONSTANT' in A.
141
+
142
+ def resolve_local_symbol(name)
143
+ ref = nil
144
+ type = nil
145
+ container = nil
146
+
147
+ case name
148
+ when /#{CLASS_REGEXP_STR}::([A-Z]\w*)\z/o
161
149
  symbol = $2
162
- else
163
- symbol = "#{type}#{$2}"
150
+ container = @context.find_symbol_module($1)
151
+ when /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o
152
+ type = $2
153
+ if '.' == type # will find either #method or ::method
154
+ symbol = $3
155
+ else
156
+ symbol = "#{type}#{$3}"
157
+ end
158
+ container = @context.find_symbol_module($1)
159
+ when /^([.#]|::)#{METHOD_REGEXP_STR}/o
160
+ type = $1
161
+ if '.' == type
162
+ symbol = $2
163
+ else
164
+ symbol = "#{type}#{$2}"
165
+ end
166
+ container = @context
164
167
  end
165
- container = @context
166
- end
167
168
 
168
- if container then
169
- unless RDoc::TopLevel === container then
170
- if '.' == type then
171
- if 'new' == symbol then # AnyClassName.new will be class method
169
+ if container
170
+ unless TopLevel === container
171
+ if '.' == type
172
+ if 'new' == symbol # AnyClassName.new will be class method
173
+ ref = container.find_local_symbol symbol
174
+ ref = container.find_ancestor_local_symbol symbol unless ref
175
+ else
176
+ ref = container.find_local_symbol "::#{symbol}"
177
+ ref = container.find_ancestor_local_symbol "::#{symbol}" unless ref
178
+ ref = container.find_local_symbol "##{symbol}" unless ref
179
+ ref = container.find_ancestor_local_symbol "##{symbol}" unless ref
180
+ end
181
+ else
172
182
  ref = container.find_local_symbol symbol
173
183
  ref = container.find_ancestor_local_symbol symbol unless ref
174
- else
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
179
184
  end
180
- else
181
- ref = container.find_local_symbol symbol
182
- ref = container.find_ancestor_local_symbol symbol unless ref
183
185
  end
184
186
  end
187
+
188
+ ref
185
189
  end
186
190
 
187
- ref
188
- end
191
+ ##
192
+ # Returns a reference to +name+.
193
+ #
194
+ # If the reference is found and +name+ is not documented +nil+ will be
195
+ # returned. If +name+ is not found +nil+ is returned.
189
196
 
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.
197
+ def resolve(name)
198
+ return @seen[name] if @seen.include? name
195
199
 
196
- def resolve(name)
197
- return @seen[name] if @seen.include? name
200
+ ref = @context.find_symbol name
198
201
 
199
- ref = @context.find_symbol name
202
+ ref = resolve_local_symbol name unless ref
200
203
 
201
- ref = resolve_local_symbol name unless ref
204
+ # Try a page name
205
+ ref = @store.page name if not ref and name =~ /^[\w.\/]+$/
202
206
 
203
- # Try a page name
204
- ref = @store.page name if not ref and name =~ /^[\w.\/]+$/
207
+ ref = nil if Alias === ref # external alias, can't link to it
205
208
 
206
- ref = nil if RDoc::Alias === ref # external alias, can't link to it
209
+ ref = nil unless ref&.display?
207
210
 
208
- ref = nil unless ref&.display?
211
+ @seen[name] = ref
209
212
 
210
- @seen[name] = ref
213
+ ref
214
+ end
211
215
 
212
- ref
213
216
  end
214
-
215
217
  end
data/lib/rdoc/encoding.rb CHANGED
@@ -1,120 +1,122 @@
1
1
  # coding: US-ASCII
2
2
  # frozen_string_literal: true
3
3
 
4
- ##
5
- # This class is a wrapper around File IO and Encoding that helps RDoc load
6
- # files and convert them to the correct encoding.
7
-
8
- module RDoc::Encoding
9
-
10
- HEADER_REGEXP = /\A
11
- (?:
12
- \#!.*\n
13
- |
14
- ^\#\s+frozen[-_]string[-_]literal[=:].+\n
15
- |
16
- ^\#\s*(?:-\*-\s*(?:[^;\n]*;\s*)*)?(?:en)?coding[=:]\s*(?<name>[^:\s;]+).*\n
17
- |
18
- <\?xml[^?]*encoding=(?<quote>["'])(?<name>.*?)\k<quote>.*\n
19
- )+
20
- /xi # :nodoc:
21
-
4
+ module RDoc
22
5
  ##
23
- # Reads the contents of +filename+ and handles any encoding directives in
24
- # the file.
25
- #
26
- # The content will be converted to the +encoding+. If the file cannot be
27
- # converted a warning will be printed and nil will be returned.
28
- #
29
- # If +force_transcode+ is true the document will be transcoded and any
30
- # unknown character in the target encoding will be replaced with '?'
31
-
32
- def self.read_file(filename, encoding, force_transcode = false)
33
- content = File.open filename, "rb" do |f| f.read end
34
- content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/
35
-
36
- utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
37
-
38
- enc = RDoc::Encoding.detect_encoding content
39
- content = RDoc::Encoding.change_encoding content, enc if enc
40
-
41
- begin
42
- encoding ||= Encoding.default_external
43
- orig_encoding = content.encoding
44
-
45
- if not orig_encoding.ascii_compatible? then
46
- content = content.encode encoding
47
- elsif utf8 then
48
- content = RDoc::Encoding.change_encoding content, Encoding::UTF_8
49
- content = content.encode encoding
50
- else
51
- # assume the content is in our output encoding
52
- content = RDoc::Encoding.change_encoding content, encoding
53
- end
54
-
55
- unless content.valid_encoding? then
56
- # revert and try to transcode
57
- content = RDoc::Encoding.change_encoding content, orig_encoding
58
- content = content.encode encoding
6
+ # This class is a wrapper around File IO and Encoding that helps RDoc load
7
+ # files and convert them to the correct encoding.
8
+
9
+ module Encoding
10
+
11
+ HEADER_REGEXP = /\A
12
+ (?:
13
+ \#!.*\n
14
+ |
15
+ ^\#\s+frozen[-_]string[-_]literal[=:].+\n
16
+ |
17
+ ^\#\s*(?:-\*-\s*(?:[^;\n]*;\s*)*)?(?:en)?coding[=:]\s*(?<name>[^:\s;]+).*\n
18
+ |
19
+ <\?xml[^?]*encoding=(?<quote>["'])(?<name>.*?)\k<quote>.*\n
20
+ )+
21
+ /xi # :nodoc:
22
+
23
+ ##
24
+ # Reads the contents of +filename+ and handles any encoding directives in
25
+ # the file.
26
+ #
27
+ # The content will be converted to the +encoding+. If the file cannot be
28
+ # converted a warning will be printed and nil will be returned.
29
+ #
30
+ # If +force_transcode+ is true the document will be transcoded and any
31
+ # unknown character in the target encoding will be replaced with '?'
32
+
33
+ def self.read_file(filename, encoding, force_transcode = false)
34
+ content = File.open filename, "rb" do |f| f.read end
35
+ content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/
36
+
37
+ utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
38
+
39
+ enc = Encoding.detect_encoding content
40
+ content = Encoding.change_encoding content, enc if enc
41
+
42
+ begin
43
+ encoding ||= ::Encoding.default_external
44
+ orig_encoding = content.encoding
45
+
46
+ if not orig_encoding.ascii_compatible?
47
+ content = content.encode encoding
48
+ elsif utf8
49
+ content = Encoding.change_encoding content, ::Encoding::UTF_8
50
+ content = content.encode encoding
51
+ else
52
+ # assume the content is in our output encoding
53
+ content = Encoding.change_encoding content, encoding
54
+ end
55
+
56
+ unless content.valid_encoding?
57
+ # revert and try to transcode
58
+ content = Encoding.change_encoding content, orig_encoding
59
+ content = content.encode encoding
60
+ end
61
+
62
+ unless content.valid_encoding?
63
+ warn "unable to convert #{filename} to #{encoding}, skipping"
64
+ content = nil
65
+ end
66
+ rescue ::Encoding::InvalidByteSequenceError,
67
+ ::Encoding::UndefinedConversionError => e
68
+ if force_transcode
69
+ content = Encoding.change_encoding content, orig_encoding
70
+ content = content.encode(encoding,
71
+ :invalid => :replace,
72
+ :undef => :replace,
73
+ :replace => '?')
74
+ return content
75
+ else
76
+ warn "unable to convert #{e.message} for #{filename}, skipping"
77
+ return nil
78
+ end
59
79
  end
60
80
 
61
- unless content.valid_encoding? then
62
- warn "unable to convert #{filename} to #{encoding}, skipping"
63
- content = nil
64
- end
65
- rescue Encoding::InvalidByteSequenceError,
66
- Encoding::UndefinedConversionError => e
67
- if force_transcode then
68
- content = RDoc::Encoding.change_encoding content, orig_encoding
69
- content = content.encode(encoding,
70
- :invalid => :replace,
71
- :undef => :replace,
72
- :replace => '?')
73
- return content
74
- else
75
- warn "unable to convert #{e.message} for #{filename}, skipping"
76
- return nil
77
- end
81
+ content
82
+ rescue ArgumentError => e
83
+ raise unless e.message =~ /unknown encoding name - (.*)/
84
+ warn "unknown encoding name \"#{$1}\" for #{filename}, skipping"
85
+ nil
86
+ rescue Errno::EISDIR, Errno::ENOENT
87
+ nil
78
88
  end
79
89
 
80
- content
81
- rescue ArgumentError => e
82
- raise unless e.message =~ /unknown encoding name - (.*)/
83
- warn "unknown encoding name \"#{$1}\" for #{filename}, skipping"
84
- nil
85
- rescue Errno::EISDIR, Errno::ENOENT
86
- nil
87
- end
90
+ ##
91
+ # Detects the encoding of +string+ based on the magic comment
88
92
 
89
- ##
90
- # Detects the encoding of +string+ based on the magic comment
93
+ def self.detect_encoding(string)
94
+ result = HEADER_REGEXP.match string
95
+ name = result && result[:name]
91
96
 
92
- def self.detect_encoding(string)
93
- result = HEADER_REGEXP.match string
94
- name = result && result[:name]
95
-
96
- name ? Encoding.find(name) : nil
97
- end
97
+ name ? ::Encoding.find(name) : nil
98
+ end
98
99
 
99
- ##
100
- # Removes magic comments and shebang
100
+ ##
101
+ # Removes magic comments and shebang
101
102
 
102
- def self.remove_magic_comment(string)
103
- string.sub HEADER_REGEXP do |s|
104
- s.gsub(/[^\n]/, '')
103
+ def self.remove_magic_comment(string)
104
+ string.sub HEADER_REGEXP do |s|
105
+ s.gsub(/[^\n]/, '')
106
+ end
105
107
  end
106
- end
107
108
 
108
- ##
109
- # Changes encoding based on +encoding+ without converting and returns new
110
- # string
111
-
112
- def self.change_encoding(text, encoding)
113
- if text.kind_of? RDoc::Comment
114
- text.encode! encoding
115
- else
116
- String.new text, encoding: encoding
109
+ ##
110
+ # Changes encoding based on +encoding+ without converting and returns new
111
+ # string
112
+
113
+ def self.change_encoding(text, encoding)
114
+ if text.kind_of? Comment
115
+ text.encode! encoding
116
+ else
117
+ String.new text, encoding: encoding
118
+ end
117
119
  end
118
- end
119
120
 
121
+ end
120
122
  end
@@ -1,18 +1,20 @@
1
1
  # frozen_string_literal: true
2
- ##
3
- # Allows an ERB template to be rendered in the context (binding) of an
4
- # existing ERB template evaluation.
2
+ module RDoc
3
+ ##
4
+ # Allows an ERB template to be rendered in the context (binding) of an
5
+ # existing ERB template evaluation.
5
6
 
6
- class RDoc::ERBPartial < ERB
7
+ class ERBPartial < ERB
7
8
 
8
- ##
9
- # Overrides +compiler+ startup to set the +eoutvar+ to an empty string only
10
- # if it isn't already set.
9
+ ##
10
+ # Overrides +compiler+ startup to set the +eoutvar+ to an empty string only
11
+ # if it isn't already set.
11
12
 
12
- def set_eoutvar(compiler, eoutvar = '_erbout')
13
- super
13
+ def set_eoutvar(compiler, eoutvar = '_erbout')
14
+ super
14
15
 
15
- compiler.pre_cmd = ["#{eoutvar} ||= +''"]
16
- end
16
+ compiler.pre_cmd = ["#{eoutvar} ||= +''"]
17
+ end
17
18
 
19
+ end
18
20
  end