Skip to content

Instantly share code, notes, and snippets.

@johansmitsnl
Created July 22, 2022 19:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johansmitsnl/e13df36e15c23815e258274413875b4c to your computer and use it in GitHub Desktop.
Save johansmitsnl/e13df36e15c23815e258274413875b4c to your computer and use it in GitHub Desktop.
html2sycamore
#!/bin/env ruby
# This lets you past HTML code on the terminal and convert it to Rust view! macro code.
# After pasting make a new line and press CTRL + D
# You can also use a pipe to convert: $ cat input.html | bundle exec ./convert.rb
require 'nokogiri'
puts "Past now your html code:"
html = Nokogiri::HTML.parse($stdin.read)
@nested_level = -3
SPACES = " "
output = ""
def lvl_up
@nested_level += 1
end
def lvl_down
@nested_level -= 1
end
def spaces
SPACES * @nested_level
end
def process_attributes(node)
node.attributes.map do |_,item|
"#{item.name}=\"#{item.value}\""
end
end
def process(node)
lvl_up
options = process_attributes(node)
children = node.children.map do |child_node|
process(child_node)
end.compact
result = case node.name
when 'div', 'nav', 'a', 'button', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'main', 'svg', 'path'
"\n" +
"#{spaces}#{node.name}#{options.any? ? "(#{options.join(", ")})" : ""} {" +
"#{children ? ("#{spaces}#{children.join("\n")}") : ""}" +
"\n" + "#{spaces}}"
when 'img'
"\n" + "#{spaces}#{node.name}#{options.any? ? "(#{options.join(", ")})" : ""} {}"
when 'text'
(node.text.strip != "" ? "\n#{spaces}\"#{node.text.strip}\"" : nil)
when 'comment'
"\n" + node.text.each_line.map {|line| "#{spaces}// #{line.strip}"}.join("\n")
when 'body'
children.join("")
when 'html'
children.join("")
else
raise "Unimplemented type: #{node.name}"
end
lvl_down
result
end
html.document.children.each do |node|
result = process(node)
output << result unless result.nil?
end
puts
puts "Result:"
puts
puts output
source 'https://rubygems.org'
gem 'nokogiri'
<div class="min-h-full">
<nav class="bg-gray-800">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<div class="flex items-center">
<div class="flex-shrink-0">
<img class="h-8 w-8" src="https://tailwindui.com/img/logos/workflow-mark-indigo-500.svg" alt="Workflow">
</div>
<div class="hidden md:block">
<div class="ml-10 flex items-baseline space-x-4">
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
<a href="#" class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium" aria-current="page">Dashboard</a>
</div>
</div>
</div>
</div>
</div>
</nav>
</div>
div(class="min-h-full") {
nav(class="bg-gray-800") {
div(class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8") {
div(class="flex items-center justify-between h-16") {
div(class="flex items-center") {
div(class="flex-shrink-0") {
img(class="h-8 w-8", src="https://tailwindui.com/img/logos/workflow-mark-indigo-500.svg", alt="Workflow") {}
}
div(class="hidden md:block") {
div(class="ml-10 flex items-baseline space-x-4") {
// Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white"
a(href="#", class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium", aria-current="page") {
"Dashboard"
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment