sevgi-showcase 0.93.1 → 0.94.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 +4 -0
- data/LICENSE +5 -0
- data/README.md +50 -2
- data/lib/sevgi/showcase/dark.rb +64 -0
- data/lib/sevgi/showcase/minitest/shell.rb +59 -13
- data/lib/sevgi/showcase/version.rb +1 -1
- data/lib/sevgi/showcase.rb +1 -0
- data/srv/checker-board.sevgi +1 -1
- data/srv/checker-board.svg +1 -1
- data/srv/gear-wheel.sevgi +7 -2
- data/srv/gear-wheel.svg +3 -2
- data/srv/grid-cells.sevgi +6 -2
- data/srv/grid-cells.svg +25 -26
- data/srv/heart-mask.sevgi +5 -2
- data/srv/heart-mask.svg +2 -2
- data/srv/meter-face.sevgi +1 -1
- data/srv/meter-face.svg +1 -1
- data/srv/ruler-hline.sevgi +25 -22
- data/srv/ruler-hline.svg +90 -90
- data/srv/ruler-hline.yml +0 -1
- data/srv/ruler-line.yml +0 -1
- data/srv/snow-flake.yml +1 -3
- metadata +7 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36b54e0f7d4b51e0815f49a28194c841e5e56ace94742c2598f95dcf4677e72c
|
|
4
|
+
data.tar.gz: b31295af208cee2aa2aad3061556f9848190c78610733510e73dd557b541995e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 646bd6e535ee9c3d61efbc49ee0e443dec23af2e94cd5b16210bae05f0a70e1a68cbf75272efbcb1d9b2af7ab84d55a2fca470b8bb15f4a806b99822bc30432e
|
|
7
|
+
data.tar.gz: 7ff66e247c4d5f0a98dd9fd69b27ee7e14088f67390482fd596630d1a21067fc9c9a16983af747201f44479bba547bb36f8001af26486adb0d2e1d2be5ed1f08
|
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
data/README.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Sevgi Showcase
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Executable examples, rendered outputs, and documentation-site support.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
gem install sevgi-showcase
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Require
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
require "sevgi/showcase"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
suite = Sevgi::Test::Suite.new("srv")
|
|
21
|
+
suite.valids.map(&:name)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Ruby compatibility
|
|
25
|
+
|
|
26
|
+
Requires Ruby 3.4.0 or newer. CI verifies Ruby 3.4 and the current development Ruby from `.ruby-version`.
|
|
27
|
+
|
|
28
|
+
## Native prerequisites
|
|
29
|
+
|
|
30
|
+
Showcase examples use the top-level Sevgi stack. SVG-only examples need no native export gems.
|
|
31
|
+
|
|
32
|
+
PDF/PNG export workflows match `sevgi-sundries` and require the optional Ruby gems `cairo`, `rsvg2`, and `hexapdf`.
|
|
33
|
+
On Debian/Ubuntu:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
sudo apt-get update
|
|
37
|
+
sudo apt-get install -y libcairo2-dev libgdk-pixbuf-2.0-dev libgirepository1.0-dev libglib2.0-dev librsvg2-dev pkg-config
|
|
38
|
+
gem install cairo rsvg2 hexapdf
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
On macOS with Homebrew:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
brew install cairo gdk-pixbuf gobject-introspection librsvg pkg-config
|
|
45
|
+
gem install cairo rsvg2 hexapdf
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Links
|
|
49
|
+
|
|
50
|
+
- Documentation: https://sevgi.roktas.dev
|
|
51
|
+
- API documentation: https://www.rubydoc.info/gems/sevgi-showcase
|
|
52
|
+
- Source: https://github.com/roktas/sevgi/tree/main/showcase
|
|
53
|
+
- Changelog: https://github.com/roktas/sevgi/blob/main/CHANGELOG.md
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sevgi
|
|
4
|
+
module Showcase
|
|
5
|
+
# Applies dark-theme color mappings to showcase source files.
|
|
6
|
+
# @api private
|
|
7
|
+
module Dark
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
# Applies a color mapping to source text.
|
|
11
|
+
# @param source [String] source text
|
|
12
|
+
# @param mapping [Hash{String => String}] source color to dark color mapping
|
|
13
|
+
# @return [String] transformed source text
|
|
14
|
+
# @raise [Sevgi::ArgumentError] when a mapping key is not found
|
|
15
|
+
def apply(source, mapping)
|
|
16
|
+
applied = Hash.new(0)
|
|
17
|
+
content = replace_quoted(source, mapping, applied)
|
|
18
|
+
content = replace_percent_words(content, mapping, applied)
|
|
19
|
+
missing = mapping.keys.reject { applied[it].positive? }
|
|
20
|
+
|
|
21
|
+
ArgumentError.("Unapplied dark mapping(s): #{missing.join(", ")}") unless missing.empty?
|
|
22
|
+
|
|
23
|
+
content
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Applies a color mapping to a source file and preserves its mode.
|
|
27
|
+
# @param source [String] source file path
|
|
28
|
+
# @param target [String] target file path
|
|
29
|
+
# @param mapping [Hash{String => String}] source color to dark color mapping
|
|
30
|
+
# @return [String] target file path
|
|
31
|
+
# @raise [Sevgi::ArgumentError] when a mapping key is not found
|
|
32
|
+
def apply_file(source, target, mapping)
|
|
33
|
+
target.tap do
|
|
34
|
+
File.write(target, apply(File.read(source), mapping))
|
|
35
|
+
File.chmod(File.stat(source).mode & 0o777, target)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def replace_percent_words(source, mapping, applied)
|
|
42
|
+
source.gsub(/%[wW]\[[^\]]*\]/m) do |literal|
|
|
43
|
+
mapping.reduce(literal) do |text, (key, value)|
|
|
44
|
+
text.gsub(/(^|[\s\[])(#{Regexp.escape(key)})(?=$|[\s\]])/) do
|
|
45
|
+
applied[key] += 1
|
|
46
|
+
"#{Regexp.last_match(1)}#{value}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def replace_quoted(source, mapping, applied)
|
|
53
|
+
source.gsub(/(?<quote>["'])(?<value>.*?)\k<quote>/) do |literal|
|
|
54
|
+
key = Regexp.last_match[:value]
|
|
55
|
+
value = mapping[key]
|
|
56
|
+
next literal unless value
|
|
57
|
+
|
|
58
|
+
applied[key] += 1
|
|
59
|
+
"#{Regexp.last_match[:quote]}#{value}#{Regexp.last_match[:quote]}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -45,11 +45,13 @@ module Sevgi
|
|
|
45
45
|
|
|
46
46
|
# Runs a command and captures stdout, stderr, and exit status.
|
|
47
47
|
# @param args [Array<String>] command and arguments
|
|
48
|
+
# @yield optional stdin writer evaluated with stdin as receiver
|
|
49
|
+
# @yieldreturn [Object]
|
|
48
50
|
# @return [Sevgi::Test::Shell::Result]
|
|
51
|
+
# @raise [StandardError] when the input block raises; the child is terminated and reaped before propagation
|
|
49
52
|
def run(*args, &block)
|
|
50
53
|
out, err, status = Open3.popen3(*args) do |stdin, stdout, stderr, thread|
|
|
51
|
-
|
|
52
|
-
outputs(stdout, stderr, thread)
|
|
54
|
+
capture(stdin, stdout, stderr, thread, &block)
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
Result[args, out, err, status.exitstatus]
|
|
@@ -57,22 +59,39 @@ module Sevgi
|
|
|
57
59
|
|
|
58
60
|
private
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
stdin.close unless stdin.closed?
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def outputs(stdout, stderr, thread)
|
|
66
|
-
# handle `^C`
|
|
62
|
+
# rubocop:disable Lint/RescueException
|
|
63
|
+
def capture(stdin, stdout, stderr, thread, &block)
|
|
67
64
|
trap = trap("INT") { handle_sigint(thread.pid) }
|
|
65
|
+
readers = outputs(stdout, stderr)
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
collect_capture(stdin, thread, readers, &block)
|
|
68
|
+
rescue Exception
|
|
69
|
+
cleanup_failed_capture(stdin, thread, readers)
|
|
70
|
+
raise
|
|
73
71
|
ensure
|
|
72
|
+
close_input(stdin)
|
|
74
73
|
trap("INT", trap) if trap
|
|
75
74
|
end
|
|
75
|
+
# rubocop:enable Lint/RescueException
|
|
76
|
+
|
|
77
|
+
def cleanup_failed_capture(stdin, thread, readers)
|
|
78
|
+
close_input(stdin)
|
|
79
|
+
stop_process(thread)
|
|
80
|
+
Array(readers).each(&:join)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def close_input(stdin)
|
|
84
|
+
stdin.close unless stdin.closed?
|
|
85
|
+
rescue IOError
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def collect_capture(stdin, thread, readers, &block)
|
|
90
|
+
inputs(stdin, thread, &block)
|
|
91
|
+
close_input(stdin)
|
|
92
|
+
|
|
93
|
+
[readers[0].value, readers[1].value, thread.value]
|
|
94
|
+
end
|
|
76
95
|
|
|
77
96
|
def handle_sigint(pid)
|
|
78
97
|
message, signal = if @coathooks > 1
|
|
@@ -87,6 +106,33 @@ module Sevgi
|
|
|
87
106
|
rescue Errno::ESRCH
|
|
88
107
|
warn("No process to kill.")
|
|
89
108
|
end
|
|
109
|
+
|
|
110
|
+
def inputs(stdin, thread, &block)
|
|
111
|
+
stdin.instance_exec(thread, &block) if block
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def kill_process(signal, pid)
|
|
115
|
+
::Process.kill(signal, pid)
|
|
116
|
+
rescue Errno::ESRCH
|
|
117
|
+
nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def outputs(stdout, stderr)
|
|
121
|
+
[
|
|
122
|
+
Thread.new { stdout.readlines.map(&:chomp) },
|
|
123
|
+
Thread.new { stderr.readlines.map(&:chomp) }
|
|
124
|
+
]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def stop_process(thread)
|
|
128
|
+
return unless thread&.alive?
|
|
129
|
+
|
|
130
|
+
kill_process("TERM", thread.pid)
|
|
131
|
+
return if thread.join(1)
|
|
132
|
+
|
|
133
|
+
kill_process("KILL", thread.pid)
|
|
134
|
+
thread.join
|
|
135
|
+
end
|
|
90
136
|
end
|
|
91
137
|
|
|
92
138
|
extend self
|
data/lib/sevgi/showcase.rb
CHANGED
data/srv/checker-board.sevgi
CHANGED
data/srv/checker-board.svg
CHANGED
data/srv/gear-wheel.sevgi
CHANGED
|
@@ -6,8 +6,13 @@ GEAR_STYLE = {
|
|
|
6
6
|
stroke: "none"
|
|
7
7
|
}.freeze
|
|
8
8
|
|
|
9
|
-
SVG :minimal, viewBox: "0 0 100 100"
|
|
10
|
-
|
|
9
|
+
SVG :minimal, width: 100, height: 100, viewBox: "0 0 100 100" do
|
|
10
|
+
rect x: 0, y: 0, width: 100, height: 100, fill: "lightgreen"
|
|
11
|
+
|
|
12
|
+
mask id: "hole",
|
|
13
|
+
maskUnits: "userSpaceOnUse",
|
|
14
|
+
maskContentUnits: "userSpaceOnUse",
|
|
15
|
+
x: 0, y: 0, width: 100, height: 100 do
|
|
11
16
|
rect x: 0, y: 0, width: 100, height: 100, fill: "white"
|
|
12
17
|
circle cx: 50, cy: 50, r: 15, fill: "black"
|
|
13
18
|
end
|
data/srv/gear-wheel.svg
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
<svg viewBox="0 0 100 100"
|
|
2
|
-
<
|
|
1
|
+
<svg width="100" height="100" viewBox="0 0 100 100">
|
|
2
|
+
<rect x="0" y="0" width="100" height="100" fill="lightgreen"/>
|
|
3
|
+
<mask id="hole" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
|
|
3
4
|
<rect x="0" y="0" width="100" height="100" fill="white"/>
|
|
4
5
|
<circle cx="50" cy="50" r="15" fill="black"/>
|
|
5
6
|
</mask>
|
data/srv/grid-cells.sevgi
CHANGED
|
@@ -6,14 +6,18 @@ COLORS = %w[#FF6961 #77DD77 #FFD700].freeze
|
|
|
6
6
|
COLS = 8
|
|
7
7
|
ROWS = 3
|
|
8
8
|
|
|
9
|
-
SVG :minimal,
|
|
10
|
-
|
|
9
|
+
SVG :minimal,
|
|
10
|
+
width: COLS * CELL_SIZE,
|
|
11
|
+
height: ROWS * CELL_SIZE,
|
|
12
|
+
viewBox: "0 0 #{COLS * CELL_SIZE} #{ROWS * CELL_SIZE}" do
|
|
13
|
+
css ".cell" => { stroke: "white" }
|
|
11
14
|
|
|
12
15
|
COLS.times do |col|
|
|
13
16
|
ROWS.times do |row|
|
|
14
17
|
rect class: "cell",
|
|
15
18
|
x: col * CELL_SIZE, y: row * CELL_SIZE,
|
|
16
19
|
width: CELL_SIZE, height: CELL_SIZE,
|
|
20
|
+
rx: (CELL_SIZE * 0.1).round,
|
|
17
21
|
fill: COLORS[(col + row) % COLORS.length]
|
|
18
22
|
end
|
|
19
23
|
end
|
data/srv/grid-cells.svg
CHANGED
|
@@ -1,34 +1,33 @@
|
|
|
1
|
-
<svg viewBox="0 0 160 60">
|
|
1
|
+
<svg width="160" height="60" viewBox="0 0 160 60">
|
|
2
2
|
<style type="text/css">
|
|
3
3
|
<![CDATA[
|
|
4
4
|
.cell {
|
|
5
5
|
stroke: white;
|
|
6
|
-
rx: 2;
|
|
7
6
|
}
|
|
8
7
|
]]>
|
|
9
8
|
</style>
|
|
10
|
-
<rect class="cell" x="0" y="0" width="20" height="20" fill="#FF6961"/>
|
|
11
|
-
<rect class="cell" x="0" y="20" width="20" height="20" fill="#77DD77"/>
|
|
12
|
-
<rect class="cell" x="0" y="40" width="20" height="20" fill="#FFD700"/>
|
|
13
|
-
<rect class="cell" x="20" y="0" width="20" height="20" fill="#77DD77"/>
|
|
14
|
-
<rect class="cell" x="20" y="20" width="20" height="20" fill="#FFD700"/>
|
|
15
|
-
<rect class="cell" x="20" y="40" width="20" height="20" fill="#FF6961"/>
|
|
16
|
-
<rect class="cell" x="40" y="0" width="20" height="20" fill="#FFD700"/>
|
|
17
|
-
<rect class="cell" x="40" y="20" width="20" height="20" fill="#FF6961"/>
|
|
18
|
-
<rect class="cell" x="40" y="40" width="20" height="20" fill="#77DD77"/>
|
|
19
|
-
<rect class="cell" x="60" y="0" width="20" height="20" fill="#FF6961"/>
|
|
20
|
-
<rect class="cell" x="60" y="20" width="20" height="20" fill="#77DD77"/>
|
|
21
|
-
<rect class="cell" x="60" y="40" width="20" height="20" fill="#FFD700"/>
|
|
22
|
-
<rect class="cell" x="80" y="0" width="20" height="20" fill="#77DD77"/>
|
|
23
|
-
<rect class="cell" x="80" y="20" width="20" height="20" fill="#FFD700"/>
|
|
24
|
-
<rect class="cell" x="80" y="40" width="20" height="20" fill="#FF6961"/>
|
|
25
|
-
<rect class="cell" x="100" y="0" width="20" height="20" fill="#FFD700"/>
|
|
26
|
-
<rect class="cell" x="100" y="20" width="20" height="20" fill="#FF6961"/>
|
|
27
|
-
<rect class="cell" x="100" y="40" width="20" height="20" fill="#77DD77"/>
|
|
28
|
-
<rect class="cell" x="120" y="0" width="20" height="20" fill="#FF6961"/>
|
|
29
|
-
<rect class="cell" x="120" y="20" width="20" height="20" fill="#77DD77"/>
|
|
30
|
-
<rect class="cell" x="120" y="40" width="20" height="20" fill="#FFD700"/>
|
|
31
|
-
<rect class="cell" x="140" y="0" width="20" height="20" fill="#77DD77"/>
|
|
32
|
-
<rect class="cell" x="140" y="20" width="20" height="20" fill="#FFD700"/>
|
|
33
|
-
<rect class="cell" x="140" y="40" width="20" height="20" fill="#FF6961"/>
|
|
9
|
+
<rect class="cell" x="0" y="0" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
10
|
+
<rect class="cell" x="0" y="20" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
11
|
+
<rect class="cell" x="0" y="40" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
12
|
+
<rect class="cell" x="20" y="0" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
13
|
+
<rect class="cell" x="20" y="20" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
14
|
+
<rect class="cell" x="20" y="40" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
15
|
+
<rect class="cell" x="40" y="0" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
16
|
+
<rect class="cell" x="40" y="20" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
17
|
+
<rect class="cell" x="40" y="40" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
18
|
+
<rect class="cell" x="60" y="0" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
19
|
+
<rect class="cell" x="60" y="20" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
20
|
+
<rect class="cell" x="60" y="40" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
21
|
+
<rect class="cell" x="80" y="0" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
22
|
+
<rect class="cell" x="80" y="20" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
23
|
+
<rect class="cell" x="80" y="40" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
24
|
+
<rect class="cell" x="100" y="0" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
25
|
+
<rect class="cell" x="100" y="20" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
26
|
+
<rect class="cell" x="100" y="40" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
27
|
+
<rect class="cell" x="120" y="0" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
28
|
+
<rect class="cell" x="120" y="20" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
29
|
+
<rect class="cell" x="120" y="40" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
30
|
+
<rect class="cell" x="140" y="0" width="20" height="20" rx="2" fill="#77DD77"/>
|
|
31
|
+
<rect class="cell" x="140" y="20" width="20" height="20" rx="2" fill="#FFD700"/>
|
|
32
|
+
<rect class="cell" x="140" y="40" width="20" height="20" rx="2" fill="#FF6961"/>
|
|
34
33
|
</svg>
|
data/srv/heart-mask.sevgi
CHANGED
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
HEART_PATH = "M10,35 A20,20,0,0,1,50,35 A20,20,0,0,1,90,35 Q90,65,50,95 Q10,65,10,35 Z"
|
|
5
5
|
|
|
6
|
-
SVG :minimal, viewBox: "-10 -10 120 120" do
|
|
7
|
-
mask id: "heart"
|
|
6
|
+
SVG :minimal, width: 120, height: 120, viewBox: "-10 -10 120 120" do
|
|
7
|
+
mask id: "heart",
|
|
8
|
+
maskUnits: "userSpaceOnUse",
|
|
9
|
+
maskContentUnits: "userSpaceOnUse",
|
|
10
|
+
x: 0, y: 0, width: 100, height: 100 do
|
|
8
11
|
rect x: 0, y: 0, width: 100, height: 100, fill: "white"
|
|
9
12
|
path d: HEART_PATH, fill: "black"
|
|
10
13
|
end
|
data/srv/heart-mask.svg
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<svg viewBox="-10 -10 120 120">
|
|
2
|
-
<mask id="heart">
|
|
1
|
+
<svg width="120" height="120" viewBox="-10 -10 120 120">
|
|
2
|
+
<mask id="heart" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
|
|
3
3
|
<rect x="0" y="0" width="100" height="100" fill="white"/>
|
|
4
4
|
<path d="M10,35 A20,20,0,0,1,50,35 A20,20,0,0,1,90,35 Q90,65,50,95 Q10,65,10,35 Z" fill="black"/>
|
|
5
5
|
</mask>
|
data/srv/meter-face.sevgi
CHANGED
|
@@ -6,7 +6,7 @@ LED_GAP = 2
|
|
|
6
6
|
LED_WIDTH = 10
|
|
7
7
|
TOTAL_WIDTH = (LED_COUNT * (LED_WIDTH + LED_GAP)) + 8
|
|
8
8
|
|
|
9
|
-
SVG :minimal, viewBox: "0 0 #{TOTAL_WIDTH} 30" do
|
|
9
|
+
SVG :minimal, width: TOTAL_WIDTH, height: 30, viewBox: "0 0 #{TOTAL_WIDTH} 30" do
|
|
10
10
|
rect x: 2, y: 2, width: TOTAL_WIDTH - 4, height: 26,
|
|
11
11
|
rx: 4, fill: "none", stroke: "#666"
|
|
12
12
|
|
data/srv/meter-face.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg viewBox="0 0 128 30">
|
|
1
|
+
<svg width="128" height="30" viewBox="0 0 128 30">
|
|
2
2
|
<rect x="2" y="2" width="124" height="26" rx="4" fill="none" stroke="#666"/>
|
|
3
3
|
<rect x="5" y="5" width="10" height="20" rx="3" fill="green" fill-opacity="1"/>
|
|
4
4
|
<rect x="17" y="5" width="10" height="20" rx="3" fill="green" fill-opacity="1"/>
|
data/srv/ruler-hline.sevgi
CHANGED
|
@@ -1,52 +1,55 @@
|
|
|
1
1
|
#!/usr/bin/env -S ruby -S sevgi
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
# 15 cm width (ruler's length)
|
|
5
|
+
WIDTH = 150
|
|
6
|
+
# 2 cm height
|
|
7
|
+
HEIGHT = 20
|
|
6
8
|
|
|
7
9
|
STYLE = {
|
|
8
|
-
".labels": {
|
|
9
|
-
".majors": {
|
|
10
|
-
".halves": {
|
|
11
|
-
".minors": {
|
|
12
|
-
".frame":
|
|
10
|
+
".labels": {fill: "black", font: "3pt monospace"},
|
|
11
|
+
".majors": {stroke: "black", "stroke-width": 0.2},
|
|
12
|
+
".halves": {stroke: "black", "stroke-width": 0.1},
|
|
13
|
+
".minors": {stroke: "black", "stroke-width": 0.1},
|
|
14
|
+
".frame": {stroke: "black", "stroke-width": 0.1, fill: "none"}
|
|
13
15
|
}.freeze
|
|
14
16
|
|
|
15
|
-
SVG
|
|
16
|
-
css
|
|
17
|
+
SVG(width: "210mm", height: "50mm", viewBox: "0 0 210 50") do
|
|
18
|
+
css(STYLE)
|
|
17
19
|
|
|
18
|
-
rect
|
|
20
|
+
rect(id: "frame", width: WIDTH, height: HEIGHT, class: "frame")
|
|
19
21
|
|
|
20
|
-
layer
|
|
22
|
+
layer(id: "minors") do
|
|
21
23
|
length = 2
|
|
22
24
|
|
|
23
25
|
(0..WIDTH).step(1) do |x|
|
|
24
|
-
VLineBy
|
|
25
|
-
VLineBy
|
|
26
|
+
VLineBy(x:, y: 0, length: length, class: "minors")
|
|
27
|
+
VLineBy(x:, y: HEIGHT, length: -length, class: "minors")
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
|
|
29
|
-
layer
|
|
31
|
+
layer(id: "halves") do
|
|
30
32
|
length = 4
|
|
31
33
|
|
|
32
34
|
(0..WIDTH).step(5) do |x|
|
|
33
|
-
VLineBy
|
|
34
|
-
VLineBy
|
|
35
|
+
VLineBy(x:, y: 0, length: length, class: "halves")
|
|
36
|
+
VLineBy(x:, y: HEIGHT, length: -length, class: "halves")
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
layer
|
|
40
|
+
layer(id: "majors") do
|
|
39
41
|
length = 6
|
|
40
42
|
|
|
41
43
|
(10..(WIDTH - 10)).step(10) do |x|
|
|
42
|
-
VLineBy
|
|
43
|
-
VLineBy
|
|
44
|
+
VLineBy(x:, y: 0, length: length, class: "majors")
|
|
45
|
+
VLineBy(x:, y: HEIGHT, length: -length, class: "majors")
|
|
44
46
|
end
|
|
45
47
|
|
|
46
|
-
layer
|
|
48
|
+
layer(id: "labels") do
|
|
47
49
|
(10..(WIDTH - 10)).step(10).each_with_index do |x, i|
|
|
48
|
-
text
|
|
50
|
+
text((i + 1).to_s, "text-anchor": "middle", x:, y: length + 5.5, class: "labels")
|
|
49
51
|
end
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
|
-
end
|
|
54
|
+
end
|
|
55
|
+
.Save()
|
data/srv/ruler-hline.svg
CHANGED
|
@@ -331,98 +331,98 @@
|
|
|
331
331
|
<path d="M 150 20 v -2" class="minors"/>
|
|
332
332
|
</g>
|
|
333
333
|
<g id="halves">
|
|
334
|
-
<path d="M 0 0 v 4" class="
|
|
335
|
-
<path d="M 0 20 v -4" class="
|
|
336
|
-
<path d="M 5 0 v 4" class="
|
|
337
|
-
<path d="M 5 20 v -4" class="
|
|
338
|
-
<path d="M 10 0 v 4" class="
|
|
339
|
-
<path d="M 10 20 v -4" class="
|
|
340
|
-
<path d="M 15 0 v 4" class="
|
|
341
|
-
<path d="M 15 20 v -4" class="
|
|
342
|
-
<path d="M 20 0 v 4" class="
|
|
343
|
-
<path d="M 20 20 v -4" class="
|
|
344
|
-
<path d="M 25 0 v 4" class="
|
|
345
|
-
<path d="M 25 20 v -4" class="
|
|
346
|
-
<path d="M 30 0 v 4" class="
|
|
347
|
-
<path d="M 30 20 v -4" class="
|
|
348
|
-
<path d="M 35 0 v 4" class="
|
|
349
|
-
<path d="M 35 20 v -4" class="
|
|
350
|
-
<path d="M 40 0 v 4" class="
|
|
351
|
-
<path d="M 40 20 v -4" class="
|
|
352
|
-
<path d="M 45 0 v 4" class="
|
|
353
|
-
<path d="M 45 20 v -4" class="
|
|
354
|
-
<path d="M 50 0 v 4" class="
|
|
355
|
-
<path d="M 50 20 v -4" class="
|
|
356
|
-
<path d="M 55 0 v 4" class="
|
|
357
|
-
<path d="M 55 20 v -4" class="
|
|
358
|
-
<path d="M 60 0 v 4" class="
|
|
359
|
-
<path d="M 60 20 v -4" class="
|
|
360
|
-
<path d="M 65 0 v 4" class="
|
|
361
|
-
<path d="M 65 20 v -4" class="
|
|
362
|
-
<path d="M 70 0 v 4" class="
|
|
363
|
-
<path d="M 70 20 v -4" class="
|
|
364
|
-
<path d="M 75 0 v 4" class="
|
|
365
|
-
<path d="M 75 20 v -4" class="
|
|
366
|
-
<path d="M 80 0 v 4" class="
|
|
367
|
-
<path d="M 80 20 v -4" class="
|
|
368
|
-
<path d="M 85 0 v 4" class="
|
|
369
|
-
<path d="M 85 20 v -4" class="
|
|
370
|
-
<path d="M 90 0 v 4" class="
|
|
371
|
-
<path d="M 90 20 v -4" class="
|
|
372
|
-
<path d="M 95 0 v 4" class="
|
|
373
|
-
<path d="M 95 20 v -4" class="
|
|
374
|
-
<path d="M 100 0 v 4" class="
|
|
375
|
-
<path d="M 100 20 v -4" class="
|
|
376
|
-
<path d="M 105 0 v 4" class="
|
|
377
|
-
<path d="M 105 20 v -4" class="
|
|
378
|
-
<path d="M 110 0 v 4" class="
|
|
379
|
-
<path d="M 110 20 v -4" class="
|
|
380
|
-
<path d="M 115 0 v 4" class="
|
|
381
|
-
<path d="M 115 20 v -4" class="
|
|
382
|
-
<path d="M 120 0 v 4" class="
|
|
383
|
-
<path d="M 120 20 v -4" class="
|
|
384
|
-
<path d="M 125 0 v 4" class="
|
|
385
|
-
<path d="M 125 20 v -4" class="
|
|
386
|
-
<path d="M 130 0 v 4" class="
|
|
387
|
-
<path d="M 130 20 v -4" class="
|
|
388
|
-
<path d="M 135 0 v 4" class="
|
|
389
|
-
<path d="M 135 20 v -4" class="
|
|
390
|
-
<path d="M 140 0 v 4" class="
|
|
391
|
-
<path d="M 140 20 v -4" class="
|
|
392
|
-
<path d="M 145 0 v 4" class="
|
|
393
|
-
<path d="M 145 20 v -4" class="
|
|
394
|
-
<path d="M 150 0 v 4" class="
|
|
395
|
-
<path d="M 150 20 v -4" class="
|
|
334
|
+
<path d="M 0 0 v 4" class="halves"/>
|
|
335
|
+
<path d="M 0 20 v -4" class="halves"/>
|
|
336
|
+
<path d="M 5 0 v 4" class="halves"/>
|
|
337
|
+
<path d="M 5 20 v -4" class="halves"/>
|
|
338
|
+
<path d="M 10 0 v 4" class="halves"/>
|
|
339
|
+
<path d="M 10 20 v -4" class="halves"/>
|
|
340
|
+
<path d="M 15 0 v 4" class="halves"/>
|
|
341
|
+
<path d="M 15 20 v -4" class="halves"/>
|
|
342
|
+
<path d="M 20 0 v 4" class="halves"/>
|
|
343
|
+
<path d="M 20 20 v -4" class="halves"/>
|
|
344
|
+
<path d="M 25 0 v 4" class="halves"/>
|
|
345
|
+
<path d="M 25 20 v -4" class="halves"/>
|
|
346
|
+
<path d="M 30 0 v 4" class="halves"/>
|
|
347
|
+
<path d="M 30 20 v -4" class="halves"/>
|
|
348
|
+
<path d="M 35 0 v 4" class="halves"/>
|
|
349
|
+
<path d="M 35 20 v -4" class="halves"/>
|
|
350
|
+
<path d="M 40 0 v 4" class="halves"/>
|
|
351
|
+
<path d="M 40 20 v -4" class="halves"/>
|
|
352
|
+
<path d="M 45 0 v 4" class="halves"/>
|
|
353
|
+
<path d="M 45 20 v -4" class="halves"/>
|
|
354
|
+
<path d="M 50 0 v 4" class="halves"/>
|
|
355
|
+
<path d="M 50 20 v -4" class="halves"/>
|
|
356
|
+
<path d="M 55 0 v 4" class="halves"/>
|
|
357
|
+
<path d="M 55 20 v -4" class="halves"/>
|
|
358
|
+
<path d="M 60 0 v 4" class="halves"/>
|
|
359
|
+
<path d="M 60 20 v -4" class="halves"/>
|
|
360
|
+
<path d="M 65 0 v 4" class="halves"/>
|
|
361
|
+
<path d="M 65 20 v -4" class="halves"/>
|
|
362
|
+
<path d="M 70 0 v 4" class="halves"/>
|
|
363
|
+
<path d="M 70 20 v -4" class="halves"/>
|
|
364
|
+
<path d="M 75 0 v 4" class="halves"/>
|
|
365
|
+
<path d="M 75 20 v -4" class="halves"/>
|
|
366
|
+
<path d="M 80 0 v 4" class="halves"/>
|
|
367
|
+
<path d="M 80 20 v -4" class="halves"/>
|
|
368
|
+
<path d="M 85 0 v 4" class="halves"/>
|
|
369
|
+
<path d="M 85 20 v -4" class="halves"/>
|
|
370
|
+
<path d="M 90 0 v 4" class="halves"/>
|
|
371
|
+
<path d="M 90 20 v -4" class="halves"/>
|
|
372
|
+
<path d="M 95 0 v 4" class="halves"/>
|
|
373
|
+
<path d="M 95 20 v -4" class="halves"/>
|
|
374
|
+
<path d="M 100 0 v 4" class="halves"/>
|
|
375
|
+
<path d="M 100 20 v -4" class="halves"/>
|
|
376
|
+
<path d="M 105 0 v 4" class="halves"/>
|
|
377
|
+
<path d="M 105 20 v -4" class="halves"/>
|
|
378
|
+
<path d="M 110 0 v 4" class="halves"/>
|
|
379
|
+
<path d="M 110 20 v -4" class="halves"/>
|
|
380
|
+
<path d="M 115 0 v 4" class="halves"/>
|
|
381
|
+
<path d="M 115 20 v -4" class="halves"/>
|
|
382
|
+
<path d="M 120 0 v 4" class="halves"/>
|
|
383
|
+
<path d="M 120 20 v -4" class="halves"/>
|
|
384
|
+
<path d="M 125 0 v 4" class="halves"/>
|
|
385
|
+
<path d="M 125 20 v -4" class="halves"/>
|
|
386
|
+
<path d="M 130 0 v 4" class="halves"/>
|
|
387
|
+
<path d="M 130 20 v -4" class="halves"/>
|
|
388
|
+
<path d="M 135 0 v 4" class="halves"/>
|
|
389
|
+
<path d="M 135 20 v -4" class="halves"/>
|
|
390
|
+
<path d="M 140 0 v 4" class="halves"/>
|
|
391
|
+
<path d="M 140 20 v -4" class="halves"/>
|
|
392
|
+
<path d="M 145 0 v 4" class="halves"/>
|
|
393
|
+
<path d="M 145 20 v -4" class="halves"/>
|
|
394
|
+
<path d="M 150 0 v 4" class="halves"/>
|
|
395
|
+
<path d="M 150 20 v -4" class="halves"/>
|
|
396
396
|
</g>
|
|
397
397
|
<g id="majors">
|
|
398
|
-
<path d="M 10 0 v 6" class="
|
|
399
|
-
<path d="M 10 20 v -6" class="
|
|
400
|
-
<path d="M 20 0 v 6" class="
|
|
401
|
-
<path d="M 20 20 v -6" class="
|
|
402
|
-
<path d="M 30 0 v 6" class="
|
|
403
|
-
<path d="M 30 20 v -6" class="
|
|
404
|
-
<path d="M 40 0 v 6" class="
|
|
405
|
-
<path d="M 40 20 v -6" class="
|
|
406
|
-
<path d="M 50 0 v 6" class="
|
|
407
|
-
<path d="M 50 20 v -6" class="
|
|
408
|
-
<path d="M 60 0 v 6" class="
|
|
409
|
-
<path d="M 60 20 v -6" class="
|
|
410
|
-
<path d="M 70 0 v 6" class="
|
|
411
|
-
<path d="M 70 20 v -6" class="
|
|
412
|
-
<path d="M 80 0 v 6" class="
|
|
413
|
-
<path d="M 80 20 v -6" class="
|
|
414
|
-
<path d="M 90 0 v 6" class="
|
|
415
|
-
<path d="M 90 20 v -6" class="
|
|
416
|
-
<path d="M 100 0 v 6" class="
|
|
417
|
-
<path d="M 100 20 v -6" class="
|
|
418
|
-
<path d="M 110 0 v 6" class="
|
|
419
|
-
<path d="M 110 20 v -6" class="
|
|
420
|
-
<path d="M 120 0 v 6" class="
|
|
421
|
-
<path d="M 120 20 v -6" class="
|
|
422
|
-
<path d="M 130 0 v 6" class="
|
|
423
|
-
<path d="M 130 20 v -6" class="
|
|
424
|
-
<path d="M 140 0 v 6" class="
|
|
425
|
-
<path d="M 140 20 v -6" class="
|
|
398
|
+
<path d="M 10 0 v 6" class="majors"/>
|
|
399
|
+
<path d="M 10 20 v -6" class="majors"/>
|
|
400
|
+
<path d="M 20 0 v 6" class="majors"/>
|
|
401
|
+
<path d="M 20 20 v -6" class="majors"/>
|
|
402
|
+
<path d="M 30 0 v 6" class="majors"/>
|
|
403
|
+
<path d="M 30 20 v -6" class="majors"/>
|
|
404
|
+
<path d="M 40 0 v 6" class="majors"/>
|
|
405
|
+
<path d="M 40 20 v -6" class="majors"/>
|
|
406
|
+
<path d="M 50 0 v 6" class="majors"/>
|
|
407
|
+
<path d="M 50 20 v -6" class="majors"/>
|
|
408
|
+
<path d="M 60 0 v 6" class="majors"/>
|
|
409
|
+
<path d="M 60 20 v -6" class="majors"/>
|
|
410
|
+
<path d="M 70 0 v 6" class="majors"/>
|
|
411
|
+
<path d="M 70 20 v -6" class="majors"/>
|
|
412
|
+
<path d="M 80 0 v 6" class="majors"/>
|
|
413
|
+
<path d="M 80 20 v -6" class="majors"/>
|
|
414
|
+
<path d="M 90 0 v 6" class="majors"/>
|
|
415
|
+
<path d="M 90 20 v -6" class="majors"/>
|
|
416
|
+
<path d="M 100 0 v 6" class="majors"/>
|
|
417
|
+
<path d="M 100 20 v -6" class="majors"/>
|
|
418
|
+
<path d="M 110 0 v 6" class="majors"/>
|
|
419
|
+
<path d="M 110 20 v -6" class="majors"/>
|
|
420
|
+
<path d="M 120 0 v 6" class="majors"/>
|
|
421
|
+
<path d="M 120 20 v -6" class="majors"/>
|
|
422
|
+
<path d="M 130 0 v 6" class="majors"/>
|
|
423
|
+
<path d="M 130 20 v -6" class="majors"/>
|
|
424
|
+
<path d="M 140 0 v 6" class="majors"/>
|
|
425
|
+
<path d="M 140 20 v -6" class="majors"/>
|
|
426
426
|
<g id="labels">
|
|
427
427
|
<text text-anchor="middle" x="10" y="11.5" class="labels">1</text>
|
|
428
428
|
<text text-anchor="middle" x="20" y="11.5" class="labels">2</text>
|
data/srv/ruler-hline.yml
CHANGED
data/srv/ruler-line.yml
CHANGED
data/srv/snow-flake.yml
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sevgi-showcase
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.94.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Recai Oktaş
|
|
@@ -15,22 +15,25 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.94.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.94.0
|
|
26
26
|
description: Provides documents and examples to demonstrate the Sevgi toolkit.
|
|
27
27
|
email: roktas@gmail.com
|
|
28
28
|
executables: []
|
|
29
29
|
extensions: []
|
|
30
30
|
extra_rdoc_files: []
|
|
31
31
|
files:
|
|
32
|
+
- CHANGELOG.md
|
|
33
|
+
- LICENSE
|
|
32
34
|
- README.md
|
|
33
35
|
- lib/sevgi/showcase.rb
|
|
36
|
+
- lib/sevgi/showcase/dark.rb
|
|
34
37
|
- lib/sevgi/showcase/minitest.rb
|
|
35
38
|
- lib/sevgi/showcase/minitest/script.rb
|
|
36
39
|
- lib/sevgi/showcase/minitest/shell.rb
|
|
@@ -82,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
82
85
|
requirements:
|
|
83
86
|
- - ">="
|
|
84
87
|
- !ruby/object:Gem::Version
|
|
85
|
-
version: 3.4.0
|
|
88
|
+
version: 3.4.0
|
|
86
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
90
|
requirements:
|
|
88
91
|
- - ">="
|