Class: Markly::Renderer::HTML

Inherits:
Generic
  • Object
show all
Defined in:
lib/markly/renderer/html.rb

Constant Summary collapse

TABLE_CELL_ALIGNMENT =
{
	left: ' align="left"',
	right: ' align="right"',
	center: ' align="center"'
}.freeze

Instance Attribute Summary

Attributes inherited from Generic

#in_plain, #in_tight

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Generic

#block, #blocksep, #container, #containersep, #cr, #out, #plain, #reference_def, #render

Constructor Details

#initialize(ids: false, headings: nil, tight: false, **options) ⇒ HTML

Returns a new instance of HTML.



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/markly/renderer/html.rb', line 24

def initialize(ids: false, headings: nil, tight: false, **options)
	super(**options)
	
	# Initialize heading tracker if IDs are enabled
	@headings = headings || (ids ? Headings.new : nil)
	
	@section = nil
	@tight = tight
	
	@footnotes = {}
end

Class Method Details

.anchor_for(node) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/markly/renderer/html.rb', line 50

def self.anchor_for(node)
	# Convert to plaintext, strip trailing whitespace, convert to lowercase:
	text = node.to_plaintext.chomp.downcase
	
	# Replace sequences of whitespace with hyphens:
	text.gsub!(/\s+/, "-")
	
	return text
end

Instance Method Details

#anchor_for(node) ⇒ Object



60
61
62
# File 'lib/markly/renderer/html.rb', line 60

def anchor_for(node)
	self.class.anchor_for(node)
end

#blockquote(node) ⇒ Object



137
138
139
140
141
142
143
# File 'lib/markly/renderer/html.rb', line 137

def blockquote(node)
	block do
		container("<blockquote#{source_position(node)}>\n", "</blockquote>") do
			out(:children)
		end
	end
end

#code(node) ⇒ Object



219
220
221
222
223
# File 'lib/markly/renderer/html.rb', line 219

def code(node)
	out("<code>")
	out(escape_html(node.string_content))
	out("</code>")
end

#code_block(node) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/markly/renderer/html.rb', line 151

def code_block(node)
	block do
		if flag_enabled?(GITHUB_PRE_LANG)
			out("<pre#{source_position(node)}")
			out(' lang="', node.fence_info.split(/\s+/)[0], '"') if node.fence_info && !node.fence_info.empty?
			out("><code>")
		else
			out("<pre#{source_position(node)}><code")
			if node.fence_info && !node.fence_info.empty?
				out(' class="language-', node.fence_info.split(/\s+/)[0], '">')
			else
				out(">")
			end
		end
		out(escape_html(node.string_content))
		out("</code></pre>")
	end
end

#document(_) ⇒ Object



36
37
38
39
40
41
# File 'lib/markly/renderer/html.rb', line 36

def document(_)
	@section = false
	super
	out("</ol>\n</section>\n") if @written_footnote_ix
	out("</section>") if @section
end

#emph(node) ⇒ Object



188
189
190
# File 'lib/markly/renderer/html.rb', line 188

def emph(node)
	out("<em>", :children, "</em>")
end

#footnote_definition(node) ⇒ Object



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/markly/renderer/html.rb', line 287

def footnote_definition(node)
	unless @footnote_ix
		out("<section class=\"footnotes\" data-footnotes>\n<ol>\n")
		@footnote_ix = 0
	end
	
	@footnote_ix += 1
	label = node.string_content
	@footnotes[@footnote_ix] = label
	
	out("<li id=\"fn-#{label}\">\n", :children)
	out("\n") if out_footnote_backref
	out("</li>\n")
	# </ol>
	# </section>
end

#footnote_reference(node) ⇒ Object



280
281
282
283
284
285
# File 'lib/markly/renderer/html.rb', line 280

def footnote_reference(node)
	label = node.parent_footnote_def.string_content
	
	out("<sup class=\"footnote-ref\"><a href=\"#fn-#{label}\" id=\"fnref-#{label}\" data-footnote-ref>#{node.string_content}</a></sup>")
	# out(node.to_html)
end

#header(node) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/markly/renderer/html.rb', line 64

def header(node)
	block do
		if @headings
			out("</section>") if @section
			@section = true
			out("<section#{id_for(node)}>")
		end
		
		out("<h", node.header_level, "#{source_position(node)}>", :children,
				"</h", node.header_level, ">")
	end
end

#hrule(node) ⇒ Object



145
146
147
148
149
# File 'lib/markly/renderer/html.rb', line 145

def hrule(node)
	block do
		out("<hr#{source_position(node)} />")
	end
end

#html(node) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/markly/renderer/html.rb', line 170

def html(node)
	block do
		if flag_enabled?(UNSAFE)
			out(tagfilter(node.string_content))
		else
			out("<!-- raw HTML omitted -->")
		end
	end
end

#id_for(node) ⇒ Object



43
44
45
46
47
48
# File 'lib/markly/renderer/html.rb', line 43

def id_for(node)
	if @headings
		anchor = @headings.anchor_for(node)
		return " id=\"#{CGI.escape_html anchor}\""
	end
end

