.lib/ruby/data_embed.rb

changeset 1003
0cf4b33dd117
equal deleted inserted replaced
1002:8284b9cac608 1003:0cf4b33dd117
1 module DataEmbed
2 module_function
3
4 # Returns a hash of filename => content read from the DATA section of a given
5 # source, or the caller. Does not cache for you. If given a handle, it is
6 # read; a string, used as a file path to read; a module or class, its file is
7 # guessed using +const_source_location+.
8 #
9 # Note: This isn't careful with encoding. A battle-tested version of this
10 # that should be okay with encodings can be found in Sinatra.
11 #
12 # @example Read my own data section
13 # files = DataEmbed.data_section(__FILE__)
14 #
15 # @example A specific module
16 # files = DataEmbed.data_section(Some::Class)
17 #
18 # @example The DATA global (only opened for $0 unlike perl)
19 # files = DataEmbed.data_section(DATA)
20 #
21 # @param source [Module, String, #read]
22 # @return [{String => String}]
23 def data_section(source)
24 data =
25 case source
26 when Module
27 File.read(Object.const_source_location(source.name)[0])
28 when String
29 File.read(source)
30 else
31 source.read
32 end
33
34 data
35 .split(/^__END__$/, 2)
36 .last
37 .split(/^@@\s*(.+?)\s*\r?\n/m)
38 .tap { _1.shift if _1.length.odd? }
39 .each_slice(2)
40 .to_h
41 .transform_values { _1.gsub(/\n+\z/, "\n") }
42 end
43
44 # Process the given tmpl using ERB, with % trim enabled. Either a binding or
45 # a hash may be given. Only locals are available to the template if a hash
46 # is used.
47 #
48 # @param tmpl [String]
49 # @param vars [Binding, Hash]
50 # @return [String]
51 def process_template(tmpl, vars)
52 require "erb"
53
54 ERB
55 .new(tmpl, trim_mode: "%")
56 .public_send(vars.is_a?(Binding) ? :result : :result_with_hash, vars)
57 end
58
59 # Process templates in both keys and values of the given hash
60 #
61 # @param data [{String => String}]
62 # @param vars [Binding, Hash]
63 # @return [{String => String}]
64 def process_templates(data, vars)
65 data
66 .transform_keys { process_template(_1, vars) }
67 .transform_values! { process_template(_1, vars) }
68 end
69 end

mercurial