sevgi-standard 0.95.0 → 0.98.2

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: bbd8aa9bd86beedb621d7f5a2231821c3e33e15f038a6b9b858764fc6789e16e
4
- data.tar.gz: c2aa30f2b04fe0b7769667223902ba92d17aa99e3e5d182d79c24ec5fbf53961
3
+ metadata.gz: 3787ffa0eaba0ccbed4e09617d690e86bd573e582a998c66f9c3aaaff1a0e5ea
4
+ data.tar.gz: 0afd16d8886430a82f8294ebaeccb320adec60a6265a9ced7e765116fe74b48e
5
5
  SHA512:
6
- metadata.gz: e180e41124e5579fef07b58ff3fb7b54371feebd118919a33ca1720bf3d50623d4accdd419d0465df0721b16ca866a9722a8196177d5aa1c7194ef8093fc906d
7
- data.tar.gz: a28509223d1ec39ff0feb51d60df71f4a1b3c1d459173d596f67f7c76a8a1a2c06457f6d60fd1ce1b2e16786ea0ffd7bc89ac49e1a928750a9a6c3c7b79b7fb0
6
+ metadata.gz: 928b65a3adaf1c1bf5eb5a75de77989fe7574fdb037833dea0986a08e1f89466dbe879ab28327fa14ed513bc897be0535d10ae507bc0a95ab4c8a05b4cd3d413
7
+ data.tar.gz: b7016a3f90576b7e0e669a0b569a86689d95197ec06500b242b1f1f9ae79cf871f37796d4dc32ff1df517fd84bf2062a1aefda2759d858d59dd67a08284aab3d
data/CHANGELOG.md CHANGED
@@ -5,6 +5,131 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 0.98.2 - 2026-07-25
9
+
10
+ ### Fixed
11
+
12
+ - Restored the `sevgi` CLI's main-object scope so bare toolkit calls remain available inside script helper classes.
13
+
14
+ ## 0.98.1 - 2026-07-20
15
+
16
+ ### Changed
17
+
18
+ - Changed the `sevgi` CLI to use the executor's isolated scope by default.
19
+
20
+ ### Removed
21
+
22
+ - Removed the redundant `-n` and `--nomain` CLI options; library consumers can still select `main: true` through
23
+ `Sevgi.execute` and `Sevgi.execute_file` when needed.
24
+
25
+ ## 0.98.0 - 2026-07-20
26
+
27
+ ### Added
28
+
29
+ - Added standard-input support to `sevgi`, `igves`, and `igsev`; `sevgi --as NAME` and
30
+ `Sevgi.execute_file(..., as: NAME)` supply the logical source basename used by implicit SVG, PDF, and PNG
31
+ destinations without changing physical load identity.
32
+
33
+ ## 0.97.0 - 2026-07-19
34
+
35
+ ### Added
36
+
37
+ - Added `sevgi-appendix`, containing the Sevgi agent skill and a RuboCop plugin for preserving readable `.sevgi` DSL
38
+ source alongside rubyfmt-formatted Ruby; the umbrella `sevgi` gem installs the matching Appendix version.
39
+ - Added `sevgi --skill` to report the validated path of the matching packaged agent skill for product-neutral setup.
40
+ - Added `igsev` to the umbrella gem for normalizing an SVG file through a complete SVG-to-Sevgi-to-SVG round trip.
41
+
42
+ ### Changed
43
+
44
+ - Made Homebrew the recommended complete CLI installation while retaining Bundler and focused component gems for Ruby
45
+ application dependencies.
46
+
47
+ ## 0.96.0 - 2026-07-18
48
+
49
+ ### Added
50
+
51
+ - Added exact, subtree-wide attribute omission to Derender content/file conversion, evaluation, and inclusion APIs;
52
+ `igves --omit` exposes the same behavior from the command line.
53
+ - Added `Sevgi.SVG` as the explicit namespaced form of the top-level SVG document entrypoint.
54
+ - Added the opt-in recursive `SVG::Modules` contract for callable drawing namespaces.
55
+ - Added callable drawing-module `base` blocks, document and paper registry introspection, Canvas structural equality,
56
+ renderer options on `RenderChildren`, axis translation helpers, and a CC BY RDF helper.
57
+ - Formalized non-rendering `-` metadata and `+` attribute updates as `Attributes::META_PREFIX` and
58
+ `Attributes::UPDATE_SUFFIX`; repeated Array updates now concatenate into a stable flat value.
59
+
60
+ ### Changed
61
+
62
+ - Breaking: replaced the `SVG = Sevgi::Graphics` alias with an independent SVG facade. Facade operations now use
63
+ capitalized names such as `SVG.Canvas` and `SVG.Document`; lowercase component helpers remain on
64
+ `Sevgi::Graphics`, and the stuttering `SVG.SVG` form was removed.
65
+ - Breaking: made low-level `Executor.execute` and `execute_file` runners private; consumers use
66
+ `Sevgi.execute` and `Sevgi.execute_file` while retaining the public result and error types.
67
+ - Breaking: removed the abstract `Document::Base` layer from the selectable document-profile registry; `Minimal` and
68
+ `Default` are now sibling concrete profiles, and custom profile hierarchies should derive from `Base`.
69
+ - Breaking: renamed Parallelogram segment and constraint arguments by geometric role: `base`, `side`, and
70
+ `constraint` replace axis-implying constructor names.
71
+ - Made degree-based sine and cosine exact at integer quarter turns, eliminating cardinal Geometry residue.
72
+ - Documented complete file-system failure families for file comparison, output, touch, and upward location helpers.
73
+ - Formalized generated Tile ids, positional CSS classes, template placement, and per-use callback signatures.
74
+ - Formalized String and Symbol ids across Derender selection APIs and documented file-read failures consistently.
75
+ - Breaking: made top-level `Decompile`, `Derender`, `Evaluate`, and `EvaluateChildren` consume inline SVG/XML;
76
+ file inputs now use the corresponding `File`-suffixed entrypoints.
77
+ - Breaking: replaced callable drawing module `call` block registration with argument-independent `base` blocks;
78
+ inherited bases run parent-first, and modules with one drawing method conventionally name it `call`.
79
+ - Breaking: made bracket and call notation the canonical Geometry constructors. Among Data value types, bracket notation
80
+ is public only for Point, Segment, LengthAngle, Margin, and Paper; use `.new` for Location and result carriers, and
81
+ `Stay` for traversal stop tokens.
82
+ - Breaking: aligned Point and Segment comparison with Ruby `Comparable`; malformed or unrelated comparison operands now
83
+ return nil from `<=>`.
84
+ - Breaking: executor entrypoints now return immutable `Executor::Result` values and expose only `execute` and
85
+ `execute_file`; inspect `result.error`, `result.stack`, and `result.value` instead of executor scopes or lifecycle state.
86
+ - Breaking: wrapper attributes and callable arguments use distinct channels, `With` rejects parentless receivers, and
87
+ unsupported direct constructors are private; use the documented factories for Content, concrete Geometry lined
88
+ elements, and Grid query values.
89
+ - Breaking: Canvas uses `.new` for explicit fields, `.from_paper(paper, **overrides)` for paper conversion, and
90
+ `.call`/`Graphics.canvas` for dispatch; the misleading keyword-only `.from_paper(width:, height:)` form was removed.
91
+ - Breaking: `Save`, `Write`, `PNG`, `PDF`, and Sundries native export normalize successful destinations to expanded
92
+ String paths and create missing parent directories; change-aware SVG writes still return nil when unchanged.
93
+ - Breaking: renamed `Derender.evaluate_file_children` to `evaluate_children_file`; decompiled nodes now own immutable
94
+ public state while parser, strategy, and construction plumbing remain private.
95
+ - Expanded runtime/YARD parity checks and exact contracts for inherited, extended, generated, and dynamic API surfaces,
96
+ forwarded options, error channels, path ownership, whitespace, namespaces, nil behavior, and return values.
97
+
98
+ ### Fixed
99
+
100
+ - Rejected directories from default file discovery while preserving custom locator matchers.
101
+ - Kept `Ancestral` context in non-rendering `-context` metadata instead of leaking it into SVG attributes.
102
+ - Preserved source Canvas units and names when deriving fitted Grid canvases.
103
+ - Prevented stale documentation assets from mixing old layouts with new HTML, and moved sidebar navigation into the
104
+ tablet menu at 1024px and below.
105
+ - Normalized numeric slots owned by path, shape, transform, tile, and Inkscape page helpers to finite SVG number spelling;
106
+ arbitrary user-supplied attributes remain untouched.
107
+ - Made named callable wrapper and symbol ids stable while omitting defaults for anonymous modules, and indexed every
108
+ rendered id value, including false and numeric values, through its serialized string.
109
+ - Preserved signed Geometry constraint directions, rejected invalid sweep/export channels through Sevgi error families,
110
+ and validated raw output paths before expansion or rendering.
111
+ - Made callable module configuration copy-owned and freeze-aware, document subclasses inherit their nearest profile, and
112
+ false executor boot receivers remain explicit rather than defaulting to an internal scope.
113
+ - Made element trees, attributes, identifiers, locator results, document profiles, Derender nodes, shell results, and
114
+ executor results retain owned immutable snapshots where their public contracts promise value semantics.
115
+ - Corrected Shell combined-output separators, nil export density errors, document render-option routing, executor source
116
+ snapshots, selected-node namespace/whitespace documentation, and Standard character-data validation.
117
+
118
+ ### Removed
119
+
120
+ - Removed public access to pluralization tables and the internal SVG save extension; pluralization rules are now deeply
121
+ immutable.
122
+ - Removed public documentation and constant access for command-line implementation modules; the `sevgi` and `igves`
123
+ executables remain unchanged.
124
+ - Removed eager loading and public documentation of private Showcase build/test support; explicit support entrypoints
125
+ now keep the harness under the Showcase namespace.
126
+ - Removed public access to document profile name normalizers; registry operations retain them as private plumbing.
127
+ - Removed the redundant `Margin.margin` constructor; use canonical bracket notation.
128
+ - Removed public executor orchestration, obsolete callable-module hooks, the old public attribute syntax constants, and
129
+ direct construction of abstract or internally wired Content, Element, and Grid query types.
130
+ - Removed accidental public access to abstract Lined factories, internal element-name/export maps, result/location
131
+ bracket constructors, and direct Stop construction.
132
+
8
133
  ## 0.95.0 - 2026-07-11
