tapmach 0.2.0 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +167 -34
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -136,6 +136,9 @@ var main_default = `<!DOCTYPE html>
136
136
  <head>
137
137
  <meta charset="UTF-8">
138
138
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
139
+ <link rel="preconnect" href="https://fonts.googleapis.com">
140
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
141
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" rel="stylesheet">
139
142
  <title>tapmach</title>
140
143
  <script>
141
144
  const sleep = (ms) => new Promise(res => setTimeout(res, ms));
@@ -194,11 +197,30 @@ var main_default = `<!DOCTYPE html>
194
197
  font-size: 14pt;
195
198
  font-family: "JetBrains Mono", monospace;
196
199
 
200
+ height: 43vh;
197
201
  }
198
202
  textarea:focus {
199
203
  border-color: #444;
200
204
  }
201
205
 
206
+ /* Controls Header */
207
+ .controls-header {
208
+ width: 100%;
209
+ display: flex;
210
+ flex-wrap: wrap;
211
+ align-items: center;
212
+ justify-content: flex-end;
213
+ gap: 20px;
214
+ padding: 10px 20px;
215
+ box-sizing: border-box;
216
+ }
217
+ @media (max-width: 600px) {
218
+ .controls-header {
219
+ justify-content: center;
220
+ gap: 10px;
221
+ }
222
+ }
223
+
202
224
  /* Run Button */
203
225
  .run-btn {
204
226
  background-color: var(--cell-bg);
@@ -219,9 +241,9 @@ var main_default = `<!DOCTYPE html>
219
241
  gap: 8px;
220
242
  transform-origin: center;
221
243
 
222
- position: absolute;
223
- top: 5px;
224
- right: 5px;
244
+ flex-shrink: 0;
245
+ position: static;
246
+ margin: 0;
225
247
  }
226
248
  .run-btn:hover {
227
249
  background-color: #494d64;
@@ -233,13 +255,12 @@ var main_default = `<!DOCTYPE html>
233
255
 
234
256
  /* Speed Control */
235
257
  .speed-control {
236
- position: absolute;
237
- top: 12px;
238
- right: 60px;
258
+ position: static;
259
+ margin: 0;
239
260
  display: flex;
240
261
  align-items: center;
241
262
  gap: 8px;
242
- font-size: 12px;
263
+ font-size: 11pt;
243
264
  color: var(--text);
244
265
  }
245
266
  .speed-control input {
@@ -258,27 +279,50 @@ var main_default = `<!DOCTYPE html>
258
279
  margin: 0;
259
280
  }
260
281
 
282
+ /* Lang Control */
283
+ .lang-control {
284
+ position: static;
285
+ margin: 0;
286
+ display: flex;
287
+ align-items: center;
288
+ gap: 8px;
289
+ font-size: 11pt;
290
+ color: var(--text);
291
+ }
292
+ .lang-control select {
293
+ background: var(--cell-bg);
294
+ color: var(--text);
295
+ border: 1px solid rgba(202, 211, 245, 0.1);
296
+ border-radius: 4px;
297
+ padding: 4px 8px;
298
+ font-family: "JetBrains Mono", monospace;
299
+ outline: none;
300
+ cursor: pointer;
301
+ appearance: none;
302
+ -webkit-appearance: none;
303
+ }
304
+
261
305
  /* Scrolling Container */
262
306
  #viewport {
263
307
  width: 98vw;
264
308
  max-height: 45vh;
265
309
  height: 45vh;
266
- margin-top: 8vh;
310
+ margin-top: 1vh;
267
311
  overflow-y: auto;
268
312
  white-space: nowrap;
269
313
  padding: 10px;
270
314
  scroll-behavior: smooth;
271
315
  background: rgba(0, 0, 0, 0.2);
272
316
  border-radius: 4px;
317
+ flex-grow: 1;
273
318
  }
274
319
  #tape {
275
320
  display: grid;
276
321
  grid-template-columns: repeat(auto-fill, var(--size));
277
- gap: 4px;
322
+ gap: 2px;
278
323
  justify-content: center;
279
324
  padding-left: 0;
280
325
  padding-right: 0;
281
- gap: 0;
282
326
  }
283
327
 
284
328
  /* Cell Styling */
@@ -286,7 +330,7 @@ var main_default = `<!DOCTYPE html>
286
330
  width: var(--size);
287
331
  height: var(--size);
288
332
  background: var(--cell-bg);
289
- border: 1px solid var(--bg);
333
+ border: 1px solid rgba(0, 0, 0, 0);
290
334
  display: flex;
291
335
  align-items: center;
292
336
  justify-content: center;
@@ -295,7 +339,7 @@ var main_default = `<!DOCTYPE html>
295
339
  flex-shrink: 0;
296
340
  }
297
341
  .cell.active {
298
- border: 1px solid #a6da95;
342
+ border: 2px solid #a6da95;
299
343
  }
300
344
 
301
345
  /* Animations */
@@ -346,22 +390,35 @@ var main_default = `<!DOCTYPE html>
346
390
  </style>
347
391
  </head>
348
392
  <body>
349
- <div class="speed-control">
350
- <label for="speed">Interval (ms):</label>
351
- <input type="number" id="speed" value="1000" min="0" step="100">
393
+ <div class="controls-header">
394
+ <div class="status">
395
+ -
396
+ </div>
397
+ <div class="lang-control">
398
+ <label for="lang">Mode:</label>
399
+ <select id="lang">
400
+ <option value="default">Default</option>
401
+ <option value="shortcodes">Shortcodes</option>
402
+ <option value="numberless shortcodes">Numberless Shortcodes</option>
403
+ </select>
404
+ </div>
405
+ <div class="speed-control">
406
+ <label for="speed">Interval (ms):</label>
407
+ <input type="number" id="speed" value="1000" min="0" step="100">
408
+ </div>
409
+ <button class="run-btn">
410
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
411
+ <path d="M8 5v14l11-7z"/>
412
+ </svg>
413
+ </button>
352
414
  </div>
353
- <button class="run-btn">
354
- <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
355
- <path d="M8 5v14l11-7z"/>
356
- </svg>
357
- </button>
358
415
 
359
416
  <div id="viewport">
360
417
  <div id="tape"></div>
361
418
  </div>
362
419
 
363
420
  <div id="textarea">
364
- <textarea name="main" id="main-textarea" rows="15" spellcheck="false" autocorrect="off" autofocus></textarea>
421
+ <textarea name="main" id="main-textarea" spellcheck="false" autocorrect="off" autofocus></textarea>
365
422
  </div>
366
423
 
367
424
  <script>
@@ -388,7 +445,7 @@ var main_default = `<!DOCTYPE html>
388
445
  return tokens;
389
446
  }
390
447
 
391
- function tokenToCode(code, currentToken, nextToken, speed) {
448
+ function tokenToCode_Default(code, currentToken, nextToken, speed) {
392
449
  if (currentToken === 'create_cell') {
393
450
  code.push('create_cell(');
394
451
  } else if (currentToken === 'destroy_cell') {
@@ -410,18 +467,73 @@ var main_default = `<!DOCTYPE html>
410
467
  }
411
468
  }
