stylesheet.nim 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # author: Ethosa
  2. import
  3. macros,
  4. strutils
  5. type
  6. StyleSheetObj* = object
  7. dict*: seq[tuple[key, value: string]]
  8. StyleSheetRef* = ref StyleSheetObj
  9. proc StyleSheet*(arg: seq[tuple[key, value: string]] = @[]): StyleSheetRef =
  10. StyleSheetRef(dict: arg)
  11. proc StyleSheet*(arg: string): StyleSheetRef =
  12. let tmp = arg.split(Whitespace)
  13. StyleSheetRef(dict: @[(tmp[0], tmp[1])])
  14. proc StyleSheet*(arg: openarray[tuple[key, value: string]]): StyleSheetRef =
  15. var res: seq[tuple[key, value: string]] = @[]
  16. for i in arg:
  17. res.add(i)
  18. StyleSheetRef(dict: res)
  19. proc `$`*(a: StyleSheetRef): string =
  20. for i in a.dict:
  21. result &= i.key & ": " & i.value & ";\n"
  22. if result != "":
  23. result = result[0..^2]
  24. proc `[]`*(a: StyleSheetRef, key: string): string =
  25. for i in a.dict:
  26. if i.key == key:
  27. return i.value
  28. proc `[]=`*(a: StyleSheetRef, key, value: string) =
  29. for i in 0..a.dict.high:
  30. if a.dict[i].key == key:
  31. a.dict[i].value = value
  32. return
  33. a.dict.add((key, value))
  34. proc len*(a: StyleSheetRef): int {.inline.} =
  35. ## Returns styles count.
  36. a.dict.len()
  37. # --- Macros --- #
  38. proc toStr(a: NimNode): string {.compileTime.} =
  39. result =
  40. case a.kind
  41. of nnkIdent, nnkStrLit:
  42. $a
  43. of nnkIntLit:
  44. $(intVal(a))
  45. of nnkFloatLit:
  46. $(floatVal(a))
  47. of nnkInfix:
  48. $a[1] & "-" & $a[2]
  49. else:
  50. ""
  51. if a.kind == nnkCall:
  52. for i in 1..a.len()-1:
  53. result &= a[i].toStr() & ", "
  54. if result != "":
  55. result = $a[0] & "(" & result[0..^3] & ")"
  56. else:
  57. result = $a[0] & "()"
  58. macro style*(obj: untyped): untyped =
  59. ## Translates CSS-like code into StyleSheet.
  60. ##
  61. ## ### Example
  62. ## .. code-block:: nim
  63. ##
  64. ## echo style(
  65. ## {
  66. ## background-color: rgba(255, 255, 255, 1),
  67. ## color: rgb(0, 0, 0)
  68. ## }
  69. ## )
  70. if obj.kind == nnkTableConstr:
  71. var
  72. cssp = StyleSheetRef(dict: @[])
  73. arr = newNimNode(nnkBracket)
  74. for child in obj.children():
  75. if child.kind == nnkExprColonExpr:
  76. # smth: 0 0 0 0 0 0 0 0 0 0 -> style['smth'] = "0 0 0 0 0 0 0 0 0 0"
  77. if child[1].kind == nnkCommand:
  78. var
  79. val = ""
  80. right = child[1]
  81. val &= child[1][0].toStr()
  82. while right.kind == nnkCommand:
  83. val &= " " & child[1][0].toStr()
  84. right = right[1]
  85. cssp[child[0].toStr()] = val
  86. else:
  87. cssp[child[0].toStr()] = child[1].toStr()
  88. for i in cssp.dict:
  89. arr.add(newPar(newLit(i.key), newLit(i.value)))
  90. result = newCall("StyleSheet", newCall("@", arr))