Class: Coradoc::AsciiDoc::Model::Base

Inherits:
Lutaml::Model::Serializable
  • Object
show all
Includes:
Lutaml::Model::ComparableModel
Defined in:
lib/coradoc/asciidoc/model/base.rb

Overview

Base class for all Coradoc model objects.

The Base class provides common functionality for all document model elements, including serialization support, tree traversal, and attribute management.

All model classes inherit from this class to get:

  • Lutaml::Model serialization capabilities

  • ComparableModel functionality

  • Visit pattern for tree traversal

  • Polymorphic content serialization

Examples:

Implementing a custom model class

class CustomBlock < Coradoc::AsciiDoc::Model::Base
  attribute :content, :string
  attribute :children, array: true
end

Using the visit pattern

doc.visit do |element, phase|
  puts "#{phase}: #{element.class}" if element.is_a?(Paragraph)
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#idString? (readonly)

Returns Optional identifier for the element.

Returns:

  • (String, nil)

    Optional identifier for the element



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
97
98
99
100
101
102
103
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
# File 'lib/coradoc/asciidoc/model/base.rb', line 33

class Base < Lutaml::Model::Serializable
  include Lutaml::Model::ComparableModel

  attribute :id, :string

  # Element classification for spacing and serialization decisions.
  # Subclasses override these to declare their level.
  def block_level?
    false
  end

  def inline?
    false
  end

  # Generate a warning message whenever this method is called.
  def simplify_block_content(content)
    warn '[DEPRECATION] #simplify_block_content is called inside a Lutaml Model.  This is still a WIP.'
    # print part of the stack trace
    caller_locations(1, 3).each do |location|
      warn "  #{location.path}:#{location.lineno} in #{location.label}"
    end

    content
  end

  # Visit pattern for traversing the document tree
  def self.visit(element, &block)
    return element if element.nil?

    element = yield element, :pre
    element = case element
              when Coradoc::AsciiDoc::Model::Base
                element.visit(&block)
              when Array
                element.map { |child| visit(child, &block) }
                       .flatten.compact
              when Hash
                result = {}
                element.each do |k, v|
                  result[k] = visit(v, &block)
                end
                result
              else
                element
              end
    yield element, :post
  end

  def visit(&block)
    self.class.attributes.each_key do |attr_name|
      child = public_send(attr_name)
      result = self.class.visit(child, &block)
      public_send(:"#{attr_name}=", result) if result != child
    end
    self
  end

  # Serialize polymorphic content to AsciiDoc string
  # Handles: Arrays, Strings, nil, and model objects
  # Raises ArgumentError for unknown types to force proper handling
  def serialize_content(content)
    case content
    when Array
      content.map { |elem| serialize_content(elem) }.join
    when String
      content
    when nil
      ''
    when Coradoc::AsciiDoc::Model::Base, Lutaml::Model::Serializable
      # All model objects should respond to to_adoc
      content.to_adoc
    else
      # This is a programming error - we received an unexpected type
      raise ArgumentError,
            "Cannot serialize #{content.class.name} in content. " \
            'Expected String, nil, Array, Coradoc::AsciiDoc::Model::Base, or ' \
            "Lutaml::Model::Serializable. Got: #{content.inspect[0..100]}"
    end
  end

  # Does a shallow attribute dump of the object,
  # for use when instantiating a new object (e.g. of a subclass) from an
  # existing one.
  def to_h
    self.class.attributes.keys.each_with_object({}) do |attribute, acc|
      acc[attribute] = public_send(attribute)
    end
  end

  # Serialize this model element to AsciiDoc
  #
  # This is the unified serialization method for all Model objects.
  # It uses the ElementRegistry system which provides serializers
  # for each model type.
  #
  # @return [String] AsciiDoc representation of this element
  #
  # @example Serialize a paragraph to AsciiDoc
  #   para = Coradoc::AsciiDoc::Model::Paragraph.new("Hello World")
  #   para.to_adoc # => "Hello World\n"
  #
  def to_adoc
    Coradoc::AsciiDoc::Serializer.serialize(self)
  end
end

Class Method Details

.visit(element) {|element, :post| ... } ⇒ Object

Visit pattern for traversing the document tree

Yields:

  • (element, :post)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/coradoc/asciidoc/model/base.rb', line 60

def self.visit(element, &block)
  return element if element.nil?

  element = yield element, :pre
  element = case element
            when Coradoc::AsciiDoc::Model::Base
              element.visit(&block)
            when Array
              element.map { |child| visit(child, &block) }
                     .flatten.compact
            when Hash
              result = {}
              element.each do |k, v|
                result[k] = visit(v, &block)
              end
              result
            else
              element
            end
  yield element, :post
end

Instance Method Details

#block_level?Boolean

Element classification for spacing and serialization decisions. Subclasses override these to declare their level.

Returns:

  • (Boolean)


40
41
42
# File 'lib/coradoc/asciidoc/model/base.rb', line 40

def block_level?
  false
end

#inline?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/coradoc/asciidoc/model/base.rb', line 44

def inline?
  false
end

#serialize_content(content) ⇒ Object

Serialize polymorphic content to AsciiDoc string Handles: Arrays, Strings, nil, and model objects Raises ArgumentError for unknown types to force proper handling



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/coradoc/asciidoc/model/base.rb', line 94

def serialize_content(content)
  case content
  when Array
    content.map { |elem| serialize_content(elem) }.join
  when String
    content
  when nil
    ''
  when Coradoc::AsciiDoc::Model::Base, Lutaml::Model::Serializable
    # All model objects should respond to to_adoc
    content.to_adoc
  else
    # This is a programming error - we received an unexpected type
    raise ArgumentError,
          "Cannot serialize #{content.class.name} in content. " \
          'Expected String, nil, Array, Coradoc::AsciiDoc::Model::Base, or ' \
          "Lutaml::Model::Serializable. Got: #{content.inspect[0..100]}"
  end
end

#simplify_block_content(content) ⇒ Object

Generate a warning message whenever this method is called.



49
50
51
52
53
54
55
56
57
# File 'lib/coradoc/asciidoc/model/base.rb', line 49

def simplify_block_content(content)
  warn '[DEPRECATION] #simplify_block_content is called inside a Lutaml Model.  This is still a WIP.'
  # print part of the stack trace
  caller_locations(1, 3).each do |location|
    warn "  #{location.path}:#{location.lineno} in #{location.label}"
  end

  content
end

#to_adocString

Serialize this model element to AsciiDoc

This is the unified serialization method for all Model objects. It uses the ElementRegistry system which provides serializers for each model type.

Examples:

Serialize a paragraph to AsciiDoc

para = Coradoc::AsciiDoc::Model::Paragraph.new("Hello World")
para.to_adoc # => "Hello World\n"

Returns:

  • (String)

    AsciiDoc representation of this element



135
136
137
# File 'lib/coradoc/asciidoc/model/base.rb', line 135

def to_adoc
  Coradoc::AsciiDoc::Serializer.serialize(self)
end

#to_hObject

Does a shallow attribute dump of the object, for use when instantiating a new object (e.g. of a subclass) from an existing one.



117
118
119
120
121
# File 'lib/coradoc/asciidoc/model/base.rb', line 117

def to_h
  self.class.attributes.keys.each_with_object({}) do |attribute, acc|
    acc[attribute] = public_send(attribute)
  end
end

#visit(&block) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/coradoc/asciidoc/model/base.rb', line 82

def visit(&block)
  self.class.attributes.each_key do |attr_name|
    child = public_send(attr_name)
    result = self.class.visit(child, &block)
    public_send(:"#{attr_name}=", result) if result != child
  end
  self
end