9
134
 
10
135
  ### Security
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Sevgi Standard
2
2
 
3
- SVG element, attribute, and conformance data used by Sevgi validation.
3
+ Sevgi Standard supplies the SVG element and attribute data used by validation.
4
4
 
5
5
  ## Install
6
6
 
@@ -23,15 +23,15 @@ Sevgi::Standard.attribute?(:width)
23
23
 
24
24
  ## Ruby compatibility
25
25
 
26
- Requires Ruby 3.4.0 or newer. CI verifies Ruby 3.4.0 and the current development Ruby from `.ruby-version`.
26
+ Requires Ruby 3.4.0 or newer. CI verifies the current Ruby 3.4 release and the development Ruby from `.ruby-version`.
27
27
 
28
28
  ## Native prerequisites
29
29
 
30
- None beyond Ruby and this gem's Ruby dependencies.
30
+ This gem needs only Ruby and its Ruby dependencies.
31
31
 
32
32
  ## Links
33
33
 
34
- - Documentation: https://sevgi.roktas.dev
35
- - API documentation: https://www.rubydoc.info/gems/sevgi-standard
36
- - Source: https://github.com/roktas/sevgi/tree/main/standard
37
- - Changelog: https://github.com/roktas/sevgi/blob/main/CHANGELOG.md
34
+ - Documentation: <https://sevgi.roktas.dev>
35
+ - API documentation: <https://www.rubydoc.info/gems/sevgi-standard>
36
+ - Source: <https://github.com/roktas/sevgi/tree/main/standard>
37
+ - Changelog: <https://github.com/roktas/sevgi/blob/main/CHANGELOG.md>
@@ -38,6 +38,7 @@ module Sevgi
38
38
  # @param elements [Array<String, Symbol>, String, Symbol, nil] child element names
39
39
  # @return [Boolean] true when the usage conforms
40
40
  # @raise [Sevgi::ArgumentError] when any name is not a valid public name
41
+ # @raise [Sevgi::ArgumentError] when cdata is not a String or nil
41
42
  # @raise [Sevgi::ValidationError] when the usage violates the standard data
42
43
  def call(attributes: nil, cdata: nil, elements: nil)
43
44
  if attributes
@@ -60,33 +61,45 @@ module Sevgi
60
61
  # @param elements [Array<String, Symbol>, nil] child element names
61
62
  # @return [Boolean] true when the usage conforms or the element is ignored
62
63
  # @raise [Sevgi::ArgumentError] when any name is not a valid public name
64
+ # @raise [Sevgi::ArgumentError] when cdata is not a String or nil
63
65
  # @raise [Sevgi::ValidationError] when the usage violates the standard data
64
66
  # @raise [Sevgi::PanicError] when the standard data refers to an invalid model
65
67
  def self.call(element, attributes: nil, cdata: nil, elements: nil)
66
68
  element = Name.normalize!(element, context: "element")
67
69
  attributes = Name.list!(attributes, context: "attribute")
68
70
  elements = Name.list!(elements, context: "element") || []
71
+ cdata = normalize_cdata(cdata)
69
72
 
