leptris 1.9.121.0 → 1.9.144.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of leptris might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85000791341954ae6ac1ad4b81236ad657e0c9d3dad1914ce182de881e8631ef
4
- data.tar.gz: 55657d439219c20317b1a0c66916817cb131d502a25120cbc9566bd4d17e7c0e
3
+ metadata.gz: ce24363303ca7b04d2cc2862985a5db2a2358e03910cac76f1fc21c417a84ed5
4
+ data.tar.gz: 97f81edbb20997881c632c369eda7c2d2cb219582cd9e19cf8b0e458855c4a4c
5
5
  SHA512:
6
- metadata.gz: fe1948ea43444c5057909c2a53e9cc2e3f0682db71a46ead7be72cccc65051036c568bd560615ed6426c8da3b5a074f33bd6a222eb3dc0734d4a8da72e9ec33b
7
- data.tar.gz: '088636076490098a9e58a964f45d06a0bc21cd78d5164df2fa04a69f194a0540cfeb9309af95ea9fd67e518533c7c006eb018b84b5de14a9d4266153dfba4a27'
6
+ metadata.gz: 06622c78d7f4ed9cfcf8aae54f696d237f819d5d33f0875f2b3145e63b624f837c45fb7b160dc2e5c11de23ea95db7cfffbdc49ea04d5f0087f7e04cfb57fb23
7
+ data.tar.gz: 23e5b135a9146e96d7d452255e6ff7d77d875285c687bd58af6c6276486b5c161e1c82911ca90a419f72422eae7cb2f538e609451d2b9882ce7bb31464dbb95b
data/CHANGELOG.md CHANGED
@@ -5,6 +5,58 @@ All notable changes to Leptris will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.144.0] - 2026-09-12
9
+
10
+ ### Changed
11
+
12
+ - **Lockstep with libleptris 1.9.144** (1.9.121 → 1.9.144; audit
13
+ 270 → 289 after attaching 19 new symbols).
14
+ - **`Leptris::XML::Schematron`** — ISO Schematron validation
15
+ (libleptris 1.9.127/1.9.128; schematron-conformance corpus
16
+ 50/50): `Schematron.parse(schema_xml, phase: nil)` / `.parse_file`
17
+ compile once, then `#valid?(doc)` answers the boolean and
18
+ `#validate(doc)` returns the SVRL report as a queryable
19
+ `Document` (failed-assert / successful-report with @location).
20
+ - **`Leptris::XML::Diff`** — native tree diff (libleptris
21
+ 1.9.127, namespace-aware 1.9.129): `Leptris::XML.diff(a, b,
22
+ ignore_ws: false)` → `#ops` (`{type:, name:, path:, before:,
23
+ after:}`; insert/delete/update_text/update_attr with
24
+ positional `/name[i]` paths) and `#to_s` (the serialized op
25
+ list); `Diff.identical?(a, b, ignore_ws:)` answers the boolean
26
+ fast path.
27
+ - **XQuery external variables** (libleptris 1.9.133) —
28
+ `XQuery#eval(doc, params)` binds `declare variable $x external`
29
+ through `leptris_xquery_eval_params` with QT3 `<param select>`
30
+ semantics (each value is an XPath expression in an empty
31
+ context); a binding overrides a default initializer, and an
32
+ empty params hash takes the same lane — the engine decides
33
+ between the default and failure.
34
+ - **`Element#expanded_name`** (libleptris 1.9.144) —
35
+ `{local:, prefix:, namespace_uri:}` in one C call.
36
+ - **`#xpath_versioned(expression, version)`** — version-pinned
37
+ evaluation via `leptris_xpath_eval_versioned`: `:xpath10`
38
+ keeps the strict 1.0 surface (3.x syntax raises), `:xpath31`
39
+ evaluates the full grammar. A separate method by design —
40
+ `#xpath`'s trailing-hash argument is the namespace-binding
41
+ channel.
42
+ - **`Node#digest(drop_ws:)`** — the #869 content-defined Merkle
43
+ digest behind diff pruning.
44
+ - **Serialization: `to_xml(..., expand_empty:)`** — the
45
+ `<e></e>` vs `<e/>` switch at the C seam.
46
+ - Engine arc: the W3C QT3 suite adoption (fn/substring 45/45,
47
+ fn/contains 41/41, fn/starts-with 43/43, fn/ends-with 34/34,
48
+ fn/concat 80/80 — int64 integer fidelity keeps
49
+ `xs:integer('999999999999999999')` exact) and the WHATWG HTML
50
+ completion arc (frameset, in-head-noscript, character
51
+ references, comment close forms, **full adoption agency**
52
+ 1.9.137 — `"<h1>a<h2>b</h1>c</h2>"` now yields
53
+ `<h1>a</h1><h2>b</h2>c` per the spec — initial-mode comment
54
+ placement, in-head comments, foreign-content integration
55
+ scopes, in-table clear-stack, script-data escapes, RCDATA/
56
+ rawtext, numeric-reference end states; html5lib floor
57
+ 928 → 933). #965: relational comparisons no longer swap
58
+ operands (`10 >= @n` compares as written).
59
+
8
60
  ## [1.9.115.0] - 2026-09-09
