Skip to content

Instantly share code, notes, and snippets.

@garybernhardt
Last active November 10, 2024 20:51
Show Gist options
  • Save garybernhardt/546022b191ed2b2636e020371b5918d6 to your computer and use it in GitHub Desktop.
Save garybernhardt/546022b191ed2b2636e020371b5918d6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'base64'
require 'nokogiri'
require 'uri'
def main
html = Nokogiri::HTML($stdin.read)
inline_all_images(html)
inline_all_css(html)
$stdout.write(html.to_s)
end
def inline_all_images(html)
html.css("img").each do |img|
img['src'] = base64_image_src(img['src'])
end
end
def inline_all_css(html)
html.css(%{link[rel="stylesheet"]}).each do |link|
unless is_remote_path?(link['href'])
inline_css_node(link)
end
end
end
def inline_css_node(link)
style_node = Nokogiri::XML::Node.new("style", link.parent)
style_node.content = File.read(path_to_local_path(link['href']))
link.add_next_sibling(style_node)
link.remove
end
def base64_image_src(path)
content_type = {
".svg" => "image/svg+xml",
".jpg" => "image/jpeg",
}.fetch(File.extname(path))
base64ed_data = Base64.encode64(File.read(path))
"data:#{content_type};base64,#{base64ed_data}"
end
def is_remote_path?(path)
uri = URI.parse(path)
uri.scheme != nil || path.start_with?("//")
end
def path_to_local_path(path)
# We treat the current working directory as the root of the "server", so any
# absolute path in the markup becomes a path relative to the current
# directory.
path.sub(/^\//, "")
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment