dieses 0.0.1

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/BEN/304/260OKU.md +0 -0
  3. data/CHANGELOG.md +14 -0
  4. data/LICENSE.md +675 -0
  5. data/README.md +18 -0
  6. data/bin/dieses +10 -0
  7. data/bin/diesis +10 -0
  8. data/dieses.gemspec +36 -0
  9. data/lib/dieses.rb +7 -0
  10. data/lib/dieses/application.rb +24 -0
  11. data/lib/dieses/application/batch.rb +127 -0
  12. data/lib/dieses/application/canvas.rb +51 -0
  13. data/lib/dieses/application/cli.rb +6 -0
  14. data/lib/dieses/application/cli/multi.rb +106 -0
  15. data/lib/dieses/application/cli/single.rb +100 -0
  16. data/lib/dieses/application/common.rb +27 -0
  17. data/lib/dieses/application/mixins.rb +5 -0
  18. data/lib/dieses/application/mixins/lines.rb +105 -0
  19. data/lib/dieses/application/mixins/scribes.rb +91 -0
  20. data/lib/dieses/application/mixins/squares.rb +23 -0
  21. data/lib/dieses/application/paper.rb +146 -0
  22. data/lib/dieses/application/pen.rb +161 -0
  23. data/lib/dieses/application/sheet.rb +111 -0
  24. data/lib/dieses/application/sheets.rb +58 -0
  25. data/lib/dieses/application/sheets/copperplate.rb +20 -0
  26. data/lib/dieses/application/sheets/cursive.rb +19 -0
  27. data/lib/dieses/application/sheets/graph.rb +27 -0
  28. data/lib/dieses/application/sheets/italics.rb +19 -0
  29. data/lib/dieses/application/sheets/lettering.rb +30 -0
  30. data/lib/dieses/application/sheets/lined.rb +24 -0
  31. data/lib/dieses/application/sheets/print.rb +19 -0
  32. data/lib/dieses/application/sheets/ruled.rb +25 -0
  33. data/lib/dieses/application/sheets/spencerian.rb +20 -0
  34. data/lib/dieses/application/sheets/thumbnail.rb +37 -0
  35. data/lib/dieses/error.rb +5 -0
  36. data/lib/dieses/geometry.rb +8 -0
  37. data/lib/dieses/geometry/element.rb +66 -0
  38. data/lib/dieses/geometry/equation.rb +57 -0
  39. data/lib/dieses/geometry/equation/slant.rb +88 -0
  40. data/lib/dieses/geometry/equation/steep.rb +70 -0
  41. data/lib/dieses/geometry/error.rb +7 -0
  42. data/lib/dieses/geometry/line.rb +67 -0
  43. data/lib/dieses/geometry/point.rb +98 -0
  44. data/lib/dieses/geometry/rect.rb +173 -0
  45. data/lib/dieses/geometry/support.rb +3 -0
  46. data/lib/dieses/support.rb +9 -0
  47. data/lib/dieses/support/class.rb +100 -0
  48. data/lib/dieses/support/const.rb +78 -0
  49. data/lib/dieses/support/enum.rb +63 -0
  50. data/lib/dieses/support/float.rb +43 -0
  51. data/lib/dieses/support/hash.rb +19 -0
  52. data/lib/dieses/support/kernel.rb +36 -0
  53. data/lib/dieses/support/math.rb +20 -0
  54. data/lib/dieses/version.rb +5 -0
  55. metadata +226 -0
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'ostruct'
5
+
6
+ module Dieses
7
+ module Application
8
+ class Sheet
9
+ module DSL
10
+ def sheet(name, desc, default: Undefined)
11
+ Sheets.register name, klass: self, desc: desc, default: default
12
+ end
13
+
14
+ def variant(key, desc, **kwargs)
15
+ variants key.to_sym => Proto.new(name: key, desc: desc, param: Param.new(**kwargs))
16
+ end
17
+
18
+ def variate(**kwargs, &block)
19
+ kwargs.transform_values! { |value| [*value] }
20
+
21
+ builder = proc { |keys, values| Proto.(**keys.zip(values).to_h) }
22
+ variants = [nil].product(*kwargs.values).map { |_, *values| builder.call(kwargs.keys, values) }
23
+ variants.each do |variant|
24
+ variant.instance_exec(&block)
25
+ self.variant variant.name, variant.desc, **variant.to_h
26
+ end
27
+ variants
28
+ end
29
+
30
+ def self.extended(klass)
31
+ super
32
+
33
+ klass.extend Support::ClassAttribute
34
+
35
+ klass.define :proto
36
+ klass.define :variants, default: {}
37
+ klass.define :param, default: Param.new
38
+ end
39
+ end
40
+
41
+ extend DSL
42
+
43
+ class Proto < OpenStruct
44
+ def derivate(**kwargs)
45
+ self.class.new(name: name, desc: desc, **kwargs).freeze
46
+ end
47
+
48
+ def to_s
49
+ name.to_s
50
+ end
51
+
52
+ def self.call(**kwargs)
53
+ new(**kwargs)
54
+ end
55
+
56
+ def self.formatted(*protos, prefix: EMPTY_STRING)
57
+ longest_length = protos.map { |proto| proto.name.to_s.length }.max
58
+
59
+ protos.map do |proto|
60
+ lines = ["#{prefix}#{proto.name.to_s.ljust(longest_length)} #{proto.desc}"]
61
+ lines = [*lines, *yield(proto)] if block_given?
62
+ lines
63
+ end.flatten.join("\n")
64
+ end
65
+ end
66
+
67
+ extend Forwardable
68
+ def_delegators :@pen, :draw
69
+
70
+ attr_reader :paper, :variant
71
+
72
+ def initialize(paper, variant: Undefined)
73
+ @paper = paper
74
+ @variant = Undefined.equal?(variant) ? self.class.default_variant : self.class.variant!(variant)
75
+ @param = parametrize
76
+ @canvas = Canvas.new(paper)
77
+ @pen = Pen.new(@canvas)
78
+
79
+ setup if respond_to? :setup
80
+ end
81
+
82
+ def produce(**kwargs)
83
+ call
84
+ canvas.render(**kwargs)
85
+ end
86
+
87
+ private
88
+
89
+ attr_reader :canvas, :param
90
+
91
+ def parametrize(**param)
92
+ Param.new(**self.class.param.to_h, **variant.param.to_h, **param.to_h)
93
+ end
94
+
95
+ class << self
96
+ def default_variant
97
+ return variant!(default) unless Undefined.equal?(proto.default)
98
+
99
+ variants.values.first
100
+ end
101
+
102
+ def variant!(name)
103
+ raise Error, "No variant defined: #{self.class}" if variants.empty?
104
+ raise Error, "No such variant for #{self.class}: #{name}" unless variants.key?(name = name.to_sym)
105
+
106
+ variants[name]
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ @registry = {}
7
+
8
+ def self.available?(name)
9
+ @registry.key? name.to_sym
10
+ end
11
+
12
+ def self.register(name, klass:, desc:, default: nil)
13
+ @registry[name = name.to_sym] = Sheet::Proto.new(name: name,
14
+ desc: desc,
15
+ klass: klass,
16
+ default: default).tap do |proto|
17
+ klass.proto proto
18
+ end
19
+ end
20
+
21
+ def self.proto(name)
22
+ raise Error, "No such sheet available: #{name}" unless @registry[name = name.to_sym]
23
+
24
+ @registry[name]
25
+ end
26
+
27
+ def self.sheet(name)
28
+ proto(name).klass
29
+ end
30
+
31
+ def self.call(name, paper, variant: nil, param: {})
32
+ sheet(name).new(paper, variant, **param).call
33
+ end
34
+
35
+ def self.available
36
+ @registry.sort.to_h.transform_values do |proto|
37
+ proto.derivate(variants: proto.klass.variants.values.map(&:derivate))
38
+ end
39
+ end
40
+
41
+ def self.defaults
42
+ {}.tap do |defaults|
43
+ available.each_key do |name|
44
+ defaults[name] = sheet(name).default_variant
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.dump(prefix: '')
50
+ Sheet::Proto.formatted(*available.values, prefix: prefix) do |proto|
51
+ Sheet::Proto.formatted(*proto.variants, prefix: prefix * 2)
52
+ end
53
+ end
54
+
55
+ Dir[File.join(__dir__, 'sheets', '*.rb')].each { |file| require file }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Copperplate < Sheet
7
+ sheet :copperplate, 'Copperplate worksheet'
8
+
9
+ include Mixins::Scribes[:sextet].with unit: [5, 7], ratio: [3/2r, 2/1r]
10
+
11
+ cline :slant, angle: 55.0, style: Style.(stroke: 'blue', 'stroke-width': 0.1)
12
+ cline :connective, angle: 50.0, style: Style.(stroke: 'blue', 'stroke-width': 0.07, 'stroke-dasharray': '2, 2')
13
+
14
+ def call
15
+ scribes
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Cursive < Sheet
7
+ sheet :cursive, 'Cursive worksheet'
8
+
9
+ include Mixins::Scribes[:quartet].with unit: [5, 7, 10]
10
+
11
+ cline :slant, angle: 60.0, style: Style.(stroke: 'blue', 'stroke-width': 0.05)
12
+
13
+ def call
14
+ scribes
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Graph < Sheet
7
+ sheet :graph, 'Graph worksheet'
8
+
9
+ include Mixins::Lines
10
+ include Mixins::Squares
11
+
12
+ variate unit: [5, 7, 10], square: [6, 8] do
13
+ self.name = "#{unit}#{square}"
14
+ self.desc = "#{square} squares with #{unit} mm unit"
15
+ end
16
+
17
+ hline :hline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
18
+ vline :vline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
19
+
20
+ def call
21
+ lines multiple: param.square
22
+ squares multiple: param.square
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Italics < Sheet
7
+ sheet :italics, 'Italics worksheet'
8
+
9
+ include Mixins::Scribes[:quartet].with unit: [5, 7, 10]
10
+
11
+ cline :slant, angle: 81.0, style: Style.(stroke: 'blue', 'stroke-width': 0.05)
12
+
13
+ def call
14
+ scribes
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Lettering < Sheet
7
+ sheet :lettering, 'Lettering worksheet'
8
+
9
+ include Mixins::Lines
10
+ include Mixins::Squares
11
+
12
+ variate unit: [5], square: [6, 8] do
13
+ self.name = "#{unit}#{square}"
14
+ self.desc = "#{square} squares with #{unit} mm unit"
15
+ end
16
+
17
+ hline :hline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
18
+ vline :vline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
19
+
20
+ cline :slant, angle: 52.0, style: Style.(stroke: 'blue', 'stroke-width': 0.1)
21
+ cline :connective, angle: 30.0, style: Style.(stroke: 'blue', 'stroke-width': 0.07, 'stroke-dasharray': '2, 2')
22
+
23
+ def call
24
+ lines multiple: param.square
25
+ squares multiple: param.square
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Lined < Sheet
7
+ sheet :lined, 'Lined worksheet'
8
+
9
+ include Mixins::Lines
10
+
11
+ variate unit: [5, 7, 10] do
12
+ self.name = unit.to_s
13
+ self.desc = "#{unit} mm unit"
14
+ end
15
+
16
+ hline :hline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
17
+
18
+ def call
19
+ lines
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Print < Sheet
7
+ sheet :print, 'Print style worksheet'
8
+
9
+ include Mixins::Scribes[:quartet].with unit: [5, 7, 10]
10
+
11
+ vline :vline, style: Style.(stroke: 'blue', 'stroke-width': '0.05')
12
+
13
+ def call
14
+ scribes
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Ruled < Sheet
7
+ sheet :ruled, 'Ruled worksheet'
8
+
9
+ include Mixins::Lines
10
+
11
+ variate unit: [5, 7, 10] do
12
+ self.name = unit.to_s
13
+ self.desc = "#{unit} mm unit"
14
+ end
15
+
16
+ hline :hline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
17
+ vline :vline, style: Style.(stroke: 'blue', 'stroke-width': '0.1')
18
+
19
+ def call
20
+ lines
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Spencerian < Sheet
7
+ sheet :spencerian, 'Spencerian worksheet'
8
+
9
+ include Mixins::Scribes[:sextet].with unit: [5, 7], ratio: [3/2r, 2/1r]
10
+
11
+ cline :slant, angle: 52.0, style: Style.(stroke: 'blue', 'stroke-width': 0.1)
12
+ cline :connective, angle: 30.0, style: Style.(stroke: 'blue', 'stroke-width': 0.07, 'stroke-dasharray': '2, 2')
13
+
14
+ def call
15
+ scribes
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ module Application
5
+ module Sheets
6
+ class Thumbnail < Sheet
7
+ sheet :thumbnail, 'Thumbnails'
8
+
9
+ DENSITY = {
10
+ '1': Param.(row: 4, col: 4, width: 8, height: 10),
11
+ '3': Param.(row: 3, col: 6, width: 8, height: 10),
12
+ '2': Param.(row: 5, col: 5, width: 6, height: 8),
13
+ '4': Param.(row: 4, col: 7, width: 6, height: 8)
14
+ }.freeze
15
+
16
+ variate density: %i[1 2 3 4], unit: 5 do
17
+ self.name = density.to_s
18
+ self.desc = "Density #{density}"
19
+ end
20
+
21
+ def call
22
+ row, col, width, height = DENSITY[param.density].to_a
23
+
24
+ draw unit: param.unit do
25
+ repeat row do
26
+ repeat col do
27
+ rect :rect, width: width, height: height, style: Style.(stroke: 'blue', 'stroke-width': '0.2', fill: 'none') # rubocop:disable Layout/LineLength
28
+ right(width + 1)
29
+ end
30
+ down(height + 1)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dieses
4
+ Error = Class.new StandardError
5
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'geometry/error'
4
+ require_relative 'geometry/element'
5
+ require_relative 'geometry/point'
6
+ require_relative 'geometry/equation'
7
+ require_relative 'geometry/line'
8
+ require_relative 'geometry/rect'