9
61
 
10
62
  ### Changed
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
8
8
  # Pin for `rake compile` and the platform-gem builds. Keep in lockstep
9
9
  # with .github/workflows/build.yml (which calls `rake compile`) and the
10
10
  # CHANGELOG when libleptris releases.
11
- LIBLEPTRIS_VERSION = "1.9.121"
11
+ LIBLEPTRIS_VERSION = "1.9.144"
12
12
  # Vendored alongside libleptris for fn:normalize-unicode (TODO
13
13
  # .restructure/20): built per platform with a RELOCATABLE @rpath
14
14
  # install name, loaded by ffi.rb before libleptris so the
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.121.0"
4
+ VERSION = "1.9.144.0"
5
5
  end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ # Tree diff between two documents (libleptris >= 1.9.126):
6
+ # equal subtrees prune in O(1) via the #869 content-defined Merkle
7
+ # digest; diverging regions align through an LCS on child digests,
8
+ # then same-named elements recurse. Attribute add/remove are
9
+ # UPDATE_ATTR ops with an empty side.
10
+ #
11
+ # diff = Leptris::XML.diff(before_doc, after_doc)
12
+ # diff.ops # => [{type: :update_text, name: "price",
13
+ # # path: "/r/item[2]/price", before: "3", after: "4"}, ...]
14
+ # diff.to_s # => serialized op list
15
+ # Leptris::XML.diff(a, b, ignore_ws: true) # ws-only text absent
16
+ #
17
+ class Leptris::XML::Diff
18
+ class Handle < ::FFI::AutoPointer
19
+ def self.release(ptr)
20
+ Leptris::XML::FFI.leptris_diff_free(ptr)
21
+ end
22
+ end
23
+
24
+ OP_TYPES = {
25
+ 1 => :insert,
26
+ 2 => :delete,
27
+ 3 => :update_text,
28
+ 4 => :update_attr,
29
+ }.freeze
30
+ private_constant :OP_TYPES
31
+
32
+ def self.compute(document_a, document_b, ignore_ws: false)
33
+ flags = ignore_ws ? 1 : 0
34
+ raw = Leptris::XML::FFI.leptris_diff(
35
+ document_a.c_ptr, document_b.c_ptr, flags, nil)
36
+ if raw.null?
37
+ raise Leptris::XML::Error,
38
+ "leptris_diff failed: #{Leptris::XML::FFI.leptris_last_error}"
39
+ end
40
+ new(Handle.new(raw))
41
+ end
42
+
43
+ # The boolean fast path canon-style consumers want: are the two
44
+ # trees structurally identical? Zero ops == identical — the
45
+ # digest pruning makes the common equal case O(1) per subtree.
46
+ def self.identical?(document_a, document_b, ignore_ws: false)
47
+ compute(document_a, document_b, ignore_ws: ignore_ws).ops.empty?
48
+ end
49
+
50
+ def initialize(handle)
51
+ @handle = handle
52
+ end
53
+
54
+ # The op list in document order: {type:, name:, path:, before:,
55
+ # after:} — paths are root-relative ("/r/i[2]"); before/after
56
+ # carry payloads (attribute values / text) where the op has them.
57
+ def ops
58
+ count = Leptris::XML::FFI.leptris_diff_op_count(@handle)
59
+ Array.new(count) do |i|
60
+ {
61
+ type: OP_TYPES[Leptris::XML::FFI.leptris_diff_op_type(@handle, i)],
62
+ name: Leptris::XML::FFI.leptris_diff_op_name(@handle, i),
63
+ path: Leptris::XML::FFI.leptris_diff_op_path(@handle, i),
64
+ before: Leptris::XML::FFI.leptris_diff_op_before(@handle, i),
65
+ after: Leptris::XML::FFI.leptris_diff_op_after(@handle, i),
66
+ }
67
+ end
68
+ end
69
+
70
+ def to_s
71
+ str_ptr = Leptris::XML::FFI.leptris_diff_serialize(@handle)
72
+ Leptris::XML::FFI.read_owned_string(str_ptr)
73
+ end
74
+ end
@@ -341,6 +341,30 @@ class Leptris::XML::Element < Leptris::XML::Node
341
341
  uri