70
73
  Element.ignore?(element) or
71
74
  validate(element, attributes:, elements:, cdata:)
72
75
  end
73
76
 
74
- def self.validate(element, attributes:, elements:, cdata:)
75
- validator = @cache[element] || new(element)
76
- result = validator.call(**arguments(attributes, elements, cdata))
77
- @cache[element] ||= validator
78
- result
79
- end
77
+ class << self
78
+ private
80
79
 
81
- def self.arguments(attributes, elements, cdata)
82
- {
83
- attributes: Attribute.concerns(attributes),
84
- elements: Element.concerns(elements),
85
- cdata:
86
- }
87
- end
80
+ def validate(element, attributes:, elements:, cdata:)
81
+ validator = @cache[element] || new(element)
82
+ result = validator.call(**arguments(attributes, elements, cdata))
83
+ @cache[element] ||= validator
84
+ result
85
+ end
86
+
87
+ def arguments(attributes, elements, cdata)
88
+ {
89
+ attributes: Attribute.concerns(attributes),
90
+ elements: Element.concerns(elements),
91
+ cdata:
92
+ }
93
+ end
94
+
95
+ def normalize_cdata(cdata)
96
+ unless cdata.nil? || cdata.is_a?(::String)
97
+ ArgumentError.("Character data must be a String or nil: #{cdata.inspect}")
98
+ end
88
99
 
89
- private_class_method :arguments, :validate
100
+ cdata unless cdata == ""
101
+ end
102
+ end
90
103
  end
91
104
 
92
105
  private_constant :Conform, :Model
@@ -43,6 +43,10 @@ module Sevgi
43
43
  # @return [Set<Symbol>] mutation-isolated set snapshot
44
44
  def all = Snapshot.copy(@all ||= Set[*data.values.flatten.uniq.sort])
45
45
 
46
+ # Returns accepted group names for this data list.
47
+ # @return [Set<Symbol>] frozen group-name snapshot
48
+ def groups = @groups ||= Set[*data.keys.sort].freeze
49
+
46
50
  # Checks whether a name belongs to a group.
47
51
  # @param name [Symbol] item name
48
52
  # @param group [Symbol] group name
@@ -94,6 +98,8 @@ module Sevgi
94
98
 
95
99
  private_constant :Common
96
100
 
101
+ # SVG attribute registry implementation.
102
+ # @api private
97
103
  module Attribute
98
104
  extend Common
99
105
  extend self
@@ -103,6 +109,8 @@ module Sevgi
103
109
 
104
110
  private_constant :Attribute
105
111
 
112
+ # SVG element registry implementation.
113
+ # @api private
106
114
  module Element
107
115
  extend Common
108
116
  extend self
@@ -112,6 +120,8 @@ module Sevgi
112
120
 
113
121
  private_constant :Element
114
122
 
123
+ # SVG specification registry implementation.
124
+ # @api private
115
125
  module Specification
116
126
  extend List
117
127
  extend self
@@ -162,11 +172,6 @@ module Sevgi
162
172
  names.replace(names.flat_map { |name| group?(name) ? list[name] : name }.uniq)
163
173
  end
164
174
 
165
- # For testing purposes
166
-
167
- def charge = data.each_key { expand(it) }
168
-
169
- def flush = (@spec = {})
170
175
  end
171
176
 
172
177
  private_constant :Specification
@@ -3,6 +3,6 @@
3
3
  module Sevgi
4
4
  module Standard
5
5
  # Current version of the Sevgi standard gem.
