skeptick 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +14 -0
  3. data/README.md +63 -289
  4. data/lib/skeptick/command.rb +8 -19
  5. data/lib/skeptick/convert.rb +65 -82
  6. data/lib/skeptick/core.rb +1 -7
  7. data/lib/skeptick/dsl_context.rb +32 -0
  8. data/lib/skeptick/sugar.rb +13 -7
  9. data/lib/skeptick/sugar/canvas.rb +8 -0
  10. data/lib/skeptick/sugar/clone.rb +9 -0
  11. data/lib/skeptick/sugar/compose.rb +50 -0
  12. data/lib/skeptick/sugar/delete.rb +9 -0
  13. data/lib/skeptick/sugar/draw.rb +7 -0
  14. data/lib/skeptick/sugar/font.rb +7 -0
  15. data/lib/skeptick/sugar/format.rb +7 -0
  16. data/lib/skeptick/sugar/geometry.rb +25 -31
  17. data/lib/skeptick/sugar/resized_image.rb +15 -0
  18. data/lib/skeptick/sugar/rounded_corners_image.rb +42 -0
  19. data/lib/skeptick/sugar/swap.rb +12 -0
  20. data/lib/skeptick/sugar/text.rb +11 -0
  21. data/lib/skeptick/sugar/torn_paper_image.rb +32 -0
  22. data/lib/skeptick/sugar/write.rb +8 -0
  23. data/lib/skeptick/version.rb +1 -1
  24. data/logo.rb +12 -11
  25. data/refresh_preview.scpt +1 -1
  26. data/skeptick.gemspec +1 -0
  27. data/test/convert_test.rb +128 -33
  28. data/test/sugar/canvas_test.rb +16 -0
  29. data/test/sugar/clone_test.rb +41 -0
  30. data/test/sugar/{composition_test.rb → compose_test.rb} +35 -87
  31. data/test/sugar/delete_test.rb +41 -0
  32. data/test/sugar/draw_test.rb +11 -0
  33. data/test/sugar/font_test.rb +11 -0
  34. data/test/sugar/format_test.rb +12 -0
  35. data/test/sugar/{resizing_test.rb → resized_image_test.rb} +5 -5
  36. data/test/sugar/rounded_corners_image_test.rb +53 -0
  37. data/test/sugar/swap_test.rb +28 -0
  38. data/test/sugar/text_test.rb +22 -0
  39. data/test/sugar/torn_paper_image_test.rb +53 -0
  40. data/test/sugar/write_test.rb +14 -0
  41. metadata +57 -34
  42. data/lib/skeptick/chain.rb +0 -55
  43. data/lib/skeptick/chain/dsl_context.rb +0 -21
  44. data/lib/skeptick/convert/dsl_context.rb +0 -27
  45. data/lib/skeptick/helper.rb +0 -26
  46. data/lib/skeptick/image.rb +0 -69
  47. data/lib/skeptick/image/dsl_context.rb +0 -29
  48. data/lib/skeptick/sugar/composition.rb +0 -55
  49. data/lib/skeptick/sugar/debugging.rb +0 -12
  50. data/lib/skeptick/sugar/drawing.rb +0 -32
  51. data/lib/skeptick/sugar/edges.rb +0 -70
  52. data/lib/skeptick/sugar/formatting.rb +0 -12
  53. data/lib/skeptick/sugar/resizing.rb +0 -16
  54. data/lib/skeptick/sugar/sequence_manipulation.rb +0 -43
  55. data/test/chain_test.rb +0 -94
  56. data/test/image_test.rb +0 -145
  57. data/test/sugar/debugging_test.rb +0 -24
  58. data/test/sugar/drawing_test.rb +0 -86
  59. data/test/sugar/edges_test.rb +0 -99
  60. data/test/sugar/formatting_test.rb +0 -19
  61. data/test/sugar/sequence_manipulation_test.rb +0 -98
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f063a9fcc9653c7f7c10c975f1de9b5d7f1bfa85
4
- data.tar.gz: bfe797cbb1dee5576f915765621ba3851bf949ed
3
+ metadata.gz: 92b23f5d9d5e194a4eed73a1a1422bd1a18de3c3
4
+ data.tar.gz: 1c7f34a26786c074d628d0cafe0aa14291b9a703
5
5
  SHA512:
6
- metadata.gz: d44e20efd63cec1053b5f6e7f6fdfb91e28f53ffa00c80975f5fe187aaa8377be7f3825927bb64e9a357a0cff187f64fca07beae1f9152e8c72122963082bbdc
7
- data.tar.gz: ec450c5a2a0ca862ca4e3ba04534f14d390e84e09e2e39bd6ff3da43dd216c9bf4abe9f8b911ccb50a55f6089e56cc9bbc37fe5acc66499fadc4a5f37f576014
6
+ metadata.gz: 31488ca6f7cc0988cabbb12f5e7ce049659bcf53d94aa333816e97bc6250db4fd29cfc15c38557bf3c3a5fbb20910bc2e7503b7b317addc79a46997f31a14a29
7
+ data.tar.gz: f67aa8409bbb944421876c4e6aa4b86d8515b8ea8b5fac36be9541657466b0974f0edd16062cc1d7fd4789af723dd93beb83a85fc56b73c78912c96f968a5e8c
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ v0.2.0
2
+
3
+ * No more aliased keywords (with, apply) only set, append, prepend
4
+ * No more aliases: build, execute; only run
5
+ * All strings are now escaped, so make sure you split arguments to `set`
6
+ * Keyword `write` renamed to text (consistent with ImageMagick)
7
+ * Keyword `save` is renamed to `write` (consistent with ImageMagick)
8
+ * No more piping support (no point, use composition instead)
9
+ * Blocks are now evaluated upon declaration (still without running the command)
10
+ * It's now ok to assign convert to a variable that's also used inside the block
11
+ * No more Image class, image method now aliased to convert
12
+ * Sugar is implemented in a much more straightforward way
13
+ * Code amount is significantly reduced
14
+
1
15
  v0.1.1
2
16
 
3
17
  * Add Skeptick.timeout (seconds) for limiting runtime of convert operations
data/README.md CHANGED
@@ -1,12 +1,3 @@
1
- ### A note on project status
2
-
3
- If looking at commits makes you think that this project is abandoned, it's not. Skeptick is being used in our production ever since its inception, and it's working great. The reason there is no new activity is as follows.
4
-
5
- * It's really working great for us
6
- * Nobody is submitting issues
7
-
8
- So don't let the lack of git activity fool you. I have plans to blog about some interesting use cases for Skeptick and link to them from this README, stay tuned.
9
-
10
1
  # Skeptick: Better ImageMagick for Ruby
11
2
 
12
3
  [![Build Status](https://travis-ci.org/maxim/skeptick.png?branch=master)](https://travis-ci.org/maxim/skeptick)
@@ -59,14 +50,14 @@ class MyClass
59
50
  # ...
60
51
  end
61
52
 
62
- cmd.build
53
+ cmd.run
63
54
  end
64
55
  end
65
56
  ```
66
57
 
67
58
  The `cmd` object seen in above example can be inspected to see the exact command
68
59
  that Skeptick will run. Simply use `cmd.inspect` or `cmd.to_s`. Skeptick never
69
- runs anything until you call `build` (except for one very special case), so you
60
+ runs anything until you call `run` (except for one very special case), so you
70
61
  can inspect commands all you want before executing them.
71
62
 
72
63
  If you don't want to require all of Skeptick, you can just require the core, and
@@ -74,8 +65,8 @@ and select any specific sugar you want.
74
65
 
75
66
  ```ruby
76
67
  require 'skeptick/core'
77
- require 'skeptick/sugar/resizing'
78
- require 'skeptick/sugar/composition'
68
+ require 'skeptick/sugar/resized_image'
69
+ require 'skeptick/sugar/compose'
79
70
  ```
80
71
 
81
72
  See the `lib/skeptick/sugar` dir for all the goodies.
@@ -103,115 +94,24 @@ obvious. Skeptick executes strings in your shell.
103
94
 
104
95
  ![Skeptick Logo](https://raw.github.com/maxim/skeptick/master/logo.png)
105
96
 
106
- This picture is produced with the following script
97
+ Take a look at [logo.rb](logo.rb) to see thow this logo was generated.
107
98
 
108
- ```ruby
109
- include Skeptick
110
-
111
- image_size = '400x120'
112
- left, top = 8, 80
113
-
114
- # Build a picture with built-in tile:granite: texture and using the
115
- # skeptick-provided sugar method `rounded_corners_image`
116
- paper = rounded_corners_image(size: image_size, radius: 25) do
117
- set :size, image_size
118
- image 'tile:granite:'
119
- apply '-brightness-contrast', '38x-33'
120
- apply :blur, '0x0.5'
121
- end
99
+ A lot is going on in the above script, no worries, it's just a showcase. I bet
100
+ the first thing you noticed is a shitstorm of little method names like `canvas`,
101
+ `font`, `write`, `draw`, etc. Well, they are all sugar. We will cover sugar
102
+ below.
122
103
 
123
- # Build a text image that says "Skeptick" using specified font, add gradient
124
- text = image do
125
- canvas :none, size: '395x110'
126
- font 'Handwriting - Dakota Regular'
127
- set :pointsize, 90
128
- set :fill, 'gradient:#37e-#007'
129
- write 'Skeptick', left: left, top: top
130
- apply :blur, '0x0.7'
131
- end
132
-
133
- bezier = \
134
- "#{left + 17 }, #{top + 17} #{left + 457}, #{top - 13} " +
135
- "#{left + 377}, #{top + 27} #{left + 267}, #{top + 27}"
136
-
137
- # Draw a curve that will appear underneath the text using bezier coordinates
138
- curve = image do
139
- canvas :none, size: '395x110'
140
- set :strokewidth, 2
141
- set :stroke, 'gradient:#37e-#007'
142
- draw "fill none bezier #{bezier}"
143
- end
144
-
145
- # Combine text and curve using `:over` blending, multiply it with paper using
146
- # `:multiply` blending, and add a torn effect using Skeptick-provided sugar
147
- # method `torn_paper_image`
148
- torn = torn_paper_image(
149
- paper * (text + curve),
150
- spread: 50,
151
- blur: '3x10'
152
- )
153
-
154
- # Create a convert command with all of the above and run it
155
- logo = convert(torn, to: "#{File.dirname(__FILE__)}/logo.png")
156
- logo.build
157
-
158
- # This is what the resulting command looks like
159
- # You can see it by running `logo.to_s`
160
- #
161
- # convert (
162
- # (
163
- # (
164
- # -size 400x120 tile:granite:
165
- # -brightness-contrast 38x-33 -blur 0x0.5
166
- # (
167
- # +clone -alpha transparent -background none
168
- # -draw roundrectangle 1,1 400,120 25,25
169
- # )
170
- # -alpha set -compose dstin -composite
171
- # )
172
- #
173
- # (
174
- # -size 395x110 canvas:none
175
- # -font Handwriting---Dakota-Regular -pointsize 90
176
- # -fill gradient:#37e-#007 -draw text 8,80 'Skeptick'
177
- # -blur 0x0.7 -size 395x110 canvas:none -strokewidth 2
178
- # -stroke gradient:#37e-#007
179
- # -draw fill none
180
- # bezier 25, 97 465, 67 385, 107 275, 107
181
- # -compose over -composite
182
- # )
183
- #
184
- # -compose multiply -composite
185
- # )
186
- #
187
- # (
188
- # +clone -alpha extract -virtual-pixel black -spread 50
189
- # -blur 0x3 -threshold 50% -spread 1 -blur 0x.7
190
- # )
191
- #
192
- # -alpha off -compose copy_opacity -composite
193
- # ) logo.png
194
-
195
- ```
196
-
197
- ## All those little commands
198
-
199
- A lot of things happened in the above script, no worries, it's just a showcase.
200
- I bet the first thing you noticed is a shitstorm of little method names like
201
- `apply`, `canvas`, `font`, `write`, `draw`, etc. Well, they are all sugar. We
202
- will cover sugar later in teh given parchment.
203
-
204
- There are actually only three real commands in all of Skeptick: `convert`,
205
- `set`, and `image`.
104
+ There are actually only 2 useful methods in all of Skeptick: `convert` and
105
+ `set`.
206
106
 
207
107
  ### Convert
208
108
 
209
- `convert` can be used both outside and inside a transformation block. You could
210
- say for example this.
109
+ `convert` can be used both standalone and inside another `convert`. You could
110
+ say this.
211
111
 
212
112
  ```ruby
213
113
  command = convert('image1.png', to: 'image2.png') do
214
- set '-resize', '200x200'
114
+ set :resize, '200x200'
215
115
  end
216
116
 
217
117
  # OUTPUT:
@@ -223,8 +123,8 @@ Or you could put it inside, and it will become a parenthesized subcommand.
223
123
  ```ruby
224
124
  command = convert('image1.png', to: 'image2.png') do
225
125
  convert do
226
- set '+clone' # pull in image1 into parentheses
227
- set '-resize 100x100' # resize image1's clone in memory
126
+ set '+clone' # pull in image1 into parentheses
127
+ set :resize, '100x100' # resize image1's clone in memory
228
128
  end
229
129
 
230
130
  set '-compose over'
@@ -254,131 +154,42 @@ end
254
154
  # -resize 300x300 whatever.png
255
155
  ```
256
156
 
257
- See what I did there? It's composability. If you have a `convert` object in a
258
- variable, you can use it inside another `convert` object down the line.
259
-
260
- ### Set
261
-
262
- `set` appends a string to your command. You can give it any arguments, it
263
- doesn't care, it will just `to_s` and concatenate them.
157
+ See what I did there? The `command` from previous snippet is passed into
158
+ `convert`. If you have a `convert` object in a variable, you can use it inside
159
+ another `convert` object down the line. Nesting possibilities are endless.
264
160
 
161
+ The same snippet could also be written like this.
265
162
  ```ruby
266
- # All same thing
267
- set '-resize 100x100'
268
- set '-resize', '100x100'
269
- set :resize, '100x100'
270
- ```
271
-
272
- Yeah that last one is special convenience. If an argument to `set` is a symbol,
273
- it will convert it to `"-#{symbol}"`. If you need `+resize` type of thing you'd
274
- just have to use a string, or sugar, but later on that.
275
-
276
- ### Image
277
-
278
- `image` is very similar to `convert`. However, `convert` is a command object
279
- that may contain many images, settings, operators, nested converts, etc. Image
280
- is also a command object that can contain many settings and operators, but it
281
- can only contain one image reference inside of it. The reference can be a path,
282
- a nested convert, or a special string representing a built-in imagemagick image,
283
- but it can be only one.
284
-
285
- ```ruby
286
- command = convert(to: '/path/to/result.png') do
287
- image '/path/to/image.png'
288
- set :resize, '200x200'
289
- end
290
-
291
- # OUTPUT:
292
- # convert /path/to/image.png -resize 200x200 /path/to/result.png
293
- ```
294
-
295
- In this case we declared an image inside a `convert` which references a path.
296
- Instead we could create an image that references a built-in image.
297
-
298
- ```ruby
299
- command = convert(to: '/path/to/result.png') do
300
- image 'rose:'
163
+ new_command = convert(to: 'whatever.png') do
164
+ image command
165
+ set :resize, '300x300'
301
166
  end
302
-
303
- # OUTPUT:
304
- # convert rose: /path/to/result.png
305
- ```
306
-
307
- You can save image objects in variables, and pass them around, but unlike
308
- `convert`, you cannot run them standalone.
309
-
310
- ```ruby
311
- rose_image = image('rose:')
312
- command = convert(rose_image, to: '/path/to/result.png')
313
-
314
- # OUTPUT:
315
- # convert rose: /path/to/result.png
316
167
  ```
317
- See, we had to wrap it in a `convert` in order to use it. You could also append
318
- this image at any point inside the convert block.
319
168
 
320
- ```ruby
321
- rose_image = image('rose:')
322
- command = convert(to: '/path/to/result.png') do
323
- image rose_image
324
- end
169
+ 2 differences: 1 - instead of passing in `command` as argument we declare it
170
+ inside the block. 2 - resize is a symbol. Any symbol passed into `set`
171
+ automatically becomes a string with dash in front of it. Speaking of set.
325
172
 
326
- # OUTPUT:
327
- # convert rose: /path/to/result.png
328
- ```
329
-
330
- As mentioned above, an image can come with its own settings and operators.
331
-
332
- ```ruby
333
- rose_image = image do
334
- set :background, 'transparent'
335
- image 'rose:'
336
- apply :resize, '200x200'
337
- end
338
-
339
- command = convert(to: '/path/to/result.png') do
340
- image rose_image
341
- end
342
- ```
343
-
344
- You could do all of this inline, the output will be the same.
345
-
346
- ```ruby
347
- command = convert(to: '/path/to/result.png') do
348
- image do
349
- set :background, 'transparent'
350
- image 'rose:'
351
- apply :resize, '200x200'
352
- end
353
- end
354
-
355
- # OUTPUT:
356
- # convert -background transparent rose: -resize 200x200 /path/to/result.png
357
- ```
173
+ ### Set
358
174
 
359
- If you have a `convert` object you can pass it as an image too.
175
+ `set` adds stuff to your command. You can give it any various arguments, it
176
+ doesn't care.
360
177
 
361
178
  ```ruby
362
- saved_convert = convert(to: 'foo.png') do
363
- image 'rose:'
364
- set :resize, '200x200'
365
- end
366
-
367
- another_convert = convert(to: 'bar.png') do
368
- image saved_convert
369
- apply :blur, '0x0.5'
370
- end
371
-
372
- # OUTPUT
373
- # convert ( rose: -resize 200x200 ) -blur 0x0.5 bar.png
179
+ # All same thing
180
+ set '-resize 100x100'
181
+ set '-resize', '100x100'
182
+ set :resize, '100x100'
374
183
  ```
375
184
 
376
- Nesting possibilities are endless.
185
+ In addition to `set` there are also `prepend` and `append` to put stuff at the
186
+ beginning or end of a command, but they are rarely useful, and mostly for
187
+ implementing your own sugar.
377
188
 
378
189
  ## Sugar
379
190
 
380
191
  Skeptick comes with a bunch of sugar. When you require Skeptick, you can simply
381
- require everything. This includes all the sugar.
192
+ require everything. This includes all the sugar functionality.
382
193
 
383
194
  ```ruby
384
195
  require 'skeptick'
@@ -389,12 +200,12 @@ sugar you want.
389
200
 
390
201
  ```ruby
391
202
  require 'skeptick/core'
392
- require 'skeptick/sugar/composition'
203
+ require 'skeptick/sugar/compose'
393
204
  ```
394
205
 
395
- ### Composition Sugar
206
+ ### Compose Sugar
396
207
 
397
- Composition is sugar that adds `compose` shortcut to Skeptick's DSL.
208
+ Compose is sugar that adds `compose` shortcut to Skeptick's DSL.
398
209
 
399
210
  ```ruby
400
211
  command = compose(:multiply, 'a.png', 'b.png', to: 'out.png') do
@@ -406,57 +217,46 @@ end
406
217
  ```
407
218
 
408
219
  It takes the blending type as the first argument, and injects some extra stuff
409
- into the resulting command, but really it's just a wrapper around `convert` as
410
- you could easily see in its implementation.
411
-
412
- ```ruby
413
- def compose(blending, *args, &blk)
414
- convert(*args, &blk).tap do |c|
415
- c.append :compose, blending.to_s
416
- c.append :composite
417
- end
418
- end
419
- ```
220
+ into the resulting command.
420
221
 
421
- As usual, you don't have to list your images as method arguments like that.
222
+ As with `convert`, you don't have to list your images as method arguments.
422
223
  Instead you could declare them inside the block using the `image` method. The
423
224
  following command does the same thing.
424
225
 
425
226
  ```ruby
426
227
  command = compose(:multiply, to: 'out.png') do
427
228
  image 'a.png'
428
- image 'b.png'
229
+ convert 'b.png'
429
230
  set :resize, '200x200'
430
231
  end
431
232
  ```
432
233
 
234
+ *Note:* `image` is alias of `convert`.
235
+
433
236
  Since most of Skeptick's power comes from the ability to infinitely nest things,
434
- here's a an example involving a nested `compose`.
237
+ here's an example involving a nested `compose`.
435
238
 
436
239
  ```ruby
437
240
  command = convert('image1.png', to: 'result.png') do
438
241
  compose(:multiply) do
439
- image 'image3.png[200x200]'
242
+ image 'image2.png[200x200]'
440
243
 
441
- convert 'image4.png' do
244
+ convert 'image3.png' do
442
245
  set :unsharp, '0x5'
443
246
  end
444
-
445
247
  end
446
248
  end
447
249
 
448
250
  # OUTPUT:
449
251
  # convert
450
- # image1.png ( image3.png[200x200] ( image4.png -unsharp 0x5 ) -compose
451
- # multiply -composite ) result.png"
252
+ # image1.png image2.png[200x200] ( image3.png -unsharp 0x5 ) -compose
253
+ # multiply -composite result.png"
452
254
  ```
453
255
 
454
256
  Notice how we nest `compose` inside of `convert`, and then `convert` inside of
455
- `compose`. The output of each acts like any declared image. In other words,
456
- wherever you would write `image "foo.png"` you could also write a nested
457
- command.
257
+ `compose`.
458
258
 
459
- ### Composition Operators
259
+ ### Compose Operators
460
260
 
461
261
  This is more of a gimmick than a real feature, but you can use math operators
462
262
  like `+`, `-`, `*`, `/`, `&`, `|` to compose images. These are all based on
@@ -468,7 +268,7 @@ image2 = image('bar.png')
468
268
  result = convert(image1 * image2, to: 'baz.png')
469
269
 
470
270
  # OUTPUT:
471
- # convert ( foo.png bar.png -compose multiply -composite ) baz.png
271
+ # convert foo.png bar.png -compose multiply -composite baz.png
472
272
  ```
473
273
 
474
274
  As you can see, this is equivalent of simply using `compose`.
@@ -478,9 +278,10 @@ As you can see, this is equivalent of simply using `compose`.
478
278
  result = compose(:multiply, 'foo.png', 'bar.png', to: 'baz.png')
479
279
  ```
480
280
 
481
- Check out `lib/skeptick/sugar/composition.rb` for what these operators do.
281
+ Check out [lib/skeptick/sugar/compose.rb](lib/skeptick/sugar/compose.rb) for
282
+ what these operators do.
482
283
 
483
- ### Sequence Manipulation Sugar
284
+ ### clone, delete, swap
484
285
 
485
286
  Skeptick provides methods `clone`, `delete`, and `swap` to
486
287
  manipulate declared images in a sequence, just like in ImageMagick CLI.
@@ -540,58 +341,31 @@ sequence. Same with `swap` - you can provide two indexes in arguments like
540
341
  `swap(1,3)` to swap any 2 images in the sequence, or without arguments it'll
541
342
  act as `+swap` - which swaps last two images.
542
343
 
543
- ### Debugging Sugar
344
+ ### Write
544
345
 
545
346
  Sometimes you might want to take a look at an intermediate image that's being
546
347
  generated inside parentheses, nested somewhere in your command. You can do so
547
- with the help of `save('/path/to/img.png')`, which is defined in
548
- `skeptick/sugar/debugging.rb`.
348
+ with the help of `write '/path/to/img.png'`, which is defined in
349
+ `skeptick/sugar/write.rb`.
549
350
 
550
351
  ```ruby
551
352
  command = convert(to: 'result.png') do
552
353
  compose(:multiply, 'a.png', 'b.png') do
553
- save('~/Desktop/debug.png')
354
+ write '~/Desktop/debug.png'
554
355
  end
555
356
 
556
- set '-resize', '200x200'
357
+ set :resize, '200x200'
557
358
  end
558
359
  ```
559
360
 
560
361
  In this case the result of inner `compose` command will be saved to desktop
561
- without affecting anything else. Again, this is a feature that already exists
562
- in ImageMagick, as becomes apparent from the resulting command.
362
+ without affecting anything else. This is a feature that already exists in
363
+ ImageMagick, as you can see for yourself from generated command:
563
364
 
564
365
  convert
565
366
  ( a.png b.png -compose multiply -composite -write ~/Desktop/debug.png )
566
367
  -resize 200x200 result.png
567
368
 
568
- ## Chain
569
-
570
- This is rarely (if ever) needed, but with Skeptick you could easily create
571
- piped commands.
572
-
573
- ```ruby
574
- command = chain(to: 'result.png') do
575
- compose(:hardlight, 'a.png', 'b.png') do
576
- set '-brightness-contrast', '2x4'
577
- end
578
-
579
- compose(:atop, 'c.png', :pipe)
580
- end
581
-
582
- # OUTPUT:
583
- # convert
584
- # a.png b.png -compose hardlight -brightness-contrast 2x4 -composite miff:- |
585
- # convert
586
- # c.png miff:- -compose atop -composite result.png
587
- ```
588
-
589
- Two things to note here. First of all, commands that are declared in the `chain`
590
- block will become piped together. Second, we use a special `:pipe` symbol in
591
- the last `compose` command. This symbol indicates where the piped-in image
592
- should appear in the image sequence. You can see this in the output string. The
593
- `miff:-` appears after c.png, as expected.
594
-
595
369
  Documentation is to be continued...
596
370
 
597
371
  ## Contributing