342
342
  end
343
343
 
344
+ # The local name, prefix, and resolved namespace URI in ONE
345
+ # call (libleptris 1.9.144) — the adapter fan-out read.
346
+ # Equivalent to #name + #prefix + #namespace, single entry.
347
+ def expanded_name
348
+ ensure_alive!
349
+ local = ::FFI::MemoryPointer.new(:pointer)
350
+ prefix = ::FFI::MemoryPointer.new(:pointer)
351
+ uri = ::FFI::MemoryPointer.new(:pointer)
352
+ Leptris::XML::FFI.leptris_element_expanded_name(
353
+ @c_ptr, local, prefix, uri)
354
+ local_ptr = local.read_pointer
355
+ prefix_ptr = prefix.read_pointer
356
+ uri_ptr = uri.read_pointer
357
+ result = {
358
+ local: local_ptr.read_string,
359
+ prefix: prefix_ptr.null? ? nil : prefix_ptr.read_string,
360
+ namespace_uri: uri_ptr.null? ? nil : uri_ptr.read_string,
361
+ }
362
+ local.free
363
+ prefix.free
364
+ uri.free
365
+ result
366
+ end
367
+
344
368
  def namespace_definitions
345
369
  return @namespace_definitions if memo_hit?(@namespace_definitions_version)
346
370
  ensure_alive!
@@ -64,6 +64,8 @@ module Leptris
64
64
  typedef :pointer, :leptris_relaxng
65
65
  typedef :pointer, :leptris_xslt
66
66
  typedef :pointer, :leptris_xquery
67
+ typedef :pointer, :leptris_schematron
68
+ typedef :pointer, :leptris_diff
67
69
  typedef :pointer, :leptris_sax_recorder
68
70
  typedef :pointer, :leptris_pull_parser
69
71
  typedef :pointer, :leptris_iterparse
@@ -744,8 +746,72 @@ attach_function :leptris_parse_string,
744
746
  attach_function :leptris_xquery_eval,
745
747
  [:leptris_xquery, :leptris_document, :leptris_element],
746
748
  :leptris_xpath_result
749
+ # External-variable XQuery evaluation (libleptris 1.9.133):
750
+ # names[i]/selects[i] bind `declare variable $name external`
751
+ # — each select is an XPath expression in an empty context
752
+ # (QT3 <param select> semantics), overriding any default
753
+ # initializer. An external with neither binding nor default
754
+ # fails evaluation.
755
+ attach_function :leptris_xquery_eval_params,
756
+ [:leptris_xquery, :leptris_document, :leptris_element,
757
+ :pointer, :pointer, :size_t], :leptris_xpath_result
747
758
  attach_function :leptris_xquery_free, [:leptris_xquery], :void
748
759
 
760
+ # Schematron validation (libleptris >= 1.9.126 family):
761
+ # parse once (optionally selecting a PHASE), validate any
762
+ # number of documents — #validate returns the SVRL report as
763
+ # a Document; #valid? answers through the SVRL root name.
764
+ attach_function :leptris_schematron_parse,
765
+ [:string, :size_t, :pointer], :leptris_schematron
766
+ attach_function :leptris_schematron_parse_file,
767
+ [:string, :pointer], :leptris_schematron
768
+ attach_function :leptris_schematron_parse_phase,
769
+ [:string, :size_t, :string, :pointer], :leptris_schematron
770
+ attach_function :leptris_schematron_free,
771
+ [:leptris_schematron], :void
772
+ attach_function :leptris_schematron_valid,
773
+ [:leptris_schematron, :leptris_document], :int
774
+ attach_function :leptris_schematron_validate,
775
+ [:leptris_schematron, :leptris_document], :leptris_document
776
+ attach_function :leptris_schematron_error,
777
+ [:leptris_schematron], :string
778
+
779
+ # Tree diff (libleptris >= 1.9.126 family): equal subtrees
780
+ # prune in O(1) by the #869 Merkle digest; diverging regions
781
+ # align via LCS on child digests, then recurse by name.
782
+ attach_function :leptris_diff,
783
+ [:leptris_document, :leptris_document, :int, :pointer],
784
+ :leptris_diff
785
+ attach_function :leptris_diff_free, [:leptris_diff], :void
786
+ attach_function :leptris_diff_op_count, [:leptris_diff], :size_t
787
+ attach_function :leptris_diff_op_type,
788
+ [:leptris_diff, :size_t], :int
789
+ attach_function :leptris_diff_op_name,
790
+ [:leptris_diff, :size_t], :string
791
+ attach_function :leptris_diff_op_path,
792
+ [:leptris_diff, :size_t], :string
793
+ attach_function :leptris_diff_op_before,
794
+ [:leptris_diff, :size_t], :string
795
+ attach_function :leptris_diff_op_after,
796
+ [:leptris_diff, :size_t], :string
797
+ attach_function :leptris_diff_serialize,
798
+ [:leptris_diff], :pointer
799
+
800
+ # One-call expanded name (libleptris 1.9.144): local name +
801
+ # prefix + resolved namespace URI in a single entry — the
802
+ # FFI-adapter fan-out read.
803
+ attach_function :leptris_element_expanded_name,
804
+ [:leptris_element, :pointer, :pointer, :pointer], :void
805
+
806
+ # Versioned XPath evaluation (libleptris lane 15): XPATH_10
807
+ # keeps the strict 1.0 surface (3.x syntax rejected with
808
+ # INVALID_ARG); XPATH_31 evaluates the full grammar.
809
+ attach_function :leptris_xpath_eval_versioned,
810
+ [:leptris_document, :leptris_element, :string, :int, :pointer],
811
+ :leptris_xpath_result
812
+ XPATH_10 = 1 # strict XPath 1.0: the 3.x surface is rejected
813
+ XPATH_31 = 3 # the full grammar (the default entry's surface)
814
+
749
815
  # One-pass entity pre-scan (libleptris 1.9.62, leptris#745):
750
816
  # 1 when the buffer holds a named entity that is not one of
