Skip to content

Instantly share code, notes, and snippets.

@snipsnipsnip
Last active December 13, 2015 08:36
Show Gist options
  • Save snipsnipsnip/a8cf3c46fcb9e0ef8755 to your computer and use it in GitHub Desktop.
Save snipsnipsnip/a8cf3c46fcb9e0ef8755 to your computer and use it in GitHub Desktop.
継承つきネスト箇条書き
require 'yaml'
# StringForest = nil | (String, StringForest)[]
# String -> StringForest
def parse_indented_forest(str)
str = str.gsub(/^( *)([^": \n][^":\n]*)$/, '\1"\2":')
handle_includes YAML.load(str)
end
def handle_includes(tree)
case included = tree.delete("include".freeze)
when Hash
handle_includes deep_merge(included, tree)
when Array
handle_includes included.inject(tree) {|t, inc| deep_merge(inc, t) }
when nil
tree.map {|k, v| v ? [k, handle_includes(v)] : k }
else
raise ArgumentError
end
end
def deep_merge(a, b)
a or return b
b or return a
a.merge(b) {|k, v, w| deep_merge(v, w) }
end
if $0 == __FILE__
require 'pp'
pp parse_indented_forest DATA.read
end
__END__
foo: &foo
bar: &bar
baz
quu
qux
hoge
include: [*foo, *bar]
bar
moga
mogo
quu
moo
fuga
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment