| Class | SM::ToHtml |
| In: |
markup/simple_markup/to_html.rb
|
| Parent: | Object |
| LIST_TYPE_TO_HTML | = | { ListBase::BULLET => [ "<ul>", "</ul>" ], ListBase::NUMBER => [ "<ol>", "</ol>" ], ListBase::UPPERALPHA => [ "<ol>", "</ol>" ], ListBase::LOWERALPHA => [ "<ol>", "</ol>" ], ListBase::LABELED => [ "<dl>", "</dl>" ], ListBase::NOTE => [ "<table>", "</table>" ], } |
| InlineTag | = | Struct.new(:bit, :on, :off) |
# File markup/simple_markup/to_html.rb, line 105
105: def accept_blank_line(am, fragment)
106: # @res << annotate("<p />") << "\n"
107: end
# File markup/simple_markup/to_html.rb, line 109
109: def accept_heading(am, fragment)
110: @res << convert_heading(fragment.head_level, am.flow(fragment.txt))
111: end
# File markup/simple_markup/to_html.rb, line 89
89: def accept_list_end(am, fragment)
90: if tag = @in_list_entry.pop
91: @res << annotate(tag) << "\n"
92: end
93: @res << html_list_name(fragment.type, false) <<"\n"
94: end
# File markup/simple_markup/to_html.rb, line 96
96: def accept_list_item(am, fragment)
97: if tag = @in_list_entry.last
98: @res << annotate(tag) << "\n"
99: end
100: @res << list_item_start(am, fragment)
101: @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n"
102: @in_list_entry[-1] = list_end_for(fragment.type)
103: end
# File markup/simple_markup/to_html.rb, line 84
84: def accept_list_start(am, fragment)
85: @res << html_list_name(fragment.type, true) <<"\n"
86: @in_list_entry.push false
87: end
# File markup/simple_markup/to_html.rb, line 66
66: def accept_paragraph(am, fragment)
67: @res << annotate("<p>") + "\n"
68: @res << wrap(convert_flow(am.flow(fragment.txt)))
69: @res << annotate("</p>") + "\n"
70: end
# File markup/simple_markup/to_html.rb, line 78
78: def accept_rule(am, fragment)
79: size = fragment.param
80: size = 10 if size > 10
81: @res << "<hr size=\"#{size}\"></hr>"
82: end
# File markup/simple_markup/to_html.rb, line 72
72: def accept_verbatim(am, fragment)
73: @res << annotate("<pre>") + "\n"
74: @res << CGI.escapeHTML(fragment.txt)
75: @res << annotate("</pre>") << "\n"
76: end
Given an HTML tag, decorate it with class information and the like if required. This is a no-op in the base class, but is overridden in HTML output classes that implement style sheets
# File markup/simple_markup/to_html.rb, line 50
50: def annotate(tag)
51: tag
52: end
# File markup/simple_markup/to_html.rb, line 170
170: def convert_flow(flow)
171: res = ""
172: flow.each do |item|
173: case item
174: when String
175: res << convert_string(item)
176: when AttrChanger
177: off_tags(res, item)
178: on_tags(res, item)
179: when Special
180: res << convert_special(item)
181: else
182: raise "Unknown flow element: #{item.inspect}"
183: end
184: end
185: res
186: end
# File markup/simple_markup/to_html.rb, line 234
234: def convert_heading(level, flow)
235: res =
236: annotate("<h#{level}>") +
237: convert_flow(flow) +
238: annotate("</h#{level}>\n")
239: end
# File markup/simple_markup/to_html.rb, line 221
221: def convert_special(special)
222: handled = false
223: Attribute.each_name_of(special.type) do |name|
224: method_name = "handle_special_#{name}"
225: if self.respond_to? method_name
226: special.text = send(method_name, special)
227: handled = true
228: end
229: end
230: raise "Unhandled special: #{special}" unless handled
231: special.text
232: end
some of these patterns are taken from SmartyPants...
# File markup/simple_markup/to_html.rb, line 190
190: def convert_string(item)
191: CGI.escapeHTML(item).
192:
193:
194: # convert -- to em-dash, (-- to en-dash)
195: gsub(/---?/, '—'). #gsub(/--/, '–').
196:
197: # convert ... to elipsis (and make sure .... becomes .<elipsis>)
198: gsub(/\.\.\.\./, '.…').gsub(/\.\.\./, '…').
199:
200: # convert single closing quote
201: gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1’" }.
202: gsub(%r{\'(?=\W|s\b)}) { "’" }.
203:
204: # convert single opening quote
205: gsub(/'/, '‘').
206:
207: # convert double closing quote
208: gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1”" }.
209:
210: # convert double opening quote
211: gsub(/'/, '“').
212:
213: # convert copyright
214: gsub(/\(c\)/, '©').
215:
216: # convert and registered trademark
217: gsub(/\(r\)/, '®')
218:
219: end
# File markup/simple_markup/to_html.rb, line 241
241: def html_list_name(list_type, is_open_tag)
242: tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}")
243: annotate(tags[ is_open_tag ? 0 : 1])
244: end
Set up the standard mapping of attributes to HTML tags
# File markup/simple_markup/to_html.rb, line 28
28: def init_tags
29: @attr_tags = [
30: InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "<b>", "</b>"),
31: InlineTag.new(SM::Attribute.bitmap_for(:TT), "<tt>", "</tt>"),
32: InlineTag.new(SM::Attribute.bitmap_for(:EM), "<em>", "</em>"),
33: ]
34: end
# File markup/simple_markup/to_html.rb, line 274
274: def list_end_for(fragment_type)
275: case fragment_type
276: when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA
277: "</li>"
278: when ListBase::LABELED
279: "</dd>"
280: when ListBase::NOTE
281: "</td></tr>"
282: else
283: raise "Invalid list type"
284: end
285: end
# File markup/simple_markup/to_html.rb, line 246
246: def list_item_start(am, fragment)
247: case fragment.type
248: when ListBase::BULLET, ListBase::NUMBER
249: annotate("<li>")
250:
251: when ListBase::UPPERALPHA
252: annotate("<li type=\"A\">")
253:
254: when ListBase::LOWERALPHA
255: annotate("<li type=\"a\">")
256:
257: when ListBase::LABELED
258: annotate("<dt>") +
259: convert_flow(am.flow(fragment.param)) +
260: annotate("</dt>") +
261: annotate("<dd>")
262:
263: when ListBase::NOTE
264: annotate("<tr>") +
265: annotate("<td valign=\"top\">") +
266: convert_flow(am.flow(fragment.param)) +
267: annotate("</td>") +
268: annotate("<td>")
269: else
270: raise "Invalid list type"
271: end
272: end
# File markup/simple_markup/to_html.rb, line 159
159: def off_tags(res, item)
160: attr_mask = item.turn_off
161: return if attr_mask.zero?
162:
163: @attr_tags.reverse_each do |tag|
164: if attr_mask & tag.bit != 0
165: res << annotate(tag.off)
166: end
167: end
168: end
# File markup/simple_markup/to_html.rb, line 148
148: def on_tags(res, item)
149: attr_mask = item.turn_on
150: return if attr_mask.zero?
151:
152: @attr_tags.each do |tag|
153: if attr_mask & tag.bit != 0
154: res << annotate(tag.on)
155: end
156: end
157: end
Here‘s the client side of the visitor pattern
# File markup/simple_markup/to_html.rb, line 57
57: def start_accepting
58: @res = ""
59: @in_list_entry = []
60: end
This is a higher speed (if messier) version of wrap
# File markup/simple_markup/to_html.rb, line 115
115: def wrap(txt, line_len = 76)
116: res = ""
117: sp = 0
118: ep = txt.length
119: while sp < ep
120: # scan back for a space
121: p = sp + line_len - 1
122: if p >= ep
123: p = ep
124: else
125: while p > sp and txt[p] != ?\s
126: p -= 1
127: end
128: if p <= sp
129: p = sp + line_len
130: while p < ep and txt[p] != ?\s
131: p += 1
132: end
133: end
134: end
135: res << txt[sp...p] << "\n"
136: sp = p
137: sp += 1 while sp < ep and txt[sp] == ?\s
138: end
139: res
140: end