sevgi-graphics 0.94.0 → 0.95.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 +4 -4
- data/CHANGELOG.md +150 -2
- data/LICENSE +672 -3
- data/README.md +1 -1
- data/lib/sevgi/graphics/attribute.rb +132 -38
- data/lib/sevgi/graphics/auxiliary/canvas.rb +38 -16
- data/lib/sevgi/graphics/auxiliary/content.rb +152 -29
- data/lib/sevgi/graphics/auxiliary/margin.rb +14 -2
- data/lib/sevgi/graphics/auxiliary/paper.rb +91 -84
- data/lib/sevgi/graphics/auxiliary/scalar.rb +40 -0
- data/lib/sevgi/graphics/auxiliary/sizes.rb +62 -0
- data/lib/sevgi/graphics/auxiliary.rb +2 -0
- data/lib/sevgi/graphics/document.rb +186 -74
- data/lib/sevgi/graphics/element.rb +41 -14
- data/lib/sevgi/graphics/mixtures/core.rb +89 -18
- data/lib/sevgi/graphics/mixtures/duplicate.rb +33 -13
- data/lib/sevgi/graphics/mixtures/export.rb +6 -0
- data/lib/sevgi/graphics/mixtures/include.rb +17 -0
- data/lib/sevgi/graphics/mixtures/inkscape.rb +15 -0
- data/lib/sevgi/graphics/mixtures/rdf.rb +20 -0
- data/lib/sevgi/graphics/mixtures/render.rb +56 -11
- data/lib/sevgi/graphics/mixtures/save.rb +9 -0
- data/lib/sevgi/graphics/mixtures/symbols.rb +3 -0
- data/lib/sevgi/graphics/mixtures/tile.rb +6 -0
- data/lib/sevgi/graphics/mixtures/underscore.rb +2 -2
- data/lib/sevgi/graphics/mixtures/validate.rb +12 -0
- data/lib/sevgi/graphics/mixtures/wrappers.rb +4 -1
- data/lib/sevgi/graphics/mixtures.rb +4 -0
- data/lib/sevgi/graphics/version.rb +1 -1
- data/lib/sevgi/graphics/xml.rb +127 -0
- data/lib/sevgi/graphics.rb +19 -18
- metadata +7 -4
|
@@ -9,6 +9,9 @@ module Sevgi
|
|
|
9
9
|
# @param mod [Module] callable drawing module
|
|
10
10
|
# @param args [Array<Object>] callable arguments
|
|
11
11
|
# @param kwargs [Hash] defs attributes
|
|
12
|
+
# @yield [name] converts each callable name to a symbol id
|
|
13
|
+
# @yieldparam name [Symbol] callable method name
|
|
14
|
+
# @yieldreturn [String, Symbol] symbol id
|
|
12
15
|
# @return [Sevgi::Graphics::Element] defs element
|
|
13
16
|
# @raise [Sevgi::ArgumentError] when mod is not a plain module
|
|
14
17
|
def Symbols(mod, *args, **kwargs, &block)
|
|
@@ -18,6 +18,8 @@ module Sevgi
|
|
|
18
18
|
# @param dy [Numeric] vertical spacing
|
|
19
19
|
# @param oy [Numeric] vertical offset
|
|
20
20
|
# @param proc [Proc, nil] optional coordinate/customization proc
|
|
21
|
+
# @yield evaluates the template drawing DSL in a generated group
|
|
22
|
+
# @yieldreturn [Object] ignored block result
|
|
21
23
|
# @return [Sevgi::Graphics::Element] self
|
|
22
24
|
# @raise [Sevgi::ArgumentError] when a required tile argument is missing or invalid
|
|
23
25
|
def Tile(
|
|
@@ -67,6 +69,8 @@ module Sevgi
|
|
|
67
69
|
# @param d [Numeric] horizontal spacing
|
|
68
70
|
# @param o [Numeric] horizontal offset
|
|
69
71
|
# @param proc [Proc, nil] optional coordinate/customization proc
|
|
72
|
+
# @yield evaluates the template drawing DSL in a generated group
|
|
73
|
+
# @yieldreturn [Object] ignored block result
|
|
70
74
|
# @return [Sevgi::Graphics::Element] self
|
|
71
75
|
# @raise [Sevgi::ArgumentError] when a required tile argument is missing or invalid
|
|
72
76
|
def TileX(id = Undefined, n: Undefined, d: Undefined, o: 0, proc: nil, &block)
|
|
@@ -100,6 +104,8 @@ module Sevgi
|
|
|
100
104
|
# @param d [Numeric] vertical spacing
|
|
101
105
|
# @param o [Numeric] vertical offset
|
|
102
106
|
# @param proc [Proc, nil] optional coordinate/customization proc
|
|
107
|
+
# @yield evaluates the template drawing DSL in a generated group
|
|
108
|
+
# @yieldreturn [Object] ignored block result
|
|
103
109
|
# @return [Sevgi::Graphics::Element] self
|
|
104
110
|
# @raise [Sevgi::ArgumentError] when a required tile argument is missing or invalid
|
|
105
111
|
def TileY(id = Undefined, n: Undefined, d: Undefined, o: 0, proc: nil, &block)
|
|
@@ -15,9 +15,9 @@ module Sevgi
|
|
|
15
15
|
# Adds an XML comment.
|
|
16
16
|
# @param comment [Object] comment text
|
|
17
17
|
# @return [Sevgi::Graphics::Element] floating comment element
|
|
18
|
-
# @raise [Sevgi::ArgumentError] when comment
|
|
18
|
+
# @raise [Sevgi::ArgumentError] when comment cannot be stringified as valid XML or would form malformed markup
|
|
19
19
|
def Comment(comment)
|
|
20
|
-
comment = comment
|
|
20
|
+
comment = XML.text(comment, context: "XML comment")
|
|
21
21
|
|
|
22
22
|
ArgumentError.("XML comment must not contain '--'") if comment.include?("--")
|
|
23
23
|
ArgumentError.("XML comment must not end with '-'") if comment.end_with?("-")
|
|
@@ -4,6 +4,18 @@ module Sevgi
|
|
|
4
4
|
module Graphics
|
|
5
5
|
module Mixtures
|
|
6
6
|
# DSL helpers for SVG standard validation.
|
|
7
|
+
#
|
|
8
|
+
# @!method CData
|
|
9
|
+
# Returns text content used as SVG character data.
|
|
10
|
+
# @return [String, nil] joined text content or nil
|
|
11
|
+
# @!method NS?(name)
|
|
12
|
+
# Reports whether a namespace is available on this element or an ancestor.
|
|
13
|
+
# @param name [Symbol, String] namespace suffix without xmlns:
|
|
14
|
+
# @return [Boolean]
|
|
15
|
+
# @!method Validate
|
|
16
|
+
# Validates this subtree against SVG standard metadata when that component is available.
|
|
17
|
+
# @return [Sevgi::Graphics::Element, nil] self after validation, or nil without sevgi/standard
|
|
18
|
+
# @raise [Sevgi::ValidationError] when SVG validation fails
|
|
7
19
|
module Validate
|
|
8
20
|
# Returns text content used as SVG character data.
|
|
9
21
|
# @return [String, nil] joined text content or nil
|
|
@@ -27,6 +27,8 @@ module Sevgi
|
|
|
27
27
|
# Builds a titled SVG symbol.
|
|
28
28
|
# @param name [String] human-readable symbol name
|
|
29
29
|
# @param kwargs [Hash] symbol attributes
|
|
30
|
+
# @yield evaluates the drawing DSL in the symbol element
|
|
31
|
+
# @yieldreturn [Object] ignored block result
|
|
30
32
|
# @return [Sevgi::Graphics::Element] symbol element
|
|
31
33
|
def Symbol(name, **kwargs, &block)
|
|
32
34
|
id = (words = name.split).map(&:downcase).join("-")
|
|
@@ -63,7 +65,8 @@ module Sevgi
|
|
|
63
65
|
# @param hash [Hash, nil] CSS rules
|
|
64
66
|
# @param attributes [Hash] style attributes or CSS rules when hash is nil
|
|
65
67
|
# @return [Sevgi::Graphics::Element] style element
|
|
66
|
-
# @raise [Sevgi::ArgumentError] when CSS
|
|
68
|
+
# @raise [Sevgi::ArgumentError] when CSS rules are malformed, cyclic, cannot be stringified, or contain invalid
|
|
69
|
+
# encoding or illegal XML 1.0 characters
|
|
67
70
|
def css(hash = nil, **attributes)
|
|
68
71
|
hash, attributes = attributes, {} unless hash
|
|
69
72
|
|
|
@@ -8,11 +8,15 @@ module Sevgi
|
|
|
8
8
|
# Includes a named mixture and optional anonymous extension into a document class.
|
|
9
9
|
# @param mod [Symbol, String] mixture constant name
|
|
10
10
|
# @param document [Class] document class receiving the mixture
|
|
11
|
+
# @yield defines methods in the anonymous mixture
|
|
12
|
+
# @yieldreturn [Object] ignored module-definition result
|
|
11
13
|
# @return [Module, nil] optional anonymous mixture when a block is given
|
|
12
14
|
# @raise [NameError] when the mixture does not exist
|
|
13
15
|
# @overload mixin(document = Graphics::Document::Base, &block)
|
|
14
16
|
# Includes only an anonymous extension into a document class.
|
|
15
17
|
# @param document [Class] document class receiving the mixture
|
|
18
|
+
# @yield defines methods in the anonymous mixture
|
|
19
|
+
# @yieldreturn [Object] ignored module-definition result
|
|
16
20
|
# @return [Module] anonymous mixture
|
|
17
21
|
# @raise [Sevgi::ArgumentError] when no named mixture or block is given
|
|
18
22
|
def self.mixin(mod = Undefined, document = Graphics::Document::Base, &block)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sevgi
|
|
4
|
+
module Graphics
|
|
5
|
+
# XML 1.0 text and qualified-name validation shared by renderer boundaries.
|
|
6
|
+
# @api private
|
|
7
|
+
module XML
|
|
8
|
+
NCNAME_START = "A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
|
|
9
|
+
"\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
|
|
10
|
+
"\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
|
|
11
|
+
NCNAME_CHAR = "#{NCNAME_START}\\-.0-9\u{B7}\u{300}-\u{36F}\u{203F}-\u{2040}".freeze
|
|
12
|
+
NCNAME = "[#{NCNAME_START}][#{NCNAME_CHAR}]*".freeze
|
|
13
|
+
QNAME = /\A#{NCNAME}(?::#{NCNAME})?\z/u
|
|
14
|
+
|
|
15
|
+
private_constant :NCNAME, :NCNAME_CHAR, :NCNAME_START, :QNAME
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
# Validates an XML 1.0 string representation.
|
|
19
|
+
# @param value [Object] value to stringify and validate
|
|
20
|
+
# @param context [String] error-message subject
|
|
21
|
+
# @return [String] UTF-8 text
|
|
22
|
+
# @raise [Sevgi::ArgumentError] when stringification, encoding, or XML character validation fails
|
|
23
|
+
def text(value, context: "XML content")
|
|
24
|
+
value = stringify(value, context:) unless value.is_a?(::String)
|
|
25
|
+
validate_string(value, context:)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Validates and snapshots a nested XML-bound value.
|
|
29
|
+
# @param value [Object] scalar or nested container
|
|
30
|
+
# @param context [String] error-message subject
|
|
31
|
+
# @param seen [Hash] container identities on the current traversal path
|
|
32
|
+
# @return [Object] validated caller-owned snapshot
|
|
33
|
+
# @raise [Sevgi::ArgumentError] when the value is cyclic, collides after stringification, or has invalid XML text
|
|
34
|
+
def snapshot(value, context:, seen: {}.compare_by_identity)
|
|
35
|
+
case value
|
|
36
|
+
when ::Hash
|
|
37
|
+
nested(value, context:, seen:) { snapshot_hash(value, context:, seen:) }
|
|
38
|
+
when ::Array
|
|
39
|
+
nested(value, context:, seen:) { value.map { snapshot(it, context:, seen:) } }
|
|
40
|
+
else
|
|
41
|
+
text(value, context:)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Validates an XML qualified name.
|
|
46
|
+
# @param value [Object] candidate name
|
|
47
|
+
# @param context [String] error-message subject
|
|
48
|
+
# @return [String] validated qualified name
|
|
49
|
+
# @raise [Sevgi::ArgumentError] when text conversion or QName validation fails
|
|
50
|
+
def name(value, context: "XML name")
|
|
51
|
+
text(value, context:).tap do |candidate|
|
|
52
|
+
ArgumentError.("#{context} is invalid: #{candidate.inspect}") unless QNAME.match?(candidate)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Validates a nested XML value without retaining its snapshot.
|
|
57
|
+
# @param value [Object] scalar or nested container
|
|
58
|
+
# @param context [String] error-message subject
|
|
59
|
+
# @return [Object] original value
|
|
60
|
+
# @raise [Sevgi::ArgumentError] when nested content is cyclic or contains invalid XML text
|
|
61
|
+
def validate(value, context: "XML content")
|
|
62
|
+
snapshot(value, context:)
|
|
63
|
+
value
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Escapes embedded CDATA terminators after validating text.
|
|
67
|
+
# @param value [Object] CDATA value
|
|
68
|
+
# @return [String] safe CDATA body
|
|
69
|
+
# @raise [Sevgi::ArgumentError] when value is not valid XML text
|
|
70
|
+
def cdata(value) = text(value).gsub("]]>", "]]]]><![CDATA[>")
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def nested(value, context:, seen:)
|
|
75
|
+
ArgumentError.("Cyclic #{context} is not supported") if seen.key?(value)
|
|
76
|
+
|
|
77
|
+
seen[value] = true
|
|
78
|
+
yield
|
|
79
|
+
ensure
|
|
80
|
+
seen.delete(value)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def snapshot_hash(value, context:, seen:)
|
|
84
|
+
value.each_with_object({}) do |(key, item), captured|
|
|
85
|
+
key = snapshot(key, context:, seen:)
|
|
86
|
+
ArgumentError.("#{context} keys collide after stringification") if captured.key?(key)
|
|
87
|
+
|
|
88
|
+
captured[key] = snapshot(item, context:, seen:)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def stringify(value, context:)
|
|
93
|
+
text = value.to_s
|
|
94
|
+
ArgumentError.("#{context} stringification must return a String") unless text.is_a?(::String)
|
|
95
|
+
|
|
96
|
+
text
|
|
97
|
+
rescue Sevgi::ArgumentError
|
|
98
|
+
raise
|
|
99
|
+
rescue ::StandardError => e
|
|
100
|
+
ArgumentError.("#{context} cannot be stringified: #{e.class}: #{e.message}")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def validate_string(value, context:)
|
|
104
|
+
ArgumentError.("#{context} must be valid UTF-8") unless value.valid_encoding?
|
|
105
|
+
|
|
106
|
+
text = value.encode("UTF-8")
|
|
107
|
+
if (codepoint = text.each_codepoint.find { !legal_codepoint?(it) })
|
|
108
|
+
ArgumentError.("#{context} contains illegal character U+#{format("%04X", codepoint)}")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
text
|
|
112
|
+
rescue ::EncodingError => e
|
|
113
|
+
ArgumentError.("#{context} must be valid UTF-8: #{e.message}")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def legal_codepoint?(codepoint)
|
|
117
|
+
[0x9, 0xA, 0xD].include?(codepoint) ||
|
|
118
|
+
(0x20..0xD7FF).cover?(codepoint) ||
|
|
119
|
+
(0xE000..0xFFFD).cover?(codepoint) ||
|
|
120
|
+
(0x10000..0x10FFFF).cover?(codepoint)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private_constant :XML
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/sevgi/graphics.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "sevgi/function"
|
|
4
4
|
|
|
5
|
+
require_relative "graphics/xml"
|
|
5
6
|
require_relative "graphics/attribute"
|
|
6
7
|
require_relative "graphics/auxiliary"
|
|
7
8
|
require_relative "graphics/element"
|
|
@@ -30,35 +31,40 @@ module Sevgi
|
|
|
30
31
|
# @return [Class] document class
|
|
31
32
|
# @raise [Sevgi::ArgumentError] when the profile is unknown
|
|
32
33
|
# @overload document(name, preambles: Undefined, attributes: Undefined)
|
|
33
|
-
#
|
|
34
|
-
#
|
|
34
|
+
# Looks up a named profile when both definition keywords are omitted. Supplying `preambles:` or `attributes:`
|
|
35
|
+
# defines a named profile, or returns an existing profile when every explicitly supplied field matches. Omitted
|
|
36
|
+
# fields are ignored during existing-profile comparison. Profile containers and strings are copied into the
|
|
37
|
+
# process-global, thread-atomic registry; mutable non-container attribute values are stringified once before
|
|
38
|
+
# registration. Concurrent identical definitions return the same canonical registered class.
|
|
35
39
|
# @param name [Symbol, String] profile name
|
|
36
40
|
# @param preambles [Array<String>, nil, Sevgi::Undefined] document preamble lines
|
|
37
|
-
# @param attributes [Hash, Sevgi::Undefined] default root attributes
|
|
41
|
+
# @param attributes [Hash, nil, Sevgi::Undefined] default root attributes; nil means an empty Hash
|
|
38
42
|
# @return [Class] document class
|
|
39
|
-
# @raise [Sevgi::ArgumentError] when a
|
|
43
|
+
# @raise [Sevgi::ArgumentError] when a profile conflicts or metadata is invalid XML, cyclic, or cannot be stringified
|
|
40
44
|
# @overload document(preambles: Undefined, attributes: Undefined)
|
|
41
45
|
# Defines an anonymous document profile without registering it globally.
|
|
42
46
|
# @param preambles [Array<String>, nil, Sevgi::Undefined] document preamble lines
|
|
43
|
-
# @param attributes [Hash, Sevgi::Undefined] default root attributes
|
|
47
|
+
# @param attributes [Hash, nil, Sevgi::Undefined] default root attributes; nil means an empty Hash
|
|
44
48
|
# @return [Class] anonymous document class
|
|
45
|
-
# @raise [Sevgi::ArgumentError] when
|
|
49
|
+
# @raise [Sevgi::ArgumentError] when metadata is invalid XML, cyclic, or cannot be stringified
|
|
46
50
|
# @return [Class] document class
|
|
47
51
|
def document(name = Undefined, preambles: Undefined, attributes: Undefined)
|
|
48
52
|
Graphics::Document.define(name, preambles:, attributes:)
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
# Defines or replaces a document profile class.
|
|
56
|
+
# Validation and snapshot capture complete before an existing registration is atomically replaced.
|
|
52
57
|
# @param name [Symbol, String] profile name
|
|
53
58
|
# @param preambles [Array<String>, nil] document preamble lines
|
|
54
|
-
# @param attributes [Hash] default root attributes
|
|
59
|
+
# @param attributes [Hash, nil] default root attributes; nil means an empty Hash
|
|
55
60
|
# @return [Class] document class
|
|
56
|
-
# @raise [Sevgi::ArgumentError] when the
|
|
61
|
+
# @raise [Sevgi::ArgumentError] when the name or metadata is invalid XML, cyclic, or cannot be stringified
|
|
57
62
|
def document!(name, preambles: [], attributes: {})
|
|
58
63
|
Graphics::Document.define(name, preambles:, attributes:, overwrite: true)
|
|
59
64
|
end
|
|
60
65
|
|
|
61
|
-
# Defines a paper profile unless the same profile already exists.
|
|
66
|
+
# Defines a paper profile unless the same profile already exists. Registration is process-global and thread-atomic;
|
|
67
|
+
# an identical concurrent definition is idempotent and a conflicting definition is rejected.
|
|
62
68
|
# @param width [Numeric] paper width
|
|
63
69
|
# @param height [Numeric] paper height
|
|
64
70
|
# @param name [Symbol, String] profile name
|
|
@@ -66,13 +72,7 @@ module Sevgi
|
|
|
66
72
|
# @return [Symbol, String] original profile name
|
|
67
73
|
# @raise [Sevgi::ArgumentError] when the profile is invalid or an existing profile has different dimensions
|
|
68
74
|
def paper(width, height, name = :custom, unit: "mm")
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if Graphics::Paper.exist?(name)
|
|
72
|
-
ArgumentError.("Paper already defined differently: #{name}") unless Graphics::Paper.public_send(name) == profile
|
|
73
|
-
else
|
|
74
|
-
Graphics::Paper.define(name, width:, height:, unit:)
|
|
75
|
-
end
|
|
75
|
+
Graphics::Paper.define(name, width:, height:, unit:, overwrite: false)
|
|
76
76
|
|
|
77
77
|
name
|
|
78
78
|
end
|
|
@@ -91,9 +91,10 @@ module Sevgi
|
|
|
91
91
|
# Builds an SVG root document.
|
|
92
92
|
# @param document [Symbol, String, Class] document profile name or document class
|
|
93
93
|
# @param canvas [Sevgi::Graphics::Canvas, Sevgi::Graphics::Paper, Symbol, String, Sevgi::Undefined, nil] canvas input
|
|
94
|
-
# @
|
|
94
|
+
# @yield evaluates the drawing DSL in the root element
|
|
95
|
+
# @yieldreturn [Object] ignored block result
|
|
95
96
|
# @return [Sevgi::Graphics::Document::Proto] SVG root element
|
|
96
|
-
# @raise [Sevgi::ArgumentError] when the document or
|
|
97
|
+
# @raise [Sevgi::ArgumentError] when the document/canvas profile or root XML attributes are invalid
|
|
97
98
|
def SVG(document = :default, canvas = Undefined, **, &block)
|
|
98
99
|
Graphics::Document.(document, canvas, **, &block)
|
|
99
100
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sevgi-graphics
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.95.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Recai Oktaş
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.95.0
|
|
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.
|
|
25
|
+
version: 0.95.0
|
|
26
26
|
description: Provides an extensible DSL for creating SVG content.
|
|
27
27
|
email: roktas@gmail.com
|
|
28
28
|
executables: []
|
|
@@ -39,6 +39,8 @@ files:
|
|
|
39
39
|
- lib/sevgi/graphics/auxiliary/content.rb
|
|
40
40
|
- lib/sevgi/graphics/auxiliary/margin.rb
|
|
41
41
|
- lib/sevgi/graphics/auxiliary/paper.rb
|
|
42
|
+
- lib/sevgi/graphics/auxiliary/scalar.rb
|
|
43
|
+
- lib/sevgi/graphics/auxiliary/sizes.rb
|
|
42
44
|
- lib/sevgi/graphics/document.rb
|
|
43
45
|
- lib/sevgi/graphics/document/base.rb
|
|
44
46
|
- lib/sevgi/graphics/document/default.rb
|
|
@@ -67,6 +69,7 @@ files:
|
|
|
67
69
|
- lib/sevgi/graphics/mixtures/validate.rb
|
|
68
70
|
- lib/sevgi/graphics/mixtures/wrappers.rb
|
|
69
71
|
- lib/sevgi/graphics/version.rb
|
|
72
|
+
- lib/sevgi/graphics/xml.rb
|
|
70
73
|
homepage: https://sevgi.roktas.dev
|
|
71
74
|
licenses:
|
|
72
75
|
- GPL-3.0-or-later
|
|
@@ -89,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
89
92
|
- !ruby/object:Gem::Version
|
|
90
93
|
version: '0'
|
|
91
94
|
requirements: []
|
|
92
|
-
rubygems_version: 4.0.
|
|
95
|
+
rubygems_version: 4.0.11
|
|
93
96
|
specification_version: 4
|
|
94
97
|
summary: Core DSL for the Sevgi toolkit.
|
|
95
98
|
test_files: []
|