751
817
  # the five predefined XML entities (nor numeric) — the moxml
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ module Leptris::XML::Schematron
6
+ module_function
7
+
8
+ def parse(schema_xml, phase: nil)
9
+ Schema.parse(schema_xml, phase: phase)
10
+ end
11
+
12
+ def parse_file(path, phase: nil)
13
+ Schema.parse_file(path, phase: phase)
14
+ end
15
+
16
+ # A compiled Schematron schema (libleptris >= 1.9.126): parse
17
+ # once — optionally selecting a PHASE, which activates only its
18
+ # patterns — then validate any number of documents. #validate
19
+ # returns the SVRL report as a queryable Document; #valid?
20
+ # answers the boolean.
21
+ #
22
+ # sch = Leptris::XML::Schematron.parse(schema_xml)
23
+ # sch.valid?(doc) # => true/false
24
+ # svrl = sch.validate(doc) # => Document (svrl:schema root)
25
+ # sch = Leptris::XML::Schematron.parse(schema_xml, phase: "Basic")
26
+ #
27
+ class Schema
28
+ class Handle < ::FFI::AutoPointer
29
+ def self.release(ptr)
30
+ Leptris::XML::FFI.leptris_schematron_free(ptr)
31
+ end
32
+ end
33
+
34
+ def self.parse(schema_xml, phase: nil)
35
+ xml = schema_xml.to_s
36
+ raw =
37
+ if phase
38
+ Leptris::XML::FFI.leptris_schematron_parse_phase(
39
+ xml, xml.bytesize, phase.to_s, nil)
40
+ else
41
+ Leptris::XML::FFI.leptris_schematron_parse(xml, xml.bytesize, nil)
42
+ end
43
+ if raw.null?
44
+ raise Leptris::XML::Error,
45
+ "schema parse failed: #{Leptris::XML::FFI.leptris_last_error}"
46
+ end
47
+ new(Handle.new(raw))
48
+ end
49
+
50
+ def self.parse_file(path, phase: nil)
51
+ raw =
52
+ if phase
53
+ xml = File.read(path)
54
+ Leptris::XML::FFI.leptris_schematron_parse_phase(
55
+ xml, xml.bytesize, phase.to_s, nil)
56
+ else
57
+ Leptris::XML::FFI.leptris_schematron_parse_file(path.to_s, nil)
58
+ end
59
+ if raw.null?
60
+ raise Leptris::XML::Error,
61
+ "schema parse failed: #{Leptris::XML::FFI.leptris_last_error}"
62
+ end
63
+ new(Handle.new(raw))
64
+ end
65
+
66
+ def initialize(handle)
67
+ @handle = handle
68
+ end
69
+
70
+ # The SVRL report as a Document (svrl:schema root — query
71
+ # failed-assert / successful-report elements like any other
72
+ # tree), or the schema-level error text.
73
+ def validate(document)
74
+ report = Leptris::XML::FFI.leptris_schematron_validate(
75
+ @handle, document.c_ptr)
76
+ if report.null?
77
+ Leptris::XML::FFI.leptris_schematron_error(@handle)
78
+ else
79
+ Leptris::XML::Document.wrap(report)
80
+ end
81
+ end
82
+
83
+ def valid?(document)
84
+ Leptris::XML::FFI.leptris_schematron_valid(
85
+ @handle, document.c_ptr) != 0
86
+ end
87
+ end
88
+ end
@@ -85,6 +85,27 @@ module Leptris::XML::Searchable
85
85
  at_xpath(expr)
86
86
  end
87
87
 
88
+ # Version-pinned evaluation (libleptris lane 15,
89
+ # leptris_xpath_eval_versioned): :xpath10 keeps the strict XPath
90
+ # 1.0 surface — 3.x syntax (arrow, bang, lookup, let, inline
91
+ # functions, string templates) raises; :xpath31 evaluates the
92
+ # full grammar (identical to #xpath's default entry). A separate
93
+ # method by design: #xpath's trailing-hash argument is the
94
+ # namespace-binding channel, and a declared keyword would
95
+ # capture it.
96
+ def xpath_versioned(expression, version)
97
+ doc_ptr = is_a?(Leptris::XML::Document) ? c_ptr : document.c_ptr
98
+ context_ptr = is_a?(Leptris::XML::Document) ? nil : c_ptr
99
+ result_ptr = Leptris::XML::FFI.leptris_xpath_eval_versioned(
100
+ doc_ptr, context_ptr, expression,
101
+ Leptris::XML::Searchable.xpath_version_code(version), nil)
102
+ if result_ptr.null?
103
+ raise Leptris::XML::XPathError,
104
+ Leptris::XML::FFI.leptris_last_error.to_s
105
+ end
106
+ Leptris::XML::Searchable.wrap_xpath_result(document, result_ptr)
107
+ end
108
+
88
109
  protected
89
110
 
90
111
  # Evaluates against a caller-owned namespace binding set; the
@@ -95,6 +116,21 @@ module Leptris::XML::Searchable
95
116
  end
96
117
  end
97
118
 
119
+
120
+ # Version pin for xpath_versioned: :xpath10
121
+ # keeps the strict XPath 1.0 surface (3.x syntax — arrow, bang,
122
+ # lookup, let, inline functions — raises); :xpath31 evaluates the
123
+ # full grammar (identical to the default entry).
124
+ def self.xpath_version_code(version)
125
+ case version
126
+ when :xpath10, "1.0" then Leptris::XML::FFI::XPATH_10
127
+ when :xpath31, "3.1" then Leptris::XML::FFI::XPATH_31
128
+ else
129
+ raise ArgumentError,
130
+ "version must be :xpath10 or :xpath31, got #{version.inspect}"
131
+ end
132
+ end
133
+
98
134
  def parse_search_args(args)
99
135
  handler = args.find { |a| !a.is_a?(String) && !a.is_a?(Hash) && !a.is_a?(Symbol) }
100
136
  args = args - [handler] if handler
