Class: SignalWire::POM::Section
- Inherits:
-
Object
- Object
- SignalWire::POM::Section
- Defined in:
- lib/signalwire/pom/section.rb
Overview
Represents a section in the Prompt Object Model.
Each section contains a title, optional body text, optional bullet points, and can have any number of nested subsections.
Mirrors Python’s “signalwire.pom.pom.Section“ exactly. See “signalwire-python/signalwire/signalwire/pom/pom.py“ for the source-of-truth specification; rendering output (markdown / XML / JSON / YAML) must match Python byte-for-byte so cross-language POM documents are interoperable.
Attributes:
-
title— the name of the section. -
body— a paragraph of text associated with the section. -
bullets— bullet-pointed items (Array<String>). -
subsections— nested Section objects. -
numbered— whether this section should be numbered. -
numbered_bullets— whether bullets should be numbered (rendered to/from the JSON/YAML keynumberedBulletsfor Python parity).
Instance Attribute Summary collapse
-
#body ⇒ Object
Returns the value of attribute body.
-
#bullets ⇒ Object
Returns the value of attribute bullets.
-
#numbered ⇒ Object
Returns the value of attribute numbered.
-
#numbered_bullets ⇒ Object
Returns the value of attribute numbered_bullets.
-
#subsections ⇒ Object
Returns the value of attribute subsections.
-
#title ⇒ Object
Returns the value of attribute title.
Instance Method Summary collapse
-
#add_body(body) ⇒ Object
Add or replace the body text for this section.
-
#add_bullets(bullets) ⇒ Object
Append bullet points to this section.
-
#add_subsection(title, body: '', bullets: nil, numbered: false, numbered_bullets: false) ⇒ Object
Add a subsection to this section, returning the new Section.
-
#initialize(title = nil, body: '', bullets: nil, numbered: nil, numbered_bullets: false) ⇒ Section
constructor
Construct a Section.
-
#render_markdown(level: 2, section_number: nil) ⇒ Object
Render this section and all its subsections as Markdown.
-
#render_xml(indent: 0, section_number: nil) ⇒ Object
Render this section and all its subsections as XML.
-
#to_h ⇒ Object
Convert the section to a Hash representation suitable for JSON or YAML serialization.
Constructor Details
#initialize(title = nil, body: '', bullets: nil, numbered: nil, numbered_bullets: false) ⇒ Section
Construct a Section.
All arguments after title are keyword arguments mirroring the Python “Section.__init__“ signature. “numbered_bullets“ is snake_case in Ruby; the camelCase “numberedBullets“ form used by Python’s JSON/YAML serialization is preserved on the wire.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/signalwire/pom/section.rb', line 33 def initialize(title = nil, body: '', bullets: nil, numbered: nil, numbered_bullets: false) @title = title unless body.is_a?(String) raise TypeError, "body must be a string, not #{body.class.name}. " \ 'If you meant to pass a list of bullet points, use bullets parameter instead.' end @body = body if !bullets.nil? && !bullets.is_a?(Array) raise TypeError, "bullets must be an Array or nil, not #{bullets.class.name}" end @bullets = bullets || [] @subsections = [] @numbered = numbered @numbered_bullets = numbered_bullets end |
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body.
25 26 27 |
# File 'lib/signalwire/pom/section.rb', line 25 def body @body end |
#bullets ⇒ Object
Returns the value of attribute bullets.
25 26 27 |
# File 'lib/signalwire/pom/section.rb', line 25 def bullets @bullets end |
#numbered ⇒ Object
Returns the value of attribute numbered.
25 26 27 |
# File 'lib/signalwire/pom/section.rb', line 25 def numbered @numbered end |
#numbered_bullets ⇒ Object
Returns the value of attribute numbered_bullets.
25 26 27 |
# File 'lib/signalwire/pom/section.rb', line 25 def numbered_bullets @numbered_bullets end |
#subsections ⇒ Object
Returns the value of attribute subsections.
25 26 27 |
# File 'lib/signalwire/pom/section.rb', line 25 def subsections @subsections end |
#title ⇒ Object
Returns the value of attribute title.
25 26 27 |
# File 'lib/signalwire/pom/section.rb', line 25 def title @title end |
Instance Method Details
#add_body(body) ⇒ Object
Add or replace the body text for this section. Mirrors Python’s “Section.add_body“ (which is documented to “Add or replace”).
55 56 57 58 59 60 61 |
# File 'lib/signalwire/pom/section.rb', line 55 def add_body(body) unless body.is_a?(String) raise TypeError, "body must be a string, not #{body.class.name}" end @body = body end |
#add_bullets(bullets) ⇒ Object
Append bullet points to this section. Does not replace existing bullets — mirrors Python’s “self.bullets.extend(bullets)“.
65 66 67 68 69 70 71 |
# File 'lib/signalwire/pom/section.rb', line 65 def add_bullets(bullets) unless bullets.is_a?(Array) raise TypeError, "bullets must be an Array, not #{bullets.class.name}" end @bullets.concat(bullets) end |
#add_subsection(title, body: '', bullets: nil, numbered: false, numbered_bullets: false) ⇒ Object
Add a subsection to this section, returning the new Section.
Raises ArgumentError when title is nil (Python raises “ValueError(“Subsections must have a title”)“; Ruby idiom is ArgumentError for invalid arguments).
78 79 80 81 82 83 84 85 |
# File 'lib/signalwire/pom/section.rb', line 78 def add_subsection(title, body: '', bullets: nil, numbered: false, numbered_bullets: false) raise ArgumentError, 'Subsections must have a title' if title.nil? sub = Section.new(title, body: body, bullets: bullets || [], numbered: numbered, numbered_bullets: numbered_bullets) @subsections << sub sub end |
#render_markdown(level: 2, section_number: nil) ⇒ Object
Render this section and all its subsections as Markdown. The output is byte-for-byte identical to Python’s “Section.render_markdown“.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/signalwire/pom/section.rb', line 104 def render_markdown(level: 2, section_number: nil) md = [] section_number = [] if section_number.nil? unless @title.nil? prefix = '' prefix = "#{section_number.join('.')}. " unless section_number.empty? md << "#{'#' * level} #{prefix}#{@title}\n" end md << "#{@body}\n" if @body && !@body.empty? @bullets.each_with_index do |bullet, idx| if @numbered_bullets md << "#{idx + 1}. #{bullet}" else md << "- #{bullet}" end end md << '' unless @bullets.empty? any_subsection_numbered = @subsections.any? { |sub| sub.numbered } @subsections.each_with_index do |subsection, idx| if !@title.nil? || !section_number.empty? new_section_number = if any_subsection_numbered && subsection.numbered != false section_number + [idx + 1] else section_number end next_level = level + 1 else new_section_number = section_number next_level = level end md << subsection.render_markdown(level: next_level, section_number: new_section_number) end md.join("\n") end |
#render_xml(indent: 0, section_number: nil) ⇒ Object
Render this section and all its subsections as XML. Output is byte-for-byte identical to Python’s “Section.render_xml“.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/signalwire/pom/section.rb', line 150 def render_xml(indent: 0, section_number: nil) indent_str = ' ' * indent xml = [] section_number = [] if section_number.nil? xml << "#{indent_str}<section>" unless @title.nil? prefix = '' prefix = "#{section_number.join('.')}. " unless section_number.empty? xml << "#{indent_str} <title>#{prefix}#{@title}</title>" end xml << "#{indent_str} <body>#{@body}</body>" if @body && !@body.empty? if @bullets && !@bullets.empty? xml << "#{indent_str} <bullets>" @bullets.each_with_index do |bullet, idx| if @numbered_bullets xml << "#{indent_str} <bullet id=\"#{idx + 1}\">#{bullet}</bullet>" else xml << "#{indent_str} <bullet>#{bullet}</bullet>" end end xml << "#{indent_str} </bullets>" end if @subsections && !@subsections.empty? xml << "#{indent_str} <subsections>" any_subsection_numbered = @subsections.any? { |sub| sub.numbered } @subsections.each_with_index do |subsection, idx| if !@title.nil? || !section_number.empty? new_section_number = if any_subsection_numbered && subsection.numbered != false section_number + [idx + 1] else section_number end else new_section_number = section_number end xml << subsection.render_xml(indent: indent + 2, section_number: new_section_number) end xml << "#{indent_str} </subsections>" end xml << "#{indent_str}</section>" xml.join("\n") end |
#to_h ⇒ Object
Convert the section to a Hash representation suitable for JSON or YAML serialization. Keys are emitted in the same order as Python so cross-port string comparisons line up.
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/signalwire/pom/section.rb', line 90 def to_h data = {} data['title'] = @title unless @title.nil? data['body'] = @body if @body && !@body.empty? data['bullets'] = @bullets if @bullets && !@bullets.empty? data['subsections'] = @subsections.map(&:to_h) if @subsections && !@subsections.empty? data['numbered'] = @numbered if @numbered data['numberedBullets'] = @numbered_bullets if @numbered_bullets data end |