Class: Rubyoshka::Renderer
Overview
A Renderer is a rendering of a Rubyoshka
Direct Known Subclasses
Constant Summary collapse
- S_TAG_METHOD_LINE =
__LINE__ + 1
- S_TAG_METHOD =
<<~EOF S_TAG_%<TAG>s_PRE = '<%<tag>s' S_TAG_%<TAG>s_CLOSE = '</%<tag>s>' def %<tag>s(text = nil, **props, &block) @buffer << S_TAG_%<TAG>s_PRE emit_props(props) unless props.empty? if block @buffer << S_GT instance_eval(&block) @buffer << S_TAG_%<TAG>s_CLOSE elsif Rubyoshka === text @buffer << S_GT emit(text) @buffer << S_TAG_%<TAG>s_CLOSE elsif text @buffer << S_GT << escape_text(text.to_s) << S_TAG_%<TAG>s_CLOSE else @buffer << S_SLASH_GT end end EOF
- R_CONST_SYM =
/^[A-Z]/
- S_LT =
'<'
- S_GT =
'>'
- S_LT_SLASH =
'</'
- S_SPACE_LT_SLASH =
' </'
- S_SLASH_GT =
'/>'
- S_SPACE =
' '
- S_EQUAL_QUOTE =
'="'
- S_QUOTE =
'"'
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
Instance Method Summary collapse
-
#cache(*vary, **opts, &block) ⇒ void
Caches the given block with the given arguments as cache key.
-
#emit(o) ⇒ void
(also: #e)
Emits the given object into the rendering buffer.
-
#emit_props(props) ⇒ void
Emits tag attributes into the rendering buffer.
- #emit_yield ⇒ Object
- #escape_text(text) ⇒ Object
- #escape_uri(uri) ⇒ Object
-
#initialize(context, template) ⇒ void
constructor
Initializes attributes and renders the given block.
-
#method_missing(sym, *args, **opts, &block) ⇒ void
Catches undefined tag method call and handles them by defining the method.
-
#text(data) ⇒ Object
Emits text into the rendering buffer.
-
#to_s ⇒ String
Returns the result of the rendering.
-
#with(**ctx, &block) ⇒ void
Sets a local context for the given block.
Constructor Details
#initialize(context, template) ⇒ void
Initializes attributes and renders the given block
14 15 16 17 18 |
# File 'lib/rubyoshka/renderer.rb', line 14 def initialize(context, template) @context = context @buffer = +'' instance_eval(&template) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, **opts, &block) ⇒ void
This method returns an undefined value.
Catches undefined tag method call and handles them by defining the method
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 |
# File 'lib/rubyoshka/renderer.rb', line 66 def method_missing(sym, *args, **opts, &block) value = @local && @local[sym] return value if value if sym =~ R_CONST_SYM # Component reference (capitalized method name) o = instance_eval(sym.to_s) rescue Rubyoshka.const_get(sym) \ rescue Object.const_get(sym) case o when ::Proc self.class.define_method(sym) { |*a, **c, &b| emit(o.(*a, **c, &b)) } emit(o.(*args, **opts, &block)) when Rubyoshka self.class.define_method(sym) do |**ctx| ctx.empty? ? emit(o) : with(**ctx) { emit(o) } end Hash === opts.empty? ? emit(o) : with(**opts) { emit(o) } when ::String @buffer << o else e = StandardError.new "Cannot render #{o.inspect}" e.set_backtrace(caller) raise e end else tag = sym.to_s code = S_TAG_METHOD % { tag: tag, TAG: tag.upcase } self.class.class_eval(code, __FILE__, S_TAG_METHOD_LINE) send(sym, *args, **opts, &block) end end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
8 9 10 |
# File 'lib/rubyoshka/renderer.rb', line 8 def context @context end |
Instance Method Details
#cache(*vary, **opts, &block) ⇒ void
This method returns an undefined value.
Caches the given block with the given arguments as cache key
176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/rubyoshka/renderer.rb', line 176 def cache(*vary, **opts, &block) key = [block.source_location.hash, vary.hash, opts.hash] if (cached = Rubyoshka.cache[key]) @buffer << cached return end cache_pos = @buffer.length instance_eval(&block) diff = @buffer[cache_pos..-1] Rubyoshka.cache[key] = diff end |
#emit(o) ⇒ void Also known as: e
This method returns an undefined value.
Emits the given object into the rendering buffer
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rubyoshka/renderer.rb', line 101 def emit(o) case o when ::Proc instance_eval(&o) when Rubyoshka instance_eval(&o.template) when Module # If module is given, the component is expected to be a const inside the module emit(o::Component) when nil else @buffer << o.to_s end end |
#emit_props(props) ⇒ void
This method returns an undefined value.
Emits tag attributes into the rendering buffer
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/rubyoshka/renderer.rb', line 136 def emit_props(props) props.each { |k, v| case k when :src, :href @buffer << S_SPACE << k.to_s << S_EQUAL_QUOTE << EscapeUtils.escape_uri(v) << S_QUOTE else case v when true @buffer << S_SPACE << k.to_s when false, nil # emit nothing else @buffer << S_SPACE << k.to_s << S_EQUAL_QUOTE << v << S_QUOTE end end } end |
#emit_yield ⇒ Object
117 118 119 120 121 122 |
# File 'lib/rubyoshka/renderer.rb', line 117 def emit_yield block = @context[:__block__] raise LocalJumpError, "no block given (emit_yield)" unless block instance_eval(&block) end |
#escape_text(text) ⇒ Object
26 27 28 |
# File 'lib/rubyoshka/renderer.rb', line 26 def escape_text(text) raise NotImplementedError end |
#escape_uri(uri) ⇒ Object
30 31 32 |
# File 'lib/rubyoshka/renderer.rb', line 30 def escape_uri(uri) EscapeUtils.escape_uri(v) end |
#text(data) ⇒ Object
Emits text into the rendering buffer
157 158 159 |
# File 'lib/rubyoshka/renderer.rb', line 157 def text(data) @buffer << escape_text(data) end |
#to_s ⇒ String
Returns the result of the rendering
22 23 24 |
# File 'lib/rubyoshka/renderer.rb', line 22 def to_s @buffer end |
#with(**ctx, &block) ⇒ void
This method returns an undefined value.
Sets a local context for the given block
165 166 167 168 169 170 |
# File 'lib/rubyoshka/renderer.rb', line 165 def with(**ctx, &block) old_local, @local = @local, ctx instance_eval(&block) ensure @local = old_local end |