img_to_script 1.0.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 +7 -0
- data/.rubocop.yml +25 -0
- data/.vscode/launch.json +21 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +271 -0
- data/Rakefile +16 -0
- data/img_to_script.gemspec +41 -0
- data/lib/img_to_script/abs_token_type.rb +33 -0
- data/lib/img_to_script/abstract_token/abs_func.rb +19 -0
- data/lib/img_to_script/abstract_token/abstract_token.rb +23 -0
- data/lib/img_to_script/abstract_token/assign_value.rb +20 -0
- data/lib/img_to_script/abstract_token/clear_screen.rb +16 -0
- data/lib/img_to_script/abstract_token/data_read.rb +19 -0
- data/lib/img_to_script/abstract_token/data_store.rb +19 -0
- data/lib/img_to_script/abstract_token/draw_chunk_by_hex_value.rb +19 -0
- data/lib/img_to_script/abstract_token/draw_line_by_abs_coords.rb +22 -0
- data/lib/img_to_script/abstract_token/draw_pixel_by_abs_coords.rb +20 -0
- data/lib/img_to_script/abstract_token/go_to.rb +19 -0
- data/lib/img_to_script/abstract_token/if_condition.rb +20 -0
- data/lib/img_to_script/abstract_token/loop_begin.rb +21 -0
- data/lib/img_to_script/abstract_token/loop_end.rb +19 -0
- data/lib/img_to_script/abstract_token/math_add.rb +20 -0
- data/lib/img_to_script/abstract_token/math_greater_than.rb +20 -0
- data/lib/img_to_script/abstract_token/math_mult.rb +20 -0
- data/lib/img_to_script/abstract_token/math_sub.rb +20 -0
- data/lib/img_to_script/abstract_token/move_point_to_abs_coords.rb +20 -0
- data/lib/img_to_script/abstract_token/parentheses.rb +19 -0
- data/lib/img_to_script/abstract_token/program_begin.rb +16 -0
- data/lib/img_to_script/abstract_token/program_end.rb +16 -0
- data/lib/img_to_script/abstract_token/remark.rb +19 -0
- data/lib/img_to_script/abstract_token/sign_func.rb +19 -0
- data/lib/img_to_script/abstract_token/wait.rb +19 -0
- data/lib/img_to_script/abstract_token.rb +8 -0
- data/lib/img_to_script/container.rb +26 -0
- data/lib/img_to_script/current_line_placeholder.rb +40 -0
- data/lib/img_to_script/formatter.rb +34 -0
- data/lib/img_to_script/generators/generator.rb +134 -0
- data/lib/img_to_script/generators/hex_mask/default.rb +24 -0
- data/lib/img_to_script/generators/hex_mask/enhanced.rb +220 -0
- data/lib/img_to_script/generators/hex_mask/hex_mask.rb +100 -0
- data/lib/img_to_script/generators/hex_mask.rb +13 -0
- data/lib/img_to_script/generators/run_length_encoding/horizontal.rb +78 -0
- data/lib/img_to_script/generators/run_length_encoding/run_length_encoding.rb +304 -0
- data/lib/img_to_script/generators/run_length_encoding/vertical.rb +79 -0
- data/lib/img_to_script/generators/run_length_encoding.rb +10 -0
- data/lib/img_to_script/generators/segmental/data_read_draw/data_read_draw.rb +70 -0
- data/lib/img_to_script/generators/segmental/data_read_draw/horizontal.rb +54 -0
- data/lib/img_to_script/generators/segmental/data_read_draw/vertical.rb +54 -0
- data/lib/img_to_script/generators/segmental/data_read_draw.rb +18 -0
- data/lib/img_to_script/generators/segmental/direct_draw/direct_draw.rb +62 -0
- data/lib/img_to_script/generators/segmental/direct_draw/horizontal.rb +16 -0
- data/lib/img_to_script/generators/segmental/direct_draw/vertical.rb +16 -0
- data/lib/img_to_script/generators/segmental/direct_draw.rb +12 -0
- data/lib/img_to_script/generators/segmental/horizontal_mixin.rb +32 -0
- data/lib/img_to_script/generators/segmental/segmental.rb +101 -0
- data/lib/img_to_script/generators/segmental/vertical_mixin.rb +38 -0
- data/lib/img_to_script/generators/segmental.rb +10 -0
- data/lib/img_to_script/generators.rb +27 -0
- data/lib/img_to_script/import.rb +5 -0
- data/lib/img_to_script/language_token.rb +8 -0
- data/lib/img_to_script/languages/mk90_basic/formatters/formatter.rb +49 -0
- data/lib/img_to_script/languages/mk90_basic/formatters/minificator.rb +316 -0
- data/lib/img_to_script/languages/mk90_basic/formatters/sliceable_tokens_mixin.rb +15 -0
- data/lib/img_to_script/languages/mk90_basic/formatters.rb +13 -0
- data/lib/img_to_script/languages/mk90_basic/mk90_basic_token.rb +59 -0
- data/lib/img_to_script/languages/mk90_basic/translators/mixin.rb +205 -0
- data/lib/img_to_script/languages/mk90_basic/translators/mk90_basic_10.rb +27 -0
- data/lib/img_to_script/languages/mk90_basic/translators/mk90_basic_20.rb +27 -0
- data/lib/img_to_script/languages/mk90_basic/translators/translator.rb +205 -0
- data/lib/img_to_script/languages/mk90_basic/translators.rb +13 -0
- data/lib/img_to_script/languages/mk90_basic.rb +17 -0
- data/lib/img_to_script/languages.rb +10 -0
- data/lib/img_to_script/task.rb +26 -0
- data/lib/img_to_script/translator.rb +31 -0
- data/lib/img_to_script/version.rb +5 -0
- data/lib/img_to_script.rb +19 -0
- data/sig/img_to_script.rbs +4 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 98fc645a04ddc50a2633b04a8d82d5ba61514d478215908e64b19a66499120fc
|
4
|
+
data.tar.gz: 7a40da06bfb2c9b7fba74bfc2cc6b201b92ea672c27203da20096f0ecb05d347
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aba04a011f62d58441ccd402077de347788629c9eb41975de644674bb389726f367f3f92e167d9680b176561442089088d100f6e9c2c97724926329492f455fa
|
7
|
+
data.tar.gz: 87f2c883e748c07836d2f0b4d24961a34784b7a8932b2682855e929c3c4f8df05e466171a69058937dac744d634e8a40ea834efdda172bac88fe6493373ff4cb
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 3.0
|
3
|
+
|
4
|
+
Style/StringLiterals:
|
5
|
+
Enabled: true
|
6
|
+
EnforcedStyle: double_quotes
|
7
|
+
|
8
|
+
Style/StringLiteralsInInterpolation:
|
9
|
+
Enabled: true
|
10
|
+
EnforcedStyle: double_quotes
|
11
|
+
|
12
|
+
Layout/LineLength:
|
13
|
+
Max: 120
|
14
|
+
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 15
|
17
|
+
|
18
|
+
Naming/MethodParameterName:
|
19
|
+
AllowedNames:
|
20
|
+
- x
|
21
|
+
- y
|
22
|
+
- x0
|
23
|
+
- x1
|
24
|
+
- y0
|
25
|
+
- y1
|
data/.vscode/launch.json
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
3
|
+
// Hover to view descriptions of existing attributes.
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
5
|
+
"version": "0.2.0",
|
6
|
+
"configurations": [
|
7
|
+
{
|
8
|
+
"type": "rdbg",
|
9
|
+
"name": "Debug current file with rdbg",
|
10
|
+
"request": "launch",
|
11
|
+
"script": "${file}",
|
12
|
+
"args": [],
|
13
|
+
"askParameters": true
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"type": "rdbg",
|
17
|
+
"name": "Attach with rdbg",
|
18
|
+
"request": "attach"
|
19
|
+
}
|
20
|
+
]
|
21
|
+
}
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 8bit-m8
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,271 @@
|
|
1
|
+
# ImgToScript
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
**img_to_script** is a Ruby gem (a library) that converts images to executable scripts that plot the binary version of the image using the simple commands e.g. “draw a line”, “draw a dot”, etc..
|
6
|
+
|
7
|
+
The gem was initially developed to convert binary images to the executable scripts for the build-in BASIC interpreter of the Soviet vintage portable computer **Elektronika MK90**. Yet it is possible to expand the gem to support other similar hardware and script languages (e.g. the build-in TI-BASIC of the Z80-based TI calculators).
|
8
|
+
|
9
|
+

