basedpl 0.1.24 → 0.1.27
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.
- package/basedpl_wasm_bg.wasm +0 -0
- package/layout.json +1 -2
- package/lb.js +51 -11
- package/package.json +5 -2
package/basedpl_wasm_bg.wasm
CHANGED
|
Binary file
|
package/layout.json
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"o": {"state": "circle"},
|
|
26
26
|
"p": "π",
|
|
27
27
|
"+": "≠",
|
|
28
|
-
"\\":
|
|
28
|
+
"\\": "⍭",
|
|
29
29
|
"a": {"state": "alpha"},
|
|
30
30
|
"s": "⌈",
|
|
31
31
|
"d": "⌊",
|
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
"epsilon": {"terminator": "∊", "keys": {"_": "⍷", "-": "⍷"}},
|
|
69
69
|
"iota": {"terminator": "⍳", "keys": {"_": "⍸", "-": "⍸"}},
|
|
70
70
|
"circle": {"terminator": "○", "keys": {"-": "⊖", "\\": "⍉", "/": "⊘", "*": "⍟", "m": "⊗", "u": "⨸", "t": "⌾", "8": "⍟"}},
|
|
71
|
-
"stile": {"terminator": "|", "keys": {"~": "⍭", "`": "⍭"}},
|
|
72
71
|
"alpha": {"terminator": "⍺", "keys": {"_": "⍶", "-": "⍶"}},
|
|
73
72
|
"del": {"terminator": "∇", "keys": {"|": "⍒", "\\": "⍒"}},
|
|
74
73
|
"take": {"terminator": "↑", "keys": {"j": "↕"}},
|
package/lb.js
CHANGED
|
@@ -80,6 +80,9 @@
|
|
|
80
80
|
.bpl_choices{position:fixed;max-height:240px;max-width:calc(100vw - 16px);overflow:auto;border:1px solid #888;border-radius:4px;box-shadow:0 3px 12px #0003;padding:4px}
|
|
81
81
|
.bpl_choices button{display:block;width:100%;text-align:left;white-space:nowrap}
|
|
82
82
|
.bpl_choices small{display:block;padding:4px}
|
|
83
|
+
.ngn_lb .bpl_dead::after{content:'▾';font-size:9px;margin-left:1px}
|
|
84
|
+
.bpl_choices.bpl_menu{max-width:min(320px,calc(100vw - 16px))}
|
|
85
|
+
.bpl_menu button{display:inline-block;width:auto;min-width:28px;text-align:center}
|
|
83
86
|
@media(prefers-color-scheme:dark){.ngn_lb,.bpl_choices{background:#222;color:#ddd}.ngn_lb button:hover,.bpl_choices button:hover{background:#bbb;color:#111}}
|
|
84
87
|
</style>`;
|
|
85
88
|
d.body.append(host);
|
|
@@ -91,32 +94,60 @@
|
|
|
91
94
|
toggle.textContent = overlay ? '▼' : '▲';
|
|
92
95
|
d.body.style.paddingTop = overlay || bar.hidden ? originalPadding : `${bar.offsetHeight}px`;
|
|
93
96
|
}
|
|
97
|
+
const names = new Map(symbols.map(({glyph, name, monad, dyad, aliases}) =>
|
|
98
|
+
[glyph, [...new Set([name, monad, dyad, aliases].join(' ').split(' ').filter(Boolean))].join(' ')]));
|
|
99
|
+
function stateGlyphs(state) {
|
|
100
|
+
const {terminator, keys} = layout.states[state];
|
|
101
|
+
return [terminator, ...Object.values(keys).flatMap(value => typeof value === 'string' ? [value] : stateGlyphs(value.state))];
|
|
102
|
+
}
|
|
103
|
+
const groups = new Map(Object.values(layout.option).filter(value => value.state).map(({state}) =>
|
|
104
|
+
[layout.states[state].terminator, [...new Set(stateGlyphs(state))]]));
|
|
105
|
+
const variants = new Set([...groups.values()].flatMap(glyphs => glyphs.slice(1)));
|
|
94
106
|
function button(glyph, name) {
|
|
95
107
|
const b = d.createElement('button');
|
|
96
|
-
b.type = 'button'; b.textContent = glyph; b.title = name + shortcuts.get(glyph); b.dataset.glyph = glyph;
|
|
108
|
+
b.type = 'button'; b.textContent = glyph; b.title = (name || glyph) + (shortcuts.get(glyph) || ''); b.dataset.glyph = glyph;
|
|
97
109
|
return b;
|
|
98
110
|
}
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
// Related glyphs stay together; arrows meet at the boundary between menus and plain buttons.
|
|
112
|
+
const order = [...new Set([
|
|
113
|
+
...'^_⍺⍵∇∆⋄¯¨○⎕∨∧≡∊⍳⊂∩⊥⊤↑↓←→↢↣⇄⊣⊢×÷⌊⌈≤≥≠√π⍭', ...groups.keys(), ...names.keys()
|
|
114
|
+
])];
|
|
115
|
+
for (const glyph of [...order.filter(g => groups.has(g)), ...order.filter(g => !groups.has(g))]) {
|
|
116
|
+
if (!groups.has(glyph) && (variants.has(glyph) || /^[\x20-\x7e]+$/.test(glyph))) continue;
|
|
117
|
+
const b = button(glyph, names.get(glyph));
|
|
118
|
+
if (groups.has(glyph)) {
|
|
119
|
+
b.textContent = {'^': '²', '_': '₂'}[glyph] || glyph;
|
|
120
|
+
b.classList.add('bpl_dead');
|
|
121
|
+
b.setAttribute('aria-expanded', 'false');
|
|
122
|
+
b.title += ' (variants)';
|
|
123
|
+
}
|
|
124
|
+
bar.append(b);
|
|
125
|
+
}
|
|
101
126
|
new ResizeObserver(reflow).observe(bar);
|
|
102
127
|
reflow();
|
|
103
128
|
|
|
104
|
-
function cancel() {
|
|
105
|
-
|
|
106
|
-
|
|
129
|
+
function cancel() {
|
|
130
|
+
choice?.anchor?.setAttribute('aria-expanded', 'false');
|
|
131
|
+
active = undefined; choice = undefined; tip.hidden = true;
|
|
132
|
+
}
|
|
133
|
+
function show(e, item, anchor) {
|
|
134
|
+
tip.classList.toggle('bpl_menu', !!anchor);
|
|
135
|
+
tip.setAttribute('aria-label', anchor ? 'BPL symbol variants' : 'BPL symbol completions');
|
|
136
|
+
anchor?.setAttribute('aria-expanded', 'true');
|
|
137
|
+
if (choice?.item.query !== item.query || choice?.anchor !== anchor) {
|
|
107
138
|
tip.replaceChildren();
|
|
108
139
|
for (const [glyph, name] of item.found) {
|
|
109
140
|
const b = button(glyph, name);
|
|
110
|
-
b.textContent = `${glyph} ${b.title}`;
|
|
141
|
+
if (!anchor) b.textContent = `${glyph} ${b.title}`;
|
|
111
142
|
tip.append(b);
|
|
112
143
|
}
|
|
113
144
|
if (!item.found.length) {
|
|
114
145
|
const note = d.createElement('small'); note.textContent = 'Unknown symbol'; tip.append(note);
|
|
115
146
|
}
|
|
116
147
|
}
|
|
117
|
-
choice = {e, item};
|
|
148
|
+
choice = {e, item, anchor};
|
|
118
149
|
tip.hidden = false;
|
|
119
|
-
const r = e.rect();
|
|
150
|
+
const r = anchor ? anchor.getBoundingClientRect() : e.rect();
|
|
120
151
|
tip.style.left = `${Math.max(4, Math.min(r.left, innerWidth - tip.offsetWidth - 8))}px`;
|
|
121
152
|
tip.style.top = `${Math.max(bar.hidden || overlay ? 4 : bar.offsetHeight, Math.min(r.bottom + 4, innerHeight - tip.offsetHeight - 8))}px`;
|
|
122
153
|
}
|
|
@@ -128,13 +159,19 @@
|
|
|
128
159
|
bar.addEventListener('mousedown', ev => {
|
|
129
160
|
ev.preventDefault();
|
|
130
161
|
const b = ev.target.closest('button');
|
|
162
|
+
const opened = choice?.anchor === b;
|
|
163
|
+
cancel();
|
|
131
164
|
if (b?.classList.contains('ngn_x')) { bar.hidden = true; reflow(); }
|
|
132
165
|
else if (b === toggle) {
|
|
133
166
|
overlay = !overlay;
|
|
134
167
|
try { localStorage.setItem('ngn_lb_overlay', overlay ? '1' : '0'); } catch {}
|
|
135
168
|
reflow();
|
|
136
|
-
} else if (b?.dataset.glyph && lastEditor)
|
|
137
|
-
|
|
169
|
+
} else if (b?.dataset.glyph && lastEditor) {
|
|
170
|
+
const glyph = b.dataset.glyph, group = groups.get(glyph);
|
|
171
|
+
if (group) {
|
|
172
|
+
if (!opened) show(lastEditor, {query: glyph, found: group.map(g => [g, names.get(g)])}, b);
|
|
173
|
+
} else lastEditor.insert(glyph);
|
|
174
|
+
}
|
|
138
175
|
});
|
|
139
176
|
tip.addEventListener('mousedown', ev => {
|
|
140
177
|
ev.preventDefault();
|
|
@@ -159,6 +196,9 @@
|
|
|
159
196
|
keyInput = false; lastEditor = editor(ev.target); if (active) refresh(ev.target);
|
|
160
197
|
}, true);
|
|
161
198
|
window.addEventListener('keydown', ev => {
|
|
199
|
+
if (ev.key === 'Escape' && choice?.anchor) {
|
|
200
|
+
cancel(); ev.preventDefault(); ev.stopImmediatePropagation(); return;
|
|
201
|
+
}
|
|
162
202
|
keyInput = false;
|
|
163
203
|
if (ev.code === 'AltLeft') leftAlt = true;
|
|
164
204
|
if (ev.code === 'AltRight') rightAlt = true;
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "basedpl",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "BasedPL, the Based-array Programming Language, is an APL-derived array language, borrowing ideas from J and BQN, with an emphasis on simple, consistent notation.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
|
-
"repository":
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/AnswerDotAI/basedpl.git"
|
|
9
|
+
},
|
|
7
10
|
"type": "module",
|
|
8
11
|
"main": "basedpl_wasm.js"
|
|
9
12
|
}
|