412
469
 
413
- function convertToCode(text) {
470
+ function tokenToCode_Shortcodes(code, currentToken, nextToken, speed) {
471
+ if (currentToken === 'cc') {
472
+ code.push('create_cell(');
473
+ } else if (currentToken === 'dc') {
474
+ code.push('destroy_cell(');
475
+ } else if (currentToken === 'add') {
476
+ code.push('add(')
477
+ } else if (currentToken === 'mov') {
478
+ code.push('move(')
479
+ } else if (!isNaN(currentToken) && currentToken.trim() !== "") {
480
+ if (nextToken !== 'line_end') {
481
+ code.push(\`\${currentToken},\`)
482
+ } else {
483
+ code.push(\`\${currentToken}\`)
484
+ }
485
+ } else if (currentToken === 'line_end') {
486
+ code.push(\`); await sleep(\${speed});\`);
487
+ } else {
488
+ throw Error(\`Can't parse the code, wrong instruction: \${currentToken}\`);
489
+ }
490
+ }
491
+
492
+ function tokenToCode_Numberless_Shortcodes(code, currentToken, nextToken, speed) {
493
+ if (currentToken === 'cc') {
494
+ code.push('create_cell();');
495
+ } else if (currentToken === 'dc') {
496
+ code.push('destroy_cell();');
497
+ } else if (currentToken === 'add') {
498
+ code.push('add(1);')
499
+ } else if (currentToken === 'sub') {
500
+ code.push('add(-1);')
501
+ } else if (currentToken === 'mov') {
502
+ code.push('move(1);')
503
+ } else if (currentToken === 'vom') {
504
+ code.push('move(-1);')
505
+ } else if (currentToken === 'line_end') {
506
+ code.push(\`await sleep(\${speed});\`);
507
+ } else {
508
+ throw Error(\`Can't parse the code, wrong instruction: \${currentToken}\`);
509
+ }
510
+ }
511
+
512
+ function convertToCode(text, lang = 'default') {
414
513
  let tokens = parse(text);
415
514
  const speed = document.getElementById('speed').value || 1000;
416
515
  let code = ['(async () => {'];
516
+ let tokenToCode = undefined;
517
+ if (lang === 'default') {
518
+ tokenToCode = tokenToCode_Default;
519
+ } else if (lang === 'shortcodes') {
520
+ tokenToCode = tokenToCode_Shortcodes;
521
+ } else if (lang === 'numberless shortcodes') {
522
+ tokenToCode = tokenToCode_Numberless_Shortcodes;
523
+ } else {
524
+ tokenToCode = tokenToCode_Default;
525
+ }
526
+
527
+ code.push(\`status.style.color = '#eed49f';status.innerHTML = ' ... ';\`);
417
528
 
418
529
  for (let i = 0; i < tokens.length; i++) {
419
530
  tokenToCode(code, tokens[i], tokens[i+1], speed);
420
531
  }
421
-
532
+
533
+ code.push(\`status.innerHTML = ' :) ';status.style.color = '#a6da95';setTimeout(() => { status.style.color = '#cad3f5'; status.innerHTML = ' - '; }, 2000);\`);
422
534
  code.push('})();')
423
535
  code = code.join('');
424
-
536
+
425
537
  return code;
426
538
  }
427
539
  </script>
@@ -450,15 +562,20 @@ var main_default = `<!DOCTYPE html>
450
562
  </script>
451
563
  <script>
452
564
  const inputField = document.getElementById('speed');
565
+ const lang = document.getElementById('lang');
453
566
 
454
567
  window.addEventListener("load", function() {
455
- inputField.value = localStorage.getItem('speed');
568
+ inputField.value = localStorage.getItem('speed') || 1000;
569
+ lang.value = localStorage.getItem('selectedLang') || "default";
456
570
  });
457
571
 
458
-
459
572
  inputField.addEventListener('input', (e) => {
460
573
  localStorage.setItem('speed', e.target.value);
461
574
  })
575
+
576
+ lang.addEventListener('change', (e) => {
577
+ localStorage.setItem('selectedLang', e.target.value);
578
+ })
462
579
  </script>
463
580
 
464
581
  <script>
@@ -468,7 +585,7 @@ var main_default = `<!DOCTYPE html>
468
585
  let current_cell = 0;
469
586
  let list = [];
470
587
 
471
- async function update() {
588
+ function update() {
472
589
  if (cells.length === 0) return;
473
590
 
474
591
  const target = cells[current_cell];
@@ -481,7 +598,7 @@ var main_default = `<!DOCTYPE html>
481
598
  target.classList.add('animate-update')
482
599
  }
483
600
 
484
- async function create_cell() {
601
+ function create_cell() {
485
602
  const val = 0;
486
603
  const div = document.createElement('div');
487
604
  div.classList.add('cell', 'animate-create', \`i\${list.length+1}\`);
@@ -504,17 +621,30 @@ var main_default = `<!DOCTYPE html>
504
621
  update();
505
622
  }
506
623
 
507
- async function destroy_cell() {
624
+ function destroy_cell() {
508
625
  const target = cells[current_cell];
509
626
  if (typeof target === null) return;
510
627
 
511
628
  target.classList.add('animate-destroy');
512
629
 
513
- setTimeout(() => target.remove(), 300);
514
- move(-1);
630
+ setTimeout(() => {
631
+ target.remove();
632
+ }, 300);
633
+ if (current_cell === 0) {
634
+ move(1);
635
+ list.splice(current_cell-1, 1);
636
+ cells.splice(current_cell-1, 1);
637
+ current_cell = 0;
638
+ } else {
639
+ move(-1);
640
+ list.splice(current_cell+1, 1);
641
+ cells.splice(current_cell+1, 1);
642
+ }
643
+
644
+ console.log(current_cell);
515
645
  }
516
646
 
517
- async function move(index) {
647
+ function move(index) {
518
648
  if (current_cell+index < 0 || current_cell+index >= cells.length) return;
519
649
 
520
650
  previous_cell = current_cell;
@@ -543,9 +673,12 @@ var main_default = `<!DOCTYPE html>
543
673
 
544
674
  <script>
545
675
  const button = document.querySelector('.run-btn');
676
+ const status = document.querySelector('.status');
546
677
  button.addEventListener('click', async (e) => {
547
678
  let text = localStorage.getItem('text-content');
548
- eval(convertToCode(text));
679
+ let selectedLang = localStorage.getItem('selectedLang');
680
+
681
+ eval(convertToCode(text, selectedLang));
549
682
  })
550
683
  </script>
551
684
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tapmach",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "module": "./src/index.ts",
5
5
  "type": "module",
6
6
  "private": false,