Class: RubyUIConverter::Transformer
- Inherits:
-
Object
- Object
- RubyUIConverter::Transformer
- Defined in:
- lib/ruby_ui_converter/transformer.rb
Overview
Walks the AST and writes Phlex/RubyUI Ruby source into a CodeBuilder.
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#template ⇒ Object
readonly
Returns the value of attribute template.
Instance Method Summary collapse
- #base_namespace ⇒ Object
-
#component_block(name, children, builder) ⇒ Object
Emits a component that wraps the given children with no attributes: ‘Name { inline }` for a single inlineable child, else a do/end block.
-
#current_form ⇒ Object
The form scope (model:, param:) currently being emitted, if any.
- #current_namespace_parts ⇒ Object
-
#emit(document, builder) ⇒ Object
Entry point: emits the body of the view_template method.
-
#emit_children(nodes, builder) ⇒ Object
— public helpers (also used by ComponentMap emitters) —————.
-
#initialize(config:, template: nil) ⇒ Transformer
constructor
A new instance of Transformer.
-
#kit_component(name, element, builder, except: [], void: false, extra: nil) ⇒ Object
Emits a Phlex::Kit-style component call (‘Link(href: x) { “Home” }`).
- #meaningful(nodes) ⇒ Object
- #render_attrs(attributes, except: []) ⇒ Object
-
#wrap_component(const, element, builder) ⇒ Object
Convenience for component emitters: render a component wrapping children.
Constructor Details
#initialize(config:, template: nil) ⇒ Transformer
Returns a new instance of Transformer.
10 11 12 13 14 |
# File 'lib/ruby_ui_converter/transformer.rb', line 10 def initialize(config:, template: nil) @config = config @template = template @form_stack = [] end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
8 9 10 |
# File 'lib/ruby_ui_converter/transformer.rb', line 8 def config @config end |
#template ⇒ Object (readonly)
Returns the value of attribute template.
8 9 10 |
# File 'lib/ruby_ui_converter/transformer.rb', line 8 def template @template end |
Instance Method Details
#base_namespace ⇒ Object
46 47 48 |
# File 'lib/ruby_ui_converter/transformer.rb', line 46 def base_namespace config.base_namespace end |
#component_block(name, children, builder) ⇒ Object
Emits a component that wraps the given children with no attributes: ‘Name { inline }` for a single inlineable child, else a do/end block. Handy for ComponentMap emitters that nest content components (e.g. `AlertDescription { notice }`).
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/ruby_ui_converter/transformer.rb', line 98 def component_block(name, children, builder) kids = meaningful(children) if kids.empty? builder.line(name) elsif kids.length == 1 && inlineable?(kids.first) builder.line("#{name} { #{inline_value(kids.first)} }") else builder.line("#{name} do") builder.indent emit_children(kids, builder) builder.dedent builder.line("end") end end |
#current_form ⇒ Object
The form scope (model:, param:) currently being emitted, if any. Set while inside a mapped form_with/form_for block; used by FormBuilder.
18 19 20 |
# File 'lib/ruby_ui_converter/transformer.rb', line 18 def current_form @form_stack.last end |
#current_namespace_parts ⇒ Object
50 51 52 |
# File 'lib/ruby_ui_converter/transformer.rb', line 50 def current_namespace_parts template ? template.namespace_parts : [] end |
#emit(document, builder) ⇒ Object
Entry point: emits the body of the view_template method.
23 24 25 |
# File 'lib/ruby_ui_converter/transformer.rb', line 23 def emit(document, builder) emit_children(meaningful(document.children), builder) end |
#emit_children(nodes, builder) ⇒ Object
— public helpers (also used by ComponentMap emitters) —————
29 30 31 |
# File 'lib/ruby_ui_converter/transformer.rb', line 29 def emit_children(nodes, builder) nodes.each { |node| emit_node(node, builder) } end |
#kit_component(name, element, builder, except: [], void: false, extra: nil) ⇒ Object
Emits a Phlex::Kit-style component call (‘Link(href: x) { “Home” }`). Parens are always kept — a bare capitalized name would be a constant. `void: true` components (Input, Checkbox…) never take a block. `extra:` prepends literal arguments (e.g. “variant: :destructive”).
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/ruby_ui_converter/transformer.rb', line 75 def kit_component(name, element, builder, except: [], void: false, extra: nil) attrs = [extra, render_attrs(element.attributes, except: except)] .compact.reject(&:empty?).join(", ") call = "#{name}(#{attrs})" kids = void ? [] : meaningful(element.children) if kids.empty? builder.line(call) elsif kids.length == 1 && inlineable?(kids.first) builder.line("#{call} { #{inline_value(kids.first)} }") else builder.line("#{call} do") builder.indent emit_children(kids, builder) builder.dedent builder.line("end") end end |
#meaningful(nodes) ⇒ Object
33 34 35 36 37 38 |
# File 'lib/ruby_ui_converter/transformer.rb', line 33 def meaningful(nodes) nodes.reject do |node| (node.is_a?(Nodes::Text) && node.content.strip.empty?) || (node.is_a?(Nodes::RawText) && node.content.strip.empty?) end end |
#render_attrs(attributes, except: []) ⇒ Object
40 41 42 43 44 |
# File 'lib/ruby_ui_converter/transformer.rb', line 40 def render_attrs(attributes, except: []) attributes.reject { |name, _| except.include?(name) } .map { |name, parts| attr_pair(name, parts) } .join(", ") end |
#wrap_component(const, element, builder) ⇒ Object
Convenience for component emitters: render a component wrapping children.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/ruby_ui_converter/transformer.rb', line 55 def wrap_component(const, element, builder) attrs = render_attrs(element.attributes) call = attrs.empty? ? "#{const}.new" : "#{const}.new(#{attrs})" kids = meaningful(element.children) if kids.empty? builder.line("render #{call}") else builder.line("render #{call} do") builder.indent emit_children(kids, builder) builder.dedent builder.line("end") end end |