fiber_pattern 0.1.0 → 0.3.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/README.md +41 -4
- data/lib/fiber_pattern/grade_rules.rb +54 -0
- data/lib/fiber_pattern/grader.rb +74 -0
- data/lib/fiber_pattern/repeat.rb +31 -0
- data/lib/fiber_pattern/scaling.rb +38 -0
- data/lib/fiber_pattern/shaping.rb +105 -0
- data/lib/fiber_pattern/sizing.rb +13 -26
- data/lib/fiber_pattern/version.rb +3 -1
- data/lib/fiber_pattern.rb +5 -0
- metadata +41 -12
- data/CHANGELOG.md +0 -8
- data/CODE_OF_CONDUCT.md +0 -10
- data/Rakefile +0 -58
- data/mise.toml +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97a576e2a84dd27f7a1690c4bddbe30adfa4eea6bd323aa19dd3389a1e10e5cb
|
|
4
|
+
data.tar.gz: fa3d3634bab8fa1cdd9f64b2c2f9027d4afc1361a67a26284ed71df6ec8b353e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfc2843e21944d714cfee9270802e629ab1d08e340f1bfb7a7b59f2e5f8bd30469369b6108ad61f3429cfc306150f7af463d53dd43665d572ed6025a33df7c3d
|
|
7
|
+
data.tar.gz: 6f065951604cbcf7612ea115b2aceeff0978f71b0620d61ddafe4e0013dfa2f400f9baa084e45d0da432c5ed999913f240e9c53f1c3a79c013537667f743f83a
|
data/README.md
CHANGED
|
@@ -83,6 +83,8 @@ Because:
|
|
|
83
83
|
|
|
84
84
|
# Pattern Stitch Repeats
|
|
85
85
|
|
|
86
|
+
Use `FiberPattern::Repeat` when a pattern requires stitch counts to align to a repeat.
|
|
87
|
+
|
|
86
88
|
Many patterns require stitch counts to be a **multiple of a repeat**.
|
|
87
89
|
|
|
88
90
|
Example: *multiple of 8 stitches*
|
|
@@ -90,7 +92,7 @@ Example: *multiple of 8 stitches*
|
|
|
90
92
|
```ruby
|
|
91
93
|
sizing = FiberPattern::Sizing.new(
|
|
92
94
|
gauge: gauge,
|
|
93
|
-
|
|
95
|
+
repeat: FiberPattern::Repeat.new(multiple: 8.stitches)
|
|
94
96
|
)
|
|
95
97
|
|
|
96
98
|
sizing.cast_on_for(38.inches)
|
|
@@ -117,8 +119,10 @@ multiple of 8 + 2
|
|
|
117
119
|
```ruby
|
|
118
120
|
sizing = FiberPattern::Sizing.new(
|
|
119
121
|
gauge: gauge,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
repeat: FiberPattern::Repeat.new(
|
|
123
|
+
multiple: 8.stitches,
|
|
124
|
+
offset: 2.stitches
|
|
125
|
+
)
|
|
122
126
|
)
|
|
123
127
|
|
|
124
128
|
sizing.cast_on_for(38.inches)
|
|
@@ -133,6 +137,38 @@ Calculation:
|
|
|
133
137
|
→ 178 stitches
|
|
134
138
|
```
|
|
135
139
|
|
|
140
|
+
# Gauge Scaling
|
|
141
|
+
|
|
142
|
+
You can also scale stitch and row counts from a pattern's gauge to a knitter's gauge.
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
pattern_gauge = FiberGauge::Gauge.new(
|
|
146
|
+
stitches: 20.stitches,
|
|
147
|
+
rows: 28.rows,
|
|
148
|
+
width: 4.inches
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
knitter_gauge = FiberGauge::Gauge.new(
|
|
152
|
+
stitches: 18.stitches,
|
|
153
|
+
rows: 24.rows,
|
|
154
|
+
width: 4.inches
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
FiberPattern::Scaling.scale_stitches(
|
|
158
|
+
100.stitches,
|
|
159
|
+
pattern_gauge,
|
|
160
|
+
knitter_gauge
|
|
161
|
+
)
|
|
162
|
+
# => 90 stitches
|
|
163
|
+
|
|
164
|
+
FiberPattern::Scaling.scale_rows(
|
|
165
|
+
56.rows,
|
|
166
|
+
pattern_gauge,
|
|
167
|
+
knitter_gauge
|
|
168
|
+
)
|
|
169
|
+
# => 48 rows
|
|
170
|
+
```
|
|
171
|
+
|
|
136
172
|
# Example: Sweater Sizing
|
|
137
173
|
|
|
138
174
|
```ruby
|
|
@@ -144,7 +180,7 @@ gauge = FiberGauge::Gauge.new(
|
|
|
144
180
|
|
|
145
181
|
sizing = FiberPattern::Sizing.new(
|
|
146
182
|
gauge: gauge,
|
|
147
|
-
|
|
183
|
+
repeat: FiberPattern::Repeat.new(multiple: 8.stitches)
|
|
148
184
|
)
|
|
149
185
|
|
|
150
186
|
chest = 40.inches
|
|
@@ -160,6 +196,7 @@ cast_on = sizing.cast_on_for(chest)
|
|
|
160
196
|
* make **pattern math predictable**
|
|
161
197
|
* integrate with **typed fiber measurement units**
|
|
162
198
|
* support **repeat-based stitch patterns**
|
|
199
|
+
* help **scale instructions between gauges**
|
|
163
200
|
* stay **small and composable**
|
|
164
201
|
|
|
165
202
|
It forms part of a broader fiber tooling ecosystem:
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Defines per-measurement step values used to grade a pattern across sizes.
|
|
5
|
+
#
|
|
6
|
+
# Each rule maps a measurement name to a step value (a FiberUnits::Length)
|
|
7
|
+
# that represents how much that measurement changes between adjacent sizes.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# rules = FiberPattern::GradeRules.new(
|
|
11
|
+
# bust: { step: 2.inches },
|
|
12
|
+
# waist: { step: 2.inches },
|
|
13
|
+
# sleeve_length: { step: 0.5.inches }
|
|
14
|
+
# )
|
|
15
|
+
# rules.step_for(:bust) # => 2.inches
|
|
16
|
+
class GradeRules
|
|
17
|
+
# @return [Hash<Symbol, Hash>] raw rules keyed by measurement name
|
|
18
|
+
attr_reader :rules
|
|
19
|
+
|
|
20
|
+
# @param rules [Hash<Symbol, Hash>] measurement rules, each with a :step key
|
|
21
|
+
def initialize(**rules)
|
|
22
|
+
validate!(rules)
|
|
23
|
+
@rules = rules.freeze
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns the step value for a given measurement.
|
|
27
|
+
#
|
|
28
|
+
# @param measurement [Symbol] measurement name
|
|
29
|
+
# @return [FiberUnits::Length] step between adjacent sizes
|
|
30
|
+
# @raise [ArgumentError] if the measurement has no rule defined
|
|
31
|
+
def step_for(measurement)
|
|
32
|
+
raise ArgumentError, "no rule defined for #{measurement.inspect}" unless rules.key?(measurement)
|
|
33
|
+
|
|
34
|
+
rules[measurement][:step]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns all measurement names that have rules defined.
|
|
38
|
+
#
|
|
39
|
+
# @return [Array<Symbol>]
|
|
40
|
+
def measurements
|
|
41
|
+
rules.keys
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def validate!(rules)
|
|
47
|
+
rules.each do |name, config|
|
|
48
|
+
unless config.is_a?(Hash) && config.key?(:step)
|
|
49
|
+
raise ArgumentError, "rule for #{name.inspect} must be a Hash with a :step key"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Applies grade rules to a base size's measurements to produce a full size range.
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# grader = FiberPattern::Grader.new(
|
|
8
|
+
# base_size: :m,
|
|
9
|
+
# measurements: { bust: 36.inches, waist: 30.inches },
|
|
10
|
+
# rules: grade_rules
|
|
11
|
+
# )
|
|
12
|
+
# grader.size(:l) # => { bust: 38.inches, waist: 32.inches }
|
|
13
|
+
# grader.all_sizes # => { xs: {...}, s: {...}, ... }
|
|
14
|
+
class Grader
|
|
15
|
+
# Standard size progression from smallest to largest.
|
|
16
|
+
SIZES = %i[xs s m l xl xxl xxxl xxxxl xxxxxl].freeze
|
|
17
|
+
|
|
18
|
+
# @return [Symbol] the base size used as the grading anchor
|
|
19
|
+
# @return [Hash<Symbol, FiberUnits::Length>] base measurements
|
|
20
|
+
# @return [FiberPattern::GradeRules] grading rules
|
|
21
|
+
attr_reader :base_size, :measurements, :rules
|
|
22
|
+
|
|
23
|
+
# @param base_size [Symbol] one of the standard SIZES
|
|
24
|
+
# @param measurements [Hash<Symbol, FiberUnits::Length>] base size measurements
|
|
25
|
+
# @param rules [FiberPattern::GradeRules] grade rules to apply
|
|
26
|
+
# @param sizes [Array<Symbol>] optional custom size list (defaults to SIZES)
|
|
27
|
+
def initialize(base_size:, measurements:, rules:, sizes: SIZES)
|
|
28
|
+
@sizes = sizes
|
|
29
|
+
validate!(base_size, measurements, rules)
|
|
30
|
+
@base_size = base_size
|
|
31
|
+
@measurements = measurements.freeze
|
|
32
|
+
@rules = rules
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns graded measurements for a single size.
|
|
36
|
+
#
|
|
37
|
+
# @param target [Symbol] the size to compute
|
|
38
|
+
# @return [Hash<Symbol, FiberUnits::Length>]
|
|
39
|
+
# @raise [ArgumentError] if the target size is not in the size list
|
|
40
|
+
def size(target)
|
|
41
|
+
raise ArgumentError, "unknown size #{target.inspect}" unless @sizes.include?(target)
|
|
42
|
+
|
|
43
|
+
offset = @sizes.index(target) - @sizes.index(base_size)
|
|
44
|
+
|
|
45
|
+
measurements.each_with_object({}) do |(name, base_value), result|
|
|
46
|
+
step = rules.step_for(name)
|
|
47
|
+
result[name] = base_value + (step * offset)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns graded measurements for all sizes.
|
|
52
|
+
#
|
|
53
|
+
# @return [Hash<Symbol, Hash<Symbol, FiberUnits::Length>>]
|
|
54
|
+
def all_sizes
|
|
55
|
+
@sizes.each_with_object({}) do |size_name, result|
|
|
56
|
+
result[size_name] = size(size_name)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def validate!(base_size, measurements, rules)
|
|
63
|
+
unless @sizes.include?(base_size)
|
|
64
|
+
raise ArgumentError, "base_size #{base_size.inspect} is not in the size list"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
measurements.each_key do |name|
|
|
68
|
+
unless rules.measurements.include?(name)
|
|
69
|
+
raise ArgumentError, "no grade rule for measurement #{name.inspect}"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Adjusts stitch counts to satisfy a repeat multiple and optional offset.
|
|
5
|
+
class Repeat
|
|
6
|
+
# @return [FiberUnits::Stitches] repeat multiple used for rounding
|
|
7
|
+
# @return [FiberUnits::Stitches] fixed offset applied before rounding
|
|
8
|
+
attr_reader :multiple, :offset
|
|
9
|
+
|
|
10
|
+
# @param multiple [FiberUnits::Stitches] repeat size required by the pattern
|
|
11
|
+
# @param offset [FiberUnits::Stitches] offset preserved when aligning to the repeat
|
|
12
|
+
def initialize(multiple:, offset: 0.stitches)
|
|
13
|
+
@multiple = multiple
|
|
14
|
+
@offset = offset
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Rounds a stitch count up to the next valid repeat-compatible value.
|
|
18
|
+
#
|
|
19
|
+
# @param stitches [FiberUnits::Stitches] stitch count to adjust
|
|
20
|
+
# @return [FiberUnits::Stitches] smallest valid count meeting the repeat constraints
|
|
21
|
+
def adjust(stitches)
|
|
22
|
+
m = multiple.value
|
|
23
|
+
o = offset.value
|
|
24
|
+
|
|
25
|
+
adjusted =
|
|
26
|
+
((stitches.value - o).to_f / m).ceil * m + o
|
|
27
|
+
|
|
28
|
+
adjusted.stitches
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Converts stitch and row counts from a pattern gauge to a knitter's gauge.
|
|
5
|
+
class Scaling
|
|
6
|
+
# Scales a stitch count to preserve width at a different stitches-per-inch rate.
|
|
7
|
+
#
|
|
8
|
+
# @param stitches [FiberUnits::Stitches] stitch count written for the pattern gauge
|
|
9
|
+
# @param pattern_gauge [FiberGauge::Gauge] gauge used by the source pattern
|
|
10
|
+
# @param knitter_gauge [FiberGauge::Gauge] gauge achieved by the knitter
|
|
11
|
+
# @return [FiberUnits::Stitches] adjusted stitch count for the knitter's gauge
|
|
12
|
+
def self.scale_stitches(stitches, pattern_gauge, knitter_gauge)
|
|
13
|
+
pattern_spi = pattern_gauge.spi
|
|
14
|
+
knitter_spi = knitter_gauge.spi
|
|
15
|
+
|
|
16
|
+
scaled =
|
|
17
|
+
(stitches.value * knitter_spi / pattern_spi).round
|
|
18
|
+
|
|
19
|
+
scaled.stitches
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Scales a row count to preserve length at a different rows-per-inch rate.
|
|
23
|
+
#
|
|
24
|
+
# @param rows [FiberUnits::Rows] row count written for the pattern gauge
|
|
25
|
+
# @param pattern_gauge [FiberGauge::Gauge] gauge used by the source pattern
|
|
26
|
+
# @param knitter_gauge [FiberGauge::Gauge] gauge achieved by the knitter
|
|
27
|
+
# @return [FiberUnits::Rows] adjusted row count for the knitter's gauge
|
|
28
|
+
def self.scale_rows(rows, pattern_gauge, knitter_gauge)
|
|
29
|
+
pattern_rpi = pattern_gauge.rpi
|
|
30
|
+
knitter_rpi = knitter_gauge.rpi
|
|
31
|
+
|
|
32
|
+
scaled =
|
|
33
|
+
(rows.value * knitter_rpi / pattern_rpi).round
|
|
34
|
+
|
|
35
|
+
scaled.rows
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Calculates evenly distributed shaping (increases or decreases) across a span of rows.
|
|
5
|
+
#
|
|
6
|
+
# @example Decreasing from 60 to 40 stitches over 30 rows
|
|
7
|
+
# shaping = FiberPattern::Shaping.new(
|
|
8
|
+
# from: 60.stitches,
|
|
9
|
+
# to: 40.stitches,
|
|
10
|
+
# over: 30.rows,
|
|
11
|
+
# method: :decrease
|
|
12
|
+
# )
|
|
13
|
+
# shaping.total_changes # => 10
|
|
14
|
+
# shaping.every_n_rows # => 3
|
|
15
|
+
# shaping.schedule # => [{row: 1, action: :dec}, {row: 4, action: :dec}, ...]
|
|
16
|
+
class Shaping
|
|
17
|
+
# @return [FiberUnits::Stitches] starting stitch count
|
|
18
|
+
# @return [FiberUnits::Stitches] ending stitch count
|
|
19
|
+
# @return [FiberUnits::Rows] total rows available for shaping
|
|
20
|
+
# @return [Symbol] shaping method (:increase or :decrease)
|
|
21
|
+
# @return [Integer] stitches changed per shaping row (default 2 for paired shaping)
|
|
22
|
+
attr_reader :from, :to, :over, :method, :stitches_per_event
|
|
23
|
+
|
|
24
|
+
# @param from [FiberUnits::Stitches] starting stitch count
|
|
25
|
+
# @param to [FiberUnits::Stitches] target stitch count
|
|
26
|
+
# @param over [FiberUnits::Rows] number of rows available for shaping
|
|
27
|
+
# @param method [Symbol] :increase or :decrease
|
|
28
|
+
# @param stitches_per_event [Integer] stitches changed per shaping row (default 2 for paired shaping)
|
|
29
|
+
def initialize(from:, to:, over:, method:, stitches_per_event: 2)
|
|
30
|
+
validate!(from, to, over, method)
|
|
31
|
+
@from = from
|
|
32
|
+
@to = to
|
|
33
|
+
@over = over
|
|
34
|
+
@method = method
|
|
35
|
+
@stitches_per_event = stitches_per_event
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Total number of shaping events needed.
|
|
39
|
+
#
|
|
40
|
+
# @return [Integer]
|
|
41
|
+
def total_changes
|
|
42
|
+
stitch_difference / stitches_per_event
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Base interval between shaping rows.
|
|
46
|
+
#
|
|
47
|
+
# @return [Integer]
|
|
48
|
+
def every_n_rows
|
|
49
|
+
return 0 if total_changes.zero?
|
|
50
|
+
|
|
51
|
+
over.value / total_changes
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Row-by-row schedule of shaping events, distributing any remainder rows
|
|
55
|
+
# evenly across the span.
|
|
56
|
+
#
|
|
57
|
+
# @return [Array<Hash>] each entry has :row and :action keys
|
|
58
|
+
def schedule
|
|
59
|
+
return [] if total_changes.zero?
|
|
60
|
+
|
|
61
|
+
changes = total_changes
|
|
62
|
+
rows_available = over.value
|
|
63
|
+
action = (method == :decrease) ? :dec : :inc
|
|
64
|
+
|
|
65
|
+
base_interval = rows_available / changes
|
|
66
|
+
remainder = rows_available % changes
|
|
67
|
+
|
|
68
|
+
schedule = []
|
|
69
|
+
current_row = 0
|
|
70
|
+
|
|
71
|
+
changes.times do |i|
|
|
72
|
+
# Spread remainder evenly: the first `remainder` intervals get +1 row
|
|
73
|
+
interval = base_interval + ((i < remainder) ? 1 : 0)
|
|
74
|
+
current_row += interval
|
|
75
|
+
schedule << {row: current_row, action: action}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
schedule
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def stitch_difference
|
|
84
|
+
(from.value - to.value).abs
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def validate!(from, to, over, method)
|
|
88
|
+
unless %i[increase decrease].include?(method)
|
|
89
|
+
raise ArgumentError, "method must be :increase or :decrease, got #{method.inspect}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if method == :decrease && from.value < to.value
|
|
93
|
+
raise ArgumentError, "from must be greater than to for :decrease shaping"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
if method == :increase && from.value > to.value
|
|
97
|
+
raise ArgumentError, "from must be less than to for :increase shaping"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if over.value <= 0
|
|
101
|
+
raise ArgumentError, "over must be a positive row count"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
data/lib/fiber_pattern/sizing.rb
CHANGED
|
@@ -6,46 +6,33 @@ module FiberPattern
|
|
|
6
6
|
# @return [Object] gauge object that responds to `required_stitches`
|
|
7
7
|
attr_reader :gauge
|
|
8
8
|
|
|
9
|
-
# @return [
|
|
10
|
-
attr_reader :
|
|
11
|
-
|
|
12
|
-
# @return [Object] optional offset to apply when rounding to stitch repeat
|
|
13
|
-
attr_reader :repeat_offset
|
|
9
|
+
# @return [FiberPattern::Repeat, nil] optional stitch repeat to round stitch counts to
|
|
10
|
+
attr_reader :repeat
|
|
14
11
|
|
|
15
12
|
# @param gauge [Object] gauge object used to derive stitch counts
|
|
16
|
-
# @param
|
|
17
|
-
|
|
18
|
-
def initialize(gauge:, stitch_repeat: nil, repeat_offset: 0.stitches)
|
|
13
|
+
# @param repeat [FiberPattern::Repeat, nil] optional stitch repeat to round stitch counts to
|
|
14
|
+
def initialize(gauge:, repeat: nil)
|
|
19
15
|
@gauge = gauge
|
|
20
|
-
@
|
|
21
|
-
@repeat_offset = repeat_offset
|
|
16
|
+
@repeat = repeat
|
|
22
17
|
end
|
|
23
18
|
|
|
24
|
-
#
|
|
19
|
+
# Calculates the number of stitches required to reach a given width, based on the provided gauge.
|
|
25
20
|
#
|
|
26
21
|
# @param width [Object] desired finished width in units accepted by the gauge
|
|
27
22
|
# @return [Integer] number of stitches required to reach the requested width
|
|
28
23
|
def cast_on_for(width)
|
|
29
24
|
stitches = gauge.required_stitches(width)
|
|
30
25
|
|
|
31
|
-
return stitches unless
|
|
26
|
+
return stitches unless repeat
|
|
32
27
|
|
|
33
|
-
|
|
28
|
+
repeat.adjust(stitches)
|
|
34
29
|
end
|
|
35
30
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
#
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def adjust_to_repeat(stitches)
|
|
42
|
-
repeat = stitch_repeat.value
|
|
43
|
-
offset = @repeat_offset.value
|
|
44
|
-
|
|
45
|
-
adjusted =
|
|
46
|
-
((stitches.value - offset).to_f / repeat).ceil * repeat + offset
|
|
47
|
-
|
|
48
|
-
adjusted.stitches
|
|
31
|
+
# Calculates the width of a given stitch count, based on the provided gauge.
|
|
32
|
+
# @param stitches [FiberUnits::Stitches] stitch count to calculate width for
|
|
33
|
+
# @return [Object] width in units accepted by the gauge
|
|
34
|
+
def width_for(stitches)
|
|
35
|
+
gauge.width_for_stitches(stitches)
|
|
49
36
|
end
|
|
50
37
|
end
|
|
51
38
|
end
|
data/lib/fiber_pattern.rb
CHANGED
|
@@ -4,6 +4,11 @@ require "fiber_units"
|
|
|
4
4
|
require "fiber_gauge"
|
|
5
5
|
require_relative "fiber_pattern/version"
|
|
6
6
|
require_relative "fiber_pattern/sizing"
|
|
7
|
+
require_relative "fiber_pattern/repeat"
|
|
8
|
+
require_relative "fiber_pattern/scaling"
|
|
9
|
+
require_relative "fiber_pattern/shaping"
|
|
10
|
+
require_relative "fiber_pattern/grade_rules"
|
|
11
|
+
require_relative "fiber_pattern/grader"
|
|
7
12
|
|
|
8
13
|
# Utilities for generating fiber pattern measurements from gauge data.
|
|
9
14
|
module FiberPattern
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fiber_pattern
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Meagan Waller
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
@@ -37,6 +37,34 @@ dependencies:
|
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: minitest
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
40
68
|
description: A Ruby gem for calculating pattern sizes and stitch counts for knitting
|
|
41
69
|
and crochet projects.
|
|
42
70
|
email:
|
|
@@ -45,23 +73,24 @@ executables: []
|
|
|
45
73
|
extensions: []
|
|
46
74
|
extra_rdoc_files: []
|
|
47
75
|
files:
|
|
48
|
-
- CHANGELOG.md
|
|
49
|
-
- CODE_OF_CONDUCT.md
|
|
50
76
|
- LICENSE.txt
|
|
51
77
|
- README.md
|
|
52
|
-
- Rakefile
|
|
53
78
|
- lib/fiber_pattern.rb
|
|
79
|
+
- lib/fiber_pattern/grade_rules.rb
|
|
80
|
+
- lib/fiber_pattern/grader.rb
|
|
81
|
+
- lib/fiber_pattern/repeat.rb
|
|
82
|
+
- lib/fiber_pattern/scaling.rb
|
|
83
|
+
- lib/fiber_pattern/shaping.rb
|
|
54
84
|
- lib/fiber_pattern/sizing.rb
|
|
55
85
|
- lib/fiber_pattern/version.rb
|
|
56
|
-
- mise.toml
|
|
57
86
|
- sig/fiber_pattern.rbs
|
|
58
|
-
homepage: https://github.com/meaganewaller/fiber_pattern
|
|
87
|
+
homepage: https://github.com/meaganewaller/craftos/tree/main/gems/fiber_pattern
|
|
59
88
|
licenses:
|
|
60
89
|
- MIT
|
|
61
90
|
metadata:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
91
|
+
source_code_uri: https://github.com/meaganewaller/craftos/tree/main/gems/fiber_pattern
|
|
92
|
+
bug_tracker_uri: https://github.com/meaganewaller/craftos/issues
|
|
93
|
+
rubygems_mfa_required: 'true'
|
|
65
94
|
rdoc_options: []
|
|
66
95
|
require_paths:
|
|
67
96
|
- lib
|
|
@@ -69,14 +98,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
69
98
|
requirements:
|
|
70
99
|
- - ">="
|
|
71
100
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: 3.
|
|
101
|
+
version: '3.4'
|
|
73
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
103
|
requirements:
|
|
75
104
|
- - ">="
|
|
76
105
|
- !ruby/object:Gem::Version
|
|
77
106
|
version: '0'
|
|
78
107
|
requirements: []
|
|
79
|
-
rubygems_version:
|
|
108
|
+
rubygems_version: 3.6.9
|
|
80
109
|
specification_version: 4
|
|
81
110
|
summary: Pattern sizing and stitch math for knitting and crochet.
|
|
82
111
|
test_files: []
|
data/CHANGELOG.md
DELETED
data/CODE_OF_CONDUCT.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# Code of Conduct
|
|
2
|
-
|
|
3
|
-
"fiber_pattern" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
|
-
|
|
5
|
-
* Participants will be tolerant of opposing views.
|
|
6
|
-
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
|
7
|
-
* When interpreting the words and actions of others, participants should always assume good intentions.
|
|
8
|
-
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
|
9
|
-
|
|
10
|
-
If you have any concerns about behaviour within this project, please contact us at ["TODO: Write your email address"](mailto:"TODO: Write your email address").
|
data/Rakefile
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
|
-
require "rspec/core/rake_task"
|
|
5
|
-
require "yard"
|
|
6
|
-
require "yard/rake/yardoc_task"
|
|
7
|
-
require "standard/rake"
|
|
8
|
-
|
|
9
|
-
# YARD Documentation tasks
|
|
10
|
-
begin
|
|
11
|
-
namespace :doc do
|
|
12
|
-
desc "Generate YARD documentation"
|
|
13
|
-
YARD::Rake::YardocTask.new(:generate) do |t|
|
|
14
|
-
t.files = ["lib/**/*.rb", "-", "README.md"]
|
|
15
|
-
t.options = [
|
|
16
|
-
"--output-dir", "doc/yard",
|
|
17
|
-
"--markup", "markdown",
|
|
18
|
-
"--title", "YarnSkein - Yarn metadata and skein calculations",
|
|
19
|
-
"--readme", "README.md"
|
|
20
|
-
]
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
desc "Regenerate documentation with cache reset"
|
|
24
|
-
task regenerate: ["doc:clean", "doc:generate"]
|
|
25
|
-
|
|
26
|
-
desc "Clean generated documentation"
|
|
27
|
-
task :clean do
|
|
28
|
-
rm_rf "doc/yard"
|
|
29
|
-
rm_rf ".yardoc"
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
desc "Start YARD server for local documentation viewing"
|
|
33
|
-
task :serve do
|
|
34
|
-
sh "bundle exec yard server --reload --port 8808"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
desc "Validate YARD documentation coverage"
|
|
38
|
-
task :coverage do
|
|
39
|
-
sh "bundle exec yard stats --list-undoc"
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
desc "Generate complete documentation with coverage report"
|
|
43
|
-
task complete: [:generate, :coverage]
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Add shorthand aliases
|
|
47
|
-
task yard: "doc:generate"
|
|
48
|
-
task yard_server: "doc:serve"
|
|
49
|
-
task yard_clean: "doc:clean"
|
|
50
|
-
rescue LoadError
|
|
51
|
-
# YARD is only available in development/test environments
|
|
52
|
-
# Silence this warning in production where it's not needed
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
task :default do
|
|
56
|
-
Rake::Task["standard"].invoke
|
|
57
|
-
Rake::Task["spec"].invoke
|
|
58
|
-
end
|
data/mise.toml
DELETED