leptris 1.9.51 → 1.9.52
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.adoc +43 -7
- data/Rakefile +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/element.rb +5 -4
- data/lib/leptris/xml/node.rb +5 -4
- data/lib/leptris/xml/serialization.rb +4 -5
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce439698a32a7737054564af4f25866e9d49b87a86f30dee916e6d04f53e8249
|
|
4
|
+
data.tar.gz: 947ef61ce70fd53664851fe073d7504b1a2c28a59591e2b7c04ea482bcbed605
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c56ca957ac03806e595f8702cf4936b5303bf51761196d9b3bc9fb2aa84fb1023becb48520e59e8ec09defc5e482e8db929ecab787fc8925754ac182eaa7a2b2
|
|
7
|
+
data.tar.gz: 04b5685bb317af87788e52425b8b8f66b2e9b77f1d5488f65354b6631285695be22a746b6536024f4b5172d63765b6ea196d4a2de74f627e86cccf6f92365967
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,48 @@ 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.52] - 2026-09-02
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Lockstep with libleptris 1.9.43** (1.9.37 → 1.9.43; no new C
|
|
13
|
+
surface — the audit holds at 255/255 attached == exported):
|
|
14
|
+
- 1.9.37: tunnel parameters (§11.7) — `xsl:with-param
|
|
15
|
+
tunnel="yes"` persists for the whole subtree, including the
|
|
16
|
+
built-in unmatched-node path. This work also fixed the
|
|
17
|
+
`shallow-skip`/`text-only-copy` subtree drop (leptris/leptris#705).
|
|
18
|
+
- 1.9.38: regex trio atomizes node arguments (#691); single-item
|
|
19
|
+
atomic `xsl:sequence` serializes (#685 remainder); #705 verified
|
|
20
|
+
against a live Saxon-HE 12.7 oracle — all four reported shapes
|
|
21
|
+
pinned, with the correction that the no-template case emits
|
|
22
|
+
EMPTY for both dispositions (the report's `312` expectation
|
|
23
|
+
contradicted Saxon).
|
|
24
|
+
- 1.9.39: `leptris_element_copy` keeps COMMENT and PI children
|
|
25
|
+
(leptris/leptris#696) — pinned with a C-level spec.
|
|
26
|
+
- 1.9.40: fn: date slice (#691-E) — `xs:date`/`xs:dateTime`/
|
|
27
|
+
`xs:time`/`xs:duration` constructors and component extractors.
|
|
28
|
+
- 1.9.41: `switch` rejected like Saxon (XPST0003 pattern-only);
|
|
29
|
+
the #692 brace guard now runs the compiler first — map
|
|
30
|
+
constructors and `try/catch` raise cleanly in XPath expression
|
|
31
|
+
context instead of returning empty silently.
|
|
32
|
+
- 1.9.42: `xsl:where-populated`, `xsl:on-non-empty`,
|
|
33
|
+
`xsl:next-match` (#690/#685).
|
|
34
|
+
- 1.9.43: `xsl:fork`, `xsl:number @start-at`, composite keys
|
|
35
|
+
(#690/#685).
|
|
36
|
+
- Nine new specs cover the above through the generic
|
|
37
|
+
`XSLT.parse/apply_to` face; the two pending #705 disposition
|
|
38
|
+
specs are un-pending with the Saxon-verified expectations.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- **`dup` keeps the serialization round-trip** (leptris/leptris#721,
|
|
43
|
+
filed this round): with #696 fixed upstream, the C copy now
|
|
44
|
+
keeps comment/PI children — but it drops namespace prefixes and
|
|
45
|
+
declarations outright (`leptris_element_namespace` resolves NULL
|
|
46
|
+
after a copy), while the round-trip preserves them byte-for-byte.
|
|
47
|
+
The dup sites' comments now carry the #721 rationale; the revert
|
|
48
|
+
to the C fast path waits on #721.
|
|
49
|
+
|
|
8
50
|
## [1.9.51] - 2026-09-01
|
|
9
51
|
|
|
10
52
|
### Changed
|
data/README.adoc
CHANGED
|
@@ -9,7 +9,9 @@ A Nokogiri-compatible Ruby binding for
|
|
|
9
9
|
https://github.com/leptris/leptris[libleptris], a pure-C99 XML 1.0 parser
|
|
10
10
|
with full https://www.w3.org/TR/1999/REC-xpath-19991116/[XPath 1.0],
|
|
11
11
|
XML Namespaces 1.0, SAX, and C14N (1.0 / 1.1 / Exclusive), plus
|
|
12
|
-
XSLT 1.0–3.0 transforms (the XPath 3.1 core rides inside them)
|
|
12
|
+
XSLT 1.0–3.0 transforms (the XPath 3.1 core rides inside them) and a
|
|
13
|
+
growing XPath 2/3.1 expression subset available standalone from
|
|
14
|
+
`#xpath` itself.
|
|
13
15
|
|
|
14
16
|
The C DOM is the single source of truth — Ruby objects are thin FFI
|
|
15
17
|
handles over the C pointers, so every Ruby method maps to one FFI call.
|
|
@@ -225,6 +227,30 @@ XPath result type follows XPath 1.0 semantics:
|
|
|
225
227
|
`count(...)` → `Float`, `boolean(...)` → `true`/`false`,
|
|
226
228
|
`string(...)` → `String`, otherwise a `Leptris::XML::NodeSet`.
|
|
227
229
|
|
|
230
|
+
Beyond XPath 1.0, the engine accepts a growing XPath 2/3.1
|
|
231
|
+
expression subset standalone — no stylesheet required:
|
|
232
|
+
|
|
233
|
+
[source,ruby]
|
|
234
|
+
----
|
|
235
|
+
doc.xpath("let $n := count(//book) return $n + 1") # => 3.0
|
|
236
|
+
doc.xpath("for $b in //book return count($b/*)") # sequence
|
|
237
|
+
doc.xpath("if (count(//book) = 2) then 'two' else '?'")
|
|
238
|
+
doc.xpath("count(1 to 4)") # => 4.0
|
|
239
|
+
doc.xpath("//book => count()") # 3.1 arrow
|
|
240
|
+
doc.xpath("//title ! string(.)") # 3.1 simple map
|
|
241
|
+
doc.xpath("'v' || count(//book)") # 3.1 concat
|
|
242
|
+
----
|
|
243
|
+
|
|
244
|
+
Two caveats: `for … return` sequences come back as opaque result
|
|
245
|
+
nodes — consume them through an aggregate (`count(...)`,
|
|
246
|
+
`string-join(...)`) until the engine materializes readable sequence
|
|
247
|
+
items; and XQuery-only syntax (`order by`, `try/catch`, map
|
|
248
|
+
constructors) raises `XPathError` rather than evaluating silently
|
|
249
|
+
wrong. The remaining grammar gaps — value comparators (`eq`),
|
|
250
|
+
quantifiers, sequence types (`instance of`), `intersect`/`except`,
|
|
251
|
+
string templates — and XQuery itself are
|
|
252
|
+
https://github.com/leptris/leptris/issues/683[tracked upstream].
|
|
253
|
+
|
|
228
254
|
=== Supported CSS selectors
|
|
229
255
|
|
|
230
256
|
Minimal subset (translated to XPath via `Leptris::XML::CssToXPath`):
|
|
@@ -339,11 +365,20 @@ result = style.apply_to(doc) # => Document
|
|
|
339
365
|
style.serialize(doc) # => String
|
|
340
366
|
----
|
|
341
367
|
|
|
342
|
-
The engine dispatches on the stylesheet's declared version
|
|
343
|
-
instruction set
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
368
|
+
The engine dispatches on the stylesheet's declared version. XSLT
|
|
369
|
+
1.0 is complete; the 3.0 instruction set has grown through
|
|
370
|
+
libleptris 1.9.36 — grouping, `xsl:accumulator`,
|
|
371
|
+
`xsl:analyze-string`, `xsl:mode/@on-no-match` dispositions,
|
|
372
|
+
`xsl:sequence`, `xsl:perform-sort`, and `fn:format-integer` — with
|
|
373
|
+
the XPath 3.1 core expressions available inside transforms (see
|
|
374
|
+
the subset list under <<Searching: XPath and CSS>>; value
|
|
375
|
+
comparators and sequence types are still out,
|
|
376
|
+
https://github.com/leptris/leptris/issues/683[tracked upstream]).
|
|
377
|
+
Known engine bug: the `shallow-skip` and `text-only-copy`
|
|
378
|
+
dispositions drop unmatched subtrees in the built-in initial
|
|
379
|
+
descent (https://github.com/leptris/leptris/issues/705[#705]) —
|
|
380
|
+
the other four dispositions are spec-correct. XQuery has no
|
|
381
|
+
entry point yet.
|
|
347
382
|
`Document#save(path, **opts)` :: serialize to a file.
|
|
348
383
|
`Document#canonicalize(version, inclusive_ns, with_comments:, exclusive:, mode:)` (alias `#c14n`) :: canonical XML.
|
|
349
384
|
`Element#canonicalize(...)` :: subtree canonicalization.
|
|
@@ -510,7 +545,8 @@ Notable differences:
|
|
|
510
545
|
past Document disposal will see the error; silence-replace-UAF patterns
|
|
511
546
|
from Nokogiri do not apply.
|
|
512
547
|
* No `Nokogiri::HTML` or `Nokogiri::CSS` parser. Leptris is XML-only.
|
|
513
|
-
* No
|
|
548
|
+
* No XQuery, no RelaxNG / DTD validation, no schema caching
|
|
549
|
+
(XSLT 1.0–3.0 is supported — see above).
|
|
514
550
|
* No built-in JRuby / TruffleRuby support — only CRuby via `ffi`.
|
|
515
551
|
|
|
516
552
|
== Performance
|
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.
|
|
11
|
+
LIBLEPTRIS_VERSION = "1.9.43"
|
|
12
12
|
|
|
13
13
|
CMAKE_FLAGS = %w[
|
|
14
14
|
-DCMAKE_BUILD_TYPE=Release
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/element.rb
CHANGED
|
@@ -252,10 +252,11 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
252
252
|
end
|
|
253
253
|
|
|
254
254
|
# Deep copy in a NEW document, via serialization round-trip:
|
|
255
|
-
# leptris_element_copy
|
|
256
|
-
# (leptris/leptris#
|
|
257
|
-
#
|
|
258
|
-
#
|
|
255
|
+
# leptris_element_copy drops namespace prefixes and declarations
|
|
256
|
+
# outright (leptris/leptris#721; its comment/PI child drop was
|
|
257
|
+
# #696, fixed upstream in 1.9.39) — the serializer preserves
|
|
258
|
+
# every child kind, prefixed names, and namespace declarations,
|
|
259
|
+
# and re-parsing rebuilds them all.
|
|
259
260
|
def dup
|
|
260
261
|
ensure_alive!
|
|
261
262
|
Leptris::XML::Document.parse(to_xml).root
|
data/lib/leptris/xml/node.rb
CHANGED
|
@@ -370,10 +370,11 @@ class Leptris::XML::Node
|
|
|
370
370
|
end
|
|
371
371
|
|
|
372
372
|
# Deep copy in a NEW document. Rounds through serialization
|
|
373
|
-
# rather than leptris_element_copy: the C copy
|
|
374
|
-
#
|
|
375
|
-
#
|
|
376
|
-
#
|
|
373
|
+
# rather than leptris_element_copy: the C copy drops namespace
|
|
374
|
+
# prefixes and declarations outright (leptris/leptris#721; the
|
|
375
|
+
# comment/PI child drop was #696, fixed upstream in 1.9.39) —
|
|
376
|
+
# the serializer preserves every child kind, prefixed names, and
|
|
377
|
+
# namespace declarations, and re-parsing rebuilds them all.
|
|
377
378
|
def dup
|
|
378
379
|
ensure_alive!
|
|
379
380
|
elem_ptr = Leptris::XML::FFI.leptris_node_as_element(@c_ptr)
|
|
@@ -98,11 +98,10 @@ module Leptris::XML::Serialization
|
|
|
98
98
|
# Element-face indent unit (leptris-ruby#109 residual 2): no
|
|
99
99
|
# element-level ext-serialize entry exists yet, so the unit path
|
|
100
100
|
# rounds the subtree through serialization into a fresh document
|
|
101
|
-
# (leptris_element_copy drops
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
#
|
|
105
|
-
# every child kind intact.
|
|
101
|
+
# (leptris_element_copy drops namespaces — leptris/leptris#721)
|
|
102
|
+
# and serializes that document without a declaration — identical
|
|
103
|
+
# output to the element serializer for the standard layout, with
|
|
104
|
+
# the unit and every child kind intact.
|
|
106
105
|
def self.to_xml_element_unit(element, unit, indent: 0)
|
|
107
106
|
document = Leptris::XML::Document.parse(element.to_xml)
|
|
108
107
|
begin
|
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.
|
|
4
|
+
version: 1.9.52
|
|
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-
|
|
11
|
+
date: 2026-09-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|