clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

chore/app-model-decomp
puzzletea / export / pdf / parse_helpers.go
parse_helpers.go 1.5K
1package pdfexport23import (4 "fmt"5 "strconv"6 "strings"7)89func splitNormalizedLines(raw string) []string {10 normalized := strings.ReplaceAll(strings.ReplaceAll(raw, "\r\n", "\n"), "\r", "\n")11 if strings.TrimSpace(normalized) == "" {12 return nil13 }14 return strings.Split(normalized, "\n")15}1617func parseNumberGrid(encoded string, width, height int) ([][]int, error) {18 rows := strings.Split(strings.TrimSpace(encoded), "\n")19 grid := make([][]int, height)20 for y := range height {21 grid[y] = make([]int, width)22 if y >= len(rows) {23 continue24 }2526 fields := strings.Fields(rows[y])27 if len(fields) == 0 {28 fields = splitCompactFields(rows[y])29 }30 if len(fields) != width {31 return nil, fmt.Errorf("decode number grid: invalid row width")32 }33 for x := range width {34 if fields[x] == "." {35 continue36 }37 value, err := strconv.Atoi(fields[x])38 if err != nil {39 return nil, fmt.Errorf("decode number grid: %w", err)40 }41 grid[y][x] = value42 }43 }44 return grid, nil45}4647func parseProvidedMask(encoded string, width, height int) [][]bool {48 rows := strings.Split(encoded, "\n")49 mask := make([][]bool, height)50 for y := range height {51 mask[y] = make([]bool, width)52 if y >= len(rows) {53 continue54 }55 for x := 0; x < width && x < len(rows[y]); x++ {56 mask[y][x] = rows[y][x] == '#'57 }58 }59 return mask60}6162func splitCompactFields(row string) []string {63 fields := make([]string, 0, len(row))64 for _, r := range row {65 fields = append(fields, string(r))66 }67 return fields68}