From 23591893b314c99b5e40a915e556a3873eec9fef Mon Sep 17 00:00:00 2001 From: Hau Nguyen Date: Sun, 23 Jul 2023 05:04:21 +0700 Subject: [PATCH] feat: gen ascii art with Go --- Makefile | 7 +- README.md | 4 + cmd/asciigen/draw.go | 149 ++++++++++++++++++++++++ cmd/asciigen/main.go | 46 ++++++++ cmd/asciigen/models.go | 28 +++++ dztech_dz60rgb_wkl/asciiart/haunt98.txt | 37 ++++++ dztech_dz60rgb_wkl/info.json | 85 ++++++++++++++ go.mod | 3 + go.sum | 0 9 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 cmd/asciigen/draw.go create mode 100644 cmd/asciigen/main.go create mode 100644 cmd/asciigen/models.go create mode 100644 dztech_dz60rgb_wkl/asciiart/haunt98.txt create mode 100644 dztech_dz60rgb_wkl/info.json create mode 100644 go.mod create mode 100644 go.sum diff --git a/Makefile b/Makefile index e6d94c5..182191b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ -.PHONY: all format clean dztech_dz60rgb_wkl +.PHONY: all format clean draw dztech_dz60rgb_wkl all: $(MAKE) format + $(MAKE) draw $(MAKE) dztech_dz60rgb_wkl format: @@ -12,6 +13,10 @@ clean: rm -rf ~/qmk_firmware/keyboards/dztech/dz60rgb_wkl/keymaps/haunt98 rm -rf dztech_dz60rgb_wkl_v2_1_haunt98.bin +draw: + curl https://raw.githubusercontent.com/qmk/qmk_firmware/master/keyboards/dztech/dz60rgb_wkl/info.json --output dztech_dz60rgb_wkl/info.json + QMK_INFO=dztech_dz60rgb_wkl/info.json QMK_KEYMAP=dztech_dz60rgb_wkl/keymaps_json/haunt98/keymap.json go run ./cmd/asciigen/*.go > dztech_dz60rgb_wkl/asciiart/haunt98.txt + dztech_dz60rgb_wkl: # Copy rm -rf ~/qmk_firmware/keyboards/dztech/dz60rgb_wkl/keymaps/haunt98 diff --git a/README.md b/README.md index fa6747f..32a2886 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ Currently firmware size: * The firmware size is fine - 15334/26624 (57%, 11290 bytes free) ``` +### Keymap + +See [asciiart](dztech_dz60rgb_wkl/asciiart/haunt98.txt). + ## Install Locate firmware file after compile successfully. diff --git a/cmd/asciigen/draw.go b/cmd/asciigen/draw.go new file mode 100644 index 0000000..24bf68c --- /dev/null +++ b/cmd/asciigen/draw.go @@ -0,0 +1,149 @@ +package main + +const ( + scaleX = 8 + scaleY = 3 +) + +func Draw( + layouts map[string]map[string][]QMKKeyDictionary, + keymap QMKKeymap, +) string { + result := "" + + for layout := range layouts { + if keymap.Layout != layout { + continue + } + + keys, ok := layouts[layout]["layout"] + if !ok { + continue + } + + // Preprocess keys + // Y aka row -> X aka col + var maxX4, maxY4 int + for i := range keys { + if int(keys[i].W) == 0 { + keys[i].W = 1 + } + + if int(keys[i].H) == 0 { + keys[i].H = 1 + } + + // TODO: Better way to handle this + // Because 0.25 + keys[i].NewX = int(keys[i].X * scaleX) + keys[i].NewY = int(keys[i].Y * scaleY) + keys[i].NewW = int(keys[i].W * scaleX) + keys[i].NewH = int(keys[i].H * scaleY) + + if keys[i].NewX+keys[i].NewW > maxX4 { + maxX4 = keys[i].NewX + keys[i].NewW + } + + if keys[i].NewY+keys[i].NewH > maxY4 { + maxY4 = keys[i].NewY + keys[i].NewH + } + } + + for _, layer := range keymap.Layers { + // Preprocess table + table := make([][]string, maxY4) + for i := 0; i < maxY4; i++ { + table[i] = make([]string, maxX4) + } + + // Fill layout + count := 0 + for _, key := range keys { + keyStr := layer[count] + keyWidthLimit := key.NewW - 2 + + // TODO: Better way to handle this + if len(keyStr) > keyWidthLimit { + keyStr = keyStr[:keyWidthLimit] + } else { + keyWidthLimit = len(keyStr) + } + + for i := key.NewY; i < key.NewY+key.NewH; i++ { + for j := key.NewX; j < key.NewX+key.NewW; j++ { + if i == key.NewY { + if j == key.NewX { + table[i][j] = "+" + } else { + table[i][j] = "-" + } + } else if i == key.NewY+key.NewH/2 { + // Write key in the middle + if j == key.NewX { + table[i][j] = "|" + } else if j < key.NewX+keyWidthLimit+1 { + table[i][j] = string(keyStr[j-key.NewX-1]) + } else { + table[i][j] = " " + } + } else { + table[i][j] = " " + } + } + } + + count++ + } + + // Postprecess table + newTable := make([][]string, 0, maxY4+1) + + // Remove empty row + for i := 0; i < len(table); i++ { + isEmptyRow := true + for j := 0; j < len(table[i]); j++ { + if table[i][j] != " " { + isEmptyRow = false + break + } + } + + if isEmptyRow { + continue + } + + // Padding + paddingRight := "|" + if table[i][len(table[i])-1] == "-" { + paddingRight = "+" + } + + newTable = append(newTable, append(table[i], paddingRight)) + } + + // Padding + paddingRow := make([]string, 0, maxX4) + for j := 0; j < maxX4; j++ { + paddingBottom := "-" + if newTable[len(newTable)-1][j] == "|" { + paddingBottom = "+" + } + paddingRow = append(paddingRow, paddingBottom) + } + newTable = append(newTable, append(paddingRow, "+")) + + str := "" + for i := range newTable { + for j := range newTable[i] { + str += newTable[i][j] + } + str += "\n" + } + + result += str + "\n" + } + + } + + return result +} diff --git a/cmd/asciigen/main.go b/cmd/asciigen/main.go new file mode 100644 index 0000000..341965c --- /dev/null +++ b/cmd/asciigen/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" +) + +func main() { + filenameInfo := os.Getenv("QMK_INFO") + if filenameInfo == "" { + log.Fatalln("ENV QMK_INFO empty") + } + + filenameKeymap := os.Getenv("QMK_KEYMAP") + if filenameKeymap == "" { + log.Fatalln("ENV QMK_KEYMAP empty") + } + + bytesInfo, err := os.ReadFile(filenameInfo) + if err != nil { + log.Fatalln("Failed to read file", filenameInfo, err) + } + + bytesKeymap, err := os.ReadFile(filenameKeymap) + if err != nil { + log.Fatalln("Failed to read file", filenameKeymap, err) + } + + qmkInfo := QMKInfo{} + if err := json.Unmarshal(bytesInfo, &qmkInfo); err != nil { + log.Fatalln("Failed to json unmarshal", filenameInfo, err) + } + + qmkKeymap := QMKKeymap{} + if err := json.Unmarshal(bytesKeymap, &qmkKeymap); err != nil { + log.Fatalln("Failed to json unmarshal", filenameKeymap, err) + } + + result := Draw( + qmkInfo.Layouts, + qmkKeymap, + ) + fmt.Println(result) +} diff --git a/cmd/asciigen/models.go b/cmd/asciigen/models.go new file mode 100644 index 0000000..2c0e55f --- /dev/null +++ b/cmd/asciigen/models.go @@ -0,0 +1,28 @@ +package main + +const ( + DefaultQMKW = 1 + DefaultQMKH = 1 +) + +// https://github.com/qmk/qmk_firmware/blob/master/docs/reference_info_json.md +type QMKInfo struct { + Layouts map[string]map[string][]QMKKeyDictionary `json:"layouts"` +} + +type QMKKeyDictionary struct { + X float32 `json:"x"` + Y float32 `json:"y"` + W float32 `json:"w"` + H float32 `json:"h"` + NewX int `json:"-"` + NewY int `json:"-"` + NewW int `json:"-"` + NewH int `json:"-"` +} + +// https://config.qmk.fm/#/ +type QMKKeymap struct { + Layers [][]string `json:"layers"` + Layout string `json:"layout"` +} diff --git a/dztech_dz60rgb_wkl/asciiart/haunt98.txt b/dztech_dz60rgb_wkl/asciiart/haunt98.txt new file mode 100644 index 0000000..a02bc2b --- /dev/null +++ b/dztech_dz60rgb_wkl/asciiart/haunt98.txt @@ -0,0 +1,37 @@ ++-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +|QK_GES |KC_1 |KC_2 |KC_3 |KC_4 |KC_5 |KC_6 |KC_7 |KC_8 |KC_9 |KC_0 |KC_MIN |KC_EQL |KC_BSL |KC_GRV | ++-----------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----------+ +|KC_TAB |KC_Q |KC_W |KC_E |KC_R |KC_T |KC_Y |KC_U |KC_I |KC_O |KC_P |KC_LBR |KC_RBR |KC_BSPC | ++-------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----------------+ +|CTL_T(KC_ESC |KC_A |KC_S |KC_D |KC_F |KC_G |KC_H |KC_J |KC_K |KC_L |KC_SCL |KC_QUO |KC_ENT | ++-----------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------------+-------+ +|KC_LSFT |KC_Z |KC_X |KC_C |KC_V |KC_B |KC_N |KC_M |KC_COM |KC_DOT |KC_SLS |KC_RSFT |MO(1) | ++-----------+-------+-----------+-------------------------------------------------------+-----------+-------+-----------+ +|KC_NO |KC_LAL |KC_LGUI |KC_SPC |KC_RGUI |KC_RAL |KC_NO | ++-----------+-------+-----------+-------------------------------------------------------+-----------+-------+-----------+ + ++-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +|KC_GRV |KC_F1 |KC_F2 |KC_F3 |KC_F4 |KC_F5 |KC_F6 |KC_F7 |KC_F8 |KC_F9 |KC_F10 |KC_F11 |KC_F12 |KC_TRN |KC_TRN | ++-----------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----------+ +|KC_TRNS |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_UP |KC_TRN |KC_TRNS | ++-------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----------------+ +|KC_TRNS |KC_VOL |KC_VOL |KC_MUT |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_LEF |KC_RGH |KC_TRNS | ++-----------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------------+-------+ +|KC_TRNS |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_DOW |KC_TRNS |KC_TRN | ++-----------+-------+-----------+-------------------------------------------------------+-----------+-------+-----------+ +|KC_NO |TG(2) |KC_TRNS |KC_TRNS |KC_TRNS |KC_TRN |KC_NO | ++-----------+-------+-----------+-------------------------------------------------------+-----------+-------+-----------+ + ++-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +|QK_BOO |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN | ++-----------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----------+ +|KC_TRNS |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRNS | ++-------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-----------------+ +|KC_CAPS |RGB_HU |RGB_SA |RGB_VA |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_HOM |KC_PGU |KC_TRN |KC_TRN |KC_TRNS | ++-----------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------------+-------+ +|KC_TRNS |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_TRN |KC_END |KC_PGD |KC_TRN |KC_TRNS |KC_TRN | ++-----------+-------+-----------+-------------------------------------------------------+-----------+-------+-----------+ +|KC_NO |KC_TRN |KC_TRNS |KC_TRNS |RGB_TOG |RGB_MO |KC_NO | ++-----------+-------+-----------+-------------------------------------------------------+-----------+-------+-----------+ + + diff --git a/dztech_dz60rgb_wkl/info.json b/dztech_dz60rgb_wkl/info.json new file mode 100644 index 0000000..52685db --- /dev/null +++ b/dztech_dz60rgb_wkl/info.json @@ -0,0 +1,85 @@ +{ + "keyboard_name": "DZ60RGB_WKL", + "manufacturer": "DZTECH", + "url": "", + "maintainer": "dztech", + "usb": { + "vid": "0x445A" + }, + "community_layouts": ["60_tsangan_hhkb"], + "layout_aliases": { + "LAYOUT_HHKB": "LAYOUT_60_tsangan_hhkb" + }, + "layouts": { + "LAYOUT_60_tsangan_hhkb": { + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0}, + {"matrix": [0, 1], "x": 1, "y": 0}, + {"matrix": [0, 2], "x": 2, "y": 0}, + {"matrix": [0, 3], "x": 3, "y": 0}, + {"matrix": [0, 4], "x": 4, "y": 0}, + {"matrix": [0, 5], "x": 5, "y": 0}, + {"matrix": [0, 6], "x": 6, "y": 0}, + {"matrix": [0, 7], "x": 7, "y": 0}, + {"matrix": [0, 8], "x": 8, "y": 0}, + {"matrix": [0, 9], "x": 9, "y": 0}, + {"matrix": [0, 10], "x": 10, "y": 0}, + {"matrix": [0, 11], "x": 11, "y": 0}, + {"matrix": [0, 12], "x": 12, "y": 0}, + {"matrix": [0, 13], "x": 13, "y": 0}, + {"matrix": [2, 12], "x": 14, "y": 0}, + + {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5}, + {"matrix": [1, 1], "x": 1.5, "y": 1}, + {"matrix": [1, 2], "x": 2.5, "y": 1}, + {"matrix": [1, 3], "x": 3.5, "y": 1}, + {"matrix": [1, 4], "x": 4.5, "y": 1}, + {"matrix": [1, 5], "x": 5.5, "y": 1}, + {"matrix": [1, 6], "x": 6.5, "y": 1}, + {"matrix": [1, 7], "x": 7.5, "y": 1}, + {"matrix": [1, 8], "x": 8.5, "y": 1}, + {"matrix": [1, 9], "x": 9.5, "y": 1}, + {"matrix": [1, 10], "x": 10.5, "y": 1}, + {"matrix": [1, 11], "x": 11.5, "y": 1}, + {"matrix": [1, 12], "x": 12.5, "y": 1}, + {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5}, + + {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75}, + {"matrix": [2, 1], "x": 1.75, "y": 2}, + {"matrix": [2, 2], "x": 2.75, "y": 2}, + {"matrix": [2, 3], "x": 3.75, "y": 2}, + {"matrix": [2, 4], "x": 4.75, "y": 2}, + {"matrix": [2, 5], "x": 5.75, "y": 2}, + {"matrix": [2, 6], "x": 6.75, "y": 2}, + {"matrix": [2, 7], "x": 7.75, "y": 2}, + {"matrix": [2, 8], "x": 8.75, "y": 2}, + {"matrix": [2, 9], "x": 9.75, "y": 2}, + {"matrix": [2, 10], "x": 10.75, "y": 2}, + {"matrix": [2, 11], "x": 11.75, "y": 2}, + {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25}, + + {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25}, + {"matrix": [3, 1], "x": 2.25, "y": 3}, + {"matrix": [3, 2], "x": 3.25, "y": 3}, + {"matrix": [3, 3], "x": 4.25, "y": 3}, + {"matrix": [3, 4], "x": 5.25, "y": 3}, + {"matrix": [3, 5], "x": 6.25, "y": 3}, + {"matrix": [3, 6], "x": 7.25, "y": 3}, + {"matrix": [3, 7], "x": 8.25, "y": 3}, + {"matrix": [3, 8], "x": 9.25, "y": 3}, + {"matrix": [3, 9], "x": 10.25, "y": 3}, + {"matrix": [3, 10], "x": 11.25, "y": 3}, + {"matrix": [3, 11], "x": 12.25, "y": 3, "w": 1.75}, + {"matrix": [3, 13], "x": 14, "y": 3}, + + {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5}, + {"matrix": [4, 1], "x": 1.5, "y": 4}, + {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5}, + {"matrix": [4, 5], "x": 4, "y": 4, "w": 7}, + {"matrix": [4, 10], "x": 11, "y": 4, "w": 1.5}, + {"matrix": [4, 11], "x": 12.5, "y": 4}, + {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5} + ] + } + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5782a22 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/haunt98/qmk_keymaps + +go 1.20 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29