Class: Coradoc::CoreModel::Base

Inherits:
Lutaml::Model::Serializable
  • Object
show all
Defined in:
lib/coradoc/core_model/base.rb

Overview

Base class for all core models

Provides common functionality for schema-agnostic document models. This class establishes the foundational structure for all CoreModel classes, including semantic equivalence comparison and common attributes.

Examples:

Creating a base model

model = CoreModel::Base.new(
  id: "example-1",
  title: "Example Title",
  element_attributes: [
    CoreModel::ElementAttribute.new(name: "role", value: "note")
  ]
)

Semantic comparison

model1 = CoreModel::Base.new(id: "test", title: "Test")
model2 = CoreModel::Base.new(id: "test", title: "Test")
model1.semantically_equivalent?(model2) # => true

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#element_attributesArray<ElementAttribute>

Returns collection of element attributes.

Returns:



38
# File 'lib/coradoc/core_model/base.rb', line 38

attribute :element_attributes, ElementAttribute, collection: true

#idString?

Returns unique identifier for the element.

Returns:

  • (String, nil)

    unique identifier for the element



30
# File 'lib/coradoc/core_model/base.rb', line 30

attribute :id, :string

#metadata_entriesArray<MetadataEntry>

Returns additional metadata entries.

Returns:



42
# File 'lib/coradoc/core_model/base.rb', line 42

attribute :metadata_entries, MetadataEntry, collection: true

#titleString?

Returns title of the element.

Returns:

  • (String, nil)

    title of the element



34
# File 'lib/coradoc/core_model/base.rb', line 34

attribute :title, :string

Class Method Details

.build(**attrs) {|instance| ... } ⇒ Object

Construct an instance and yield it for in-place mutation.

This is the programmatic-construction entry point for CoreModel nodes. It calls new exactly as a caller would, then yields the resulting instance for append-style construction. No new class hierarchy, no method_missing — the block operates on the real model object.

Per-class fluent helpers (e.g., ListBlock#add_item, ListItem#add_text) compose naturally with build:

list = ListBlock.build do |ul|
children.each { |c| ul.add_item { |li| li.add_link(c[:slug], text: c[:title]) } }
end

Without a block, build(**attrs) is identical to new(**attrs).

Yields:

  • (instance)


67
68
69
70
71
# File 'lib/coradoc/core_model/base.rb', line 67

def self.build(**attrs)
  instance = new(**attrs)
  yield instance if block_given?
  instance
end

Instance Method Details

#accept(visitor) ⇒ void

This method returns an undefined value.

Accept a visitor to traverse this element

Implements the visitor pattern for document traversal. The visitor's visit method will be called with this element.

Parameters:



173
174
175
# File 'lib/coradoc/core_model/base.rb', line 173

def accept(visitor)
  visitor.visit(self)
end

#attrHash #attr(name) ⇒ String?

Get all element attributes as a hash, or a specific attribute value by name

Overloads:

  • #attrHash

    Returns All attributes as key-value pairs.

    Returns:

    • (Hash)

      All attributes as key-value pairs

  • #attr(name) ⇒ String?

    Returns The value or nil.

    Parameters:

    • name (String)

      The attribute name

    Returns:

    • (String, nil)

      The value or nil



109
110
111
112
113
114
115
116
117
118
# File 'lib/coradoc/core_model/base.rb', line 109

def attr(name = nil)
  attrs = element_attributes || []
  if name.nil?
    # Return all attributes as hash
    attrs.each_with_object({}) { |a, h| h[a.name] = a.value }
  else
    # Return specific value
    attrs.find { |a| a.name == name }&.value
  end
end

#body_content?Boolean

True when this node counts as "real body content" for the purposes of empty-document detection and similar structural queries. Default is true; metadata and ephemeral nodes (FrontmatterBlock, CommentBlock, CommentLine) override to false. Polymorphic dispatch keeps the predicate open for future "skip-me" types — no central walker to edit (OCP).

Returns:

  • (Boolean)


183
184
185
# File 'lib/coradoc/core_model/base.rb', line 183

def body_content?
  true
end

#flat_textString

Flatten this element to a plain-text string.

Subclasses that include ChildrenContent override this to concatenate their children's text. Block-level elements without textual content (ListBlock, Table, etc.) fall back to the empty string — they are serialized structurally, not flattened into inline text.

Returns:

  • (String)


162
163
164
# File 'lib/coradoc/core_model/base.rb', line 162

def flat_text
  ""
end

#metadataHash #metadata(key) ⇒ String?

Get all metadata as a hash, or a specific metadata value by key

Overloads:

  • #metadataHash

    Returns All metadata as key-value pairs.

    Returns:

    • (Hash)

      All metadata as key-value pairs

  • #metadata(key) ⇒ String?

    Returns The value or nil.

    Parameters:

    • key (String)

      The metadata key

    Returns:

    • (String, nil)

      The value or nil



79
80
81
82
83
84
85
86
87
88
# File 'lib/coradoc/core_model/base.rb', line 79

def (key = nil)
  entries =  || []
  if key.nil?
    # Return all metadata as hash
    entries.each_with_object({}) { |e, h| h[e.key] = e.value }
  else
    # Return specific value
    entries.find { |e| e.key == key }&.value
  end
end

#semantically_equivalent?(other) ⇒ Boolean

Compare this model with another for semantic equivalence

Semantic equivalence means the models represent the same semantic content, even if their exact structure differs. This is different from equality, which requires exact matching.

Parameters:

  • other (Object)

    the object to compare with

Returns:

  • (Boolean)

    true if semantically equivalent, false otherwise



141
142
143
144
145
146
147
# File 'lib/coradoc/core_model/base.rb', line 141

def semantically_equivalent?(other)
  return false unless other.is_a?(self.class)

  comparable_attributes.all? do |attr|
    compare_attribute(attr, other)
  end
end

#set_attr(name, value) ⇒ Object

Set attribute value

Parameters:

  • name (String)

    The attribute name

  • value (String)

    The value to set



123
124
125
126
127
128
129
130
131
# File 'lib/coradoc/core_model/base.rb', line 123

def set_attr(name, value)
  self.element_attributes ||= []
  existing = element_attributes.find { |a| a.name == name }
  if existing
    existing.value = value
  else
    element_attributes << ElementAttribute.new(name: name, value: value)
  end
end

#set_metadata(key, value) ⇒ Object

Convenience method to set metadata

Parameters:

  • key (String)

    The metadata key

  • value (String)

    The value to set



93
94
95
96
97
98
99
100
101
# File 'lib/coradoc/core_model/base.rb', line 93

def (key, value)
  self. ||= []
  existing = .find { |e| e.key == key }
  if existing
    existing.value = value
  else
     << MetadataEntry.new(key: key, value: value)
  end
end

#whitespace_only?Boolean

True when this node is structurally present but carries no visible characters. Default is false; inline text and paragraph blocks override to inspect their text content.

Returns:

  • (Boolean)


190
191
192
# File 'lib/coradoc/core_model/base.rb', line 190

def whitespace_only?
  false
end