Skip to content

Commit 74a3c27

Browse files
committed
remove monkey patching, wrap, reduce complexity
1 parent 927cc5b commit 74a3c27

File tree

3 files changed

+32
-141
lines changed

3 files changed

+32
-141
lines changed

lib/coderay/encoders/html.rb

+6-4
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,11 @@ def finish options
198198
@last_opened = nil
199199
end
200200

201-
@out.extend Output
202-
@out.css = @css
203201
if options[:line_numbers]
204202
Numbering.number! @out, options[:line_numbers], options
205203
end
206-
@out.wrap! options[:wrap]
207-
@out.apply_title! options[:title]
204+
@out = Output.wrap_string_in @out, options[:wrap], @css if options[:wrap]
205+
@out = @out.sub(/(<title>)(<\/title>)/) { $1 + options[:title] + $2 } if options[:title]
208206

209207
if defined?(@real_out) && @real_out
210208
@real_out << @out
@@ -272,6 +270,10 @@ def check_options! options
272270
raise ArgumentError, 'Unknown value %p for :css.' % [options[:css]]
273271
end
274272

273+
unless [nil, false, :span, :div, :page].include? options[:wrap]
274+
raise ArgumentError, 'Unknown value %p for :wrap.' % [options[:wrap]]
275+
end
276+
275277
options[:break_lines] = true if options[:line_numbers] == :inline
276278
end
277279

lib/coderay/encoders/html/numbering.rb

+11-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
module CodeRay
22
module Encoders
3-
43
class HTML
5-
64
module Numbering # :nodoc:
7-
85
def self.number! output, mode = :table, options = {}
96
return self unless mode
107

118
options = DEFAULT_OPTIONS.merge options
129

1310
start = options[:line_number_start]
1411
unless start.is_a? Integer
15-
raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
12+
raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % [start]
1613
end
1714

1815
anchor_prefix = options[:line_number_anchors]
@@ -53,7 +50,7 @@ def self.number! output, mode = :table, options = {}
5350
end
5451
end
5552
else
56-
raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
53+
raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % [bold_every]
5754
end
5855

5956
if position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n)
@@ -83,26 +80,25 @@ def self.number! output, mode = :table, options = {}
8380
when :table
8481
line_numbers = (start ... start + line_count).map(&bolding).join("\n")
8582
line_numbers << "\n"
86-
line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)
83+
line_numbers_table_template = TABLE.sub('<%LINE_NUMBERS%>', line_numbers)
8784

8885
output.gsub!(/<\/div>\n/, '</div>')
89-
output.wrap_in! line_numbers_table_template
90-
output.wrapped_in = :div
91-
92-
when :list
93-
raise NotImplementedError, 'The :list option is no longer available. Use :table.'
86+
output.replace line_numbers_table_template.sub('<%CONTENT%>', output)
9487

9588
else
96-
raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
97-
[mode, [:table, :inline]]
89+
raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % [mode, [:table, :inline]]
9890
end
9991

10092
output
10193
end
10294

95+
TABLE = <<-TABLE
96+
<table class="CodeRay"><tr>
97+
<td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td>
98+
<td class="code"><pre><%CONTENT%></pre></td>
99+
</tr></table>
100+
TABLE
103101
end
104-
105102
end
106-
107103
end
108104
end

lib/coderay/encoders/html/output.rb

