Class: Slamdown::Conversion::Normaliser::InlineSemantics

Inherits:
Object
  • Object
show all
Defined in:
lib/slamdown/conversion/normaliser/inline_semantics.rb

Overview

Normalises inline semantic constructs after their descendants have been prepared, including styled-span recovery and whitespace shifting.

Constant Summary collapse

URL_SCHEME =
/\A([A-Za-z][A-Za-z0-9+.-]*):/.freeze
STYLE_ELEMENTS =
{
	:strong => ["strong", :strong],
	:emphasis => ["em", :emphasis],
	:deletion => ["del", :deletion],
	:underline => ["u", :underline]
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(policy, node_factory, content, breaks, url_rewriter, diagnostics) ⇒ InlineSemantics

Returns a new instance of InlineSemantics.



17
18
19
20
21
22
23
24
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 17

def initialize(policy, node_factory, content, breaks, url_rewriter, diagnostics)
	@policy = policy
	@node_factory = node_factory
	@content = content
	@breaks = breaks
	@url_rewriter = url_rewriter
	@diagnostics = diagnostics
end

Instance Method Details

#normalise_emphasis(node, semantic_kind, children, path) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 37

def normalise_emphasis(node, semantic_kind, children, path)
	wrap_inline_structure(children, path) do |fragment|
		fragment = @content.normalise_inline_sequence(fragment, :trim => false)
		normalised = @node_factory.semantic(node, semantic_kind, fragment, path)
		normalise_wrapper_whitespace(normalised, path)
	end
end

#normalise_generic(node, semantic_kind, children, path) ⇒ Object



101
102
103
104
105
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 101

def normalise_generic(node, semantic_kind, children, path)
	wrap_inline_structure(children, path) do |fragment|
		[@node_factory.semantic(node, semantic_kind, fragment, path)]
	end
end

#normalise_image(node, path) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 87

def normalise_image(node, path)
	attributes = Hash[node.attributes]
	source = attributes["src"]
	alt = @content.normalise_text(attributes.fetch("alt", "").to_s).strip
	attributes["alt"] = alt if attributes.key?("alt")

	unless source.is_a?(String) && !source.strip.empty?
		return alt.empty? ? [] : [@node_factory.text(@content.normalise_text(alt), path)]
	end

	attributes["src"] = @url_rewriter.rewrite(source.strip)
	[@node_factory.semantic(node, :image, [], path, :attributes => ordered_attributes(node.attributes, attributes))]
end


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 69

def normalise_link(node, children, path)
	children = @content.normalise_inline_sequence(children, :trim => false)
	return [] unless @content.visible_content?(children)

	attributes = Hash[node.attributes]
	destination = attributes["href"]
	return children unless usable_url?(destination) && !blacklisted_scheme?(destination.strip)

	children = flatten_links(children)
	attributes["href"] = @url_rewriter.rewrite(destination.strip)
	wrap_inline_structure(children, path) do |fragment|
		normalised = @node_factory.semantic(node, :link, fragment, path, :attributes => ordered_attributes(node.attributes, attributes))
		moved = move_edge_whitespace(normalised)
		@diagnostics.add(:link_whitespace_moved, :info, "Moved collapsible whitespace outside link text", path) unless moved == [normalised]
		moved
	end
end

#normalise_span(node, children, path) ⇒ Object



26
27
28
29
30
31
32
33
34
35
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 26

def normalise_span(node, children, path)
	styles = node.semantic_values[:styled_as]
	return children unless styles

	@diagnostics.add(:styled_span_recovered, :info, "Converted presentational span styling to semantic content", path)
	styles.reverse_each do |style|
		children = apply_generated_style(style, children, path)
	end
	children
end

#normalise_wrapper_whitespace(node, path) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 45

def normalise_wrapper_whitespace(node, path)
	moved = move_edge_whitespace(node)
	if moved.length != 1 || moved.first != node
		@diagnostics.add(:emphasis_whitespace_moved, :info, "Moved collapsible whitespace outside inline formatting", path)
	end
	moved
end

#trim_wrapper_whitespace(node) ⇒ Object



53
54
55
56
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 53

def trim_wrapper_whitespace(node)
	children = @content.normalise_inline_sequence(node.children, :trim => true)
	@content.visible_content?(children) ? [node.with(:children => children)] : []
end

#wrap_inline_structure(children, path) ⇒ Object

Reopens an inline wrapper around phrasing runs while allowing nested block output to bubble to its block parent.



59
60
61
62
63
64
65
66
67
# File 'lib/slamdown/conversion/normaliser/inline_semantics.rb', line 59

def wrap_inline_structure(children, path)
	@content.split_around_blocks(children).flat_map do |part|
		if part.is_a?(NormalisedNode)
			part
		else
			@breaks.wrap_inline_fragments(part, path) { |fragment| yield fragment }
		end
	end
end