|
10
|
+
|
11
|
+
*Vintage Elektronika MK90 renders an image with the build-in BASIC interpreter. The program was generated by the **img_to_script** gem.*
|
12
|
+
|
13
|
+
The gem was designed as a library, i.e. it neither provide a user interface, nor validates the input data. It only provides an API, the rest should be handled by the external software. To make a converter you’ll need to build an application around the **img_to_script** gem and provide a user interface, e.g. a command-line interface or a web interface.
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem "img_to_script"
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle install
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install img_to_script
|
30
|
+
|
31
|
+
## Modules
|
32
|
+
|
33
|
+
Three steps are required to complete the conversion. The gem has a dedicated module (a namespace) for each step:
|
34
|
+
|
35
|
+
- **Generator** reads the image data and creates an array of the abstract tokens. Each token represents a simple command to the interpreter, e.g.: “draw a line”, “draw a dot”, “assign a value to a variable”, “start a loop”, etc..
|
36
|
+
|
37
|
+
- **Translator** is a mediator between a generator and a formatter. It translates abstract tokens to the specific statements of the target programming language. Translator chooses keywords, separators and handles other syntax issues.
|
38
|
+
|
39
|
+
- **Formatter** takes input from the translator and formats it into the executable script (a target language code). It can serve a function of a prettier or a minificator. Another common formatter’s task is to track down and to label BASIC line numbers.
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
### API
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
ImgToScript::Task.new(
|
47
|
+
generator: generator,
|
48
|
+
translator: translator,
|
49
|
+
formatter: formatter
|
50
|
+
).run(
|
51
|
+
image: image,
|
52
|
+
scr_width: scr_width,
|
53
|
+
scr_height: scr_height
|
54
|
+
)
|
55
|
+
```
|
56
|
+
|
57
|
+
todo...
|
58
|
+
|
59
|
+
#### Returns
|
60
|
+
Array\<String\>
|
61
|
+
|
62
|
+
### Example
|
63
|
+
|
64
|
+
1. Require the gem:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
require "img_to_script"
|
68
|
+
```
|
69
|
+
|
70
|
+
2. Read an image using the `rmagick/bin_magick` gem:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
require "rmagick/bin_magick"
|
74
|
+
|
75
|
+
image = Magick::BinMagick::Image.from_file("my_file.png").to_binary!
|
76
|
+
```
|
77
|
+
|
78
|
+
3. Create a generator instance. You can also provide options via a configuration block, e.g.:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
generator = ImgToScript::Generators::RunLengthEncoding::Horizontal.new.configure do |config|
|
82
|
+
config.x_offset = -10
|
83
|
+
config.y_offset = 15
|
84
|
+
# etc.
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
4. Create a translator instance, e.g.:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
translator = ImgToScript::Languages::MK90Basic::Translators::MK90Basic10.new
|
92
|
+
```
|
93
|
+
|
94
|
+
5. Create a formatter instance. You can also provide options via a configuration block, e.g.:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
formatter = ImgToScript::Languages::MK90Basic::Formatters::Minificator.new.configure do |config|
|
98
|
+
config.line_offset = 10
|
99
|
+
config.line_step = 5
|
100
|
+
config.max_chars_per_line = 60
|
101
|
+
# etc.
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
6. Create a task instance and pass created instances as the task’s dependencies:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
task = ImgToScript::Task.new(
|
109
|
+
generator: generator,
|
110
|
+
translator: translator,
|
111
|
+
formatter: formatter
|
112
|
+
)
|
113
|
+
```
|
114
|
+
|
115
|
+
Note that you can also provide your own custom objects as long as they respond to the required public interface.
|
116
|
+
|
117
|
+
In case of the Elektronika MK90 BASIC **only** you can omit any dependency (i.e. skip any step from the 3rd to the 5th), since these are optional arguments. Then a default object with a default configuration will be used.
|
118
|
+
|
119
|
+
You can also re-configure any dependency of an existing task object, e.g.:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
task.formatter.configure do |config|
|
123
|
+
# your config...
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
127
|
+
7. Run conversion to get a script. You need to provide the image and the target device resolution:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
script = task.run(
|
131
|
+
image: image,
|
132
|
+
scr_width: 120,
|
133
|
+
scr_height: 64
|
134
|
+
)
|
135
|
+
```
|
136
|
+
|
137
|
+
## Build-in classes
|
138
|
+
|
139
|
+
### Generators
|
140
|
+
|
141
|
+
- **ImgToScript::Generators::Generator**
|
142
|
+
|
143
|
+
Base class all generators inherit from.
|
144
|
+
|
145
|
+
**Public interface**: #generate(image:, scr_width:, scr_height:)
|
146
|
+
|
147
|
+
**Configuration options**:
|
148
|
+
|
149
|
+
- x_offset, default: X_OFFSET (0)
|
150
|
+
|
151
|
+
Offset the X point on the screen.
|
152
|
+
|
153
|
+
- y_offset, default: Y_OFFSET (0)
|
154
|
+
|
155
|
+
Offset the Y point on the screen.
|
156
|
+
|
157
|
+
- clear_screen, default: CLEAR_SCREEN (true)
|
158
|
+
|
159
|
+
Add a statement to clear the screen at the begin of the script.
|
160
|
+
|
161
|
+
- pause_program, default: PAUSE_PROGRAM (true)
|
162
|
+
|
163
|
+
Add a statement to pause the program at the end of the script.
|
164
|
+
|
165
|
+
- program_begin_lbl, default: PRORGAM_BEGIN_LBL (false)
|
166
|
+
|
167
|
+
Add a statement that marks the begin of the program.
|
168
|
+
|
169
|
+
- program_end_lbl, default: PROGRAM_END_LBL (false)
|
170
|
+
|
171
|
+
Add a statement that marks the end of the program.
|
172
|
+
|
173
|
+
- **ImgToScript::Generators::HexMask::Default**
|
174
|
+
|
175
|
+
Specific for the Elektronika MK90 BASIC.
|
176
|
+
|
177
|
+
MK90's BASIC has a balanced build-in method to encode and render images. The Elektronika MK90's manual refers to it as the *hex-mask rendering* method. Each 8x1 px block of a binary image is being represented as a hex value (e.g. '00' for a tile of the 8 white pixels in a row, 'FF' for a tile of the 8 black pixels in a row, etc.). Then these hex values are being passed as arguments to the DRAM/M BASIC statement that renders the image according to the provided data.
|
178
|
+
|
179
|
+
Due to the logic of the DRAM/M operator, only vertical scan lines are supported.
|
180
|
+
|
181
|
+
- **ImgToScript::Generators::HexMask::Enhanced**
|
182
|
+
|
183
|
+
Specific for the Elektronika MK90 BASIC.
|
184
|
+
|
185
|
+
Hex-mask encoding with modifications what make output BASIC code more compact.
|
186
|
+
|
187
|
+
Due to the logic of the DRAM/M operator, only vertical scan lines are supported.
|
188
|
+
|
189
|
+
- **ImgToScript::Generators::RunLengthEncoding::Horizontal**
|
190
|
+
|
191
|
+
RLE, horizontal scan lines.
|
192
|
+
|
193
|
+
- **ImgToScript::Generators::RunLengthEncoding::Vertical**
|
194
|
+
|
195
|
+
RLE, vertical scan lines.
|
196
|
+
|
197
|
+
- **ImgToScript::Generators::Segmental::DirectDraw::Horizontal**
|
198
|
+
|
199
|
+
Directly plot segments, horizontal scan lines.
|
200
|
+
|
201
|
+
- **ImgToScript::Generators::Segmental::DirectDraw::Vertical**
|
202
|
+
|
203
|
+
Directly plot segments, vertical scan lines.
|
204
|
+
|
205
|
+
- **ImgToScript::Generators::Segmental::DataReadDraw::Horizontal**
|
206
|
+
|
207
|
+
Store and read segments' coordinates, when use them to plot segments. Horizontal scan lines.
|
208
|
+
|
209
|
+
- **ImgToScript::Generators::Segmental::DataReadDraw::Vertical**
|
210
|
+
|
211
|
+
Store and read segments' coordinates, when use them to plot segments. Vertical scan lines.
|
212
|
+
|
213
|
+
### Elektronika MK90 BASIC
|
214
|
+
|
215
|
+
#### Translators
|
216
|
+
|
217
|
+
- **ImgToScript::Languages::MK90Basic::Translators::Translator**
|
218
|
+
|
219
|
+
Base class all MK90 translators inherit from.
|
220
|
+
|
221
|
+
**Public interface**: #translate(abstract_tokens, **kwargs)
|
222
|
+
|
223
|
+
- **ImgToScript::Languages::MK90Basic::Translators::MK90Basic10**
|
224
|
+
|
225
|
+
Translates abstract tokens to the MK90 BASIC v1.0 statements.
|
226
|
+
|
227
|
+
- **ImgToScript::Languages::MK90Basic::Translators::MK90Basic20**
|
228
|
+
|
229
|
+
Translates abstract tokens to the MK90 BASIC v2.0 statements.
|
230
|
+
|
231
|
+
#### Formatters
|
232
|
+
|
233
|
+
- **ImgToScript::Languages::MK90Basic::Formatters::Formatter**
|
234
|
+
|
235
|
+
Base class all MK90 formatters inherit from.
|
236
|
+
|
237
|
+
**Public interface**: #format(tokens)
|
238
|
+
|
239
|
+
**Configuration options**:
|
240
|
+
|
241
|
+
- line_offset, default: LINE_OFFSET (1)
|
242
|
+
|
243
|
+
First BASIC line number.
|
244
|
+
|
245
|
+
- line_step, default: LINE_STEP (1)
|
246
|
+
|
247
|
+
Step between two neighbor BASIC lines.
|
248
|
+
|
249
|
+
- max_chars_per_line, default: MAX_CHARS_PER_LINE (80)
|
250
|
+
|
251
|
+
Note: MK90 BASIC doesn’t support more than 80 characters per line.
|
252
|
+
|
253
|
+
- number_lines, default: true
|
254
|
+
|
255
|
+
- **ImgToScript::Languages::MK90Basic::Formatters::Minificator**
|
256
|
+
|
257
|
+
The aim of the minificator is to make the output script as compact as possible, and so to save space at the MPO-10 cart.
|
258
|
+
|
259
|
+
## Development
|
260
|
+
|
261
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
262
|
+
|
263
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
264
|
+
|
265
|
+
## Contributing
|
266
|
+
|
267
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/8bit-mate/img_to_script.rb.
|
268
|
+
|
269
|
+
## License
|
270
|
+
|
271
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require "rubocop/rake_task"
|
13
|
+
|
14
|
+
RuboCop::RakeTask.new
|
15
|
+
|
16
|
+
task default: %i[test rubocop]
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/img_to_script/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "img_to_script"
|
7
|
+
spec.version = ImgToScript::VERSION
|
8
|
+
spec.authors = ["8bit-mate"]
|
9
|
+
spec.email = ["you@example.com"]
|
10
|
+
|
11
|
+
spec.summary = "Converts images to executable scripts."
|
12
|
+
spec.homepage = "https://github.com/8bit-mate/img_to_script.rb"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = ">= 3.0.0"
|
15
|
+
|
16
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
spec.files = Dir.chdir(__dir__) do
|
25
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
(File.expand_path(f) == __FILE__) ||
|
27
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
spec.files -= ["data/lain-mk90.jpg"]
|
31
|
+
|
32
|
+
spec.bindir = "exe"
|
33
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
34
|
+
spec.require_paths = ["lib"]
|
35
|
+
|
36
|
+
spec.add_dependency "dry-system", "~> 1.0", ">= 1.0.1"
|
37
|
+
spec.add_dependency "run_length_encoding_rb", "~> 1.0", ">= 1.0.0"
|
38
|
+
spec.add_dependency "zeitwerk", "~> 2.6", ">= 2.6.12"
|
39
|
+
|
40
|
+
spec.add_development_dependency "rmagick-bin_magick", "~> 0.2", ">= 0.2.0"
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
#
|
5
|
+
# Defines abstract tokens types.
|
6
|
+
#
|
7
|
+
module AbsTokenType
|
8
|
+
ABS_FUNC = :abs_func
|
9
|
+
ASSIGN_VALUE = :assign_value
|
10
|
+
CLEAR_SCREEN = :clear_screen
|
11
|
+
DATA_READ = :data_read
|
12
|
+
DATA_STORE = :data_store
|
13
|
+
DRAW_CHUNK_BY_HEX_VALUE = :draw_chunk_by_hex_value
|
14
|
+
DRAW_LINE_BY_ABS_COORDS = :draw_line_by_abs_coords
|
15
|
+
DRAW_PIXEL_BY_ABS_COORDS = :draw_pixel_by_abs_coords
|
16
|
+
GO_TO = :go_to
|
17
|
+
IF_CONDITION = :if_condition
|
18
|
+
LOOP_BEGIN = :loop_begin
|
19
|
+
LOOP_END = :loop_end
|
20
|
+
MATH_ADD = :math_add
|
21
|
+
MATH_GREATER_THAN = :math_greater_than
|
22
|
+
MATH_MULT = :math_mult
|
23
|
+
MATH_SUB = :math_sub
|
24
|
+
MOVE_POINT_TO_ABS_COORDS = :move_point_to_abs_coords
|
25
|
+
PARENTHESES = :parentheses
|
26
|
+
PROGRAM_BEGIN = :program_begin_lbl
|
27
|
+
PROGRAM_END_LBL = :program_end_lbl
|
28
|
+
REMARK = :remark
|
29
|
+
SIGN_FUNC = :sign_func
|
30
|
+
SIGN_GREATER_THAN = :sign_greater_than
|
31
|
+
WAIT = :wait
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Absolute value (modulus).
|
7
|
+
#
|
8
|
+
class AbsFunc < AbstractToken
|
9
|
+
attr_reader :expression
|
10
|
+
|
11
|
+
def initialize(expression:, **)
|
12
|
+
@type = AbsTokenType::ABS_FUNC
|
13
|
+
@expression = expression
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Stores single command in an abstract representation.
|
7
|
+
#
|
8
|
+
class AbstractToken
|
9
|
+
attr_reader :type, :require_nl
|
10
|
+
|
11
|
+
#
|
12
|
+
# Init. a new abstract token.
|
13
|
+
#
|
14
|
+
# @option [Boolean] require_nl (false)
|
15
|
+
# If 'true', the formatter will put the statement, that is
|
16
|
+
# assotiated with the token, on a new line.
|
17
|
+
#
|
18
|
+
def initialize(require_nl: false, **)
|
19
|
+
@require_nl = require_nl
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Assign value to a variable.
|
7
|
+
#
|
8
|
+
class AssignValue < AbstractToken
|
9
|
+
attr_reader :left, :right
|
10
|
+
|
11
|
+
def initialize(left:, right:, **)
|
12
|
+
@type = AbsTokenType::ASSIGN_VALUE
|
13
|
+
@left = left
|
14
|
+
@right = right
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Read value(s) from an array of constants.
|
7
|
+
#
|
8
|
+
class DataRead < AbstractToken
|
9
|
+
attr_reader :var_list
|
10
|
+
|
11
|
+
def initialize(var_list:, **)
|
12
|
+
@type = AbsTokenType::DATA_READ
|
13
|
+
@var_list = Array(var_list)
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Store array of contants.
|
7
|
+
#
|
8
|
+
class DataStore < AbstractToken
|
9
|
+
attr_reader :data
|
10
|
+
|
11
|
+
def initialize(data:, **)
|
12
|
+
@type = AbsTokenType::DATA_STORE
|
13
|
+
@data = Array(data)
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Draw 8x1 px block of pixels encoded by a hex value.
|
7
|
+
#
|
8
|
+
class DrawChunkByHexValue < AbstractToken
|
9
|
+
attr_reader :hex_values
|
10
|
+
|
11
|
+
def initialize(hex_values:, **)
|
12
|
+
@type = AbsTokenType::DRAW_CHUNK_BY_HEX_VALUE
|
13
|
+
@hex_values = Array(hex_values)
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Draw a line by absolute coordinates.
|
7
|
+
#
|
8
|
+
class DrawLineByAbsCoords < AbstractToken
|
9
|
+
attr_reader :x0, :y0, :x1, :y1
|
10
|
+
|
11
|
+
def initialize(x0:, y0:, x1:, y1:, **)
|
12
|
+
@type = AbsTokenType::DRAW_LINE_BY_ABS_COORDS
|
13
|
+
@x0 = x0
|
14
|
+
@y0 = y0
|
15
|
+
@x1 = x1
|
16
|
+
@y1 = y1
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Draw a pixel by absolute coordinates.
|
7
|
+
#
|
8
|
+
class DrawPixelByAbsCoords < AbstractToken
|
9
|
+
attr_reader :x, :y
|
10
|
+
|
11
|
+
def initialize(x:, y:, **)
|
12
|
+
@type = AbsTokenType::DRAW_PIXEL_BY_ABS_COORDS
|
13
|
+
@x = x
|
14
|
+
@y = y
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# Go to BASIC line.
|
7
|
+
#
|
8
|
+
class GoTo < AbstractToken
|
9
|
+
attr_reader :line
|
10
|
+
|
11
|
+
def initialize(line:, **)
|
12
|
+
@type = AbsTokenType::GO_TO
|
13
|
+
@line = line
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ImgToScript
|
4
|
+
module AbstractToken
|
5
|
+
#
|
6
|
+
# If condition.
|
7
|
+
#
|
8
|
+
class IfCondition < AbstractToken
|
9
|
+
attr_reader :expression, :consequent
|
10
|
+
|
11
|
+
def initialize(expression:, consequent:, **)
|
12
|
+
@type = AbsTokenType::IF_CONDITION
|
13
|
+
@expression = expression
|
14
|
+
@consequent = consequent
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|