stacking-order 1.0.0 → 1.1.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 +17 -7
- data/lib/stacking_order/version.rb +1 -1
- data/lib/stacking_order.rb +36 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 480df27d8a79f4868585d1e3d7bba83e25c1567405b36ab60d38d4bab161c602
|
|
4
|
+
data.tar.gz: 0d729b3fdeb4a8306a2f35930aa549ba3f800e594871be54241caafada54a240
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a02a2a4642f48f6d81a9e3aa3d91497b62ae2ceb4a86d1e71efa27e282945e0af775da8ac0098ab978cf2a64dbd8e60497d37dfdf78e6ccfeeaf602010010a5b
|
|
7
|
+
data.tar.gz: ba7e487c563a741ce4d518bb4974459fae90ed0aaa8b696ca2451cfd512d8283c3d128e5e52960bd31329aa8f1a16f3f394faa67321907748c1d614106a5f391
|
data/README.md
CHANGED
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A tiny Ruby gem that computes how to arrange records on a paginated grid so that,
|
|
4
4
|
after cutting the printed stack into columns and re-stacking them, the final pile
|
|
5
|
-
remains in sequential order.
|
|
6
|
-
|
|
5
|
+
remains in sequential order.
|
|
6
|
+
|
|
7
|
+
It is useful for printing badges, tickets, or any other grid-based layout that is
|
|
8
|
+
cut in bulk.
|
|
9
|
+
|
|
10
|
+
It has a `two_sided_flipped` option to support printing on both sides of the
|
|
11
|
+
paper, with the second side flipped, which can be used for printing traditional
|
|
12
|
+
Tibetan books (called pechas) or for similar texts from various traditions.
|
|
7
13
|
|
|
8
14
|
## Installation
|
|
9
15
|
|
|
@@ -28,6 +34,9 @@ order = StackingOrder.order(entries: 13, rows: 2, columns: 2)
|
|
|
28
34
|
# => [1, 5, 9, 13, 2, 6, 10, nil, 3, 7, 11, nil, 4, 8, 12]
|
|
29
35
|
# nil entries mark empty slots on the final, partially filled page.
|
|
30
36
|
|
|
37
|
+
StackingOrder.order(entries: 8, rows: 2, columns: 2, two_sided_flipped: true)
|
|
38
|
+
# => [1, 5, 6, 2, 3, 7, 8, 4]
|
|
39
|
+
|
|
31
40
|
StackingOrder.visualize(entries: 6, rows: 2, columns: 2)
|
|
32
41
|
# Prints page-by-page grids plus the stack order after cutting.
|
|
33
42
|
```
|
|
@@ -78,11 +87,12 @@ page-by-page grids and stack order) and returns non-zero on invalid arguments.
|
|
|
78
87
|
|
|
79
88
|
### Real-world usage
|
|
80
89
|
|
|
81
|
-
This gem powers
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
This gem powers [stacked-pdf-generator](https://github.com/jeremy/stacked-pdf-generator), which provides the pdfjam/podofocrop
|
|
91
|
+
tooling for producing final print-ready stacks.
|
|
92
|
+
|
|
93
|
+
In turn, stacked-pdf-generator is used by [pecha-printer](https://github.com/jerefrer/pecha-printer) and the hosted service at
|
|
94
|
+
<https://pecha-printer.frerejeremy.me>. Publishing the stacking logic separately lets other
|
|
95
|
+
Ruby/Rails projects (or CLI scripts) reuse it without needing the full PDF pipeline.
|
|
86
96
|
|
|
87
97
|
## Development
|
|
88
98
|
|
data/lib/stacking_order.rb
CHANGED
|
@@ -14,7 +14,7 @@ module StackingOrder
|
|
|
14
14
|
# @param rows [Integer] Number of rows in the grid on each page
|
|
15
15
|
# @param columns [Integer] Number of columns in the grid on each page
|
|
16
16
|
# @return [Array<Integer, nil>] The order in which to print entries (with nil for empty cells)
|
|
17
|
-
def order(entries:, rows:, columns:)
|
|
17
|
+
def order(entries:, rows:, columns:, two_sided_flipped: false)
|
|
18
18
|
validate_arguments!(entries, rows, columns)
|
|
19
19
|
|
|
20
20
|
return [] if entries.zero?
|
|
@@ -31,6 +31,10 @@ module StackingOrder
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
if two_sided_flipped
|
|
35
|
+
result = apply_two_sided_flip(result, rows, columns)
|
|
36
|
+
end
|
|
37
|
+
|
|
34
38
|
result.pop while result.last.nil?
|
|
35
39
|
result
|
|
36
40
|
end
|
|
@@ -38,8 +42,8 @@ module StackingOrder
|
|
|
38
42
|
# Utility method that prints the layout for the provided configuration,
|
|
39
43
|
# showing the entries on each page and the resulting stacks after cutting.
|
|
40
44
|
# Useful for debugging or CLI demos.
|
|
41
|
-
def visualize(entries:, rows:, columns:, io: $stdout)
|
|
42
|
-
result = order(entries: entries, rows: rows, columns: columns)
|
|
45
|
+
def visualize(entries:, rows:, columns:, two_sided_flipped: false, io: $stdout)
|
|
46
|
+
result = order(entries: entries, rows: rows, columns: columns, two_sided_flipped: two_sided_flipped)
|
|
43
47
|
cells_per_page = rows * columns
|
|
44
48
|
num_pages = (entries.to_f / cells_per_page).ceil
|
|
45
49
|
|
|
@@ -73,6 +77,35 @@ module StackingOrder
|
|
|
73
77
|
end
|
|
74
78
|
end
|
|
75
79
|
|
|
80
|
+
def apply_two_sided_flip(result, rows, columns)
|
|
81
|
+
cells_per_page = rows * columns
|
|
82
|
+
result.each_slice(cells_per_page).with_index.flat_map do |page, page_index|
|
|
83
|
+
padded_page = pad_page(page, cells_per_page)
|
|
84
|
+
page_index.odd? ? flip_page_rows(padded_page, rows, columns) : padded_page
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def pad_page(page, cells_per_page)
|
|
89
|
+
return page if page.length == cells_per_page
|
|
90
|
+
|
|
91
|
+
page + Array.new(cells_per_page - page.length)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def flip_page_rows(page, rows, columns)
|
|
95
|
+
if rows == 1
|
|
96
|
+
row_slice = page.slice(0, columns) || []
|
|
97
|
+
return row_slice.reverse
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
flipped = []
|
|
101
|
+
rows.times do |row_index|
|
|
102
|
+
source_row_index = rows - 1 - row_index
|
|
103
|
+
row_slice = page.slice(source_row_index * columns, columns) || []
|
|
104
|
+
flipped.concat(row_slice)
|
|
105
|
+
end
|
|
106
|
+
flipped
|
|
107
|
+
end
|
|
108
|
+
|
|
76
109
|
def validate_arguments!(entries, rows, columns)
|
|
77
110
|
raise ArgumentError, 'entries must be non-negative' if entries.negative?
|
|
78
111
|
raise ArgumentError, 'rows must be positive' if rows <= 0
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stacking-order
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-11-
|
|
10
|
+
date: 2025-11-26 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: minitest
|