lib/exporters/xml/ddi/cc_loop.rb
module Exporters::XML::DDI
# DDI 3.2 XML Exporter for {::CcLoop}
#
# {::CcLoop} is a direct alias of DDI 3.2 Loop.
#
# === Example
# doc = Nokogiri::XML::Document.new
# loop = CcLoop.first
# exporter = Exporters::XML::DDI::CcLoop.new doc
# xml_node = exporter.V3_2(loop)
#
# @see ::CcLoop
class CcLoop < DdiExporterBase
# Exports the {::CcLoop} in DDI 3.2
#
# Create a single XML node as an export of a single {::CcLoop}.
# In order to be valid DDI, this node then needs to be wrapped
# either in a ControlConstructScheme or a Fragment.
#
# @param [::CcLoop|Integer] lp_id Either the CcLoop or CcLoop ID for exporting
# @return [Nokogiri::XML::Node] New XML node
def V3_2(lp_id)
cc = lp_id.is_a?(::CcLoop) ? lp_id : ::CcLoop.find(lp_id)
lp = Nokogiri::XML::Node.new 'd:Loop', @doc
urn = create_urn_node cc
lp.add_child urn
cn = Nokogiri::XML::Node.new 'd:ConstructName', @doc
s = Nokogiri::XML::Node.new 'r:String', @doc
s['xml:lang'] = 'en-GB'
s.content = cc.label
cn.add_child s
lp.add_child cn
lp.add_child '<d:InitialValue><r:Command><r:ProgramLanguage>pseudo-code</r:ProgramLanguage>' +
'<r:CommandContent>%{command}</r:CommandContent></r:Command></d:InitialValue>' % {
command: CGI::escapeHTML(cc.loop_var.to_s) + ' = ' + cc.start_val.to_s
}
lp.add_child build_loop_while(cc)
lp.add_child build_loop_sequence_reference(cc)
ns = Nokogiri::XML::NodeSet.new @doc
ns.push lp
ns.push build_loop_sequence(cc)
ns
end
private # Private methods
def build_loop_while(cc)
command = ''
unless cc.end_val.nil?
command += cc.loop_var + ' < ' + cc.end_val
end
unless cc.end_val.nil? || cc.loop_while.nil?
command += ' && '
end
unless cc.loop_while.nil?
command += cc.loop_while
end
return '<d:LoopWhile><r:Command><r:ProgramLanguage>pseudo-code</r:ProgramLanguage>' +
'<r:CommandContent>%{command}</r:CommandContent></r:Command></d:LoopWhile>' % {
command: CGI::escapeHTML(command.to_s)
}
end
def build_loop_sequence_reference(cc)
('<d:ControlConstructReference>%{urn_node}<r:TypeOfObject>Sequence</r:TypeOfObject></d:ControlConstructReference>') % {
urn_node: create_urn_node(cc, 'selp').to_xml
}
end
def build_loop_sequence(cc)
selp = Nokogiri::XML::Node.new 'd:Sequence', @doc
selp.add_child create_urn_node(cc, 'selp')
selp_cn = Nokogiri::XML::Node.new 'd:ConstructName', @doc
selp_s = Nokogiri::XML::Node.new 'r:String', @doc
selp_s['xml:lang'] = 'en-GB'
selp_s.content = 'loop_seq_' + cc.label
selp_cn.add_child selp_s
selp.add_child selp_cn
selp_l = Nokogiri::XML::Node.new 'r:Label', @doc
selp_c = Nokogiri::XML::Node.new 'r:Content', @doc
selp_c['xml:lang'] = 'en-GB'
selp_c.content = 'loop_seq_' + cc.label
selp_l.add_child selp_c
selp_cn.add_next_sibling selp_l
selp_inner_prev = selp_l
cc.children.each do |child|
ccf = create_reference_string 'd:ControlConstructReference', child
selp_inner_prev.add_next_sibling ccf
selp_inner_prev = ccf
end
return selp
end
end
end