6
- VERSION = "0.95.0"
6
+ VERSION = "0.98.2"
7
7
  end
8
8
  end
@@ -15,6 +15,10 @@ module Sevgi
15
15
  # The registry is a Sevgi compatibility set based on SVG 2 plus the split-out SVG modules and legacy entries already
16
16
  # modeled in the bundled specifications. Supported element names must have matching specification data; abandoned or
17
17
  # unspecified proposal entries are not exposed as supported elements.
18
+ #
19
+ # @example Validate an SVG element usage
20
+ # Sevgi::Standard.conform(:rect, attributes: %i[width height]) #=> true
21
+ # Sevgi::Standard.element?(:foreignObject) #=> true
18
22
  module Standard
19
23
  extend self
20
24
 
@@ -22,8 +26,16 @@ module Sevgi
22
26
  # Returns SVG attributes, optionally restricted to one or more attribute groups.
23
27
  # @param groups [Array<String, Symbol>] attribute group names
24
28
  # @return [Set<Symbol>] mutation-isolated attribute-name snapshot
29
+ # @raise [Sevgi::ArgumentError] when a group name is invalid or not listed by {.attribute_groups}
30
+ # @example Discover and apply an attribute group
31
+ # Sevgi::Standard.attribute_groups.include?(:Core) #=> true
32
+ # Sevgi::Standard.attributes(:Core).include?(:id) #=> true
25
33
  def attributes(...) = Attribute.set(...)
26
34
 
35
+ # Returns accepted attribute group names.
36
+ # @return [Set<Symbol>] frozen group-name snapshot
37
+ def attribute_groups = Attribute.groups
38
+
27
39
  # Reports whether an attribute name is recognized by the SVG standard data.
28
40
  # @param name [String, Symbol] attribute name
29
41
  # @return [Boolean]
@@ -40,16 +52,26 @@ module Sevgi
40
52
  # @return [Boolean] true when the usage conforms
41
53
  # @raise [Sevgi::ArgumentError] when any name is not a String or Symbol
42
54
  # @raise [Sevgi::ArgumentError] when any name is not a valid SVG-style name
55
+ # @raise [Sevgi::ArgumentError] when cdata is not a String or nil
43
56
  # @raise [Sevgi::ValidationError] when the usage violates the standard data
44
57
  # @raise [Sevgi::PanicError] when the standard data refers to an invalid model
58
+ # @note Empty character data is treated as absent.
45
59
  def conform(...) = Conform.(...)
46
60
 
47
61
  # @overload elements(*groups)
48
62
  # Returns SVG elements, optionally restricted to one or more element groups.
49
63
  # @param groups [Array<String, Symbol>] element group names
50
64
  # @return [Set<Symbol>] mutation-isolated element-name snapshot
65
+ # @raise [Sevgi::ArgumentError] when a group name is invalid or not listed by {.element_groups}
66
+ # @example Discover and apply an element group
67
+ # Sevgi::Standard.element_groups.include?(:Descriptive) #=> true
68
+ # Sevgi::Standard.elements(:Descriptive) #=> Set[:desc, :metadata, :title]
51
69
  def elements(...) = Element.set(...)
52
70
 
71
+ # Returns accepted element group names.
72
+ # @return [Set<Symbol>] frozen group-name snapshot
73
+ def element_groups = Element.groups
74
+
53
75
  # Reports whether an element name is recognized by the SVG standard data.
54
76
  # @param name [String, Symbol] element name
55
77
  # @return [Boolean]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sevgi-standard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.95.0
4
+ version: 0.98.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Recai Oktaş
@@ -15,15 +15,15 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.95.0
18
+ version: 0.98.2
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.95.0
26
- description: Validates elements and attributes according to the SVG specification.
25
+ version: 0.98.2
26
+ description: Checks generated SVG against standard element and attribute rules.
27
27
  email: roktas@gmail.com
28
28
  executables: []
29
29
  extensions: []
@@ -65,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
65
  - !ruby/object:Gem::Version
66
66
  version: '0'
67
67
  requirements: []
68
- rubygems_version: 4.0.11
68
+ rubygems_version: 4.0.16
69
69
  specification_version: 4
70
- summary: SVG Validation for the Sevgi toolkit.
70
+ summary: SVG element and attribute validation for Sevgi.
71
71
  test_files: []