Hykup in 2 MinutesΒΆ

Import and require Hykup:

(require [hykup [*]])
(import [hykup [*]])

and write some (fancy) HTML:

(setv some-hykup #kup

  ; Components are separated from children with a '/'
  [div /

    ; Empty components should still have a '/'
    [span /]

    ; Classes are prefixed with a dot
    [p .large .red /]

    ; id and all other attributes are denoted as keyword arguments
    [p :id my-paragraph :style "background-color: red" /]

    ; Content can be written plainly, without quotes
    [p / I am a sentence!]

    ; Or with quotes, if needed (or wanted)
    [p / "I will (( mess up (( the Hy (( parsing"]])

and render it:

(setv rendered-html (.render some-hykup))
(print rendered-hyml)
; gives (actual output is not prettified)
; <div>
;   <span />
;   <p class="large red">
;   <p id="my-paragraph" style="background-color: red" />
;   <p>I am a sentence!</p>
;   <p>I will (( mess up (( the Hy (( parsing</p>
; </div>

or write it to a file:

(render-file "some_file.html" some-hykup)

Hy values can be interpolated either as non-vector expressions or as symbols starting with ~:

(setv
  class "yummy"
  utensil "spoon"
  attribute-name "tastiness"
  attribute-val "100%")

(defn generate-class [] "filling")
(defn generate-attribute-name "poison-level")
(defn generate-attribute-val "0%")
(defn generate-food [] "alphabet soup")

#kup [p .meal
         .~class
         .(generate-class)

         :id dinnertime
         :~attribute-name ~attribute-val
         :(generate-attribute-name) (generate-attribute-val) /

         I eat (generate-food) with a ~utensil]

; <p class="meal yummy filling"
;    id="dinnertime"
;    tastiness="100%"
;    poison-level="0%">
;    I eat alphabet soup with a spoon
; </p>

Text spacing is designed to work intuitively and desirably, but fine control is possible:

#kup [p / "Use   strings   to   add   spaces" - "..." - "use a dash to surpress spaces"}
; <p>Use   strings   to   add   spaces...use a dash to surpress spaces</p>

Boolean attributes need not be written out:

#kup [p :contenteditable / I am editable]  ; Allowed
#kup [p :contenteditable contenteditable / I am ediable]  ; Behaves exactly the same

Custom components can be defined:

(defn component-box [width chidlren &kwargs attributes]
  #kup [span :style (+ "width: " width ";"  ; use a positional argument
                       "height: " (.pop attributes "height")) ";"  ; or a keyword argument
             #** ~attributes /
             #* ~@children])

#kup [box 10px :height 20px / This text is in a box]
; <span style="width: 10px; height: 20px;">This text is in a box</span>