-
Notifications
You must be signed in to change notification settings - Fork 3
/
apl.html
105 lines (83 loc) · 5.55 KB
/
apl.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
<!DOCTYPE html>
<head><meta charset="utf-8"><title>↓</title>
<link rel=icon href='div.png'/>
<style>
@font-face{font-family:'apl'; src:url('apl.woff2') format('woff2');}
html, body{font-family:monospace;overflow:hidden;margin:none}
.kb{width:37px;height:32px; overflow:hidden;position:absolute;right:5px;border:2px solid;border-radius:6px}
.kb img{margin:-75px -87px;}
.ibm2741{resize:none;outline:none;border:none;font-family:apl;position:absolute;left:5px;top:5px;width:100%;height:calc(100vh - 15px);overflow:hidden}
</style>
</head>
<body>
<textarea id="_ibm" class="ibm2741" spellcheck="false"></textarea>
<div style="position:absolute;right:5px"><div id="kb" class="kb"><img src="aplkeys.gif" onclick="this.parentNode.classList.toggle('kb')"/></div></div>
<script type="module">
import { K } from './k.js'
var logo="M←13 13 3 5\nC←' APL\\360 '\n((2↑M)×2↓M)⍴2 4 1 3⍉((M[3 4],⍴C)⍴C)[;;?M[1 2]⍴⍴C]"
function pd(e){if(e){e.preventDefault();e.stopPropagation()}}
function ge(x){return document.getElementById(x)}
function ce(x){return document.createElement(x)}
function su(u){return (u.length)?new TextDecoder("utf-8").decode(u):""}
function us(s){return new TextEncoder("utf-8").encode(s)}
function s2(x){let s="0"+x;return (s.length>2)?s.slice(-2):s}
function hsh(){let s=decodeURIComponent(window.location.hash.substr(1));if(s=="logo")s=logo;return s.length?s.split("\n"):[]}
var au;var snd=[]
function setau(){if(au)return true;if(typeof au=='undefined')au=new AudioContext();if(au){
let x=["ret","spc","key"];for(let i=0;i<x.length;i++){let j=i;fetch(x[i]+".m4a").then(r=>r.arrayBuffer()).then(a=>au.decodeAudioData(a)).then(b=>snd[j]=b)}}}
function play(x){if(!setau())return;let s=au.createBufferSource();s.buffer=snd[x];s.connect(au.destination);s.start()}
function Q(){var q=[];q.active=false;q.do=function(x){q.push(x);if (!q.active)q.n()};q.n=function(){if(!q.length){q.active=false;return};var x=q.shift();q.active=true;x()};return q;}
var q=new Q();
function prg(){var x=hsh();for(let i=0;i<x.length;i++){let j=i;emits(x[j]+"\n");apl(x[j]);}}
// special commands:
// ↑ show last
// ← link from last
// ,← add last to link
//IBM2741
var _ibm=ge("_ibm");let d=new Date();let h=hsh();_ibm.value=[(h.length?(h.join("\n")+"\n"):"")+"OPR)",[s2(d.getHours()),s2(d.getMinutes()),s2(d.getSeconds())].join("."),[s2(d.getMonth()),s2(d.getDay()),s2(d.getFullYear())].join("/"),"KTYE"].join(" ")
_ibm.addEventListener('keydown',function(e){init();let t=_ibm;
var u={Digit1:"¨",Digit2:"¯",Digit3:"<",Digit4:"≤",Digit5:"=",Digit6:"≥",Digit7:">",Digit8:"≠",Digit9:"∨",Digit0:"^",Minus:"-",Equal:"÷",KeyQ:"?",KeyW:"⍵",KeyE:"∊",KeyR:"⍴",KeyT:"~",KeyY:"↑",KeyU:"↓",KeyI:"⍳",KeyO:"○",KeyP:"*",BracketLeft:"→",KeyA:"⍺",KeyS:"⌈",KeyD:"⌊",KeyF:"_",KeyG:"∇",KeyH:"∆",KeyJ:"∘",KeyK:"'",KeyL:"⎕",Semicolon:"(",Quote:")",KeyZ:"⊂",KeyX:"⊃",KeyC:"∩",KeyV:"∪",KeyB:"⊥",KeyN:"⊤",KeyM:"|",Comma:";",Period:":",Slash:"\\"}
var w={Minus:"+",Equal:"×",BracketLeft:"←",Semicolon:"[",Quote:"]",Comma:",",Period:".",Slash:"/"}
var c=e.code;var s=e.getModifierState("Shift");//console.log(c, s)
var n=t.value.length;var p=t.selectionStart
if(c=="Backspace"){t.selectionStart=(p>0)?p-1:0;t.selectionEnd=t.selectionStart}
if(c=="Delete"){t.value=t.value.slice(0,p)}
if(!s&&c.startsWith("Key"))emit(c.slice(3)) //AZ
if(!s&&c.startsWith("Digit"))emit(c.slice(5)) //09
if(c=="Space"){emit(" ")}
if(s&&u[c]!=undefined){emit(u[c])} //shift-apl
if(!s&&w[c]!=undefined){emit(w[c])} //unshift-apl
if(c=="Enter"){var nl=t.value.lastIndexOf("\n");let s=t.value.slice((nl<0)?0:1+nl).trim();if(s=="↑")last();else if(s=="←")link(1);else if(s==",←")link(2);else{lval=s;emits("\n");apl(s)}}
pd(e)})
var lval="";var lnk=""
function last(){_ibm.value=_ibm.value.slice(0,-1)+lval}
function link(x){if(x===2)lnk+="\n"+lval;else lnk=lval;_ibm.value=_ibm.value.slice(0,-x)+"https://ktye.github.io/apl#"+encodeURI(lnk)+"\n"+lnk+"\n ";_ibm.scroll(0,_ibm.scrollHeight)}
_ibm.addEventListener('click',init)
function emits(s){ //s+=s.endsWith("\n")?" ":""
_ibm.selectionStart=_ibm.value.length;var a=s.split("");for(var i=0;i<a.length;i++){let c=a[i];q.do(function(x){emit(c);setTimeout(function(){q.n()},(c=="\n")?100:30)})}}
function emit(c){var t=_ibm;var h=(c!=" ")
play(1+(c!=" "))
var o=t.value[t.selectionStart];if(o!=undefined)c=overstrike(o,c)
var p=t.selectionStart;t.value=t.value.slice(0,p)+c+t.value.slice(1+p)
t.selectionStart=1+p;t.selectionEnd=1+p
t.scroll(0,t.scrollHeight)}
var overstrikes={};var a="'.!'⎕⍞⎕∘⌼⊤○⍕⊥○⍎○*⍟/-⌿\\-⍀∩∘⍝○\\⍉○|⌽○∘⌾○-⊖∆|⍋∇|⍒÷⎕⌹FLE";
for(var i=0;i<26;i++)a+=String.fromCharCode(65+i)+"_"+String.fromCharCode(97+i);
for(var i=0;i<a.length;i+=3){overstrikes[a[i]+a[1+i]]=a[2+i];overstrikes[a[1+i]+a[i]]=a[2+i]}
function overstrike(a,b){var r=overstrikes[a+b];return(r==undefined)?b:r}
function apl(s){ if(0==s.length)return;
try { K.unref(K.Kx("APL", K.KC(s))); K.save(); }
catch(e){ console.log(e); K.restore() };
}
function ktry(s){
try { let x=K._.repl(K.KC(s)); K.save(); _ibm.focus() }
catch(e){ console.log(e); K.restore() }
}
var ext={
init: function() {_ibm.value="";fetch('apl.k').then(r=>r.text()).then(s=>{K.Kx(".",K.KC(s)); K.save(); prg(); _ibm.focus()})},
read: function(file) {return new Uint8Array(0)},
write:function(file,data){if(file===""){console.log(su(data)); let s=su(data); emits(s+(s.endsWith("\n")?" ":"") )}else{ }},
}
var init_=false;function init(){if(!init_){init_=true;K.kinit(ext)}}
</script>
</body></html>