qr.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package qr
  2. import (
  3. "strings"
  4. "github.com/sst/opencode/internal/styles"
  5. "github.com/sst/opencode/internal/theme"
  6. "rsc.io/qr"
  7. )
  8. var tops_bottoms = []rune{' ', '▀', '▄', '█'}
  9. // Generate a text string to a QR code, which you can write to a terminal or file.
  10. func Generate(text string) (string, int, error) {
  11. code, err := qr.Encode(text, qr.Level(0))
  12. if err != nil {
  13. return "", 0, err
  14. }
  15. t := theme.CurrentTheme()
  16. if t == nil {
  17. return "", 0, err
  18. }
  19. // Create lipgloss style for QR code with theme colors
  20. qrStyle := styles.NewStyle().Foreground(t.Text()).Background(t.Background())
  21. var result strings.Builder
  22. // content
  23. for y := 0; y < code.Size-1; y += 2 {
  24. var line strings.Builder
  25. for x := 0; x < code.Size; x += 1 {
  26. var num int8
  27. if code.Black(x, y) {
  28. num += 1
  29. }
  30. if code.Black(x, y+1) {
  31. num += 2
  32. }
  33. line.WriteRune(tops_bottoms[num])
  34. }
  35. result.WriteString(qrStyle.Render(line.String()) + "\n")
  36. }
  37. // add lower border when required (only required when QR size is odd)
  38. if code.Size%2 == 1 {
  39. var borderLine strings.Builder
  40. for range code.Size {
  41. borderLine.WriteRune('▀')
  42. }
  43. result.WriteString(qrStyle.Render(borderLine.String()) + "\n")
  44. }
  45. return result.String(), code.Size, nil
  46. }