Class: Moxml::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/moxml/config.rb

Constant Summary collapse

LINE_ENDING_LF =
"\n"
LINE_ENDING_CRLF =
"\r\n"
VALID_LINE_ENDINGS =
[LINE_ENDING_LF, LINE_ENDING_CRLF].freeze
VALID_ADAPTERS =
i[nokogiri oga rexml ox headed_ox libxml leptris].freeze
PREFERRED_ADAPTER =

Preferred CRuby default (issue #96): fastest on every measured operation and the cleanest deployment story. Only takes effect when the installed leptris supports programmatic document construction (Leptris::XML::Document.create); otherwise moxml falls back to FALLBACK_ADAPTER so released-gem environments keep working. Under Opal the default is oga only when the vendored pure-Ruby fork was compiled into the bundle — stock oga requires its C extension and cannot load there; otherwise rexml.

:leptris
FALLBACK_ADAPTER =
:nokogiri
OPAL_DEFAULT_ADAPTER =
:oga
OPAL_FALLBACK_ADAPTER =
:rexml
ENTITY_MODES =

Entity loading modes:

  • :required - Must load entities, raise error if unavailable (default)
  • :optional - Try to load, continue silently if unavailable
  • :disabled - Don't load entities, use empty registry
  • :custom - Use custom entity provider via entity_provider callback Entity-reference preservation mode (leptris-ruby#212 / upstream #1094): :expand (default) keeps the shipped behavior (entities expanded at parse, marker-driven round-trip); :keep enables first-class EntityReference nodes and skips the marker machinery when the binding supports it (leptris >= 1.9.177).
i[expand keep].freeze
ENTITY_LOAD_MODES =
i[required optional disabled custom].freeze
NAMESPACE_VALIDATION_MODES =
i[strict lenient].freeze
ENTITY_RESTORATION_MODES =

Entity restoration modes:

  • :lenient (default) — restore any known entity from the registry
  • :strict — only restore DTD-declared entities (falls back to lenient until DTD parsing is implemented)
i[strict lenient].freeze
OX_DEFAULT_SKIP =

Ox whitespace policy (issue #189): ::Ox.parse hardcodes skip: :skip_white, which collapses whitespace runs inside text content — xml:space="preserve" documents round-trip mangled. The adapter parses with ::Ox.load instead; these defaults keep every character of text content (inter-element indentation is dropped by Ox's generic mode under every skip setting, so the child lists stay identical to the old parse).

:skip_none
OX_DEFAULT_MODE =
:generic
OX_VALID_SKIPS =
i[skip_none skip_white skip_off].freeze
OX_VALID_MODES =
i[generic hash object].freeze

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter_name = nil, strict_parsing = nil, default_encoding = nil) ⇒ Config

Returns a new instance of Config.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/moxml/config.rb', line 157

def initialize(adapter_name = nil, strict_parsing = nil,
               default_encoding = nil)
  self.adapter = adapter_name || Config.default.adapter_name
  @strict_parsing = strict_parsing || Config.default.strict_parsing
  # Constant-initialized (not Config.default fallback): the
  # default Config constructs via Config.default — a fallback
  # read there recurses. Global-default propagation for these
  # knobs is not part of the contract; per-context is (#189).
  @ox_skip = OX_DEFAULT_SKIP
  @ox_mode = OX_DEFAULT_MODE
  @default_encoding = default_encoding || Config.default.default_encoding
  @default_indent = 2
  @default_line_ending = LINE_ENDING_LF
  @restore_entities = false
  @preload_entity_sets = []
  @entity_load_mode = :required
  @entity_provider = nil
  @namespace_validation_mode = :strict
  @entity_restoration_mode = :lenient
  @entity_mode = :expand
end

Class Attribute Details

.default_adapterObject



43
44
45
# File 'lib/moxml/config.rb', line 43

def default_adapter
  @default_adapter || runtime_default_adapter
end

Instance Attribute Details

#adapter_nameObject (readonly)

Returns the value of attribute adapter_name.



115
116
117
# File 'lib/moxml/config.rb', line 115

def adapter_name
  @adapter_name
end

#default_encodingObject

Returns the value of attribute default_encoding.



116
117
118
# File 'lib/moxml/config.rb', line 116

def default_encoding
  @default_encoding
end

#default_indentObject

Returns the value of attribute default_indent.



116
117
118
# File 'lib/moxml/config.rb', line 116

def default_indent
  @default_indent
end

#default_line_endingObject

Returns the value of attribute default_line_ending.



115
116
117
# File 'lib/moxml/config.rb', line 115

def default_line_ending
  @default_line_ending
end

#entity_load_modeObject

Returns the value of attribute entity_load_mode.



116
117
118
# File 'lib/moxml/config.rb', line 116

def entity_load_mode
  @entity_load_mode
end

#entity_modeObject

Returns the value of attribute entity_mode.



116
117
118
# File 'lib/moxml/config.rb', line 116

def entity_mode
  @entity_mode
end

#entity_providerObject

Returns the value of attribute entity_provider.



116
117
118
# File 'lib/moxml/config.rb', line 116

def entity_provider
  @entity_provider
end

#entity_restoration_modeObject

Returns the value of attribute entity_restoration_mode.



116
117
118
# File 'lib/moxml/config.rb', line 116

def entity_restoration_mode
  @entity_restoration_mode
end

#namespace_validation_modeObject

Returns the value of attribute namespace_validation_mode.



116
117
118
# File 'lib/moxml/config.rb', line 116

def namespace_validation_mode
  @namespace_validation_mode
end

#ox_modeObject

Returns the value of attribute ox_mode.



116
117
118
# File 'lib/moxml/config.rb', line 116

def ox_mode
  @ox_mode
end

#ox_skipObject

Returns the value of attribute ox_skip.



116
117
118
# File 'lib/moxml/config.rb', line 116

def ox_skip
  @ox_skip
end

#preload_entity_setsObject

Returns the value of attribute preload_entity_sets.



116
117
118
# File 'lib/moxml/config.rb', line 116

def preload_entity_sets
  @preload_entity_sets
end

#restore_entitiesObject

Returns the value of attribute restore_entities.



116
117
118
# File 'lib/moxml/config.rb', line 116

def restore_entities
  @restore_entities
end

#strict_parsingObject

Returns the value of attribute strict_parsing.



116
117
118
# File 'lib/moxml/config.rb', line 116

def strict_parsing
  @strict_parsing
end

Class Method Details

.defaultObject



39
40
41
# File 'lib/moxml/config.rb', line 39

def default
  @default ||= new(default_adapter, true, "UTF-8")
end

.detect_loaded_adapterObject



87
88
89
90
91
92
93
# File 'lib/moxml/config.rb', line 87

def detect_loaded_adapter
  return :nokogiri if Object.const_defined?(:Nokogiri)
  return :ox if Object.const_defined?(:Ox)
  return :oga if Object.const_defined?(:Oga)

  nil
end

.leptris_preferred_available?Boolean

True when the leptris gem is installed AND meets the adapter's binding floor (issue #149; 1.9.32 — traverse bounding #89, built-docs parts #91, and every capability surface the adapter now assumes). Memoized: the probe runs once. Below the floor the default falls back to Nokogiri rather than driving a binding the adapter no longer accommodates.

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/moxml/config.rb', line 74

def leptris_preferred_available?
  return @leptris_preferred_available if defined?(@leptris_preferred_available)

  @leptris_preferred_available = begin
    require "leptris"
    Moxml::Adapter.load(:leptris)
    Gem::Version.new(::Leptris::VERSION) >=
      Gem::Version.new(Moxml::Adapter::Leptris::MINIMUM_BINDING_VERSION)
  rescue LoadError, NameError
    false
  end
end

.opal_runtime_adapterObject

Stock oga requires its C extension, so under Opal the oga adapter can only come from the vendored pure-Ruby fork — a repo-only artifact the released gem does not ship. Bundles that compiled it in (moxml's own harness) keep oga; everyone else gets the rexml adapter, whose Opal compat ships in-gem. defined? is safe here: this branch never runs under MRI, where it would trigger autoload resolution.



62
63
64
65
66
# File 'lib/moxml/config.rb', line 62

def opal_runtime_adapter
  return OPAL_DEFAULT_ADAPTER if defined?(Moxml::Adapter::Oga)

  OPAL_FALLBACK_ADAPTER
end

.runtime_default_adapterObject



47
48
49
50
51
52
53
# File 'lib/moxml/config.rb', line 47

def runtime_default_adapter
  return opal_runtime_adapter if RUBY_ENGINE == "opal"

  return PREFERRED_ADAPTER if leptris_preferred_available?

  detect_loaded_adapter || FALLBACK_ADAPTER
end

Instance Method Details

#adapterObject



200
201
202
# File 'lib/moxml/config.rb', line 200

def adapter
  @adapter ||= Adapter.load(@adapter_name)
end

#adapter=(name) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/moxml/config.rb', line 179

def adapter=(name)
  name = name.to_sym
  @adapter = nil

  unless VALID_ADAPTERS.include?(name)
    raise Moxml::AdapterError.new(
      "Invalid adapter: #{name}",
      adapter: name,
      operation: "set_adapter",
    )
  end

  @adapter_name = name
  adapter
end

#default_adapter=(name) ⇒ Object



195
196
197
198
# File 'lib/moxml/config.rb', line 195

def default_adapter=(name)
  self.adapter = name
  self.class.default_adapter = name
end

#load_external_entitiesObject



253
254
255
# File 'lib/moxml/config.rb', line 253

def load_external_entities
  @entity_load_mode == :required
end

#load_external_entities=(value) ⇒ Object

Backward compatibility: convert old boolean to new symbol



245
246
247
248
249
250
251
# File 'lib/moxml/config.rb', line 245

def load_external_entities=(value)
  @entity_load_mode = case value
                      when true then :required
                      when false then :disabled
                      else value
                      end
end