Module: Presently::Slide::Parser

Defined in:
lib/presently/slide.rb

Overview

Parses a Markdown slide file into structured data for Presently::Slide.

Handles YAML front_matter extraction, presenter note separation, and Markdown-to-HTML rendering using the Markly AST.

Constant Summary collapse

EXTENSIONS =

Markly extensions enabled for all slide Markdown rendering.

[:table, :tasklist, :strikethrough, :autolink]

Class Method Summary collapse

Class Method Details

.load(path) ⇒ Object

Parse the file and return a Presently::Slide.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/presently/slide.rb', line 30

def load(path)
	raw = File.read(path)
	
	# Parse once, with native front matter support.
	document = Markly.parse(raw, flags: Markly::UNSAFE | Markly::FRONT_MATTER, extensions: EXTENSIONS)
	
	# Extract front matter from the first AST node if present.
	front_matter = nil
	if (front_matter_node = document.first_child) && front_matter_node.type == :front_matter
		front_matter = YAML.safe_load(front_matter_node.string_content)
		front_matter_node.delete
	end
	
	# Find the last hrule, which acts as the separator between slide content and presenter notes.
	last_hrule = nil
	document.each{|node| last_hrule = node if node.type == :hrule}
	
	if last_hrule
		notes_fragment = Markly::Node.new(:document)
		while child = last_hrule.next
			notes_fragment.append_child(child)
		end
		last_hrule.delete
		
		content = parse_sections(document.each)
		notes = render_nodes(notes_fragment.each)
	else
		content = parse_sections(document.each)
		notes = nil
	end
	
	Slide.new(path, front_matter: front_matter, content: content, notes: notes)
end

.parse_sections(nodes) ⇒ Object

Parse a list of AST nodes into sections based on top-level Markdown headings. Each heading becomes a named key; content before the first heading is collected under ‘“body”`. Headings inside code blocks are invisible to this method as they never appear as top-level AST nodes.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/presently/slide.rb', line 70

def parse_sections(nodes)
	sections = {}
	current_key = "body"
	current_nodes = []
	
	nodes.each do |node|
		if node.type == :header
			sections[current_key] = render_nodes(current_nodes) unless current_nodes.empty?
			current_key = node.to_plaintext.strip.downcase.gsub(/\s+/, "_")
			current_nodes = []
		else
			current_nodes << node
		end
	end
	
	sections[current_key] = render_nodes(current_nodes) unless current_nodes.empty?
	
	sections
end

.render_nodes(nodes) ⇒ Object

Render a list of AST nodes to HTML via a temporary document.



93
94
95
96
97
# File 'lib/presently/slide.rb', line 93

def render_nodes(nodes)
	doc = Markly::Node.new(:document)
	nodes.each{|node| doc.append_child(node.dup)}
	Renderer.new(flags: Markly::UNSAFE, extensions: EXTENSIONS).render(doc)
end