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
-
.load(path) ⇒ Object
Parse the file and return a Presently::Slide.
-
.parse_sections(nodes) ⇒ Object
Parse a list of AST nodes into sections based on top-level Markdown headings.
-
.render_nodes(nodes) ⇒ Object
Render a list of AST nodes to HTML via a temporary document.
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 |