-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bundles of elements #18
Comments
@andrew2net I've tried the following and this is currently working in I've created the following classes class PureTextElement < Shale::Mapper
attribute :text, Shale::Type::String
attribute :em, Shale::Type::String # Em
attribute :strong, Shale::Type::String # Strong
attribute :underline, Shale::Type::String # Underline
xml do
preserve_element_order true
map_content to: :text
map_element 'em', to: :em
map_element 'strong', to: :strong
map_element 'underline', to: :underline
end
end
class Sup < Shale::Mapper
attribute :pure_text_element, PureTextElement, collection: true
xml do
root 'sup'
map_element 'PureTextElement', to: :pure_text_element
end
end
require 'shale/adapter/nokogiri'
Shale.xml_adapter = Shale::Adapter::Nokogiri then I tried to convert the following XML from and to xml through shale xml = <<~XML
<sup>
<PureTextElement>
Some text <strong>Bold text</strong><em>important text</em>
</PureTextElement>
<PureTextElement>
Some text <em>Bold text</em><strong>important text</strong>
</PureTextElement>
<PureTextElement>
Some text <strong>Bold text</strong><em>important text</em>
</PureTextElement>
</sup>
XML
obj = Sup.from_xml(x)
obj.to_xml(pretty: true) and it generates the same output as input.
Can you explain what else is missing from shale? |
@HassanAkbar it is almost good but the <sup>
Some text <strong>Bold text</strong><em>important text</em>
Some text <em>Bold text</em><strong>important text</strong>
Some text <strong>Bold text</strong><em>important text</em>
</sup> I've tried to map the |
@HassanAkbar I found workaround but it looks not so elegant: module Relaton
module Model
class PureTextElement
def initialize(element)
@element = element
end
def self.cast(value)
value
end
def self.of_xml(node) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/MethodLength
case node.name
when "text"
text = node.text.strip
text.empty? ? nil : new(text)
when "em" then new Em.of_xml(node)
when "strong" then new Strong.of_xml(node)
when "sub" then new Sub.of_xml(node)
when "sup" then new Sup.of_xml(node)
when "tt" then new Tt.of_xml(node)
when "underline" then new Underline.of_xml(node)
when "strike" then new Strike.of_xml(node)
when "smallcap" then new Smallcap.of_xml(node)
when "br" then new Br.of_xml(node)
end
end
def add_to_xml(parent, doc)
if @element.is_a? String
doc.add_text(parent, @element)
else
parent << @element.to_xml
end
end
module Mapper
def self.included(base)
base.class_eval do
attribute :content, PureTextElement, collection: true
xml do
map_content to: :content, using: { from: :content_from_xml, to: :content_to_xml }
end
end
end
def content_from_xml(model, node)
(node.instance_variable_get(:@node) || node).children.each do |n|
next if n.text? && n.text.strip.empty?
model.content << PureTextElement.of_xml(n)
end
end
def content_to_xml(model, parent, doc)
model.content.each do |e|
e.add_to_xml parent, doc
end
end
end
end
end
end
module Relaton
module Model
class Sup < Shale::Mapper
include PureTextElement::Mapper
@xml_mapping.instance_eval do
root "sup"
end
end
end
end Is it possible to implement this functionality within Shale? <define name="strike">
<element name="strike">
<zeroOrMore>
<choice>
<ref name="PureTextElement"/>
<ref name="index"/>
<ref name="index-xref"/>
</choice>
</zeroOrMore>
</element>
</define> To implement this I use the code: module Relaton
module Model
class Strike < Shale::Mapper
class Content
def initialize(elements = [])
@elements = elements
end
def self.cast(value)
value
end
def self.of_xml(node)
elms = node.children.map do |n|
case n.name
when "index" then Index.of_xml n
when "index-xref" then IndexXref.of_xml n
else PureTextElement.of_xml n
end
end
new elms
end
def add_to_xml(parent, doc)
@elements.each { |e| e.add_to_xml parent, doc }
end
end
attribute :content, Content, collection: true
xml do
root "strike"
map_content to: :content, using: { from: :content_from_xml, to: :content_to_xml }
end
def content_from_xml(model, node)
model.content << Content.of_xml(node.instance_variable_get(:@node) || node)
end
def content_to_xml(model, parent, doc)
model.content.each { |e| e.add_to_xml parent, doc }
end
end
end
end |
@andrew2net I've been looking into the code and @ronaldtse Suggestion in this ticket -> metanorma/sts-ruby#12. Currently, I'm working on adding class TextWithTags < Shale::Mapper
attribute :content, Shale::Type::String
attribute :strong, Shale::Type::String, collection: true
attribute :em, Shale::Type::String, collection: true
xml do
root "text-with-tags"
map_all_content to: :content
map_content_element 'strong', to: :strong
map_content_element 'em', to: :em
end
end |
@HassanAkbar in the example the |
In grammar, which describes the Relaton data model, we have groups of elements included in other elements. For example:
With the ShaleI want to be able to use a pattern like:
We need to have any number of bundled elements (PureTextElements in the example) as children in any sequence. We need Shale to parse that sequence and render it in the same order.
The text was updated successfully, but these errors were encountered: