-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
783 lines (760 loc) · 40.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
<!DOCTYPE html>
<html lang="en">
<!-- <script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">window.jQuery || document.write('<script type="text/javascript" src="/js/lib/jquery.js">\x3C/script>');</script> -->
<script src="js/drawing.js"></script>
<script src="lib/pdf-lib.js"></script>
<script src="lib/jszip.js"></script>
<script src="lib/file-saver.js"></script>
<script language="javascript">
window.book = {
upload_blocks: [/*{ pageSelection: String, precedingBlanks: Int , file: File, pdfDoc: PDFLib.PDFDocument } */],
unified_source: { leftRotDeg: 0, rightRotDeg: 0, marginLeft: 0, marginRight: 0, marginTop: 0, marginBottom: 0, pageCount: 0, pdf_is_valid: false, maxWidth: 0, maxHeight: 0, is_large_file: false /* _scale100px: Int, */ },
imposition: { /* name: String, canCustomizeCounts:Boolean, defaultFolioCounts: Int/String, foliosPerSheet: List<Int>, cellCount_l:Int, cellCount_s:Int*/},
imposed: { /* sheets: List<List<PageNumber>>, signatures: List<List<PageNumber>>, pageCount: Int, blanks: Int, hasSplitSig: Boolean, requiresCutting: Boolean */ },
physical: { short_margin: 0, long_margin: 0, scaling: 'fit', placement: 'center' /* display_unit: String */},
page_orientation: null,
display_unit: null, // what to show, ex: cm
display_unit_scale: null, // what to multiple pts by, ex: 1/72
selected_paper_size: null, // key into PAGE_SIZES object
selected_paper_dimensions: [0,0] // width / height in PT
}
function fakeBook() {
window.book.unified_source = {pageCount: 120, maxWidth: 113.386, maxHeight: 170.079, _scale100px: 0.5879620646875864}
}
function roundIt(num) {
return Math.round((num + Number.EPSILON) * 100) / 100
}
</script>
<script type="module" language="javascript">
import { basic, vip } from './js/main.js';
import { unified_source_modifier, imposed_modifier} from './js/state_modifiers.js';
import { tests } from './tests/miscTests.js';
tests();
unified_source_modifier.attach()
imposed_modifier.attach()
window.basicLocal = basic
window.vip = vip
document.getElementById("unit_selector").value = "points";
document.getElementById("unit_selector").dispatchEvent(new Event('change'));
document.getElementById("paper_size_options").value = "LETTER";
document.getElementById("paper_size_options").dispatchEvent(new Event('change'));
</script>
<!-- Pico.css -->
<link
rel="stylesheet"
href="css/pico.min.css"
/>
<style>
:root {
/*--pico-line-height: 0.5rem;*/
--pico-form-element-spacing-vertical: 0rem;
}
.disabled {
opacity: 0.5;
pointer-events: none;
}
details summary::after {
float: left;
}
details p {
margin-left: 40px;
font-size: 0.75em;
}
#title {
h1 {
font-family: monospace;
text-align: right;
font-size: 2em;
opacity: 0.5;
}
details {
margin-left: 50%;
font-family: monospace;
margin-bottom: 50px;
}
#version_info {
margin-right: 11em;
font-size: 0.5em;
color: black;
}
}
#source_pdfs {
.upload_block {
--pico-spacing: 4px;
margin-left: 40px;
border-left: 4mm solid rgba(211, 220, 50, .6);
padding-left: 10px;
small {
display: inline;
}
.page_count {
width: 100px;
}
}
.upload_block_add {
margin-left: 50px;
}
#insert_pdf_source_errors_here {
display: block;
color: black;
background: red;
padding: 4px 12px;
border-radius: var(--pico-border-radius);
}
#example_pdf_upload_page {
float: right;
background: #daa52042;
border: 1px solid black;
}
}
#page_manipulation {
#pdf_reverse_order_label {
margin-left: 40px;
}
#pdf_marins_example{
float:right;
width: auto;
td {
background: #daa52042;
border: 1px solid black;
padding: 0px;
margin:0px;
}
}
#pdf_margins {
margin-left: 40px;
input {
width: 75px;
padding: 0px 4px;
margin: 0px;
}
label {
width: auto;
display: inline-block;
}
#pdf_margins_center {
display: inline-block;
vertical-align: middle;
text-align: right;
}
}
div {
display: inline;
}
svg {
margin-right: -55px;
margin-left: 20px;
}
fieldset {
width: auto;
}
#pdf_margin_label {
margin-left: 40px;
margin-bottom: 8px;
display: block;
}
#page_orientation_1 {
margin-left: 40px;
}
.page_orientation_radio {
margin-top: -35px;
}
#example_pdf_orientation {
display: block;
font-size: 10px;
position: relative;
text-align: center;
width: auto;
float: right;
#example_pdf_orientation_page_left {
display: inline-block;
background: #daa52042;
border: 1px solid black;
width: 100px;
height: 100px;
padding:0px;
}
#example_pdf_orientation_spine {
display: inline-block;
background: #0d0c0942;
width: 100px;
height: 100px;
padding:0px;
}
#example_pdf_orientation_page_right {
display: inline-block;
background: #daa52042;
border: 1px solid black;
width: 100px;
height: 100px;
padding:0px;
}
}
}
#imposition_layout {
.imposition_option {
display:inline-block;
width: 210px;
margin-right: 25px;
}
#imposition_more_info {
width: 50%;
font-size: 0.75em;
height: 150px;
padding: 0px;
}
#folios_per_signature {
width: 150px;
padding: 1px 5px;
margin: 0px;
}
}
table {
margin-left: 40px;
}
td:nth-child(even) {
text-align: right;
}
}
tr:nth-child(even) td:nth-child(even) {
background-color: var(--pico-table-row-stripped-background-color);
}
#imposition_layout tr:nth-child(odd) td:nth-child(even) {
background-color: transparent;
}
#printed_page_adjustment {
opacity: 0.5;
}
#pdf_signatures {
.signature_block_size {
width: 50px;
margin-left: 50px;
padding: 0px 4px;
}
small {
display:inline;
}
.custom_signatures_field {
width: 400px;
margin-left: 50px;
}
}
#printer_paper {
label {
display: inline;
}
select {
width: 10em;
}
#paper_size_options {
width: 20em;
}
#paper_margin_short, #paper_margin_long {
width: 4em;
padding: 2px;
margin-top: 0.75em;
}
#paper_size {
width: 10em;
}
fieldset {
width: auto;
/*margin-bottom: 0px;*/
}
small {
display: inline;
}
}
#pdf_placement {
small {
margin-bottom: 0px;
}
#layout_padding_center_info {
font-size: 0.75em;
}
#layout_padding {
margin-left: 40px;
input {
width: 75px;
padding: 0px 4px;
margin: 0px;
}
label, small {
width: auto;
display: inline-block;
}
#pdf_margins_center {
display: inline-block;
vertical-align: middle;
text-align: right;
}
}
#pdf_page_scaling_label, #pdf_white_space_placement_label {
display: inline;
margin-left: 40px;
}
#pdf_page_scaling, #pdf_white_space_placement {
width:auto;
}
}
#printed_page_markup {
label, #markup_sewing_stations {
width: auto;
display: inline;
}
.printed_page_markup_options {
margin-left: 40px;
}
#fold_line_weight, #cut_line_weight, #markup_crosshairs_weight, #markup_spine_order_weight, #markup_spine_bounds_weight, #markup_crosshairs_length, #markup_spine_bounds_length {
width: 4em;
padding: 0px 4px;
margin-left: 10px;
margin-bottom: 4px;
}
#cut_line_weight {
margin-left: 15px;
}
#markup_sewing_count, #markup_sewing_dist_top, #markup_sewing_dist_bottom, #markup_sewing_station_dist, #markup_sewing_dot_size {
width: 4em;
padding: 0px 4px;
margin-bottom: 4px;
margin-left: 50px;
}
#markup_cut_lines_color, #markup_fold_lines_color, #markup_crosshairs_color, #markup_spine_order_color,
#markup_spine_bounds_color,#markup_sewing_stations_color {
display: inline;
width: 30px;
padding: 0px;
margin: 0px 10px;
vertical-align: middle;
}
}
#pdf_preview {
#pdf_preview_size_warning {
margin-left: 40px;
display: block;
text-align: center;
width: 500px;
}
#preview_status_slot {
margin-left: 80px;
font-family: monospace;
margin-top: 8px;
}
button {
margin-left: 40px;
}
label {
display: inline;
margin-left: 40px
}
iframe {
width: 500px;
height: 600px;
margin-left: 40px;
margin-top: 10px;
border: solid black 1px;
}
h4 {
margin-left: 40px;
margin-top: 10px;
color: red;
}
}
#footer {
float: right;
text-align: right;
margin-right: 25px;
margin-bottom: 25px;
}
#pdf_download {
div {
margin-left: 40px;
}
#file_download_name {
width:auto;
}
}
</style>
</head>
<body>
<main class="container">
<section id="title">
<h1>Villainous Imposer<BR><small id="version_info">v0.0.6</small>[VI]</h1>
<details>
<summary>information & glossary</summary>
<p>
This is a tool written mostly for myself, made available for others. It is focused on at-home, hobbiest printing for bookbinding (or pamphlets or zines)<br>
All the processing is done on the client side- that means your work is entirely private. I need to figure out some CORS stuff (Cross-Origin Resource Sharing) and then it should work saved to your computer/offline.<BR>
Imposition is the process of arranging multiple pages of a PDF onto a printed sheet so that they appear in the correct order after folding (some cutting may be involved)<br><br>
Relevant terms, as used by this tool:<br>
<b>folio</b> - a piece of paper with a single fold down the middle. part of a signature. made up of 4 pages. made up of 2 leaves<br>
<b>leaf</b> - half of a folio. made up of 2 pages. if you were to "tear a page out of a book", you'd be tearing a leaf out<br>
<b>page</b> - single page from the PDF, single page in the result. likely has a single page number on it<br>
<b>sheet</b> - the piece of paper fed into your printer, has 2 sides<br>
<b>side</b> - the front or back of a sheet of paper. The side with the lowest page number imposed on it is considered the 'front'<br>
<b>signature</b> - one or more nested folios. sewn together to make a book. a single signature could make a pamphlet
</p>
</details>
</section>
<section id="source_pdfs">
<h2>1. Source PDF(s)</h2>
<details>
<summary>Details & Instructions</summary>
<p>
The PDFs should be a "straight" PDF - 1 PDF page should be 1 result page<br>
<mark>Do not feed PDFs already exported as a "booklet" into this tool</mark><br>
Multiple PDFs can be used, but at least one is needed<br>
If the PDFs are diffent sizes, the maximum dimensions are used<BR>
Each PDF can be preceeded by <code>N</code> blank pages (default is <code>0</code>)<br>
Page selection can be either <code>all</code> (the default), <code>,</code> separated list of page numbers, a range defined via <code>-</code>. Blank pages can be inserted via <codE>b</codE>.<br>
<mark>Invalid page numbers will be ignored, invalid input will cause an error</mark>
</p>
</details>
<section id="upload_blocks">
<section id="upload_block_add" class="upload_block_add">
<button onclick="drawing.addUploadBlock(
document.getElementById('upload_blocks'),
document.getElementById('upload_block_add'),
false
)">+</button>
</section>
</section>
<script language="javascript">
drawing.addUploadBlock(
document.getElementById('upload_blocks'),
document.getElementById('upload_block_add'),
true
)
</script>
<button onclick="vip.processUploads(
this,
document.getElementById('upload_blocks'),
document.getElementById('upload_blocks_result')
)"
>Process Uploads</button>
<br>
<details id="upload_blocks_result" style="visibility: hidden;">
<summary>Working Input Details</summary>
<p>
<span id="insert_pdf_source_details_here"></span>
<span id="insert_pdf_source_errors_here" style="visibility: hidden;"></span>
<details id="extra_pdf_info" style="margin-left: 50px;">
<summary><small>Learn more about PDFs & units </small></summary>
<p>What unit are those numbers in? Some says they're 'PDF units' -- see <a href="https://supportz.activepdf.com/hc/en-us/articles/360002401633-What-are-PDF-Units-and-Coordinates" target="_blank">this page to learn about the PDF coordidate system!</a> -- but a better answer would be to look back towards old school typesetting and learn about <a href="https://en.wikipedia.org/wiki/Point_(typography)" target="_blank">Points</a> and <a href="https://en.wikipedia.org/wiki/Pica_(typography)" target="_blank">Pica</a>
</p>
</details>
</p>
</details>
</section>
<section id="page_manipulation" class="disabled">
<h2>2. PDF Manipulation</h2>
<details>
<summary>Explanation</summary>
<p>
Cropping is to alter the PDF dimensions - negative values add white space while positive values cut into the PDF.<BR>
<br>
Rotation is about how the PDF pages are oriented relative to the spine.<BR>
Page <code>A</code> is the 1st page of the completed, closed textblock while <code>B</code> & <code>C</code> are a sample spread (spine in the middle)<BR>
The rotation of the letters indicate how the pages would be oriented.<BR>
<mark>In most cases the 1st option is what is desired/expected</mark>, but there are reasons why you might want the others<BR>
(such as a <a href="https://en.wikipedia.org/wiki/Dwarsligger" target="_blank">Dwarsligger ("sleeper" or "crossbeam" in Dutch)</a>, calendars, Tweet-based texts, books for music, etc)
</p>
</details>
<table id="pdf_marins_example" style="display:none;">
<tr><td colspan="3" id="example_pdf_margin_top"></td></tr>
<tr><td id="example_pdf_margin_left"></td><td id="example_pdf_margin_block"></td><td id="example_pdf_margin_right"></td></tr>
<tr><td colspan="3" id="example_pdf_margin_bottom"></td></tr>
</table>
<div id="pdf_margins">
PDF Cropping<br>
<label for="pdf_margin_left">left </label><input type=number size="2" id="pdf_margin_left" placeholder="0" min=0 oninput="vip.handlePdfMarginUpdate()">
<div id="pdf_margins_center">
<label for="pdf_margin_top">top</label> <input type=number size="2" placeholder="0" id="pdf_margin_top" min=0 oninput="vip.handlePdfMarginUpdate()"><br>
<label for="pdf_margin_bottom"> bottom </label><input type=number size="2" placeholder="0" id="pdf_margin_bottom" min=0 oninput="vip.handlePdfMarginUpdate()">
</div>
<input type=number size="2" id="pdf_margin_right" placeholder="0" min=0 oninput="vip.handlePdfMarginUpdate()"><label for="pdf_margin_right"> right</label>
</div>
<div id="example_pdf_orientation" style="visibility: hidden;">
<div id="example_pdf_orientation_page_right" ></div><div id="example_pdf_orientation_spine" ></div><div id="example_pdf_orientation_page_left" ></div>
</div>
<br style="float:clear;">
<span>
<div id="pdf_margin_label">PDF Rotation<br></div>
<fieldset>
<div id="page_orientation_1"></div>
<div id="page_orientation_2"></div>
<div id="page_orientation_3"></div>
<div id="page_orientation_4"></div>
<div id="page_orientation_5"></div>
<div id="page_orientation_6"></div>
<script language="javascript">
page_orientation_options = [['page_orientation_1', 0,0,0],
['page_orientation_2', -90,-90,-90],
['page_orientation_3', -90,90,-90],
['page_orientation_4', 90,90,90],
['page_orientation_5', 90,-90,90],
['page_orientation_6', 180,180,180]]
page_orientation_options.forEach((o, i) => {
drawing.renderPageRotationDemo(document.getElementById(o[0]), o[1], o[2], o[3], 50, i == 0)
})
</script>
</fieldset>
</span>
<div><label id="pdf_reverse_order_label" for="pdf_reverse_order"><input type="checkbox" role="switch" id="pdf_reverse_order" name="pdf_reverse_order"> reverse PDF order</label></div>
<br>
</section>
<section id="printer_paper">
<h2>3. Printer Paper</h2>
<details>
<summary>Instructions/Details</summary>
<p>
This has to do with <i>your</i> machine and the paper you're feeding into it. <BR><br>
The paper margins are to add white space on the edges of the printed page in case you do not have a full-bleed printer. They are mirrored on either side - so a <code>10 pt</code> margin on the Long Sides will put a <code>10 pt</code> on both sides for a total of <code>20 pt</code><br><br>
The <code>Download Test Print</code> button will give you a zip file named <code>vip_test_print</code>, which contains a PDF of same name. It looks at your selected paper size and flip orientation.
You should print this at 100% scale and then check several things - are you flipping correctly - how much of the corners are eaten away by printer margin (each white line and each black line are 1 pt a piece -- my printer eats 12pt on all sides) - what line weight & color you want for your various mark ups - and what kind of printer skew you're dealing with (more on that later)
</p>
</details>
<span class="disabled"><label for="unit_selector">Display Units</label>
<select id="unit_selector" name="unit_selector" required onchange="vip.handleUnitChange(this)">
<option value="metric" id="unit_metric" data-display="cm" data-convert-from-pt=1/28.346 selected>Metric (cm)</option>
<option value="imperial" id="unit_imperial" data-display="in" data-convert-from-pt=1/72>Imperial</option>
<option value="points" id="unit_points" data-display="pt" data-convert-from-pt=1>Points</option>
</select>
<kbd>not implemented yet</kbd>
</span>
<BR>
<fieldset role="group">
Paper Size
<select id="paper_size_options" name="paper_size_options" onchange="vip.handlePaperSizeDropdownChange(this)">
<option value="" selected>Letter</option>
<option>A4</option>
</select>
<input type="text" id="paper_size" name="paper_size" placeholder="10x30" oninput="vip.handleManualPaperSizeChange(this)"/>
</fieldset>
<small class="units">cm</small>
<BR>
Flip Paper
<label for="flip_paper_short">
short side <input type="radio" id="flip_paper_short" name="flip_paper" value="short" checked>
</label>
<label for="flip_paper_long">
long side <input type="radio" id="flip_paper_long" name="flip_paper" value="long">
</label>
<BR>
Paper Margins
short sides
<input type="number" id="paper_margin_short" name="paper_margin_short" placeholder="0" oninput="vip.handlePaperMarginUpdate()" />
<small class="units">cm</small>
long sides
<input type="number" id="paper_margin_long" name="paper_margin_long" placeholder="0" oninput="vip.handlePaperMarginUpdate()" />
<small class="units">cm</small>
<button onclick="vip.generateTestPrint()">Download Test Print</button>
</section>
<section id="imposition_layout"><h2>4. Imposition Layout</h2>
<details>
<summary>Instructions/Details</summary>
<p>
This is how the PDF pages will be tiled on the printed page<br>
<mark>Folios per Signature</mark> can take a single number (all signatures the same size) or a comma separated list of numbers of numbers for variable signature sizes (the sequence provided will be repeated if it does not account for all pages)
</p>
</details>
<table>
<tr>
<td id="imposition_more_info"><div id="imposition_more_info_text"></div></td>
<td rowspan="2"><div id="imposition_folio_calculations" style="display:none;"></div></td>
</tr>
<tr>
<td>
Folios per Signature: <input type="text" placeholder="666" disabled id="folios_per_signature" oninput="vip.handleFoliosPerSigUpdate()">
</td>
</tr>
<tr>
<td width="100%" colspan="2">
<div id="imposition_options_list"></div>
<script language="javascript">
imposition_options = [
["single", "Single", "1 page per side, no folio", false, -1, [0.5], [1,1], "Yes, this is just like the source PDF -- not really useful for bookbinding/imposition, but given all the other features (trimming, re-ordering, padding) I figured why not", false],
["folio", "Folio", "2 pages per side, 1 folio", true, 4, [1], [1,2], "Minimal folding, large book, no cutting/trimming needed. Classic for beginners but too large for my personal taste", true],
["quarto", "Quarto", "4 pages per side, 2 folio", true, 4, [2], [2,2], "Perfect! Produces something closer to a more 'typical' book IMO with room to trim -- you could cut the folios apart pre-assembly, leave them folded and wait for the trimming step to separate, or go old school and make an <a href='https://onlineacademiccommunity.uvic.ca/theopenbook/2024/02/15/opening-the-unopened/' target='_blank'>unopend book</a> for the reader to slice with their <a href='https://en.wikipedia.org/wiki/Paper_knife' target='_blank'>paper knife</a> as they read", false],
["6_side", "Sexto", "6 pages per side, 3 folio", true, 3, [3], [2,3], "A wide format, assembled via an easy Z fold - requires trimming on top and bottom to separate folios", false],
["octavo_fat", "Octavo [fat]", "8 pages per side, 4 folio", true, 4, [4], [2,4], "Starting to get smaller but still easy to assemble. This has nested folds on the top AND on the side that can sometimes be bulky - binder's prefernece", true],
["octavo_thin", "Octavo [thin]", "8 pages per side, 4 folio", true, 4, [4],[2,4], "Starting to get smaller but still easy to assemble. This has a fold on edge that could compound skew problems, but there's no nested top fold - binder's preference", true],
["8_zine", "8 Page Zine", "special assembly", false, -1, [8], [2, 4], "Classic format that requires no glue but is a fixed size. Printed on one side, it requires a small slice down the center. There are many better write-ups out there on how to assemble it- like <a href='https://www.quarantinepubliclibrary.com/tutorial' target='_blank'>like this one!</a>", true],
["sextodecimo_fat", "Sextodecimo [fat]", "16 pages per side, 8 folio", true, 4, [8], [4,4], "Palm sized on most paper, nested folds along the top. If you go with 4 folio, you'll need to cut the sheet of paper in half (top vs bottom) and then fold-- still has nested top fold. The printer skew does not seem to compound too bad", false],
["sextodecimo_thin", "Sextodecimo [thin]", "16 pages per side, 8 folio", true, 4, [8], [4,4], "Palm sized on most paper, long strip with fold in the middle. If you go with 4 folio, you'll need to cut the sheet of paper in half (left vs right) and then zig-zag fold up. Initial testing suggests the printer skew is a bit more noticable", false],
["small_3_by_3", "Small", "18 per side, 3 folio x 3", false, 3, [3,3,3], [3,6], "Custom 'zig-zag' imposition - requires cutting the sheet into strips before folding them up into fixed signature sizes (3 folio)", true],
["little_3_3_4", "Little", "20 per side, 3/3/4 folio", false, "3,3,4", [3,3,4], [4,5], "Custom imposition - requires cutting the sheet into 3 different sections which are then assembled into fixed signature sizes (two 3 folios and a 4 folio per sheet)", false],
["tiny_4_by_4", "Tiny", "32 per side, 4 folio x 4", false, 4, [4,4,4,4], [4,8], "Custom 'zig-zag' imposition - requires cutting the sheet into strips before folding them up into fixed signature sizes (4 folio)", true],
["mini", "Mini", "60 per side, 2/3 folio x 6 ", false, "3,2", [2,3,2,3,2,3,2,3,2,3,2,3], [6,10], "Custom 'zig-zag' imposition - requires cutting the sheet into strips before folding them up into fixed signature sizes- each row is made up of two signatures ", true],
]
imposition_options.forEach((o, i) => {
drawing.renderImpositionOptions(document.getElementById("imposition_options_list"), o, i)
})
</script>
</td>
</tr>
</table>
</section>
<section id="pdf_placement" class="disabled">
<h2>5. PDF Placement</h2>
<details>
<summary>Instructions/Details</summary>
<p>
For PDF scaling:
<b>Original</b><br>
Retains the original PDF sizing, which could potentially spill out and over onto other pages, resulting in overlapping the PDF content (there is no clipping)<br>
Only the <code>top</code> and <code>inner</code> margins are considered. Positive values shift it down/away from the spine. Negative values shift it up/towards the spine.<BR>
<b>Fit - Proportional</b><br>
Maintains the original PDF aspect ratio, scaled down to fit into the space provided<br>
Positive padding numbers push the PDF inward, makes it smaller. Negative padding pulls it out, making it larger. A padding of <code>N</code> on one side and <code>-N</code> on the other side of the PDF is the same as translating/shifting it. The PDF will scale such that it's small enough to honor the tightest constraints (ex: inner/outer margins that squeeze the PDF will override top/bottom margins that expand the PDF)<BR>
<b>Fill - Stretch</b><br>
Distors the PDF's aspect ratio, stretching it in both directions to fill the entire space allowed<BR>
Positive padding numbers push the PDF inward, makes it smaller. Negative padding pulls it out, making it larger. A padding of <code>N</code> on one side and <code>-N</code> on the other side of the PDF is the same as translating/shifting it.
</p>
</details>
<div>
<label id="pdf_page_scaling_label" for="pdf_page_scaling">PDF Scaling</label>
<select id="pdf_page_scaling" name="select" required onchange="vip.handlePdfPageScaling(this)">
<option value="original" id="scaling_original">Original</option>
<option value="fit" id="scaling_fit" selected>Fit - Proportional</option>
<option value="fill" id="scaling_fill">Fill - Stretch</option>
</select>
</div>
<div id="layout_padding">
Padding<br>
<label for="pdf_padding_inner">inner </label><input type=number size="2" id="pdf_padding_inner" oninput="vip.handleImpositionPaddingUpdate()"><small class="units">cm</small>
<div id="pdf_margins_center">
<label for="pdf_padding_top">top</label> <input type=number size="2" id="pdf_padding_top" oninput="vip.handleImpositionPaddingUpdate()"><small class="units">cm</small><br>
<div id="layout_padding_center_info"></div>
<label for="pdf_padding_bottom" id="pdf_padding_bottom_label"> bottom <input type=number size="2" id="pdf_padding_bottom" oninput="vip.handleImpositionPaddingUpdate()"><small class="units">cm</small></label>
</div>
<label for="pdf_padding_outer" id="pdf_padding_outer_label"> outer<input type=number size="2" id="pdf_padding_outer" oninput="vip.handleImpositionPaddingUpdate()"><small class="units">cm</small></label>
</div>
<div>
<label id="pdf_white_space_placement_label" for="pdf_white_space_placement">PDF Positioning</label>
<select id="pdf_white_space_placement" name="select" required onchange="vip.handlePdfPagePlacement(this)">
<option value="snug_center" id="placement_snug_center">snug against spine, centered vertically</option>
<option value="snug_top" id="placement_snug_top">snug against spine, top aligned</option>
<option value="center" id="placement_center" selected>centered horizontally, centered vertially</option>
<option value="center_top" id="placement_center_top">centered horizontally, top aligned</option>
</select>
</div>
<kbd class="disabled">spacing/placement preview not implemented yet</kbd>
<svg height="150" width="150" id="pdf_placement_svg" style="display: none;">
</svg>
<script language="javascript">
drawing.renderPreviewSvg(document.getElementById("pdf_placement_svg"))
</script>
</section>
<section id="printed_page_markup">
<h2>6. Markup</h2>
<details>
<summary>Details</summary>
<p>
When entering line weigh values, be aware that you can use decimals/go lower than <code>1</code><BR>
Fold lines (dashed) are for signature assembly - they will need to be cut at some point but it doesn't have to be right away (cut during textblock trimming)<BR>
Cut lines (solid) are for signature assembly - they need to be cut at time of fold up/sewing<Br>
Cut & Fold lines will only be marked on one side of the sheet. This is the "mountain" side of the fold - you should always be able to see the fold or cut line after the fold<BR>
Crosshairs are at every non-sheet-corner intersection and are meant to be very tiny visual guides to help with alignment/folding. They are on both sides of the sheet<BR>
</p>
</details>
<div class="printed_page_markup_options">
<input type="checkbox" id="markup_fold_lines" name="markup_fold_lines" value="fold" onchange="vip.handleMarkupDetailsChange(this, 'markup_fold_lines_details')" checked> <label for="markup_fold_lines"> fold lines</label> <span id="markup_fold_lines_details"><small><Input type=number id="fold_line_weight" placeholder="0.5"/> <span id="fold_line_weight_label">line weight (pt)</span></small><input type="color" id="markup_fold_lines_color" value="#969696" /> </span></br>
<span class="disabled"><input type="checkbox" id="markup_cut_lines" name="markup_cut_lines" value="cut" onchange="vip.handleMarkupDetailsChange(this, 'markup_cut_lines_details')" checked><label for="markup_cut_lines"> cut lines</label><span id="markup_cut_lines_details"><small> <Input type=number id="cut_line_weight" placeholder="2"/> <span id="cut_line_weight_label">line weight (pt)</span></small><input type="color" id="markup_cut_lines_color" value="#666666" /> </span><kbd>not implemented yet</kbd></span></br>
<input type="checkbox" id="markup_crosshairs" name="markup_crosshairs" value="cross" onchange="vip.handleMarkupDetailsChange(this, 'markup_crosshairs_details')" checked> <label for="markup_crosshairs"> cross-hairs</label> <span id="markup_crosshairs_details"><small><Input type=number id="markup_crosshairs_weight" placeholder="0.25"/> <span id="markup_crosshairs_weight_label">line weight (pt)</span> | <Input type=number id="markup_crosshairs_length" placeholder="10"/> <span id="markup_crosshairs_length_label">cross-hair leg length (pt)</span></small><input type="color" id="markup_crosshairs_color" value="#333333" /></span> </br>
<input type="checkbox" id="markup_spine_order" name="markup_spine_order" value="order" onchange="vip.handleMarkupDetailsChange(this, 'markup_spine_order_details')" checked> <label for="markup_spine_order"> spine marks: order</label><span id="markup_spine_order_details"> <Input type=number id="markup_spine_order_weight" placeholder="5"/> <span id="markup_spine_order_weight_label">line weight (pt)</span><input type="color" id="markup_spine_order_color" value="#B8B8B8" /> </span></br>
<input type="checkbox" id="markup_spine_bounds" name="markup_spine_bounds" value="order" onchange="vip.handleMarkupDetailsChange(this, 'markup_spine_bounds_details')" checked> <label for="markup_spine_bounds"> spine marks: bounds</label> <span id="markup_spine_bounds_details"><small> <Input type=number id="markup_spine_bounds_weight" placeholder="2"/> <span id="markup_spine_bounds_weight_label">line weight (pt)</span> | <Input type=number id="markup_spine_bounds_length" placeholder="10"/> <span id="markup_spine_bounds_length_label"> length (pt)</span><input type="color" id="markup_spine_bounds_color" value="#757575" /></small> </span></br>
<div>
<input type="checkbox" id="markup_sewing" name="markup_sewing" value="sewing" checked onchange="vip.handleSewingStationChange(this)"> <label for="markup_sewing">sewing / punching guides</label>
<select id="markup_sewing_stations" name="markup_sewing_stations">
<option value="outer">spine only</option>
<option value="inner">inner folio only</option>
<option value="inner_outer" selected>spine & inner folio</option>
</select>
<input type="color" id="markup_sewing_stations_color" value="#4b4b4b" />
<div id="markup_sewing_stations_details">
<input type="number" id="markup_sewing_dist_top" name="markup_sewing_dist_top" placeholder="36"> <label for="markup_sewing_dist_top"> distance from head to top hole (pt)</label><br/>
<input type="number" id="markup_sewing_dist_bottom" name="markup_sewing_dist_bottom" placeholder="54"> <label for="markup_sewing_dist_bottom"> distance from tail to bottom hole (pt)</label><br/>
<input type="number" id="markup_sewing_count" name="markup_sewing_count" placeholder="2"> <label for="markup_sewing_count"> count of sewing stations</label> <br/>
<input type="number" id="markup_sewing_station_dist" name="markup_sewing_station_dist" placeholder="36"> <label for="markup_sewing_station_dist"> distance between points at each sewing station (pt)</label><br/>
<input type="number" id="markup_sewing_dot_size" name="markup_sewing_dot_size" placeholder="2"> <label for="markup_sewing_dot_size"> guideline dot size (pt)</label>
</div>
</div>
</div>
</section>
<section id="printed_page_adjustment">
<h2>7. Post-Processing</h2>
<details>
<summary>Instructions/Details</summary>
<p>
This is to address printer skew
</p>
</details>
<kbd>not implemented yet</kbd>
</section>
<section id="pdf_preview" class="disabled">
<h2>8. Preview</h2>
<div id="pdf_preview_size_warning" style="display: none;">
<kbd>⚠️ dealing with large file(s) ⚠️</kbd>
<code>'preview first signature'</code> recommened <br> <small>downloading PDF should still work even if preview doesn't</small>
</div><br>
<button id="preview_pdf_btn" onclick="vip.refreshPreview()">Preview PDF</button>
<label for="pdf_results_preview_mode">
<input type="checkbox" role="switch" id="pdf_results_preview_mode" name="pdf_results_preview_mode">
only preview first signature
</label>
<div style="display: none;" id="preview_status_slot">status one 123</div>
<h4 style="display: none;" id="preview_error_slot">There was an error</h4>
<center>
<iframe id="pdf_results_preview" type="application/pdf" style="display: none"></iframe>
</center>
</section>
<section id="pdf_download" class="disabled">
<h2>9 Download</h2>
<details>
<summary>Details</summary>
<p>
Note that <code>each signature as separate file</code> outputs full sheets -- if the imposition configuration has signatures that do not fill up entire sheets, the files downloaded will be full sheets and thus could contain extra folios
</p>
</details>
<div>
Download: <br>
<label for="download-aggregate">
<input type="checkbox" id="download-aggregate" name="download-aggregate" checked="">
aggregate file (all signatures in one file)
</label>
<label for="download-signatures">
<input type="checkbox" id="download-signatures" name="download-signatures">
each signature as separate file
</label>
<label for="download-front-back">
<input type="checkbox" role="switch" id="download-front-back" name="download-front-back">
front / back of sheets as separate files
</label>
<BR>
<input type=text id="file_download_name" placeholder="your_file_name">.pdf
<button onclick="vip.downloadFile(document.getElementById('file_download_name').value, document.getElementById('file_download_name').getAttribute('placeholder'))">get that file!</button>
<kbd class="disabled">saving/persisting imposer settings not implemented yet</kbd><br><br>
<kbd class="disabled">imposer does not yet work when saved locally</kbd>
</div>
</section>
</main>
<section id="footer">
<small>
PDF library by <a href="https://pdf-lib.js.org/" target="_blank">PDF-LIB</a><br>
CSS library by <a href="https://picocss.com/" target="_blank">pico</a><br>
download libraries by <a href="https://github.com/eligrey/FileSaver.js/tree/master" target="_blank">FileSaver.js</a> & <a href="http://stuartk.com/jszip" target="_blank">JSZip</a><br>
based on <a href="https://momijizukamori.github.io/bookbinder-js/" target="_blank">Bookbinder-JS</a><br>
part of the <a href="https://www.renegadeguild.org/" target="_blank">Renegade Bindery</a> <a href="https://www.renegadeguild.org/" target="_blank"><img width="25px" src="./img/renegade.png"></a>
</small>
</section>
<!-- Minimal theme switcher -->
<!-- <script src="js/minimal-theme-switcher.js"></script> -->
<!-- Modal -->
<!-- <script src="js/modal.js"></script> -->
</body>
</html>