+15-122
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,31 @@
11
module CodeRay
22
module Encoders
3-
43
class HTML
5-
6-
# This module is included in the output String of the HTML Encoder.
7-
#
8-
# It provides methods like wrap, div, page etc.
9-
#
10-
# Remember to use #clone instead of #dup to keep the modules the object was
11-
# extended with.
12-
#
13-
# TODO: Rewrite this without monkey patching.
144
module Output
15-
16-
attr_accessor :css
17-
18-
class << self
19-
20-
# Raises an exception if an object that doesn't respond to to_str is extended by Output,
21-
# to prevent users from misuse. Use Module#remove_method to disable.
22-
def extended o # :nodoc:
23-
warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
24-
end
25-
26-
def make_stylesheet css, in_tag = false # :nodoc:
27-
sheet = css.stylesheet
28-
sheet = <<-'CSS' if in_tag
29-
<style type="text/css">
30-
#{sheet}
31-
</style>
32-
CSS
33-
sheet
34-
end
35-
36-
def page_template_for_css css # :nodoc:
37-
sheet = make_stylesheet css
38-
PAGE.apply 'CSS', sheet
39-
end
40-
41-
end
42-
43-
def wrapped_in? element
44-
wrapped_in == element
45-
end
46-
47-
def wrapped_in
48-
@wrapped_in ||= nil
49-
end
50-
attr_writer :wrapped_in
51-
52-
def wrap_in! template
53-
Template.wrap! self, template, 'CONTENT'
54-
self
55-
end
56-
57-
def apply_title! title
58-
self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 }
59-
self
60-
end
61-
62-
def wrap! element, *args
63-
return self if not element or element == wrapped_in
5+
def self.wrap_string_in string, element, css = nil
646
case element
65-
when :div
66-
raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
67-
wrap_in! DIV
687
when :span
69-
raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
70-
wrap_in! SPAN
8+
SPAN
9+
when :div
10+
return string if string[/\A<(?:div|table)\b/]
11+
DIV
7112
when :page
72-
wrap! :div if wrapped_in? nil
73-
raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
74-
wrap_in! Output.page_template_for_css(@css)
75-
if args.first.is_a?(Hash) && title = args.first[:title]
76-
apply_title! title
77-
end
78-
self
79-
when nil
80-
return self
13+
string = wrap_string_in(string, :div) unless string[/\A<(?:div|table)\b/]
14+
PAGE.sub('<%CSS%>', css ? css.stylesheet : '')
8115
else
82-
raise "Unknown value %p for :wrap" % element
83-
end
84-
@wrapped_in = element
85-
self
86-
end
87-
88-
def stylesheet in_tag = false
89-
Output.make_stylesheet @css, in_tag
90-
end
91-
92-
#-- don't include the templates in docu
93-
94-
class Template < String # :nodoc:
95-
96-
def self.wrap! str, template, target
97-
target = Regexp.new(Regexp.escape("<%#{target}%>"))
98-
if template =~ target
99-
str[0,0] = $`
100-
str << $'
101-
else
102-
raise "Template target <%%%p%%> not found" % target
103-
end
104-
end
105-
106-
def apply target, replacement
107-
target = Regexp.new(Regexp.escape("<%#{target}%>"))
108-
if self =~ target
109-
Template.new($` + replacement + $')
110-
else
111-
raise "Template target <%%%p%%> not found" % target
112-
end
113-
end
114-
16+
raise ArgumentError, 'Unknown wrap element: %p' % [element]
17+
end.sub('<%CONTENT%>', string)
11518
end
116-
117-
SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>'
118-
119-
DIV = Template.new <<-DIV
19+
20+
SPAN = '<span class="CodeRay"><%CONTENT%></span>'
21+
22+
DIV = <<-DIV
12023
<div class="CodeRay">
12124
<div class="code"><pre><%CONTENT%></pre></div>
12225
</div>
12326
DIV
124-
125-
TABLE = Template.new <<-TABLE
126-
<table class="CodeRay"><tr>
127-
<td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td>
128-
<td class="code"><pre><%CONTENT%></pre></td>
129-
</tr></table>
130-
TABLE
131-
132-
PAGE = Template.new <<-PAGE
27+
28+
PAGE = <<-PAGE
13329
<!DOCTYPE html>
13430
<html>
13531
<head>
@@ -157,10 +53,7 @@ def apply target, replacement
15753
</body>
15854
</html>
15955
PAGE
160-
16156
end
162-
16357
end
164-
16558
end
16659
end

0 commit comments

Comments
 (0)