class Showoff::Compiler::Fixups
adds misc fixup methods to the compiler
Public Class Methods
updateClasses!(doc)
click to toggle source
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.
@param doc [Nokogiri::HTML::DocumentFragment]
The slide document
@return [Nokogiri::HTML::DocumentFragment]
The document with classes applied.
# 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)
click to toggle source
This munges commandline code blocks for the proper classing @see
https://github.com/puppetlabs/showoff/blob/3f43754c84f97be4284bb34f9bc7c42175d45226/lib/showoff.rb#L1107 https://github.com/puppetlabs/showoff/blob/3f43754c84f97be4284bb34f9bc7c42175d45226/lib/showoff.rb#L1135-L1163
# 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={})
click to toggle source
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. @see
https://github.com/puppetlabs/showoff/blob/220d6eef4c5942eda625dd6edc5370c7490eced7/lib/showoff.rb#L1076-L1103
# 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)
click to toggle source
Ensure that all links open in a new window. Perhaps move some of this to glossary.rb
# 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)
click to toggle source
This munges code blocks to ensure the proper syntax highlighting @see
https://github.com/puppetlabs/showoff/blob/3f43754c84f97be4284bb34f9bc7c42175d45226/lib/showoff.rb#L1105-L1133
# 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