phy: 行の先頭以外の r, rx, ry を取り込みで受け入れる(P-16解消)
KLE本家は拒否するが、VIAとRemapは読む。Remapで扱える基板を取り込めない 状態にしないため、位置を問わず受け入れる。本家のコードから行頭チェックを 外した挙動をそのまま採る。出力は従来どおり行頭にのみ置く。 Journal: journal/2026-09-21-kle-lenient-row.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSKcJLPAaPLchG4LXxk6cY
This commit is contained in:
+4
-8
@@ -334,6 +334,7 @@ const kleData = (ConfigObject | KeyLabel)[][]
|
|||||||
- ユニットサイズ(mm)、ビジュアルオフセット、クラスター構造、部品ノード、per-key LEDはKLE JSONに出力されない
|
- ユニットサイズ(mm)、ビジュアルオフセット、クラスター構造、部品ノード、per-key LEDはKLE JSONに出力されない
|
||||||
- バリアント構造はKLE JSONに出力しない。VariantGroupごとにバリアントを1つ選び、その配下だけを畳んで出力する
|
- バリアント構造はKLE JSONに出力しない。VariantGroupごとにバリアントを1つ選び、その配下だけを畳んで出力する
|
||||||
- 部品グループ・スイッチの向きはKLE JSONに出力しない。sm, sb, st には取り込み時に保持した値をそのまま書き戻す
|
- 部品グループ・スイッチの向きはKLE JSONに出力しない。sm, sb, st には取り込み時に保持した値をそのまま書き戻す
|
||||||
|
- r, rx, ry は行の先頭にのみ置く。KLE本家はそれ以外の位置に置かれたものを読まない
|
||||||
- p, sm, sb, st は空文字に戻す指定がKLE側で無視される。値を持つキーと持たないキーが混在する配置は、
|
- p, sm, sb, st は空文字に戻す指定がKLE側で無視される。値を持つキーと持たないキーが混在する配置は、
|
||||||
KLEで開いた時点で後続のキーに前の値が残る
|
KLEで開いた時点で後続のキーに前の値が残る
|
||||||
- KLEの `p` はキーキャップのプロファイル名(SA、DCSなど)であり、PHYのプロファイルとは対応させない
|
- KLEの `p` はキーキャップのプロファイル名(SA、DCSなど)であり、PHYのプロファイルとは対応させない
|
||||||
@@ -348,7 +349,9 @@ const kleData = (ConfigObject | KeyLabel)[][]
|
|||||||
- 構造の復元は保証しない。KLE側での編集が大きいほど、クラスター構造は失われる
|
- 構造の復元は保証しない。KLE側での編集が大きいほど、クラスター構造は失われる
|
||||||
- 配列の順番は照合に使わない。KLEは保存時にキーを「角度 → rx → ry → y → x」の順に並べ替えるため、順番は形状から決まる以上の情報を持たない
|
- 配列の順番は照合に使わない。KLEは保存時にキーを「角度 → rx → ry → y → x」の順に並べ替えるため、順番は形状から決まる以上の情報を持たない
|
||||||
|
|
||||||
r, rx, ry を行の先頭以外に置いたKLE JSONが公開されている。KLE本家はこれを読み込まずエラーにする。
|
r, rx, ry は行の先頭以外に置かれていても受け入れ、そのキー以降に適用する。
|
||||||
|
rx, ry を持つキーでは、座標を (rx, ry) に戻してから x, y を加える。
|
||||||
|
KLE本家はこの位置の r, rx, ry をエラーにするが、VIAとRemapは読む。Remapで扱える基板を取り込めない状態にしない。
|
||||||
|
|
||||||
KLEの rx, ry, r はキーの絶対配置 (x, y, rotation) に変換して取り込む。元の rx, ry は保持しない。
|
KLEの rx, ry, r はキーの絶対配置 (x, y, rotation) に変換して取り込む。元の rx, ry は保持しない。
|
||||||
|
|
||||||
@@ -403,10 +406,3 @@ Beyond KLEはスイッチの品種を持たないため、対応づける先が
|
|||||||
- 位置づけ: 未解決の問い。数値入力以外に、原点をどこへ吸着させるか
|
- 位置づけ: 未解決の問い。数値入力以外に、原点をどこへ吸着させるか
|
||||||
- 現状の認識: キーのローカル原点(左上角)・キー中心・境界矩形の角と中心が候補。相対グリッドとは別の機構になる
|
- 現状の認識: キーのローカル原点(左上角)・キー中心・境界矩形の角と中心が候補。相対グリッドとは別の機構になる
|
||||||
- 格上げ条件: 原点移動を実装し、吸着なしで足りるか、足りない場合どの候補が要るかを確認する
|
- 格上げ条件: 原点移動を実装し、吸着なしで足りるか、足りない場合どの候補が要るかを確認する
|
||||||
|
|
||||||
### P-16 KLE本家が拒否するJSONを取り込むか
|
|
||||||
|
|
||||||
- 位置づけ: 未解決の問い。本文「KLE JSONの取り込み」が扱えていない
|
|
||||||
- 現状の認識: r, rx, ry を行の先頭以外に置いたJSONが公開されている(1505件中1件)。KLE本家はエラーにするが、
|
|
||||||
VIAのパーサーは読める。本家に合わせて拒否するか、読めるものは読むかが未定
|
|
||||||
- 格上げ条件: 取り込みの寛容さの方針をユーザーが決める
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# 行の先頭以外の r, rx, ry を受け入れるか
|
||||||
|
|
||||||
|
## 結論
|
||||||
|
|
||||||
|
受け入れる。位置を問わず、そのキー以降に適用する。rx, ry は座標を (rx, ry) に戻してから x, y を加える
|
||||||
|
(KLE本家のコードから行頭チェックだけを外したときの挙動と同じ)。
|
||||||
|
|
||||||
|
決め手は Remap が読めること。ユーザーの判断: 「Remapで扱えるものを拒否したくない」。
|
||||||
|
|
||||||
|
| 案 | 取り込める基板 | 既存の解釈への影響 | 出力への影響 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 本家に合わせて拒否 | 1505件中1504件 | なし | なし |
|
||||||
|
| **r だけ受け入れ** | 1505件 | なし | なし |
|
||||||
|
| **r, rx, ry とも受け入れ(採用)** | 1505件 | なし | なし |
|
||||||
|
|
||||||
|
3案とも出力は変わらない。本家の serialize はクラスターが変わると必ず行を割るので、
|
||||||
|
r, rx, ry は常に行頭にしか出ない。寛容化しても非互換なJSONを生む側には回らない。
|
||||||
|
|
||||||
|
## 実データ
|
||||||
|
|
||||||
|
コーパス1505件(KLE本家プリセット12 + samples 9 + the-via/keyboards 1484)で、
|
||||||
|
行の先頭以外の r, rx, ry を持つのは `owlab/spring/spring.json` の1件だけ。内訳は r が15回、rx/ry は0回。
|
||||||
|
|
||||||
|
spring は Alice系。物理行ごとに配列を1つ書き、行の途中で r を 0 → 12 → -12 → 0 と切り替えている。
|
||||||
|
行頭チェックを外して読むと素直に開く(67キー、左右±12度のスプレイ + 回転なしの外側2列)。
|
||||||
|
|
||||||
|
```
|
||||||
|
0,3 x=3.25 r=0 0,4 x=4.44 r=12 0,8 x=8.72 r=-12 0,12 x=12.85 r=0
|
||||||
|
1,2 x=2.50 r=0 1,3 x=3.70 r=12 1,7 x=8.48 r=-12 1,11 x=12.60 r=0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 寛容化が既存の解釈を変えないこと
|
||||||
|
|
||||||
|
本家 serial.js の該当箇所は throw だけで、意味づけは残りの行が決めている。
|
||||||
|
|
||||||
|
```js
|
||||||
|
if(key.r != null) { if(k!=0) {deserializeError(...)} current.rotation_angle = key.r; }
|
||||||
|
if(key.rx != null) { if(k!=0) {deserializeError(...)} current.rotation_x = cluster.x = key.rx; extend(current, cluster); }
|
||||||
|
```
|
||||||
|
|
||||||
|
throw を3つ消したパーサーと本家で全1505件を読み比べ、本家が読めた1504件は**キー配列が完全一致**。
|
||||||
|
変わるのは今エラーになる1件だけ。
|
||||||
|
|
||||||
|
## 他のツールの受け入れ
|
||||||
|
|
||||||
|
| ツール | 行の途中の r/rx/ry | 根拠 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| KLE本家 `serial.js` | 拒否 | `'r' can only be used on the first key in a row` |
|
||||||
|
| kle-serial (ijprest, TS移植) | 拒否 | 同じチェックを移植 |
|
||||||
|
| Vial `kle_serial.py` | 拒否 | `k != 0 and ("r" in item or ...)` |
|
||||||
|
| kicad-kbplacer | 拒否 | 同じチェックあり |
|
||||||
|
| VIA `@the-via/reader` | 許容 | reduceで位置チェックなし |
|
||||||
|
| Remap `KeyboardModel.ts` | 許容 | `Current.setOp()` に位置チェックなし |
|
||||||
|
| QMK `kle2xy.py` | 無関係 | r/rx/ry を読まない(回転を捨てる) |
|
||||||
|
|
||||||
|
Remap の `Current` を位置計算だけ移植して、throw を外した本家と突き合わせた。行の途中の r、
|
||||||
|
行の途中の rx/ry、途中で r=0 に戻す、spring 全体、いずれも一致する。VIA reader はコードを読んだだけで、
|
||||||
|
`cursor.y = ry` としか書いていないため rx/ry の扱いは本家と違う可能性がある(spring は rx=ry=0 なので影響なし)。
|
||||||
|
|
||||||
|
同じ突き合わせをコーパス全件でやると19件が不一致になるが、いずれも行頭側の ry の解釈やラベルなしキーの扱いで、
|
||||||
|
今回の話とは別件。簡易移植での比較なので Remap 本体で再現したわけでもない。追っていない。
|
||||||
|
|
||||||
|
## 取り込んで書き戻す
|
||||||
|
|
||||||
|
spring を寛容パーサーで読み、PHY経由で本家の serialize に通すと、5行 → 26行のJSONになる。
|
||||||
|
本家の deserialize が読め、配置も元と一致した。寛容化は本家で開けないファイルの修復経路になる。
|
||||||
Reference in New Issue
Block a user