sevgi-appendix 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.
@@ -0,0 +1,79 @@
1
+ # Ruby Discipline
2
+
3
+ A `.sevgi` file is executable Ruby evaluated with Sevgi's drawing vocabulary. It is not a separate template language or
4
+ configuration format. Apply ordinary Ruby design and readability rules unless the compact DSL form is clearer.
5
+
6
+ - Use local variables for local drawing state and constants for genuine module/script invariants.
7
+ - Use Arrays, Hashes, ranges, loops, Enumerables, methods, and modules directly; do not recreate them as a second DSL.
8
+ - Separate input data from drawing behavior when that makes either easier to read or test.
9
+ - Extract reusable drawing behavior into ordinary methods or `SVG::Module`; use `SVG::Modules` for an owned nested
10
+ module family.
11
+ - Prefer explicit arguments and return values over hidden global state, `eval`, monkey patches, or unnecessary
12
+ metaprogramming.
13
+ - Keep side effects at the output boundary: build a document, then `Render`, `Save`, `Out`, `PDF`, or `PNG` deliberately.
14
+ - Preserve the surrounding project's Ruby version, naming, error, test, and formatting conventions.
15
+ - Hand-format `.sevgi` source for DSL readability. Do not run a broad Ruby formatter or autocorrect over `.sevgi`
16
+ files when it would flatten or obscure the drawing.
17
+
18
+ ## Preserve the DSL Shape
19
+
20
+ Let drawing code read as a Sevgi program rather than mechanically parenthesized Ruby. Use braces for a one-line block,
21
+ `do`/`end` for a multiline block, and omit optional parentheses from statement-like SVG elements and Sevgi operations.
22
+ Keep parentheses when they bind a compact block or chained expression clearly, as in
23
+ `SVG(:minimal) { circle r: 4 }.Render`.
24
+
25
+ Avoid:
26
+
27
+ ```ruby
28
+ SVG(:minimal) do
29
+ g({ id: "mark" }) do
30
+ rect({ x: 2, y: 2, width: 12, height: 8 })
31
+ circle({ cx: 8, cy: 6, r: 3 })
32
+ end
33
+ end.Save("mark.svg")
34
+ ```
35
+
36
+ Prefer:
37
+
38
+ ```ruby
39
+ SVG :minimal do
40
+ g id: "mark" do
41
+ rect x: 2, y: 2, width: 12, height: 8
42
+ circle cx: 8, cy: 6, r: 3
43
+ end
44
+ end.Save "mark.svg"
45
+ ```
46
+
47
+ The first form is valid Ruby; the problem is loss of the drawing vocabulary's visual rhythm.
48
+
49
+ ## Callable Modules
50
+
51
+ Extend a Ruby module with `SVG::Module`. Its public instance methods are drawing steps; name the only step `call`, or
52
+ give several steps descriptive names. Private methods remain ordinary implementation helpers. A focused
53
+ `require "sevgi/graphics"` consumer uses `Sevgi::Graphics::Module` and `Sevgi::Graphics::Modules` instead of the full
54
+ facade constants.
55
+
56
+ `base` registers argument-independent invariant SVG content that runs once per invocation before the public drawing
57
+ steps. It is not general initialization or an ordering hook.
58
+
59
+ ```ruby
60
+ Badge = Module.new do
61
+ extend SVG::Module
62
+
63
+ base { css ".badge" => { fill: "tomato" } }
64
+ def call(label:) = text label, class: "badge"
65
+ end
66
+
67
+ SVG(:minimal) { Call Badge, label: "OK" }.Render
68
+ ```
69
+
70
+ `Call` draws directly. On an Inkscape profile, `Group`, `Layer`, and `Layer!` wrap the same invocation in a group,
71
+ normal layer, or insensitive layer; `Symbols` expands the public steps into reusable symbols. Lowercase `layer` and
72
+ `layer!` instead open explicit layer blocks without invoking a module. Use `SVG::Modules` only when one namespace owns
73
+ a nested family of callable modules.
74
+
75
+ Ruby arithmetic is appropriate for domain data and values the program must know. It does not supersede the renderer
76
+ ownership rule in [drawing.md](drawing.md): idiomatic Ruby can still be the wrong layer for a rendering calculation.
77
+
78
+ Use the [Library Mode guide](https://sevgi.roktas.dev/library-mode/) for facade and module composition, and the
79
+ [Script Mode guide](https://sevgi.roktas.dev/script-mode/) for executable source behavior.
@@ -0,0 +1,35 @@
1
+ # SVG Routing
2
+
3
+ Use this page to identify the SVG mechanism, then verify exact behavior in MDN or the SVG specification. Do not turn
4
+ this index into a cookbook of one-off drawing tips.
5
+
6
+ | Rendering concept | Start with |
7
+ | --- | --- |
8
+ | Coordinate system and responsive scaling | `viewBox`, viewport dimensions, `preserveAspectRatio` |
9
+ | Relative placement of an element tree | `transform`; use Sevgi's transform helpers when available |
10
+ | Reusable drawing definitions | `defs`, `symbol`, `use` |
11
+ | Repeated visual fill | `pattern` |
12
+ | Paint | presentation attributes or CSS, gradients, opacity |
13
+ | Visibility boundaries | `clipPath` for hard clipping; `mask` for luminance/alpha compositing |
14
+ | Line decoration | `marker`, stroke width, line cap, line join, dash array |
15
+ | Renderer effects | `filter` and filter primitives |
16
+ | Text relationships | text positioning and anchoring attributes; leave font metrics to the renderer |
17
+
18
+ Resolve questions in this order:
19
+
20
+ 1. Identify the relationship the drawing needs, not a guessed numeric result.
21
+ 2. Find the standard SVG element, attribute, or CSS behavior that owns it.
22
+ 3. Check target-renderer support and inheritance rules when the feature is context-sensitive.
23
+ 4. Express it through normal Sevgi element calls and attributes. Use `Element` only when a verified XML element name
24
+ cannot dispatch safely as a Ruby call, such as a name that conflicts with an existing Ruby or Sevgi method. Never use
25
+ it as a fallback for an unverified DSL word.
26
+ 5. Compute geometry only when SVG does not provide the value needed by the program.
27
+
28
+ Authoritative references:
29
+
30
+ - [MDN SVG reference](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference)
31
+ - [W3C SVG 2 specification](https://www.w3.org/TR/SVG2/)
32
+ - [Sevgi SVG Essentials](https://sevgi.roktas.dev/svg/)
33
+
34
+ Do not invent an SVG name from memory when validation matters. Check MDN and let Sevgi Standard validate known element
35
+ names, attributes, content, and nesting.
@@ -0,0 +1,48 @@
1
+ # Toolkit Routing
2
+
3
+ ## Choose the Owner
4
+
5
+ | Need | Component / entry point | Boundary |
6
+ | --- | --- | --- |
7
+ | Build SVG documents and element trees | Graphics; `SVG(...)`, SVG element calls | Default starting point for every drawing |
8
+ | Choose paper size, canvas geometry, or root serialization metadata | `SVG.Paper`, `SVG.Canvas`, `SVG.Document` | Keep physical size, drawing surface, and document profile independent |
9
+ | Validate SVG vocabulary and nesting | Standard | Use validation; do not hand-maintain element/attribute allowlists |
10
+ | Calculate geometry SVG cannot supply | `Sevgi::Geometry` | Use for constructed values, intersections, sweeps, and algorithmic bounds—not renderer layout |
11
+ | Fit rulers, grids, and reusable tile layouts | `Sevgi::Sundries`, `SVG.Grid` | Choose the exact model through `layout.md` |
12
+ | Reuse supported cross-component helpers | `Sevgi::F` | Check before adding a project-local Sevgi helper; it is not a general utility library |
13
+ | Import or inspect existing SVG/XML | Derender facade methods | Choose the source/evaluation relationship through `derender.md` |
14
+ | Render SVG as PDF or PNG | Sundries export / document `PDF` and `PNG` | Choose the output boundary through `output.md` |
15
+
16
+ Before reimplementing shared behavior, check `Sevgi::F` for degree trigonometry and precision, `.sevgi` discovery,
17
+ generated-file I/O, argv-safe child processes, Sevgi-facing names, and status output.
18
+
19
+ ## In a Checkout
20
+
21
+ When a Sevgi checkout is available, prefer its canonical sources:
22
+
23
+ | Need | Source |
24
+ | --- | --- |
25
+ | Machine-readable DSL inventory and examples | `showcase/doc/data/dsl.yml` |
26
+ | Task-oriented user semantics | `showcase/doc/content/` |
27
+ | Runnable complete drawings | examples under `showcase/srv` that are linked from the user docs or DSL catalog |
28
+ | Exact public contracts | the owning component's `lib/` YARD comments |
29
+ | Rendered local YARD | `.local/var/ruby/doc/api` after `bundle exec rake doc` |
30
+
31
+ ## Lookup Order
32
+
33
+ 1. Read the task-relevant user guide for semantics and workflow.
34
+ 2. Search the structured DSL inventory and linked runnable Showcase examples for the nearest drawing pattern.
35
+ 3. Read the rendered DSL catalog for an exact drawing word and executable example.
36
+ 4. Read YARD for signatures, return values, and failure contracts.
37
+ 5. Read MDN or the SVG specification for renderer behavior.
38
+
39
+ | Topic | User guide | YARD |
40
+ | --- | --- | --- |
41
+ | Script and library forms | [Getting Started](https://sevgi.roktas.dev/getting-started/), [Library Mode](https://sevgi.roktas.dev/library-mode/) | [`sevgi`](https://www.rubydoc.info/gems/sevgi) |
42
+ | SVG documents and DSL | [SVG Essentials](https://sevgi.roktas.dev/svg/), [DSL Catalog](https://sevgi.roktas.dev/dsl/) | [`sevgi-graphics`](https://www.rubydoc.info/gems/sevgi-graphics) |
43
+ | Geometry | [Geometry](https://sevgi.roktas.dev/geometry/) | [`sevgi-geometry`](https://www.rubydoc.info/gems/sevgi-geometry) |
44
+ | Rulers, grids, tiles, export | [Sundries](https://sevgi.roktas.dev/sundries/) | [`sevgi-sundries`](https://www.rubydoc.info/gems/sevgi-sundries) |
45
+ | Shared helpers | [Functions](https://sevgi.roktas.dev/functions/) | [`sevgi-function`](https://www.rubydoc.info/gems/sevgi-function) |
46
+ | SVG/XML import and round trip | [Derender](https://sevgi.roktas.dev/derender/) | [`sevgi-derender`](https://www.rubydoc.info/gems/sevgi-derender) |
47
+
48
+ When working in a Sevgi checkout, prefer the checked-out docs and source over an installed gem's online YARD version.
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop/cop/style/block_delimiters"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ # Cops that preserve the visual rhythm of executable Sevgi DSL source.
8
+ module Sevgi
9
+ # Uses braces for one-line blocks and do/end for multiline blocks.
10
+ class BlockDelimiters < Style::BlockDelimiters
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop/cop/style/method_call_with_args_parentheses"
4
+
5
+ module RuboCop
6
+ # RuboCop's custom-cop namespace.
7
+ module Cop
8
+ module Sevgi
9
+ # Omits optional parentheses from bare DSL-shaped calls and capitalized Sevgi operations.
10
+ #
11
+ # Ordinary Ruby calls with explicit receivers retain their normal style. The inherited RuboCop implementation
12
+ # still preserves parentheses where Ruby syntax or expression binding benefits from them.
13
+ class Parentheses < Style::MethodCallWithArgsParentheses
14
+ # Checks a method call when its shape belongs to the Sevgi drawing vocabulary.
15
+ # @param node [RuboCop::AST::SendNode] method call
16
+ # @return [void]
17
+ def on_send(node)
18
+ return if node.method_name.end_with?("?")
19
+
20
+ super if node.receiver.nil? || node.method_name.match?(/\A[A-Z]/)
21
+ end
22
+
23
+ alias on_csend on_send
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop/cop/style/string_literals"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sevgi
8
+ # Uses double-quoted strings consistently in Sevgi DSL source.
9
+ class StringLiterals < Style::StringLiterals
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sevgi/block_delimiters"
4
+ require_relative "sevgi/parentheses"
5
+ require_relative "sevgi/string_literals"
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lint_roller"
4
+
5
+ require_relative "../../sevgi/appendix"
6
+
7
+ # RuboCop integration shipped with Sevgi Appendix.
8
+ module RuboCop
9
+ # Sevgi DSL integration for RuboCop.
10
+ module Sevgi
11
+ # Connects Sevgi's `.sevgi` rules to RuboCop's plugin system.
12
+ class Plugin < LintRoller::Plugin
13
+ # Describes this plugin to lint_roller.
14
+ # @return [LintRoller::About] plugin metadata
15
+ def about
16
+ LintRoller::About.new(
17
+ name: "sevgi-appendix",
18
+ version: ::Sevgi::Appendix::VERSION,
19
+ homepage: "https://sevgi.roktas.dev",
20
+ description: "RuboCop rules for the Sevgi SVG DSL"
21
+ )
22
+ end
23
+
24
+ # Reports whether this plugin supports the requested lint engine.
25
+ # @param context [LintRoller::Context] lint engine context
26
+ # @return [Boolean] true for RuboCop
27
+ def supported?(context) = context.engine == :rubocop
28
+
29
+ # Returns the RuboCop configuration bundled with this gem.
30
+ # @param _context [LintRoller::Context] lint engine context
31
+ # @return [LintRoller::Rules] path-backed RuboCop rules
32
+ def rules(_context)
33
+ LintRoller::Rules.new(
34
+ type: :path,
35
+ config_format: :rubocop,
36
+ value: File.expand_path("../../../rubocop/config/default.yml", __dir__)
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ require_relative "cop/sevgi_cops"
6
+ require_relative "sevgi/plugin"
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ module Appendix
5
+ # Appendix package version.
6
+ VERSION = "0.98.2"
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "appendix/version"
4
+
5
+ module Sevgi
6
+ # Development extras distributed with Sevgi but kept outside its drawing runtime.
7
+ module Appendix
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sevgi/appendix"
4
+ require_relative "rubocop/sevgi"
@@ -0,0 +1,67 @@
1
+ AllCops:
2
+ Include:
3
+ - "**/*.sevgi"
4
+
5
+ Sevgi:
6
+ Enabled: true
7
+ Include:
8
+ - "**/*.sevgi"
9
+
10
+ Sevgi/BlockDelimiters:
11
+ Description: "Use braces for one-line blocks and do/end for multiline blocks in Sevgi DSL source."
12
+ EnforcedStyle: line_count_based
13
+ SupportedStyles:
14
+ - line_count_based
15
+ - semantic
16
+ - braces_for_chaining
17
+ - always_braces
18
+ ProceduralMethods:
19
+ - benchmark
20
+ - bm
21
+ - bmbm
22
+ - create
23
+ - each_with_object
24
+ - measure
25
+ - new
26
+ - realtime
27
+ - tap
28
+ - with_object
29
+ FunctionalMethods:
30
+ - let
31
+ - let!
32
+ - subject
33
+ - watch
34
+ AllowedMethods:
35
+ - lambda
36
+ - proc
37
+ - it
38
+ AllowedPatterns: []
39
+ AllowBracesOnProceduralOneLiners: false
40
+ BracesRequiredMethods: []
41
+ VersionAdded: "0.97.0"
42
+
43
+ Sevgi/Parentheses:
44
+ Description: "Omit optional parentheses from bare DSL calls and capitalized Sevgi operations."
45
+ EnforcedStyle: omit_parentheses
46
+ SupportedStyles:
47
+ - require_parentheses
48
+ - omit_parentheses
49
+ IgnoreMacros: true
50
+ AllowedMethods: []
51
+ AllowedPatterns: []
52
+ IncludedMacros: []
53
+ IncludedMacroPatterns: []
54
+ AllowParenthesesInMultilineCall: true
55
+ AllowParenthesesInChaining: true
56
+ AllowParenthesesInCamelCaseMethod: false
57
+ AllowParenthesesInStringInterpolation: true
58
+ VersionAdded: "0.97.0"
59
+
60
+ Sevgi/StringLiterals:
61
+ Description: "Use double-quoted strings in Sevgi DSL source."
62
+ EnforcedStyle: double_quotes
63
+ SupportedStyles:
64
+ - single_quotes
65
+ - double_quotes
66
+ ConsistentQuotesInMultiline: false
67
+ VersionAdded: "0.97.0"
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sevgi-appendix
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.98.2
5
+ platform: ruby
6
+ authors:
7
+ - Recai Oktaş
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: lint_roller
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rubocop
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.72.2
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '2.0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.72.2
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '2.0'
46
+ description: Packages the Sevgi agent skill and RuboCop rules for readable .sevgi
47
+ source.
48
+ email: roktas@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - CHANGELOG.md
54
+ - LICENSE
55
+ - README.md
56
+ - agents/skills/sevgi/SKILL.md
57
+ - agents/skills/sevgi/agents/openai.yaml
58
+ - agents/skills/sevgi/references/derender.md
59
+ - agents/skills/sevgi/references/drawing.md
60
+ - agents/skills/sevgi/references/dsl.md
61
+ - agents/skills/sevgi/references/inspection.md
62
+ - agents/skills/sevgi/references/layout.md
63
+ - agents/skills/sevgi/references/output.md
64
+ - agents/skills/sevgi/references/ruby.md
65
+ - agents/skills/sevgi/references/svg.md
66
+ - agents/skills/sevgi/references/toolkit.md
67
+ - lib/rubocop/cop/sevgi/block_delimiters.rb
68
+ - lib/rubocop/cop/sevgi/parentheses.rb
69
+ - lib/rubocop/cop/sevgi/string_literals.rb
70
+ - lib/rubocop/cop/sevgi_cops.rb
71
+ - lib/rubocop/sevgi.rb
72
+ - lib/rubocop/sevgi/plugin.rb
73
+ - lib/sevgi-appendix.rb
74
+ - lib/sevgi/appendix.rb
75
+ - lib/sevgi/appendix/version.rb
76
+ - rubocop/config/default.yml
77
+ homepage: https://sevgi.roktas.dev
78
+ licenses:
79
+ - GPL-3.0-or-later
80
+ metadata:
81
+ changelog_uri: https://github.com/roktas/sevgi/blob/main/CHANGELOG.md
82
+ source_code_uri: https://github.com/roktas/sevgi/tree/main/appendix
83
+ bug_tracker_uri: https://github.com/roktas/sevgi/issues
84
+ rubygems_mfa_required: 'true'
85
+ default_lint_roller_plugin: RuboCop::Sevgi::Plugin
86
+ sevgi_skill_path: agents/skills/sevgi
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 3.4.0
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 4.0.16
102
+ specification_version: 4
103
+ summary: Development extras for the Sevgi SVG DSL.
104
+ test_files: []