public
Last active — forked from josevalim/_yerb.rb

  • Download Gist
_yerb.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
# = YERB
#
# Who needs HAML when you have YAML + ERB? :)
#
# See example.yaml below for an example. You can run this code
# by cloning this gist and then `ruby _yerb.rb example.yaml`.
#
# Notice that you need Ruby 1.9 so the hash order is preserved.
# Obviously, this is just for fun. Definitely slow as hell.
#
require "erb"
require "yaml"
 
class YERB
DOCTYPES = {
:html => "<!DOCTYPE html>"
}
 
ID = /#([^\.#\(]+)/
CLASS = /\.([^\.#\(]+)/
ATTRIBUTES = /(\{.*\})/
 
def initialize(path)
@path = path
end
 
def result(*args)
yaml = evaluate(File.read(@path), *args)
to_document(YAML.load(yaml))
end
 
protected
 
def evaluate(content, *args)
ERB.new(content).result(*args)
end
 
def to_document(hash)
doctype = hash.keys.first.to_sym
 
output = ""
output << DOCTYPES[doctype].to_s
output << "\n"
output << to_tags(hash)
output
end
 
def to_tags(hash)
hash.map do |key, value|
key = key.dup
attributes = get_attributes(key)
get_id(key, attributes)
get_classes(key, attributes)
tag(key, attributes, get_contents(value))
end.join("\n")
end
 
def get_attributes(key)
attributes = nil
key.gsub!(ATTRIBUTES) do
attributes = eval($1)
nil
end
attributes || {}
end
 
def get_id(key, attributes)
key.gsub!(ID) do
attributes[:id] = $1
nil
end
end
 
def get_classes(key, attributes)
classes = []
match = key.gsub!(CLASS) do
classes << $1
nil
end
attributes[:class] = classes.join(" ") if match
end
 
def get_contents(value)
case value
when Hash
to_tags(value)
when Array
value.map { |i| get_contents(i) }.join("\n")
else
value.to_s
end
end
 
def tag(tag, attributes, content)
attributes = attributes.map { |k,v| "#{k}=#{v.to_s.inspect}" }.join(" ")
attributes = " #{attributes}" unless attributes.empty?
"<#{tag}#{attributes}>#{content}</#{tag}>"
end
end
 
puts YERB.new(ARGV.first).result if ARGV.first
example.yaml
YAML
1 2 3 4 5 6 7 8 9 10 11 12
html:
head:
title: YERB Example
body:
p#intro:
Yes, this is still valid YAML after the embedded ruby code is evaluated.
ul.cool_list:
<% 1.upto(10) do |i| %>
- li: <%= i %> item in the list
<% end %>
a{:href => "http://blog.plataformatec.com.br"}:
"Odd, isn't it?"

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.