Class: Showoff::Compiler::Fixups

Inherits:
Object
  • Object
show all
Defined in:
lib/showoff/compiler/fixups.rb

Overview

adds misc fixup methods to the compiler

Class Method Summary collapse

Class Method Details

.updateClasses!(doc) ⇒ Nokogiri::HTML::DocumentFragment

Find any <p> or <img> tags with classes defined via the prefixed dot syntax. Remove .break and .comment paragraphs and apply classes/alt to the rest.

Parameters:

  • doc (Nokogiri::HTML::DocumentFragment)

    The slide document

Returns:

  • (Nokogiri::HTML::DocumentFragment)

    The document with classes applied.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/showoff/compiler/fixups.rb', line 13

def self.updateClasses!(doc)
  doc.search('p').select {|p| p.text.start_with? '.'}.each do |p|
    # The first string of plain text in the paragraph
    node = p.children.first
    classes, sep, text = node.content.partition(' ')
    classes = classes.split('.')
    classes.shift

    if ['break', 'comment'].include? classes.first
      p.remove
    else
      p.add_class(classes.join(' '))
      node.content = text
    end
  end

  doc.search('img').select {|img| img.attr('alt').start_with? '.'}.each do |img|
    classes, sep, text = img.attr('alt').partition(' ')
    classes = classes.split('.')
    classes.shift

    img.add_class(classes.join(' '))
    img.set_attribute('alt', text)
  end

  doc
end

.updateCommandlineBlocks!(doc) ⇒ Object

This munges commandline code blocks for the proper classing



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/showoff/compiler/fixups.rb', line 91

def self.updateCommandlineBlocks!(doc)
  parser = CommandlineParser.new
  doc.search('.commandline > pre > code').each do |code|
    out = code.text
    code.content = ''
    tree = parser.parse(out)
    transform = Parslet::Transform.new do
      rule(:prompt => simple(:prompt), :input => simple(:input), :output => simple(:output)) do
        command = Nokogiri::XML::Node.new('code', doc)
        command.set_attribute('class', 'command')
        command.content = "#{prompt} #{input}"
        code << command

        # Add newline after the input so that users can
        # advance faster than the typewriter effect
        # and still keep inputs on separate lines.
        code << "\n"

        unless output.to_s.empty?

          result = Nokogiri::XML::Node.new('code', doc)
          result.set_attribute('class', 'result')
          result.content = output
          code << result
        end
      end
    end
    transform.apply(tree)
  end

  doc
end

.updateImagePaths!(doc, options = {}) ⇒ Object

Because source slide files can be nested in arbitrarily deep directories we need to simplify paths to images when we flatten it out to a single HTML file.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/showoff/compiler/fixups.rb', line 128

def self.updateImagePaths!(doc, options={})
  doc.search('img').each do |img|
    slide_dir = File.dirname(options[:name])

    # We need to turn all URLs into relative from the root. If it starts with '/'
    # then we can assume the author meant to start the path at the presentation root.
    if img[:src].start_with? '/'
      img[:src] = img[:src][1..-1]
    else
      # clean up the path and remove some of the relative nonsense
      img[:src] = Pathname.new(File.join(slide_dir, img[:src])).cleanpath.to_path
    end
  end
end

.updateLinks!(doc) ⇒ Object

Ensure that all links open in a new window. Perhaps move some of this to glossary.rb



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/showoff/compiler/fixups.rb', line 42

def self.updateLinks!(doc)
  doc.search('a').each do |link|
    next unless link['href']
    next if link['href'].start_with? '#'
    next if link['href'].start_with? 'glossary://'
    # Add a target so we open all external links from notes in a new window
    link.set_attribute('target', '_blank')
  end

  doc
end

.updateSyntaxHighlighting!(doc) ⇒ Object

This munges code blocks to ensure the proper syntax highlighting



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/showoff/compiler/fixups.rb', line 57

def self.updateSyntaxHighlighting!(doc)
  doc.search('pre').each do |pre|
    pre.search('code').each do |code|
      out  = code.text
      lang = code.get_attribute('class')

      # Skip this if we've got an empty code block
      next if out.empty?

      # catch fenced code blocks from commonmarker
      if (lang and lang.start_with? 'language-' )
        pre.set_attribute('class', 'highlight')
        # turn the colon separated name back into classes
        code.set_attribute('class', lang.gsub(':', ' '))

      # or we've started a code block with a Showoff language tag
      elsif out.strip[0, 3] == '@@@'
        lines = out.split("\n")
        lang  = lines.shift.gsub('@@@', '').strip
        pre.set_attribute('class', 'highlight')
        code.set_attribute('class', 'language-' + lang.downcase) if !lang.empty?
        code.content = lines.join("\n")
      end

    end
  end

  doc
end