@@ -46,10 +46,28 @@ class Leptris::XML::XQuery
46
46
  # FLWOR results arrive as the sequence channel — read them through
47
47
  # an aggregate until the engine materializes readable sequence
48
48
  # items (same caveat as the XPath for-return subset).
49
- def eval(doc_or_element)
49
+ # +params+ binds external variables (libleptris 1.9.133): each
50
+ # value is an XPath expression evaluated in an empty context
51
+ # (QT3 <param select> semantics) — {"x" => "21 * 2"} binds
52
+ # `declare variable $x external`. A binding overrides the
53
+ # declaration's default initializer; an external with neither
54
+ # fails evaluation. An empty params hash takes the same lane —
55
+ # the engine decides between default initializer and failure.
56
+ def eval(doc_or_element, params = nil)
50
57
  context = Leptris::XML::EvaluationContext.of(doc_or_element)
51
- result_ptr = Leptris::XML::FFI.leptris_xquery_eval(
52
- @handle, context.document.c_ptr, context.context_node_ptr)
58
+ result_ptr =
59
+ if params
60
+ names, name_anchors = Leptris::XML::CStringArray.to_c(
61
+ params.keys.map(&:to_s))
62
+ selects, select_anchors = Leptris::XML::CStringArray.to_c(
63
+ params.values.map(&:to_s))
64
+ Leptris::XML::FFI.leptris_xquery_eval_params(
65
+ @handle, context.document.c_ptr, context.context_node_ptr,
66
+ names, selects, params.size)
67
+ else
68
+ Leptris::XML::FFI.leptris_xquery_eval(
69
+ @handle, context.document.c_ptr, context.context_node_ptr)
70
+ end
53
71
  if result_ptr.null?
54
72
  raise Leptris::XML::XPathError,
55
73
  Leptris::XML::FFI.leptris_last_error.to_s
data/lib/leptris/xml.rb CHANGED
@@ -23,6 +23,8 @@ module Leptris
23
23
  autoload :SAX, "leptris/xml/sax"
24
24
  autoload :XPath, "leptris/xml/xpath"
25
25
  autoload :EvaluationContext, "leptris/xml/evaluation_context"
26
+ autoload :Schematron, "leptris/xml/schematron"
27
+ autoload :Diff, "leptris/xml/diff"
26
28
  autoload :IterationScope, "leptris/xml/iteration_scope"
27
29
  autoload :ResultText, "leptris/xml/result_text"
28
30
  autoload :ResultAttr, "leptris/xml/result_attr"
@@ -39,6 +41,14 @@ module Leptris
39
41
  recover: recover)
40
42
  end
41
43
 
44
+ # Tree diff between two documents: equal subtrees prune in
45
+ # O(1) by content digest; diverging regions align by LCS.
46
+ # +ignore_ws+ treats whitespace-only text nodes as absent.
47
+ def self.diff(document_a, document_b, ignore_ws: false)
48
+ Leptris::XML::Diff.compute(document_a, document_b,
49
+ ignore_ws: ignore_ws)
50
+ end
51
+
42
52
  # Does +string+ contain a named entity reference that is not
43
53
  # one of the five predefined XML entities (nor numeric)? One C
44
54
  # pass (libleptris 1.9.62) — downstream adapters use it to skip
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.121.0
4
+ version: 1.9.144.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-09 00:00:00.000000000 Z
11
+ date: 2026-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -106,6 +106,7 @@ files:
106
106
  - lib/leptris/xml/cdata.rb
107
107
  - lib/leptris/xml/comment.rb
108
108
  - lib/leptris/xml/css_to_xpath.rb
109
+ - lib/leptris/xml/diff.rb
109
110
  - lib/leptris/xml/doc_type.rb
110
111
  - lib/leptris/xml/document.rb
111
112
  - lib/leptris/xml/document_fragment.rb
@@ -128,6 +129,7 @@ files:
128
129
  - lib/leptris/xml/sax/dom_dispatch.rb
129
130
  - lib/leptris/xml/sax/parser.rb
130
131
  - lib/leptris/xml/sax/recorder.rb
132
+ - lib/leptris/xml/schematron.rb
131
133
  - lib/leptris/xml/searchable.rb
132
134
  - lib/leptris/xml/serialization.rb
133
135
  - lib/leptris/xml/text.rb