p5rb_cli 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f7e4ff0549fb0d7163d03434b1a7efd3b8e4f00819280797ce04154f021a19af
4
+ data.tar.gz: 3cc537a3d241257aaaa20ea4561a130513b02a24e3d8ecd08abc3a3be40ef44c
5
+ SHA512:
6
+ metadata.gz: 3f4c9b07797c32db5235cff71b016ec001956b8028e8971435c65e854cd24931f4809b07d9cab5815b1c3fb09d4b64e3136e612b53d7223577a818f79a916910
7
+ data.tar.gz: b635d263e7964d9e9e7805846aa14de3c4f2623392d180ad1bb9e68374dce747bc74cdfdcfe360db05fa90a9a272cb030abbdf89eca4f18dbbbfddc72eb0b6ae
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/standardrb/standard
3
+ ruby_version: 3.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-02-23
4
+
5
+ - Initial release
data/README.ja.md ADDED
@@ -0,0 +1,59 @@
1
+ # p5.rb CLI
2
+
3
+ p5.rb CLIは、Rubyを使ってp5.jsのようなクリエイティブコーディングを手軽に始められるコマンドラインツールです。インタラクティブなアニメーションやビジュアルアートを、Rubyのシンプルな文法で作成できます。
4
+
5
+ ## インストール
6
+
7
+ ```bash
8
+ gem install p5rb_cli
9
+ ```
10
+
11
+ ## 使い方
12
+
13
+ インストール後、以下のコマンドが使用できます:
14
+
15
+ ### 新しいスケッチの作成
16
+
17
+ ```bash
18
+ p5rb new <NAME>
19
+ ```
20
+
21
+ このコマンドは指定したディレクトリに新しいp5.rbスケッチを生成します。生成されるスケッチには、基本的なセットアップとサンプルコードが含まれています。
22
+
23
+ ### スケッチの実行
24
+
25
+ ```bash
26
+ p5rb run <SCRIPT_FILE>
27
+ ```
28
+
29
+ このコマンドは指定したスケッチをローカルサーバーで実行し、ブラウザで表示します。変更を加えると自動的にブラウザが更新されます。
30
+
31
+ ### その他のコマンド
32
+
33
+ 詳細な使い方を確認するには:
34
+
35
+ ```bash
36
+ p5rb help
37
+ ```
38
+
39
+ ## サンプルコード
40
+
41
+ ```ruby
42
+ def setup
43
+ createCanvas(400, 400)
44
+ background(220)
45
+ end
46
+
47
+ def draw
48
+ fill(255, 0, 0)
49
+ circle(mouseX, mouseY, 50)
50
+ end
51
+ ```
52
+
53
+ ## 開発に参加する
54
+
55
+ バグ報告やプルリクエストは大歓迎です。GitHubの[p5rb_cliリポジトリ](https://github.com/ongaeshi/p5rb_cli)でお願いします。
56
+
57
+ ## ライセンス
58
+
59
+ このプロジェクトは[MITライセンス](https://opensource.org/licenses/MIT)の下でオープンソースとして公開されています。
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # p5.rb CLI
2
+
3
+ p5.rb CLI is a command-line tool that makes it easy to start creative coding with Ruby, inspired by p5.js. Create interactive animations and visual art using Ruby's simple and elegant syntax.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install p5rb_cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ After installation, you can use the following commands:
14
+
15
+ ### Create a New Sketch
16
+
17
+ ```bash
18
+ p5rb new <NAME>
19
+ ```
20
+
21
+ This command generates a new p5.rb sketch in the specified directory. The generated sketch includes basic setup and sample code.
22
+
23
+ ### Run a Sketch
24
+
25
+ ```bash
26
+ p5rb run <SCRIPT_FILE>
27
+ ```
28
+
29
+ This command runs the specified sketch on a local server and displays it in your browser. The browser automatically updates when you make changes to your code.
30
+
31
+ ### Other Commands
32
+
33
+ To see detailed usage information:
34
+
35
+ ```bash
36
+ p5rb help
37
+ ```
38
+
39
+ ## Sample Code
40
+
41
+ ```ruby
42
+ def setup
43
+ createCanvas(400, 400)
44
+ background(220)
45
+ end
46
+
47
+ def draw
48
+ fill(255, 0, 0)
49
+ circle(mouseX, mouseY, 50)
50
+ end
51
+ ```
52
+
53
+ ## Contributing
54
+
55
+ Bug reports and pull requests are welcome on GitHub at the [p5rb_cli repository](https://github.com/ongaeshi/p5rb_cli).
56
+
57
+ ## License
58
+
59
+ This project is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,14 @@
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 "standard/rake"
13
+
14
+ task default: %i[test standard]
data/exe/p5rb ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "p5rb_cli"
4
+
5
+ P5rbCli::Cli.start(ARGV)
@@ -0,0 +1,60 @@
1
+ <!doctype html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
8
+ integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
9
+ <link rel="icon" href="https://i.gyazo.com/0aa7908931f32799b49503d24ea1456f.png">
10
+
11
+ <title>p5.rb</title>
12
+ </head>
13
+
14
+ <body>
15
+ <nav class="navbar navbar-expand-md navbar-light rob-navbar">
16
+ <div class="container-fluid">
17
+ <div class="navbar-brand rob-navbar">
18
+ <img src="https://i.gyazo.com/0aa7908931f32799b49503d24ea1456f.png" alt="" width="24"
19
+ class="d-inline-block align-text-top">
20
+ p5.rb
21
+ </div>
22
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
23
+ aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
24
+ <span class="navbar-toggler-icon"></span>
25
+ </button>
26
+ <div class="collapse navbar-collapse" id="navbarNav">
27
+ <ul class="navbar-nav">
28
+ <li class="nav-item">
29
+ <a class="nav-link active rob-navbar" aria-current="page" href="https://p5js.org/reference/"
30
+ target="_blank">Reference</a>
31
+ </li>
32
+ <li class="nav-item">
33
+ <a class="nav-link active rob-navbar" aria-current="page" href="https://github.com/ongaeshi/p5rb_cli/"
34
+ target="_blank">GitHub</a>
35
+ </li>
36
+ </ul>
37
+ </div>
38
+ </div>
39
+ </nav>
40
+ <div class="container-fluid py-2">
41
+ <div class="row">
42
+ <div class="col-lg">
43
+ <main></main>
44
+ <button id="run" type="button" class="btn btn-primary mb-1">Run</button>
45
+ <button id="save-button" type="button" class="btn btn-secondary mb-1 float-end">Save</button>
46
+ <textarea id="error-console" class="form-control font-monospace" rows="5" readonly></textarea>
47
+ </div>
48
+ </div>
49
+
50
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
51
+ integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
52
+ crossorigin="anonymous"></script>
53
+ <script src="https://bundle.run/buffer@6.0.3"></script>
54
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.1/dist/browser.umd.js"></script>
55
+ <script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
56
+ <script src="p5editor.js"></script>
57
+ <link rel="stylesheet" href="style.css">
58
+ </body>
59
+
60
+ </html>
@@ -0,0 +1,79 @@
1
+ const { DefaultRubyVM } = window["ruby-wasm-wasi"];
2
+ const globalData = {};
3
+ let myP5 = null;
4
+
5
+ const main = async () => {
6
+ const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/dist/ruby.wasm");
7
+ // const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/dist/ruby+stdlib.wasm");
8
+ const module = await WebAssembly.compileStreaming(response);
9
+ globalData.module = module;
10
+ document.getElementById("run").onclick = runScript;
11
+ runScript();
12
+ };
13
+
14
+ main();
15
+
16
+ const runScript = async () => {
17
+ const { vm } = await DefaultRubyVM(globalData.module);
18
+ globalData.vm = vm;
19
+
20
+ {
21
+ const p5rb = await fetch("p5editor.rb");
22
+ const t = await p5rb.text();
23
+ vm.eval(t);
24
+ }
25
+
26
+ document.getElementById("error-console").value = "";
27
+
28
+ try {
29
+ const main = await fetch("main.rb");
30
+ const t = await main.text();
31
+ vm.eval(t);
32
+ } catch (e) {
33
+ document.getElementById("error-console").value += e.message + "\n"
34
+ throw e
35
+ }
36
+
37
+ function registerRubyMethod(p5, name) {
38
+ let isDefined = vm.eval(`defined?(${name}) == "method"`).toJS()
39
+ if (!isDefined) {
40
+ return
41
+ }
42
+ p5[name] = function () {
43
+ try {
44
+ vm.eval(name)
45
+ } catch (e) {
46
+ document.getElementById("error-console").value += e.message + "\n"
47
+ throw e
48
+ }
49
+ };
50
+ }
51
+
52
+ // Initialize p5.js
53
+ function sketch(p5) {
54
+ vm.eval("P5").call("init", vm.wrap(p5))
55
+ registerRubyMethod(p5, "preload");
56
+ registerRubyMethod(p5, "setup");
57
+ registerRubyMethod(p5, "draw");
58
+ registerRubyMethod(p5, "mouseMoved");
59
+ registerRubyMethod(p5, "mouseDragged");
60
+ registerRubyMethod(p5, "mousePressed");
61
+ registerRubyMethod(p5, "mouseReleased");
62
+ registerRubyMethod(p5, "mouseClicked");
63
+ registerRubyMethod(p5, "doubleClicked");
64
+ registerRubyMethod(p5, "mouseWheel");
65
+ registerRubyMethod(p5, "keyPressed");
66
+ registerRubyMethod(p5, "keyReleased");
67
+ registerRubyMethod(p5, "keyTyped");
68
+ }
69
+
70
+ myP5 && myP5.remove();
71
+ myP5 = new p5(sketch, 'main');
72
+ document.getElementById("save-button").onclick = () => {
73
+ const date = new Date();
74
+ const dateString = date.toISOString().split('T')[0].replace(/-/g, ''); // YYYYMMDD format
75
+ const timeString = date.toTimeString().split(' ')[0].replace(/:/g, ''); // HHMMSS format
76
+ myP5.saveCanvas(`p5rb_${dateString}_${timeString}`, 'png');
77
+ };
78
+ }
79
+
@@ -0,0 +1,285 @@
1
+ require 'js'
2
+
3
+ # --------------------------------------------
4
+ # Constants
5
+ #
6
+ # Copyright: p5.js(https://p5js.org/copyright.html)
7
+ # The p5.js library is free software;
8
+ # you can redistribute it and/or modify it under the terms of
9
+ # the GNU Lesser General Public License as published
10
+ # by the Free Software Foundation, version 2.1.
11
+ # --------------------------------------------
12
+ _PI = Math::PI
13
+
14
+ # The default, two-dimensional renderer.
15
+ P2D = 'p2d'
16
+
17
+ # One of the two render modes in p5.js: P2D (default renderer) and WEBGL
18
+ # Enables 3D render by introducing the third dimension: Z
19
+ WEBGL = 'webgl'
20
+
21
+ # ENVIRONMENT
22
+ ARROW = 'default'
23
+ CROSS = 'crosshair'
24
+ HAND = 'pointer'
25
+ MOVE = 'move'
26
+ TEXT = 'text'
27
+ WAIT = 'wait'
28
+
29
+ # TRIGONOMETRY
30
+
31
+ # HALF_PI is a mathematical constant with the value
32
+ # 1.57079632679489661923. It is half the ratio of the
33
+ # circumference of a circle to its diameter. It is useful in
34
+ # combination with the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
35
+ HALF_PI = _PI / 2
36
+
37
+ # PI is a mathematical constant with the value
38
+ # 3.14159265358979323846. It is the ratio of the circumference
39
+ # of a circle to its diameter. It is useful in combination with
40
+ # the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
41
+ PI = _PI
42
+
43
+ # QUARTER_PI is a mathematical constant with the value 0.7853982.
44
+ # It is one quarter the ratio of the circumference of a circle to
45
+ # its diameter. It is useful in combination with the trigonometric
46
+ # functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
47
+ QUARTER_PI = _PI / 4
48
+
49
+ # TAU is an alias for TWO_PI, a mathematical constant with the
50
+ # value 6.28318530717958647693. It is twice the ratio of the
51
+ # circumference of a circle to its diameter. It is useful in
52
+ # combination with the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
53
+ TAU = _PI * 2
54
+
55
+ # TWO_PI is a mathematical constant with the value
56
+ # 6.28318530717958647693. It is twice the ratio of the
57
+ # circumference of a circle to its diameter. It is useful in
58
+ # combination with the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
59
+ TWO_PI = _PI * 2
60
+
61
+ # Constant to be used with the <a href="#/p5/angleMode">angleMode()</a> function, to set the mode in
62
+ # which p5.js interprets and calculates angles (either DEGREES or RADIANS).
63
+ DEGREES = 'degrees'
64
+
65
+ # Constant to be used with the <a href="#/p5/angleMode">angleMode()</a> function, to set the mode
66
+ # in which p5.js interprets and calculates angles (either RADIANS or DEGREES).
67
+ RADIANS = 'radians'
68
+ DEG_TO_RAD = _PI / 180.0
69
+ RAD_TO_DEG = 180.0 / _PI
70
+
71
+ CORNER = 'corner'
72
+ CORNERS = 'corners'
73
+ RADIUS = 'radius'
74
+ RIGHT = 'right'
75
+ LEFT = 'left'
76
+ CENTER = 'center'
77
+ TOP = 'top'
78
+ BOTTOM = 'bottom'
79
+ BASELINE = 'alphabetic'
80
+
81
+ POINTS = 0x0000
82
+ LINES = 0x0001
83
+ LINE_STRIP = 0x0003
84
+ LINE_LOOP = 0x0002
85
+ TRIANGLES = 0x0004
86
+ TRIANGLE_FAN = 0x0006
87
+ TRIANGLE_STRIP = 0x0005
88
+
89
+ QUADS = 'quads'
90
+ QUAD_STRIP = 'quad_strip'
91
+ TESS = 'tess'
92
+ CLOSE = 'close'
93
+ OPEN = 'open'
94
+ CHORD = 'chord'
95
+ PIE = 'pie'
96
+ PROJECT = 'square' # PEND: careful this is counterintuitive
97
+ SQUARE = 'butt'
98
+ ROUND = 'round'
99
+ BEVEL = 'bevel'
100
+ MITER = 'miter'
101
+
102
+ # COLOR
103
+ RGB = 'rgb'
104
+ # HSB (hue, saturation, brightness) is a type of color model.
105
+ # You can learn more about it at
106
+ # <a href="https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html">HSB</a>.
107
+ HSB = 'hsb'
108
+ HSL = 'hsl'
109
+
110
+ # DOM EXTENSION
111
+
112
+ # AUTO allows us to automatically set the width or height of an element (but not both),
113
+ # based on the current height and width of the element. Only one parameter can
114
+ # be passed to the <a href="/#/p5.Element/size">size</a> function as AUTO, at a time.
115
+ AUTO = 'auto'
116
+
117
+ # INPUT
118
+ ALT = 18
119
+ BACKSPACE = 8
120
+ CONTROL = 17
121
+ DELETE = 46
122
+ DOWN_ARROW = 40
123
+ ENTER = 13
124
+ ESCAPE = 27
125
+ LEFT_ARROW = 37
126
+ OPTION = 18
127
+ RETURN = 13
128
+ RIGHT_ARROW = 39
129
+ SHIFT = 16
130
+ TAB = 9
131
+ UP_ARROW = 38
132
+
133
+ # RENDERING
134
+ BLEND = 'source-over'
135
+ REMOVE = 'destination-out'
136
+ ADD = 'lighter'
137
+ #ADD: 'add', #
138
+ #SUBTRACT: 'subtract', #
139
+ DARKEST = 'darken'
140
+ LIGHTEST = 'lighten'
141
+ DIFFERENCE = 'difference'
142
+ SUBTRACT = 'subtract'
143
+ EXCLUSION = 'exclusion'
144
+ MULTIPLY = 'multiply'
145
+ SCREEN = 'screen'
146
+ REPLACE = 'copy'
147
+ OVERLAY = 'overlay'
148
+ HARD_LIGHT = 'hard-light'
149
+ SOFT_LIGHT = 'soft-light'
150
+ DODGE = 'color-dodge'
151
+ BURN = 'color-burn'
152
+
153
+ # FILTERS
154
+ THRESHOLD = 'threshold'
155
+ GRAY = 'gray'
156
+ OPAQUE = 'opaque'
157
+ INVERT = 'invert'
158
+ POSTERIZE = 'posterize'
159
+ DILATE = 'dilate'
160
+ ERODE = 'erode'
161
+ BLUR = 'blur'
162
+
163
+ # TYPOGRAPHY
164
+ NORMAL = 'normal'
165
+ ITALIC = 'italic'
166
+ BOLD = 'bold'
167
+ BOLDITALIC = 'bold italic'
168
+ CHAR = 'CHAR'
169
+ WORD = 'WORD'
170
+
171
+ # TYPOGRAPHY-INTERNAL
172
+ _DEFAULT_TEXT_FILL = '#000000'
173
+ _DEFAULT_LEADMULT = 1.25
174
+ _CTX_MIDDLE = 'middle'
175
+
176
+ # VERTICES
177
+ LINEAR = 'linear'
178
+ QUADRATIC = 'quadratic'
179
+ BEZIER = 'bezier'
180
+ CURVE = 'curve'
181
+
182
+ # WEBGL DRAWMODES
183
+ STROKE = 'stroke'
184
+ FILL = 'fill'
185
+ TEXTURE = 'texture'
186
+ IMMEDIATE = 'immediate'
187
+
188
+ # WEBGL TEXTURE MODE
189
+ # NORMAL already exists for typography
190
+ IMAGE = 'image'
191
+
192
+ # WEBGL TEXTURE WRAP AND FILTERING
193
+ # LINEAR already exists above
194
+ NEAREST = 'nearest'
195
+ REPEAT = 'repeat'
196
+ CLAMP = 'clamp'
197
+ MIRROR = 'mirror'
198
+
199
+ # DEVICE-ORIENTATION
200
+ LANDSCAPE = 'landscape'
201
+ PORTRAIT = 'portrait'
202
+
203
+ # DEFAULTS
204
+ _DEFAULT_STROKE = '#000000'
205
+ _DEFAULT_FILL = '#FFFFFF'
206
+
207
+ GRID = 'grid'
208
+ AXES = 'axes'
209
+ LABEL = 'label'
210
+ FALLBACK = 'fallback'
211
+ CONTAIN = 'contain'
212
+ COVER = 'cover'
213
+
214
+ # --------------------------------------------
215
+ # Library
216
+ # --------------------------------------------
217
+ # JS::Object can call property via function style
218
+ class JS::Object
219
+ def method_missing(sym, *args, &block)
220
+ ret = self[sym]
221
+
222
+ case ret.typeof
223
+ when "undefined"
224
+ str = sym.to_s
225
+ if str[-1] == "="
226
+ self[str.chop.to_sym] = args.first
227
+ return args.first
228
+ end
229
+
230
+ super
231
+ when "function"
232
+ self.call(sym, *args, &block).to_r
233
+ else
234
+ ret.to_r
235
+ end
236
+ end
237
+
238
+ def respond_to_missing?(sym, include_private)
239
+ return true if super
240
+ self[sym].typeof != "undefined"
241
+ end
242
+
243
+ def to_r
244
+ case self.typeof
245
+ when "number"
246
+ self.to_f
247
+ when "string"
248
+ self.to_s
249
+ else
250
+ self
251
+ end
252
+ end
253
+ end
254
+
255
+ # Call p5.js global functions
256
+ $p5 = nil
257
+
258
+ def method_missing(sym, *args, &block)
259
+ return super unless $p5.respond_to?(:[])
260
+ ret = $p5[sym]
261
+
262
+ case ret.typeof
263
+ when "undefined"
264
+ # str = sym.to_s
265
+ # if str[-1] == "="
266
+ # $p5[str.chop.to_sym] = args.first
267
+ # return args.first
268
+ # end
269
+ super
270
+ when "function"
271
+ $p5.call(sym, *args, &block).to_r
272
+ else
273
+ ret.to_r
274
+ end
275
+ end
276
+
277
+ module P5
278
+ Vector = JS.global[:p5][:Vector]
279
+
280
+ module_function
281
+
282
+ def init(p5)
283
+ $p5 = p5
284
+ end
285
+ end
@@ -0,0 +1,30 @@
1
+ nav {
2
+ outline: solid 1px #a2a5a8;
3
+ }
4
+
5
+ .rob-navbar {
6
+ background-color: #f8f9fa !important;
7
+ color: #25292e !important;
8
+ }
9
+
10
+ .navbar-brand {
11
+ font-size: 1.1rem;
12
+ }
13
+
14
+ @media (min-width: 768px) { /* Medium(md) */
15
+ .CodeMirror {
16
+ height: 320px;
17
+ }
18
+ }
19
+
20
+ @media (min-width: 992px) { /* Large(lg) */
21
+ .CodeMirror {
22
+ height: 540px;
23
+ }
24
+ }
25
+
26
+ @media (min-width: 1200px) { /* Extra Large(xl) */
27
+ .CodeMirror {
28
+ height: 800px;
29
+ }
30
+ }
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module P5rbCli
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,51 @@
1
+ require 'webrick'
2
+
3
+ def run_web_app(script_file)
4
+ if script_file.nil? || !File.exist?(script_file)
5
+ puts "Not found script file: #{script_file}"
6
+ return
7
+ end
8
+
9
+ root = File.join(File.dirname(script_file))
10
+ server = WEBrick::HTTPServer.new(
11
+ Port: 8000,
12
+ DocumentRoot: root
13
+ )
14
+
15
+ static_root = File.join(File.dirname(__FILE__), "static")
16
+ server.mount_proc '/' do |req, res|
17
+ case req.path
18
+ when "/" || "/index.html"
19
+ res.body = File.read(File.join(static_root, 'index.html'))
20
+ res.content_type = 'text/html'
21
+ when "/p5editor.js"
22
+ res.body = File.read(File.join(static_root, 'p5editor.js'))
23
+ res.content_type = 'application/javascript'
24
+ when "/p5editor.rb"
25
+ res.body = File.read(File.join(static_root, 'p5editor.rb'))
26
+ res.content_type = 'application/ruby'
27
+ when "/style.css"
28
+ res.body = File.read(File.join(static_root, 'style.css'))
29
+ res.content_type = 'text/css'
30
+ when "/main.rb"
31
+ res.body = File.read(script_file)
32
+ res.content_type = 'application/ruby'
33
+ else
34
+ path = File.join(File.dirname(script_file), req.path)
35
+ if File.exist?(path)
36
+ res.body = File.binread(path)
37
+ res.content_type = case File.extname(path)
38
+ when ".png" then 'image/png'
39
+ when ".jpg" then 'image/jpeg'
40
+ else 'application/octet-stream'
41
+ end
42
+ else
43
+ res.body = "Not Found"
44
+ res.status = 404
45
+ end
46
+ end
47
+ end
48
+ trap('INT') { server.shutdown }
49
+ puts "Serving at http://localhost:8000/"
50
+ server.start
51
+ end
data/lib/p5rb_cli.rb ADDED
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "p5rb_cli/version"
4
+ require_relative "p5rb_cli/web_app"
5
+ require "thor"
6
+ require "fileutils"
7
+
8
+ module P5rbCli
9
+ class Cli < Thor
10
+ def self.exit_on_failure?
11
+ true
12
+ end
13
+
14
+ desc "new NAME", "Create a new p5.rb script"
15
+ def new(name)
16
+ name += ".rb" unless name.end_with?(".rb")
17
+
18
+ if FileTest.exist?(name)
19
+ raise Thor::Error, "ERROR: '#{File.absolute_path(name)}' already exists"
20
+ end
21
+
22
+ File.write(name, <<~CODE)
23
+ # p5.rb - A Ruby implementation of p5.js
24
+ #
25
+ # This library allows you to create sketches using Ruby, similar to p5.js.
26
+ #
27
+ # - Define `setup` and `draw` method to create a sketch.
28
+ # - API is compatible with p5.js.
29
+ # - API naming follows PascalCase for consistency with p5.js.
30
+ #
31
+ # Example:
32
+ # def setup
33
+ # createCanvas(400, 400)
34
+ # end
35
+ #
36
+ # def draw
37
+ # background(220)
38
+ # ellipse(200, 200, 50, 50)
39
+ # end
40
+ #
41
+ # --- Major Methods ---
42
+ #
43
+ # - createCanvas(width, height) -> Creates a drawing canvas.
44
+ # - background(color) -> Sets the background color.
45
+ # - fill(color) -> Sets the fill color for shapes.
46
+ # - stroke(color) -> Sets the outline color for shapes.
47
+ # - noStroke() -> Disables shape outlines.
48
+ # - ellipse(x, y, w, h) -> Draws an ellipse at (x, y) with width w and height h.
49
+ # - rect(x, y, w, h) -> Draws a rectangle at (x, y) with width w and height h.
50
+ # - line(x1, y1, x2, y2) -> Draws a line from (x1, y1) to (x2, y2).
51
+ # - text(str, x, y) -> Draws text at (x, y).
52
+ # - push() -> Saves the current drawing state (transformation, styles, etc.).
53
+ # - pop() -> Restores the last saved drawing state.
54
+ # - width, height -> Returns the canvas dimensions.
55
+ # - frameCount -> Returns the number of frames elapsed.
56
+ # - mouseX, mouseY -> Returns the current mouse position.
57
+ # - keyPressed? -> Returns true if a key is pressed.
58
+ # - mousePressed? -> Returns true if the mouse button is pressed.
59
+
60
+ def setup
61
+ createCanvas(400, 400)
62
+ background(200)
63
+ end
64
+
65
+ def draw
66
+ background(200)
67
+ (0..width).step(50) do |x|
68
+ (0..height).step(50) do |y|
69
+ ellipse(x, y, 40, 40)
70
+ end
71
+ end
72
+ end
73
+ CODE
74
+ end
75
+
76
+ desc "run SCRIPT_FILE", "Run p5.rb script on server"
77
+ def run_command(script_file)
78
+ run_web_app(script_file)
79
+ end
80
+ map "run" => "run_command"
81
+ end
82
+ end
data/sig/p5rb_cli.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module P5rbCli
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: p5rb_cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ongaeshi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-03-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: webrick
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.9'
41
+ description: p5.rb CLI is a command-line tool that allows you to create p5.js-like
42
+ sketches using Ruby. It provides commands to generate new sketches and run them
43
+ in a local web server.
44
+ email:
45
+ - ongaeshi0621@gmail.com
46
+ executables:
47
+ - p5rb
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".standard.yml"
52
+ - CHANGELOG.md
53
+ - README.ja.md
54
+ - README.md
55
+ - Rakefile
56
+ - exe/p5rb
57
+ - lib/p5rb_cli.rb
58
+ - lib/p5rb_cli/static/index.html
59
+ - lib/p5rb_cli/static/p5editor.js
60
+ - lib/p5rb_cli/static/p5editor.rb
61
+ - lib/p5rb_cli/static/style.css
62
+ - lib/p5rb_cli/version.rb
63
+ - lib/p5rb_cli/web_app.rb
64
+ - sig/p5rb_cli.rbs
65
+ homepage: https://github.com/ongaeshi/p5rb_cli
66
+ licenses: []
67
+ metadata:
68
+ homepage_uri: https://github.com/ongaeshi/p5rb_cli
69
+ source_code_uri: https://github.com/ongaeshi/p5rb_cli
70
+ changelog_uri: https://github.com/ongaeshi/p5rb_cli/blob/master/CHANGELOG.md
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 3.0.0
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 3.5.22
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: A CLI tool for creating p5.js-like sketches using Ruby.
90
+ test_files: []