#image(node) ⇒ Object



206
207
208
209
210
211
212
213
# File 'lib/markly/renderer/html.rb', line 206

def image(node)
	out('<img src="', escape_href(node.url), '"')
	plain do
		out(' alt="', :children, '"')
	end
	out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
	out(" />")
end

#inline_html(node) ⇒ Object



180
181
182
183
184
185
186
# File 'lib/markly/renderer/html.rb', line 180

def inline_html(node)
	if flag_enabled?(UNSAFE)
		out(tagfilter(node.string_content))
	else
		out("<!-- raw HTML omitted -->")
	end
end

#linebreak(_node) ⇒ Object



225
226
227
# File 'lib/markly/renderer/html.rb', line 225

def linebreak(_node)
	out("<br />\n")
end


200
201
202
203
204
# File 'lib/markly/renderer/html.rb', line 200

def link(node)
	out('<a href="', node.url.nil? ? "" : escape_href(node.url), '"')
	out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
	out(">", :children, "</a>")
end

#list(node) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/markly/renderer/html.rb', line 93

def list(node)
	old_tight = @tight
	@tight = node.list_tight
	
	block do
		if node.list_type == :bullet_list
			container("<ul#{source_position(node)}>\n", "</ul>") do
				out(:children)
			end
		else
			start = if node.list_start == 1
				"<ol#{source_position(node)}>\n"
			else
				"<ol start=\"#{node.list_start}\"#{source_position(node)}>\n"
			end
			container(start, "</ol>") do
				out(:children)
			end
		end
	end
	
	@tight = old_tight
end

#list_item(node) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/markly/renderer/html.rb', line 117

def list_item(node)
	block do
		tasklist_data = tasklist(node)
		container("<li#{source_position(node)}#{tasklist_data}>#{' ' if tasklist?(node)}", "</li>") do
			out(:children)
		end
	end
end

#paragraph(node) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/markly/renderer/html.rb', line 77

def paragraph(node)
	if @tight && node.parent.type != :blockquote
		out(:children)
	else
		block do
			container("<p#{source_position(node)}>", "</p>") do
				out(:children)
				if node.parent.type == :footnote_definition && node.next.nil?
					out(" ")
					out_footnote_backref
				end
			end
		end
	end
end

#softbreak(_) ⇒ Object



229
230
231
232
233
234
235
236
237
# File 'lib/markly/renderer/html.rb', line 229

def softbreak(_)
	if flag_enabled?(HARD_BREAKS)
		out("<br />\n")
	elsif flag_enabled?(NO_BREAKS)
		out(" ")
	else
		out("\n")
	end
end

#strikethrough(_) ⇒ Object



276
277
278
# File 'lib/markly/renderer/html.rb', line 276

def strikethrough(_)
	out("<del>", :children, "</del>")
end

#strong(node) ⇒ Object



192
193
194
195
196
197
198
# File 'lib/markly/renderer/html.rb', line 192

def strong(node)
	if node.parent.nil? || node.parent.type == node.type
		out(:children)
	else
		out("<strong>", :children, "</strong>")
	end
end

#table(node) ⇒ Object



239
240
241
242
243
244
245
# File 'lib/markly/renderer/html.rb', line 239

def table(node)
	@alignments = node.table_alignments
	@needs_close_tbody = false
	out("<table#{source_position(node)}>\n", :children)
	out("</tbody>\n") if @needs_close_tbody
	out("</table>\n")
end

#table_cell(node) ⇒ Object



270
271
272
273
274
# File 'lib/markly/renderer/html.rb', line 270

def table_cell(node)
	align = TABLE_CELL_ALIGNMENT.fetch(@alignments[@column_index], "")
	out(@in_header ? "<th#{align}#{source_position(node)}>" : "<td#{align}#{source_position(node)}>", :children, @in_header ? "</th>\n" : "</td>\n")
	@column_index += 1
end

#table_header(node) ⇒ Object



247
248
249
250
251
252
253
# File 'lib/markly/renderer/html.rb', line 247

def table_header(node)
	@column_index = 0
	
	@in_header = true
	out("<thead>\n<tr#{source_position(node)}>\n", :children, "</tr>\n</thead>\n")
	@in_header = false
end

#table_row(node) ⇒ Object



255
256
257
258
259
260
261
262
# File 'lib/markly/renderer/html.rb', line 255

def table_row(node)
	@column_index = 0
	if !@in_header && !@needs_close_tbody
		@needs_close_tbody = true
		out("<tbody>\n")
	end
	out("<tr#{source_position(node)}>\n", :children, "</tr>\n")
end

#tasklist(node) ⇒ Object



126
127
128
129
130
131
132
133
134
135
# File 'lib/markly/renderer/html.rb', line 126

def tasklist(node)
	return "" unless tasklist?(node)
	
	state = if checked?(node)
		'checked="" disabled=""'
	else
		'disabled=""'
	end
	"><input type=\"checkbox\" #{state} /"
end

#text(node) ⇒ Object



215
216
217
# File 'lib/markly/renderer/html.rb', line 215

def text(node)
	out(escape_html(node.string_content))
end