leptris 1.9.174.10 → 1.9.177.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0e347192431e6ed3ff15bed0fca55fb103ba7307a33d889014e72c3ece0dba8
4
- data.tar.gz: f7edb28afa62063bbc1f0ab2cfcc349619a8944249f69f41b40e054e016b5b45
3
+ metadata.gz: 9144461ce7cc58b12f57c1a5c497336f5712568654db476342b32b9d6d35dc93
4
+ data.tar.gz: a6fe5f35bf5891c3794f8bf5533c115b26b9eb19545d361aeafcb3b9b1935af0
5
5
  SHA512:
6
- metadata.gz: 660309e07c7ce84a4a68bdca9c46a1970f0af6a1bd2e316acca600de60cf54cbd445cd0814232593dd1752f59965d7df8ede74c14da977005b48cbec4ec276fd
7
- data.tar.gz: ffe8c0e4f6fc98f4bda50187b3c740e278aae6c82ec384f1ac6843673276b916910a1ab72a4c740a69e0006992418c83eb92280a619b18fac69c8568f5b7639e
6
+ metadata.gz: ee1362b97425fd76000f28d3232badcb7dd23d979e992cfd296ca17ee6bddeb716bd93b01830f22fd17103475cbfa4eccbcc918691625982fe4b79ca760de897
7
+ data.tar.gz: e1079b8c90d48d43e17d7ad3e7ebb55a8cbf87246cd61d0eed9eb2a44fc7c3cc91e5f2c034843ee1914f818d1c686b9596b433f96f2e22795fe02a005a75c21b
data/CHANGELOG.md CHANGED
@@ -5,6 +5,35 @@ 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.177.0] - 2026-09-16
9
+
10
+ ### Changed — libleptris 1.9.174 → 1.9.177 (lockstep)
11
+
12
+ - **Node-surface parity (upstream #1094, #212 — the big one)**:
13
+ entity references (`&name;` stays a first-class
14
+ `EntityReference` node under the new
15
+ `ParseOptions.keep_entity_refs` flag — text splits around them,
16
+ character references still expand, serialization is verbatim;
17
+ `Document#create_entity_reference`), the XML declaration
18
+ (`xml_version`/`xml_encoding`/`xml_standalone` readers and
19
+ writers — `#version` stays the mutation counter), programmatic
20
+ DOCTYPE (`Document#set_doctype` with PUBLIC/SYSTEM ids,
21
+ serializing in document position), and document-PI parity
22
+ (`add_pi` returns the PI node with identity and epilog
23
+ anchoring; `Document#remove_child` removes PIs/comments). The
24
+ ext's kind dispatch knows the new node kind.
25
+ - **C14N: redundant namespace redeclarations omitted** (upstream
26
+ #1096) — spec-pinned.
27
+ - **Document lifecycle** (upstream #1093): pool destroy parks the
28
+ arenas — the fresh-doc build row's teardown share should drop;
29
+ clean-host battery pending.
30
+ - XSLT/XPath/HTML perf + conformance run (1.9.175-177).
31
+
32
+ ### Added
33
+
34
+ - `Leptris::XML::EntityReference`, the ten new FFI faces, the
35
+ `KEEP_ENTITY_REFS` parse flag.
36
+
8
37
  ## [1.9.174.10] - 2026-09-16
9
38
 
10
39
  ### 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.174"
11
+ LIBLEPTRIS_VERSION = "1.9.177"
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
@@ -1212,7 +1212,8 @@ static VALUE nn_address(VALUE self)
1212
1212
  * Init; the per-node Ruby frames (wrap/construct/memo/alive)
1213
1213
  * disappear. */
1214
1214
  static VALUE c_b_element = Qundef, c_b_text, c_b_comment, c_b_cdata,
1215
- c_b_pi, c_b_node, c_b_result_text, c_b_result_attr,
1215
+ c_b_pi, c_b_entity_ref, c_b_node, c_b_result_text,
1216
+ c_b_result_attr,
1216
1217
  c_b_attr, c_ffi_pointer, c_b_document, c_b_freed;
1217
1218
  static VALUE c_iteration_scope;
1218
1219
  static ID id_ptr_new;
@@ -1229,6 +1230,7 @@ static void resolve_binding_classes(void)
1229
1230
  c_b_comment = rb_path2class("Leptris::XML::Comment");
1230
1231
  c_b_cdata = rb_path2class("Leptris::XML::CDATA");
1231
1232
  c_b_pi = rb_path2class("Leptris::XML::ProcessingInstruction");
1233
+ c_b_entity_ref = rb_path2class("Leptris::XML::EntityReference");
1232
1234
  c_b_node = rb_path2class("Leptris::XML::Node");
1233
1235
  c_b_result_text = rb_path2class("Leptris::XML::ResultText");
1234
1236
  c_b_result_attr = rb_path2class("Leptris::XML::ResultAttr");
@@ -1244,6 +1246,7 @@ static void resolve_binding_classes(void)
1244
1246
  rb_gc_register_mark_object(c_b_comment);
1245
1247
  rb_gc_register_mark_object(c_b_cdata);
1246
1248
  rb_gc_register_mark_object(c_b_pi);
1249
+ rb_gc_register_mark_object(c_b_entity_ref);
1247
1250
  rb_gc_register_mark_object(c_b_node);
1248
1251
  rb_gc_register_mark_object(c_b_result_text);
1249
1252
  rb_gc_register_mark_object(c_b_result_attr);
@@ -1263,6 +1266,7 @@ static VALUE binding_klass_for(int kind)
1263
1266
  case 2: return c_b_comment;
1264
1267
  case 3: return c_b_cdata;
1265
1268
  case 4: return c_b_pi;
1269
+ case 10: return c_b_entity_ref; /* #212 / upstream #1094 */
1266
1270
  default: return c_b_node;
1267
1271
  }
1268
1272
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.174.10"
4
+ VERSION = "1.9.177.0"
5
5
  end
@@ -505,15 +505,82 @@ class Leptris::XML::Document
505
505
  Leptris::XML::Node.wrap(ptr, self)
506
506
  end
507
507
 
508
- # Append a document-level processing instruction. Returns self.
508
+ # Append a document-level processing instruction. Returns the PI
509
+ # node (epilog anchor — after the root; identity via
510
+ # leptris_document_append_pi, libleptris 1.9.176 / #212).
509
511
  def add_pi(target, data = "")
510
- witness = Leptris::XML::FFI.leptris_document_add_pi(
512
+ witness = Leptris::XML::FFI.leptris_document_append_pi(
511
513
  c_ptr, target.to_s, data.to_s)
512
- raise Leptris::XML::Error, "leptris_document_add_pi failed" if witness.null?
514
+ raise Leptris::XML::Error, "leptris_document_append_pi failed" if witness.null?
515
+ @version += 1
516
+ Leptris::XML::Node.wrap(witness, self)
517
+ end
518
+
519
+ # Remove a document-level PI or comment from the document
520
+ # children chain (libleptris 1.9.176 / #212). The node stays
521
+ # document-owned. Raises when the node is not in the chain.
522
+ def remove_child(node)
523
+ Leptris::XML::FFI.check_status(
524
+ Leptris::XML::FFI.leptris_document_remove_child(c_ptr, node.c_ptr))
513
525
  @version += 1
514
526
  self
515
527
  end
516
528
 
529
+ # Create an &name; entity reference node (libleptris 1.9.176 /
530
+ # #212): serializes back verbatim once attached.
531
+ def create_entity_reference(name)
532
+ ptr = Leptris::XML::FFI.leptris_entity_ref_node_create(
533
+ c_ptr, name.to_s)
534
+ raise Leptris::XML::Error, "leptris_entity_ref_node_create failed" if ptr.null?
535
+ Leptris::XML::Node.wrap_fresh(ptr, self, Leptris::XML::FFI::NODE_ENTITY_REF)
536
+ end
537
+
538
+ # The XML declaration (libleptris 1.9.176 / #212). `#version`
539
+ # stays the mutation counter — the declaration reads are
540
+ # xml_-prefixed.
541
+ def xml_version
542
+ Leptris::XML::FFI.leptris_document_version(c_ptr)
543
+ end
544
+
545
+ def xml_standalone
546
+ v = Leptris::XML::FFI.leptris_document_standalone(c_ptr)
547
+ v < 0 ? nil : (v == 1)
548
+ end
549
+
550
+ def xml_encoding
551
+ Leptris::XML::FFI.leptris_document_encoding(c_ptr)
552
+ end
553
+
554
+ def xml_version=(value)
555
+ Leptris::XML::FFI.check_status(
556
+ Leptris::XML::FFI.leptris_document_set_version(c_ptr, value.to_s))
557
+ value
558
+ end
559
+
560
+ def xml_encoding=(value)
561
+ Leptris::XML::FFI.check_status(
562
+ Leptris::XML::FFI.leptris_document_set_encoding(c_ptr, value.to_s))
563
+ value
564
+ end
565
+
566
+ def xml_standalone=(value)
567
+ Leptris::XML::FFI.check_status(
568
+ Leptris::XML::FFI.leptris_document_set_standalone(c_ptr,
569
+ value.nil? ? -1 : (value ? 1 : 0)))
570
+ value
571
+ end
572
+
573
+ # Programmatic DOCTYPE (libleptris 1.9.176 / #212): create and
574
+ # set the document's DOCTYPE (root name + optional PUBLIC/SYSTEM
575
+ # ids); serializes in document position. Returns the DocType.
576
+ def set_doctype(name, public_id: nil, system_id: nil)
577
+ dt = Leptris::XML::FFI.leptris_document_set_doctype(
578
+ c_ptr, name.to_s, public_id, system_id)
579
+ raise Leptris::XML::Error, "leptris_document_set_doctype failed" if dt.null?
580
+ @version += 1
581
+ Leptris::XML::DocType.new(dt, self)
582
+ end
583
+
517
584
  # Append a document-level comment (epilog position, after the
518
585
  # root element) — the add_pi twin (libleptris 1.9.160, #1032;
519
586
  # parsed document-level comments round-tripped since 1.9.3/#578,
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # An unexpanded &name; entity reference — a first-class node when
4
+ # parsing with ParseOptions.keep_entity_refs (libleptris 1.9.176,
5
+ # upstream #1094 / leptris-ruby#212), or created via
6
+ # Document#create_entity_reference. Serializes back verbatim as
7
+ # &name;; text runs around it split into their own Text siblings.
8
+ class Leptris::XML::EntityReference < Leptris::XML::Node
9
+ def name
10
+ Leptris::XML::FFI.leptris_entity_ref_node_name(c_ptr)
11
+ end
12
+ alias_method :node_name, :name
13
+ end
@@ -337,6 +337,29 @@ attach_function :leptris_parse_string,
337
337
  # node_first_child without the intermediate handle).
338
338
  attach_function :leptris_document_first_child,
339
339
  [:leptris_document], :leptris_node_ref
340
+ # Node-surface parity (libleptris 1.9.176, upstream #1094,
341
+ # leptris-ruby#212): entity references, the XML declaration,
342
+ # programmatic DOCTYPE, and document-PI identity/removal.
343
+ attach_function :leptris_entity_ref_node_create,
344
+ [:leptris_document, :string], :leptris_node_ref
345
+ attach_function :leptris_entity_ref_node_name,
346
+ [:leptris_node_ref], :string
347
+ attach_function :leptris_document_version,
348
+ [:leptris_document], :string
349
+ attach_function :leptris_document_standalone,
350
+ [:leptris_document], :int
351
+ attach_function :leptris_document_set_version,
352
+ [:leptris_document, :string], :leptris_status
353
+ attach_function :leptris_document_set_encoding,
354
+ [:leptris_document, :string], :leptris_status
355
+ attach_function :leptris_document_set_standalone,
356
+ [:leptris_document, :int], :leptris_status
357
+ attach_function :leptris_document_set_doctype,
358
+ [:leptris_document, :string, :string, :string], :leptris_doctype
359
+ attach_function :leptris_document_append_pi,
360
+ [:leptris_document, :string, :string], :leptris_node_ref
361
+ attach_function :leptris_document_remove_child,
362
+ [:leptris_document, :leptris_node_ref], :leptris_status
340
363
  # Wrap-free subtree visitation (1.9.20, upstream #645a):
341
364
  # enter/leave pairs for elements, depth from the walk's root,
342
365
  # one C call — no NodeSet/Array churn per level. The document
@@ -1070,11 +1093,15 @@ attach_function :leptris_parse_string,
1070
1093
  NODE_COMMENT = 2
1071
1094
  NODE_CDATA = 3
1072
1095
  NODE_PI = 4
1096
+ NODE_ENTITY_REF = 10
1073
1097
  # Internal XPath-synthetic text node (leptris/types.h): the
1074
1098
  # carrier for sequence/map/array items in result nodesets —
1075
1099
  # readable only through the result handle, so the binding
1076
1100
  # captures the value at materialization (ResultText).
1077
1101
  NODE_SYNTHETIC_TEXT = 8
1102
+ # #1094: &name; references stay unexpanded first-class nodes
1103
+ # when this flag parses (character references still expand).
1104
+ LEPTRIS_PARSE_KEEP_ENTITY_REFS = 4
1078
1105
  NODE_DOCTYPE = 5
1079
1106
  NODE_ATTRIBUTE = 6
1080
1107
 
@@ -132,6 +132,8 @@ class Leptris::XML::Node
132
132
  Leptris::XML::CDATA.new(c_ptr, document, parent: parent, node_type: node_type)
133
133
  when Leptris::XML::FFI::NODE_PI
134
134
  Leptris::XML::ProcessingInstruction.new(c_ptr, document, parent: parent, node_type: node_type)
135
+ when Leptris::XML::FFI::NODE_ENTITY_REF
136
+ Leptris::XML::EntityReference.new(c_ptr, document, parent: parent, node_type: node_type)
135
137
  else
136
138
  new(c_ptr, document, parent: parent, node_type: node_type)
137
139
  end
@@ -17,6 +17,13 @@ class Leptris::XML::ParseOptions
17
17
  # defaulted attributes.
18
18
  DTDATTR = Leptris::XML::FFI::LEPTRIS_PARSE_DTDATTR
19
19
 
20
+ # Keep &name; entity references unexpanded as first-class
21
+ # EntityReference nodes (libleptris 1.9.176, upstream #1094 /
22
+ # leptris-ruby#212): text runs split around them, character
23
+ # references still expand, and the references serialize back
24
+ # verbatim.
25
+ KEEP_ENTITY_REFS = Leptris::XML::FFI::LEPTRIS_PARSE_KEEP_ENTITY_REFS
26
+
20
27
  attr_reader :flags
21
28
 
22
29
  # Recover (libleptris 1.9.0, #547): a parse failure returns an
@@ -32,6 +39,10 @@ class Leptris::XML::ParseOptions
32
39
  @recover = recover ? true : false
33
40
  end
34
41
 
42
+ def self.keep_entity_refs
43
+ new(KEEP_ENTITY_REFS)
44
+ end
45
+
35
46
  def self.noblanks
36
47
  new(NOBLANKS)
37
48
  end
@@ -52,6 +63,10 @@ class Leptris::XML::ParseOptions
52
63
  @flags & DTDATTR != 0
53
64
  end
54
65
 
66
+ def keep_entity_refs?
67
+ @flags & KEEP_ENTITY_REFS != 0
68
+ end
69
+
55
70
  def dtdattr=(value)
56
71
  if value then @flags |= DTDATTR else @flags &= ~DTDATTR end
57
72
  end
data/lib/leptris/xml.rb CHANGED
@@ -9,6 +9,7 @@ module Leptris
9
9
  autoload :Comment, "leptris/xml/comment"
10
10
  autoload :CDATA, "leptris/xml/cdata"
11
11
  autoload :ProcessingInstruction, "leptris/xml/processing_instruction"
12
+ autoload :EntityReference, "leptris/xml/entity_reference"
12
13
  autoload :Attr, "leptris/xml/attr"
13
14
  autoload :Namespace, "leptris/xml/namespace"
14
15
  autoload :Document, "leptris/xml/document"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.174.10
4
+ version: 1.9.177.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -164,6 +164,7 @@ files:
164
164
  - lib/leptris/xml/document.rb
165
165
  - lib/leptris/xml/document_fragment.rb
166
166
  - lib/leptris/xml/element.rb
167
+ - lib/leptris/xml/entity_reference.rb
167
168
  - lib/leptris/xml/evaluation_context.rb
168
169
  - lib/leptris/xml/ffi.rb
169
170
  - lib/leptris/xml/iteration_scope.rb