lib/deck/slide.rb in deckrb-0.1.0 vs lib/deck/slide.rb in deckrb-0.1.1

- old
+ new

@@ -1,32 +1,36 @@ # based on work by Alex and others in Showoff require 'redcarpet' +require 'deck/noko' - module Deck class Slide < Erector::Widget + include Deck::Noko + # todo: test this method def self.from_file markdown_file split File.read(markdown_file) end # given a chunk of Markdown text, splits it into an array of Slide objects def self.split content - unless content =~ /^\<?!SLIDE/m - content = content.gsub(/^# /m, "<!SLIDE>\n# ") + unless content =~ /^\<?!SLIDE/m # this only applies to files with no !SLIDEs at all, which is odd + content = content. + gsub(/^# /m, "<!SLIDE>\n# "). + gsub(/^(.*)\n(===+)/, "<!SLIDE>\n\\1\n\\2") end lines = content.split("\n") slides = [] slides << (slide = Slide.new) until lines.empty? line = lines.shift if line =~ /^<?!SLIDE(.*)>?/ slides << (slide = Slide.new(:classes => $1)) - elsif line =~ /^# / and !slide.empty? + elsif (line =~ /^# / or lines.first =~ /^(===+)/) and !slide.empty? # every H1 defines a new slide, unless there's a !SLIDE before it slides << (slide = Slide.new) slide << line else @@ -42,19 +46,19 @@ #### attr_reader :classes, :markdown_text needs :classes => nil, :markdown_text => nil, :slide_id => nil - - + + def initialize options = {} super options - + @classes = process_classes @markdown_text = "" end - + def process_classes ["slide"] + case @classes when NilClass [] when String @@ -62,11 +66,11 @@ when Array @classes else raise "can't deal with :classes => #{@classes.inspect}" end - end + end def markdown @@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, :no_intra_emphasis => true, :tables => true, @@ -77,44 +81,62 @@ :lax_html_blocks => false, :space_after_headers => true, :superscript => false ) end - + def <<(s) @markdown_text << s @markdown_text << "\n" end - + def empty? @markdown_text.strip == "" end - + def slide_id @slide_id ||= begin lines = @markdown_text.split("\n") raise "an empty slide has no id" if lines.empty? - lines.first.gsub(/^#*/, '').strip.downcase.gsub(/[^\w\s]/, '').gsub(/\s/, '_') + lines.first.downcase.gsub(/[^\w\s]/, '').strip.gsub(/\s/, '_') end end - - def header_only? - markdown_text.strip =~ /^# / and markdown_text.strip.split("\n").size == 1 - end - - def massaged_markdown_text - unless header_only? - "##{markdown_text.strip}" - else - markdown_text - end - end - + def content section :class => @classes, :id => slide_id do text "\n" # markdown HTML should be left-aligned, in case of PRE blocks and other quirks - html = markdown.render(massaged_markdown_text) + html = markdown.render(markdown_text) + html = munge(html) rawtext html - end + end end + + private + + # if there is an H1, change it to an H2, unless it's the only thing there + # TODO: or unless the slide class is whatever + def mutate_h1? doc + h1s = doc.css('h1') || [] + if h1s.size == 0 + false + else + stuff = doc.css('body>*') + if stuff.size == 1 + false + else + true + end + end + end + + def munge html + doc = noko_doc(html) + if mutate_h1? doc + doc.css('h1').each {|node| node.node_name = "h2"} + doc.css('body').inner_html + "\n" + else + html + end + end + end end