aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2019-01-22 20:15:37 -0400
committerEduardo Julian2019-01-22 20:15:37 -0400
commit701cad823deaf887478f5b3b0095d5e732ed1da9 (patch)
treea59f0ef5881c6f9d3676024a5039cf0f1b7d386a
parentf8c9375490f00d39729c0e969b60ce825d29e7ea (diff)
- WIP: Expansion of CSS machinery.
- Expansion of l10n/i18n machinery.
-rw-r--r--lux-mode/lux-mode.el2
-rw-r--r--stdlib/source/lux/control/functor.lux4
-rw-r--r--stdlib/source/lux/data/format/css.lux159
-rw-r--r--stdlib/source/lux/data/format/css/property.lux231
-rw-r--r--stdlib/source/lux/data/format/css/selector.lux175
-rw-r--r--stdlib/source/lux/data/format/css/value.lux625
-rw-r--r--stdlib/source/lux/data/format/html.lux9
-rw-r--r--stdlib/source/lux/data/text/encoding.lux8
-rw-r--r--stdlib/source/lux/type/abstract.lux3
-rw-r--r--stdlib/source/lux/type/quotient.lux38
-rw-r--r--stdlib/source/lux/world/internationalization/language.lux16
-rw-r--r--stdlib/source/lux/world/internationalization/locale.lux30
-rw-r--r--stdlib/source/lux/world/internationalization/territory.lux19
-rw-r--r--stdlib/test/tests.lux8
14 files changed, 1198 insertions, 129 deletions
diff --git a/lux-mode/lux-mode.el b/lux-mode/lux-mode.el
index 47983ed83..1babb75fe 100644
--- a/lux-mode/lux-mode.el
+++ b/lux-mode/lux-mode.el
@@ -246,7 +246,7 @@ Called by `imenu--generic-function'."
;; Type
(type//syntax (altRE "|" "&" "->" "All" "Ex" "Rec" "primitive" "\\$" "type"))
(type//checking (altRE ":" ":coerce" ":~" ":assume" ":of" ":cast" ":share"))
- (type//abstract (altRE "abstract:" ":abstraction" ":representation" "\\^:representation"))
+ (type//abstract (altRE "abstract:" ":abstraction" ":representation" ":transmutation" "\\^:representation"))
(type//unit (altRE "unit:" "scale:"))
(type//poly (altRE "poly:" "derived:"))
;; Data
diff --git a/stdlib/source/lux/control/functor.lux b/stdlib/source/lux/control/functor.lux
index 00a5c776b..415d57c93 100644
--- a/stdlib/source/lux/control/functor.lux
+++ b/stdlib/source/lux/control/functor.lux
@@ -27,6 +27,6 @@
(signature: #export (Contravariant f)
(: (All [a b]
- (-> (-> a b)
- (-> (f b) (f a))))
+ (-> (-> b a)
+ (-> (f a) (f b))))
map-1))
diff --git a/stdlib/source/lux/data/format/css.lux b/stdlib/source/lux/data/format/css.lux
index fbdad1885..feb6fc8a9 100644
--- a/stdlib/source/lux/data/format/css.lux
+++ b/stdlib/source/lux/data/format/css.lux
@@ -1,97 +1,84 @@
(.module:
- [lux #*
+ [lux (#- Name and)
[data
- ["." color (#+ Color)]
+ ["." color (#+ Color Pigment)]
["." number]
["." text
- format]
+ format
+ ["." encoding (#+ Encoding)]]
[collection
- ["." list ("list/." Functor<List> Monoid<List>)]]]])
+ ["." list ("list/." Functor<List> Monoid<List>)]]]
+ [type
+ abstract]
+ [world
+ [net (#+ URL)]]]
+ [/
+ ["." selector (#+ Selector Combinator)]
+ ["." value (#+ Value)]
+ ["." property (#+ Property)]])
-(type: #export Selector
- Text)
+(abstract: #export Style
+ {#.doc "The style associated with a CSS selector."}
-(type: #export Property Text)
-(type: #export Value Text)
+ Text
-(type: #export Style
- {#.doc "The style associated with a CSS selector."}
- (List [Property Value]))
-
-(type: #export Rule [Selector Style])
-
-(type: #export Sheet (List Rule))
-
-(type: #export CSS Text)
-
-(def: #export (inline style)
- (-> Style Text)
- (|> style
- (list/map (function (_ [key val]) (format key ": " val)))
- (text.join-with "; ")))
-
-(def: #export (css sheet)
- (-> Sheet CSS)
- (|> sheet
- (list/map (function (_ [selector style])
- (if (list.empty? style)
- ""
- (format selector "{" (inline style) "}"))))
- (text.join-with text.new-line)))
-
-(def: #export (rgb color)
- (-> Color Value)
- (let [[red green blue] (color.to-rgb color)]
- (format "rgb(" (|> red .int %i)
- "," (|> green .int %i)
- "," (|> blue .int %i)
- ")")))
-
-(def: #export (rgba color alpha)
- (-> Color Rev Value)
- (let [[red green blue] (color.to-rgb color)]
- (format "rgba(" (|> red .int %i)
- "," (|> green .int %i)
- "," (|> blue .int %i)
- "," (if (r/= (:: number.Interval<Rev> top) alpha)
- "1.0"
- (format "0" (%r alpha)))
- ")")))
-
-(def: #export (rule selector style children)
- (-> Selector Style Sheet Sheet)
- (list& [selector style]
- (list/map (function (_ [sub-selector sub-style])
- [(format selector sub-selector) sub-style])
- children)))
-
-(do-template [<name> <type>]
- [(def: #export <name>
- (-> <type> <type> <type>)
- list/compose)]
-
- [merge Style]
- [cascade Sheet]
+ (def: #export empty Style (:abstraction ""))
+
+ (def: property-separator " ")
+
+ (def: #export (with [property value])
+ (All [brand]
+ (-> [(Property brand) (Value brand)]
+ (-> Style Style)))
+ (|>> :representation
+ (format (property.name property) ": " (value.value value) ";" ..property-separator)
+ :abstraction))
+
+ (def: #export inline
+ (-> Style Text)
+ (|>> :representation))
)
-(do-template [<name> <suffix>]
- [(def: #export (<name> value)
- (-> Frac Value)
- (format (%f value) <suffix>))]
-
- [em "em"]
- [ex "ex"]
- [rem "rem"]
- [ch "ch"]
- [vw "vw"]
- [vh "vh"]
- [vmin "vmin"]
- [vmax "vmax"]
- [% "%"]
- [cm "cm"]
- [mm "mm"]
- [in "in"]
- [px "px"]
- [pt "pt"]
- [pc "pc"]
+(abstract: #export CSS
+ {}
+
+ Text
+
+ (def: #export (rule selector style)
+ (-> Selector Style CSS)
+ (:abstraction (format (selector.selector selector) " " "{" (..inline style) "}")))
+
+ (def: #export (char-set encoding)
+ (-> Encoding CSS)
+ (:abstraction (format "@charset" " " (%t (encoding.name encoding)) ";")))
+
+ (def: css-separator text.new-line)
+
+ (def: #export (and pre post)
+ (-> CSS CSS CSS)
+ (:abstraction (format (:representation pre) ..css-separator
+ (:representation post))))
+
+ (def: #export (alter combinator selector css)
+ (-> Combinator Selector CSS CSS)
+ (|> css
+ :representation
+ (text.split-all-with ..css-separator)
+ (list/map (|>> (format (selector.selector (combinator selector (selector.tag ""))))))
+ (text.join-with ..css-separator)
+ :abstraction))
+
+ (def: #export (dependent combinator selector style inner)
+ (-> Combinator Selector Style CSS CSS)
+ (..and (..rule selector style)
+ (..alter combinator selector inner)))
+
+ (do-template [<name> <combinator>]
+ [(def: #export <name>
+ (-> Selector Style CSS CSS)
+ (..dependent <combinator>))]
+
+ [scope selector.in]
+ [complex selector.sub]
+ )
)
diff --git a/stdlib/source/lux/data/format/css/property.lux b/stdlib/source/lux/data/format/css/property.lux
new file mode 100644
index 000000000..b6a97cea4
--- /dev/null
+++ b/stdlib/source/lux/data/format/css/property.lux
@@ -0,0 +1,231 @@
+(.module:
+ [lux (#- All Cursor)
+ [data
+ ["." color (#+ Color)]
+ ["." number]
+ ["." text
+ format]
+ [collection
+ ["." list ("list/." Functor<List> Monoid<List>)]]]
+ [type
+ abstract]
+ ["." macro
+ ["." code]
+ ["s" syntax (#+ syntax:)]]
+ [world
+ [net (#+ URL)]]]
+ [//
+ [value (#+ All
+ Length Thickness Time
+ Location Area
+ Slice
+ Alignment Direction
+ Animation Animation-Fill
+ Column-Fill Column-Span
+ Iteration Count
+ Play
+ Timing Visibility Attachment
+ Blend Span Image
+ Angle Repeat Border
+ Collapse Break Caption
+ Clear
+ Content
+ Cursor
+ Shadow Clip)]])
+
+(syntax: (text-identifier {identifier s.text})
+ (wrap (list (code.local-identifier identifier))))
+
+(abstract: #export (Property brand)
+ {}
+
+ Text
+
+ (def: #export name
+ (-> (Property Any) Text)
+ (|>> :representation))
+
+ (do-template [<brand> <alias>+ <property>+]
+ [(`` (do-template [<alias> <property>]
+ [(def: #export <alias>
+ (Property <brand>)
+ (:abstraction <property>))]
+
+ (~~ (macro.multi <alias>+))))
+
+ (with-expansions [<rows> (macro.multi <property>+)]
+ (do-template [<property>]
+ [(`` (def: #export (~~ (text-identifier <property>))
+ (Property <brand>)
+ (:abstraction <property>)))]
+
+ <rows>))]
+
+ [All
+ []
+ [["all"]]]
+
+ [Length
+ []
+ [["border-image-outset"]
+ ["border-image-width"]
+ ["bottom"]
+ ["column-gap"]
+ ["column-width"]]]
+
+ [Time
+ []
+ [["animation-delay"]
+ ["animation-duration"]]]
+
+ [Slice
+ []
+ [["border-image-slice"]]]
+
+ [Color
+ [[text-color "color"]]
+ [["background-color"]
+ ["border-color"]
+ ["border-bottom-color"]
+ ["border-left-color"]
+ ["border-right-color"]
+ ["border-top-color"]
+ ["caret-color"]
+ ["column-rule-color"]]]
+
+ [Alignment
+ []
+ [["align-content"]
+ ["align-items"]
+ ["align-self"]]]
+
+ [Direction
+ []
+ [["animation-direction"]]]
+
+ [Animation
+ []
+ [["animation-name"]]]
+
+ [Animation-Fill
+ []
+ [["animation-fill-mode"]]]
+
+ [Column-Fill
+ []
+ [["column-fill"]]]
+
+ [Column-Span
+ []
+ [["column-span"]]]
+
+ [Iteration
+ []
+ [["animation-iteration-count"]]]
+
+ [Count
+ []
+ [["column-count"]]]
+
+ [Play
+ []
+ [["animation-play-state"]]]
+
+ [Timing
+ []
+ [["animation-timing-function"]]]
+
+ [Visibility
+ []
+ [["backface-visibility"]]]
+
+ [Attachment
+ []
+ [["background-attachment"]]]
+
+ [Blend
+ []
+ [["background-blend-mode"]]]
+
+ [Image
+ []
+ [["background-image"]
+ ["border-image-source"]]]
+
+ [Span
+ []
+ [["background-clip"]
+ ["background-origin"]
+ ["box-sizing"]]]
+
+ [Location
+ []
+ [["background-position"]]]
+
+ [Repeat
+ []
+ [["background-repeat"]
+ ["border-image-repeat"]]]
+
+ [Area
+ []
+ [["background-size"]
+ ["border-radius"]
+ ["border-bottom-left-radius"]
+ ["border-bottom-right-radius"]
+ ["border-top-left-radius"]
+ ["border-top-right-radius"]
+ ["border-spacing"]]]
+
+ [Border
+ []
+ [["border-style"]
+ ["border-bottom-style"]
+ ["border-left-style"]
+ ["border-right-style"]
+ ["border-top-style"]
+ ["column-rule-style"]]]
+
+ [Thickness
+ []
+ [["border-width"]
+ ["border-bottom-width"]
+ ["border-left-width"]
+ ["border-right-width"]
+ ["border-top-width"]
+ ["column-rule-width"]]]
+
+ [Collapse
+ []
+ [["border-collapse"]]]
+
+ [Break
+ []
+ [["box-decoration-break"]]]
+
+ [Caption
+ []
+ [["caption-side"]]]
+
+ [Clear
+ []
+ [["clear"]]]
+
+ [Shadow
+ []
+ [["box-shadow"]]]
+
+ [Clip
+ []
+ [["clip"]]]
+
+ [Content
+ []
+ [["counter-reset"]
+ ["counter-increment"]]]
+
+ [Cursor
+ []
+ [["cursor"]]]
+ )
+ )
diff --git a/stdlib/source/lux/data/format/css/selector.lux b/stdlib/source/lux/data/format/css/selector.lux
new file mode 100644
index 000000000..f5a33e833
--- /dev/null
+++ b/stdlib/source/lux/data/format/css/selector.lux
@@ -0,0 +1,175 @@
+(.module:
+ [lux (#- and id is? not)
+ [data
+ ["." text
+ format]]
+ [type
+ abstract]
+ [world
+ [internationalization
+ ["." locale (#+ Locale)]]]])
+
+(type: #export Tag Text)
+(type: #export ID Text)
+(type: #export Class Text)
+(type: #export Attribute Text)
+
+(abstract: #export Selector
+ {}
+
+ Text
+
+ (def: #export selector
+ (-> Selector Text)
+ (|>> :representation))
+
+ (def: #export any
+ Selector
+ (:abstraction "*"))
+
+ (def: #export tag
+ (-> Tag Selector)
+ (|>> :abstraction))
+
+ (do-template [<name> <type> <prefix>]
+ [(def: #export <name>
+ (-> <type> Selector)
+ (|>> (format <prefix>) :abstraction))]
+
+ [id ID "#"]
+ [class Class "."]
+ )
+
+ (type: #export Combinator
+ (-> Selector Selector Selector))
+
+ (do-template [<name> <combinator>]
+ [(def: #export (<name> left right)
+ Combinator
+ (:abstraction (format (:representation left)
+ <combinator>
+ (:representation right))))]
+
+ [and ","]
+ [in " "]
+ [sub ">"]
+ [after "+"]
+ [later "~"]
+ )
+
+ (def: #export (with attribute)
+ (-> Attribute Selector)
+ (:abstraction (format "[" attribute "]")))
+
+ (do-template [<name> <check>]
+ [(def: #export (<name> attribute value base)
+ (-> Attribute Text Selector Selector)
+ (:abstraction (format (:representation base) "[" attribute <check> value "]")))]
+
+ [is? "="]
+ [has? "~="]
+ [has-start? "|="]
+ [starts? "^="]
+ [ends? "$="]
+ [contains? "*="]
+ )
+
+ (do-template [<name> <pseudo>]
+ [(def: #export (<name> base)
+ (-> Selector Selector)
+ (:abstraction (format (:representation base) <pseudo>)))]
+
+ [active ":active"]
+ [after! "::after"]
+ [before! "::before"]
+
+ [checked ":checked"]
+ [default ":default"]
+ [disabled ":disabled"]
+ [empty ":empty"]
+ [enabled ":enabled"]
+ [first-child ":first-child"]
+ [first-letter "::first-letter"]
+ [first-line "::first-line"]
+ [first-of-type ":first-of-type"]
+ [focused ":focus"]
+ [hovered ":hover"]
+ [in-range ":in-range"]
+ [indeterminate ":indeterminate"]
+ [invalid ":invalid"]
+ [last-child ":last-child"]
+ [last-of-type ":last-of-type"]
+ [link ":link"]
+ [only-of-type ":only-of-type"]
+ [only-child ":only-child"]
+ [optional ":optional"]
+ [out-of-range ":out-of-range"]
+ [placeholder "::placeholder"]
+ [read-only ":read-only"]
+ [read-write ":read-write"]
+ [required ":required"]
+ [root ":root"]
+ [selection "::selection"]
+ [target ":target"]
+ [valid ":valid"]
+ [visited ":visited"]
+ )
+
+ (def: #export (language locale base)
+ (-> Locale Selector Selector)
+ (|> locale
+ locale.code
+ (text.enclose ["(" ")"])
+ (format (:representation base) ":lang")
+ :abstraction))
+
+ (def: #export not
+ (-> Selector Selector)
+ (|>> :representation
+ (text.enclose ["(" ")"])
+ (format ":not")
+ :abstraction))
+
+ (abstract: #export Index
+ {}
+
+ Text
+
+ (def: #export simple
+ (-> Nat Index)
+ (|>> %n :abstraction))
+
+ (do-template [<name> <index>]
+ [(def: #export <name> Index (:abstraction <index>))]
+
+ [odd "odd"]
+ [even "even"]
+ )
+
+ (type: #export Formula
+ {#constant Int
+ #variable Int})
+
+ (def: #export (formula input)
+ (-> Formula Index)
+ (let [(^slots [#constant #variable]) input]
+ (:abstraction (format (if (i/< +0 variable)
+ (%i variable)
+ (%n (.nat variable)))
+ (%i constant)))))
+
+ (do-template [<name> <pseudo>]
+ [(def: #export (<name> index base)
+ (-> Index Selector Selector)
+ (|> (:representation index)
+ (text.enclose ["(" ")"])
+ (format (:representation Selector base) <pseudo>)
+ (:abstraction Selector)))]
+
+ [nth-child ":nth-child"]
+ [nth-last-child ":nth-last-child"]
+ [nth-last-of-type ":nth-last-of-type"]
+ [nth-of-type ":nth-of-type"]
+ )
+ )
+ )
diff --git a/stdlib/source/lux/data/format/css/value.lux b/stdlib/source/lux/data/format/css/value.lux
new file mode 100644
index 000000000..8f485f429
--- /dev/null
+++ b/stdlib/source/lux/data/format/css/value.lux
@@ -0,0 +1,625 @@
+(.module:
+ [lux (#- All Cursor and)
+ [data
+ ["." color (#+ Color Pigment)]
+ ["." maybe]
+ ["." number]
+ ["." text
+ format]
+ [collection
+ ["." list ("list/." Functor<List>)]]]
+ [type
+ abstract]
+ ["." macro
+ ["." code]
+ ["s" syntax (#+ syntax:)]]
+ [world
+ [net (#+ URL)]]])
+
+(syntax: (text-identifier {identifier s.text})
+ (wrap (list (code.local-identifier identifier))))
+
+(template: (enumeration: <abstraction> <representation> <out> <sample>+)
+ (abstract: #export <abstraction>
+ {}
+
+ <representation>
+
+ (def: #export <out>
+ (-> <abstraction> <representation>)
+ (|>> :representation))
+
+ (`` (do-template [<name> <value>]
+ [(def: #export <name> <abstraction> (:abstraction <value>))]
+
+ (~~ (macro.multi <sample>+))
+ ))))
+
+(template: (multi: <multi> <type> <separator>)
+ (def: #export (<multi> pre post)
+ (-> (Value <type>) (Value <type>) (Value <type>))
+ (:abstraction (format (:representation pre)
+ <separator>
+ (:representation post)))))
+
+(abstract: #export (Value brand)
+ {}
+
+ Text
+
+ (def: #export value
+ (-> (Value Any) Text)
+ (|>> :representation))
+
+ (do-template [<name> <value>]
+ [(def: #export <name> Value (:abstraction <value>))]
+
+ [initial "initial"]
+ [inherit "inherit"]
+ )
+
+ (do-template [<brand> <alias>+ <value>+]
+ [(abstract: #export <brand> {} Any)
+
+ (`` (do-template [<name> <value>]
+ [(def: #export <name>
+ (Value <brand>)
+ (:abstraction <value>))]
+
+ (~~ (macro.multi <alias>+))))
+
+ (with-expansions [<rows> (macro.multi <value>+)]
+ (do-template [<value>]
+ [(`` (def: #export (~~ (text-identifier <value>))
+ (Value <brand>)
+ (:abstraction <value>)))]
+
+ <rows>))]
+
+ [All
+ []
+ [["unset"]]]
+
+ [Length
+ []
+ []]
+
+ [Time
+ []
+ []]
+
+ [Thickness
+ []
+ [["medium"]
+ ["thin"]
+ ["thick"]]]
+
+ [Slice
+ []
+ [["fill"]]]
+
+ [Alignment
+ [[auto-alignment "auto"]]
+ [["stretch"]
+ ["center"]
+ ["flex-start"]
+ ["flex-end"]
+ ["baseline"]
+ ["space-between"]
+ ["space-around"]]]
+
+ [Direction
+ [[normal-direction "normal"]]
+ [["reverse"]
+ ["alternate"]
+ ["alternate-reverse"]]]
+
+ [Animation
+ []
+ []]
+
+ [Animation-Fill
+ [[fill-forwards "forwards"]
+ [fill-backwards "backwards"]
+ [fill-both "both"]]
+ []]
+
+ [Column-Fill
+ []
+ [["balance"]
+ ["auto"]]]
+
+ [Column-Span
+ []
+ [["all"]]]
+
+ [Iteration
+ []
+ [["infinite"]]]
+
+ [Count
+ []
+ []]
+
+ [Play
+ []
+ [["paused"]
+ ["running"]]]
+
+ [Timing
+ []
+ [["linear"]
+ ["ease"]
+ ["ease-in"]
+ ["ease-out"]
+ ["ease-in-out"]
+ ["step-start"]
+ ["step-end"]]]
+
+ [Visibility
+ [[invisible "hidden"]]
+ [["visible"]]]
+
+ [Attachment
+ []
+ [["scroll"]
+ ["fixed"]
+ ["local"]]]
+
+ [Blend
+ [[normal-blend "normal"]]
+ [["multiply"]
+ ["screen"]
+ ["overlay"]
+ ["darken"]
+ ["lighten"]
+ ["color-dodge"]
+ ["saturation"]
+ ["color"]
+ ["luminosity"]]]
+
+ [Span
+ []
+ [["border-box"]
+ ["padding-box"]
+ ["content-box"]]]
+
+ [Image
+ [[no-image "none"]]
+ []]
+
+ [Repeat
+ [[stretch-repeat "stretch"]]
+ [["repeat"]
+ ["repeat-x"]
+ ["repeat-y"]
+ ["no-repeat"]
+ ["space"]
+ ["round"]]]
+
+ [Location
+ [[left-top "left top"]
+ [left-center "left center"]
+ [left-bottom "left bottom"]
+ [right-top "right top"]
+ [right-center "right center"]
+ [right-bottom "right bottom"]
+ [center-top "center top"]
+ [center-center "center center"]
+ [center-bottom "center bottom"]]
+ []]
+
+ [Area
+ []
+ [["cover"]
+ ["contain"]]]
+
+ [Border
+ []
+ [["hidden"]
+ ["dotted"]
+ ["dashed"]
+ ["solid"]
+ ["double"]
+ ["groove"]
+ ["ridge"]
+ ["inset"]
+ ["outset"]]]
+
+ [Collapse
+ []
+ [["separate"]
+ ["collapse"]]]
+
+ [Break
+ []
+ [["slice"]
+ ["clone"]]]
+
+ [Caption
+ []
+ [["top"]
+ ["bottom"]]]
+
+ [Clear
+ [[clear-left "left"]
+ [clear-right "right"]
+ [clear-both "both"]]
+ []]
+
+ [Counter
+ []
+ []]
+
+ [Content
+ []
+ [["open-quote"]
+ ["close-quote"]
+ ["no-open-quote"]
+ ["no-close-quote"]]]
+
+ [Cursor
+ [[horizontal-text "text"]]
+ [["alias"]
+ ["all-scroll"]
+ ["cell"]
+ ["context-menu"]
+ ["col-resize"]
+ ["copy"]
+ ["crosshair"]
+ ["default"]
+ ["e-resize"]
+ ["ew-resize"]
+ ["grab"]
+ ["grabbing"]
+ ["help"]
+ ["move"]
+ ["n-resize"]
+ ["ne-resize"]
+ ["nesw-resize"]
+ ["ns-resize"]
+ ["nw-resize"]
+ ["nwse-resize"]
+ ["no-drop"]
+ ["none"]
+ ["not-allowed"]
+ ["pointer"]
+ ["progress"]
+ ["row-resize"]
+ ["s-resize"]
+ ["se-resize"]
+ ["sw-resize"]
+ ["vertical-text"]
+ ["w-resize"]
+ ["wait"]
+ ["zoom-in"]
+ ["zoom-out"]]]
+
+ [Shadow
+ []
+ []]
+
+ [Clip
+ []
+ []]
+ )
+
+ (def: value-separator ",")
+
+ (def: (apply name inputs)
+ (-> Text (List Text) Value)
+ (|> inputs
+ (text.join-with ..value-separator)
+ (text.enclose ["(" ")"])
+ (format name)
+ :abstraction))
+
+ (enumeration: Step Text
+ step
+ [[start "start"]
+ [end "end"]])
+
+ (def: #export (steps intervals step)
+ (-> Nat Step (Value Timing))
+ (..apply "steps" (list (%n intervals) (..step step))))
+
+ (def: #export (cubic-bezier p0 p1 p2 p3)
+ (-> Frac Frac Frac Frac (Value Timing))
+ (|> (list p0 p1 p2 p3)
+ (list/map %f)
+ (..apply "cubic-bezier")))
+
+ (def: #export iteration
+ (-> Nat (Value Iteration))
+ (|>> %n :abstraction))
+
+ (def: #export count
+ (-> Nat (Value Count))
+ (|>> %n :abstraction))
+
+ (def: #export animation
+ (-> Text (Value Animation))
+ (|>> :abstraction))
+
+ (def: #export (rgb color)
+ (-> Color (Value Color))
+ (let [[red green blue] (color.to-rgb color)]
+ (..apply "rgb" (list (%n red)
+ (%n green)
+ (%n blue)))))
+
+ (def: #export (rgba pigment)
+ (-> Pigment (Value Color))
+ (let [(^slots [#color.color #color.alpha]) pigment
+ [red green blue] (color.to-rgb color)]
+ (..apply "rgba" (list (%n red)
+ (%n green)
+ (%n blue)
+ (if (r/= (:: number.Interval<Rev> top) alpha)
+ "1.0"
+ (format "0" (%r alpha)))))))
+
+ (do-template [<name> <suffix>]
+ [(def: #export (<name> value)
+ (-> Frac (Value Length))
+ (:abstraction (format (%f value) <suffix>)))]
+
+ [em "em"]
+ [ex "ex"]
+ [rem "rem"]
+ [ch "ch"]
+ [vw "vw"]
+ [vh "vh"]
+ [vmin "vmin"]
+ [vmax "vmax"]
+ [% "%"]
+ [cm "cm"]
+ [mm "mm"]
+ [in "in"]
+ [px "px"]
+ [pt "pt"]
+ [pc "pc"]
+ )
+
+ (def: (%int value)
+ (Format Int)
+ (if (i/< +0 value)
+ (%i value)
+ (%n (.nat value))))
+
+ (do-template [<name> <suffix>]
+ [(def: #export (<name> value)
+ (-> Int (Value Time))
+ (:abstraction (format (if (i/< +0 value)
+ (%i value)
+ (%n (.nat value)))
+ <suffix>)))]
+
+
+ [seconds "s"]
+ [milli-seconds "ms"]
+ )
+
+ (def: #export thickness
+ (-> (Value Length) (Value Thickness))
+ (|>> :transmutation))
+
+ (def: #export slice-number/1
+ (-> Nat (Value Slice))
+ (|>> %n :abstraction))
+
+ (def: slice-separator " ")
+
+ (def: #export (slice-number/2 horizontal vertical)
+ (-> Nat Nat (Value Slice))
+ (:abstraction (format (%n horizontal) ..slice-separator
+ (%n vertical))))
+
+ (def: percent-limit Nat (.inc 100))
+
+ (def: (percentage value)
+ (-> Nat Text)
+ (format (%n (n/% percent-limit value)) "%"))
+
+ (def: #export slice-percent/1
+ (-> Nat (Value Slice))
+ (|>> percentage :abstraction))
+
+ (def: #export (slice-percent/2 horizontal vertical)
+ (-> Nat Nat (Value Slice))
+ (:abstraction (format (..percentage horizontal) ..slice-separator
+ (..percentage vertical))))
+
+ (def: length-separator " ")
+
+ (do-template [<name> <type>]
+ [(def: #export (<name> horizontal vertical)
+ (-> (Value Length) (Value Length) (Value <type>))
+ (:abstraction (format (:representation horizontal)
+ ..length-separator
+ (:representation vertical))))]
+
+ [location Location]
+ [area Area]
+ )
+
+ (def: #export (area/1 length)
+ (-> (Value Length) (Value Area))
+ (..area length length))
+
+ (def: #export image
+ (-> URL (Value Image))
+ (|>> %t
+ (list)
+ (..apply "url")))
+
+ (abstract: #export Stop
+ {}
+
+ Text
+
+ (def: #export stop
+ (-> (Value Color) Stop)
+ (|>> (:representation Value) (:abstraction Stop)))
+
+ (def: stop-separator " ")
+
+ (def: #export (single-stop length color)
+ (-> (Value Length) (Value Color) Stop)
+ (:abstraction (format (:representation Value color) ..stop-separator
+ (:representation Value length))))
+
+ (def: #export (double-stop start end color)
+ (-> (Value Length) (Value Length) (Value Color) Stop)
+ (:abstraction (format (:representation Value color) ..stop-separator
+ (:representation Value start) ..stop-separator
+ (:representation Value end))))
+
+ (abstract: #export Hint
+ {}
+
+ Text
+
+ (def: #export hint
+ (-> (Value Length) Hint)
+ (|>> (:representation Value) (:abstraction Hint)))
+
+ (def: (with-hint [hint stop])
+ (-> [(Maybe Hint) Stop] Text)
+ (case hint
+ #.None
+ (:representation Stop stop)
+
+ (#.Some hint)
+ (format (:representation Hint hint) ..value-separator (:representation Stop stop))))))
+
+ (type: #export (List/1 a)
+ [a (List a)])
+
+ (abstract: #export Angle
+ {}
+
+ Text
+
+ (def: #export (turn value)
+ (-> Rev Angle)
+ (:abstraction (format (%r value) "turn")))
+
+ (def: degree-limit Nat 360)
+
+ (def: #export (degree value)
+ (-> Nat Angle)
+ (:abstraction (format (%n (n/% ..degree-limit value)) "deg")))
+
+ (do-template [<name> <degree>]
+ [(def: #export <name> Angle (..degree <degree>))]
+
+ [to-top 0]
+ [to-right 90]
+ [to-bottom 180]
+ [to-left 270]
+ )
+
+ (do-template [<name> <function>]
+ [(def: #export (<name> angle start next)
+ (-> Angle Stop (List/1 [(Maybe Hint) Stop]) (Value Image))
+ (let [[now after] next]
+ (..apply <function> (list& (:representation Angle angle)
+ (with-hint now)
+ (list/map with-hint after)))))]
+
+ [linear-gradient "linear-gradient"]
+ [repeating-linear-gradient "repeating-linear-gradient"]
+ )
+ )
+
+ (enumeration: Shape Text
+ shape
+ [[ellipse "ellipse"]
+ [circle "circle"]])
+
+ (enumeration: Extent Text
+ extent
+ [[closest-side "closest-side"]
+ [closest-corner "closest-corner"]
+ [farthest-side "farthest-side"]
+ [farthest-corner "farthest-corner"]])
+
+ (do-template [<name> <function>]
+ [(def: #export (<name> shape extent location start next)
+ (-> Shape (Maybe Extent) (Value Location)
+ Stop (List/1 [(Maybe Hint) Stop])
+ (Value Image))
+ (let [after-extent (format "at " (:representation location))
+ with-extent (case extent
+ (#.Some extent)
+ (format (..extent extent) " " after-extent)
+
+ #.None
+ after-extent)
+ where (format (..shape shape) " " with-extent)
+ [now after] next]
+ (..apply <function> (list& (..shape shape)
+ (with-hint now)
+ (list/map with-hint after)))))]
+
+ [radial-gradient "radial-gradient"]
+ [repeating-radial-gradient "repeating-radial-gradient"]
+ )
+
+ (def: default-length (px +0.0))
+
+ (def: #export (shadow horizontal vertical blur spread color inset?)
+ (-> (Value Length) (Value Length)
+ (Maybe (Value Length)) (Maybe (Value Length))
+ (Value Color) Bit
+ (Value Shadow))
+ (let [with-inset (if inset?
+ (list "inset")
+ (list))]
+ (|> (list& (:representation horizontal)
+ (:representation vertical)
+ (|> blur (maybe.default ..default-length) :representation)
+ (|> spread (maybe.default ..default-length) :representation)
+ (:representation color)
+ with-inset)
+ (text.join-with " ")
+ :abstraction)))
+
+ (type: #export Rectangle
+ {#top (Value Length)
+ #right (Value Length)
+ #bottom (Value Length)
+ #left (Value Length)})
+
+ (def: #export (clip rectangle)
+ (-> Rectangle (Value Clip))
+ (`` (..apply "rect" (list (~~ (do-template [<side>]
+ [(:representation (get@ <side> rectangle))]
+
+ [#top] [#right] [#bottom] [#left]))))))
+
+ (def: #export counter
+ (-> Text (Value Counter))
+ (|>> :abstraction))
+
+ (def: #export current-count
+ (-> (Value Counter) (Value Content))
+ (|>> :representation (list) (..apply "counter")))
+
+ (def: #export text
+ (-> Text (Value Content))
+ (|>> %t :abstraction))
+
+ (def: #export attribute
+ (-> Text (Value Content))
+ (|>> (list) (..apply "attr")))
+
+ (def: #export media
+ (-> URL (Value Content))
+ (|>> (list) (..apply "url")))
+
+ (multi: multi-image Image ",")
+ (multi: multi-shadow Shadow ",")
+ (multi: multi-content Content " ")
+ )
diff --git a/stdlib/source/lux/data/format/html.lux b/stdlib/source/lux/data/format/html.lux
index 7eb26bf5a..4adb63b7a 100644
--- a/stdlib/source/lux/data/format/html.lux
+++ b/stdlib/source/lux/data/format/html.lux
@@ -13,12 +13,13 @@
[world
[net (#+ URL)]]]
[//
- ["." css (#+ CSS)]
+ ["." css (#+ CSS)
+ ["." selector]]
["." xml (#+ XML)]])
-(type: #export Tag Text)
-
-(type: #export ID Text)
+(type: #export Tag selector.Tag)
+(type: #export ID selector.ID)
+(type: #export Class selector.Class)
(type: #export Attributes
{#.doc "Attributes for an HTML tag."}
diff --git a/stdlib/source/lux/data/text/encoding.lux b/stdlib/source/lux/data/text/encoding.lux
index 6e617e75b..00b5b719b 100644
--- a/stdlib/source/lux/data/text/encoding.lux
+++ b/stdlib/source/lux/data/text/encoding.lux
@@ -15,13 +15,13 @@
## https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html
-(abstract: #export Char-Set
+(abstract: #export Encoding
{}
Text
- (do-template [<name> <charset>]
- [(def: #export <name> Char-Set (:abstraction <charset>))]
+ (do-template [<name> <encoding>]
+ [(def: #export <name> Encoding (:abstraction <encoding>))]
[ascii "ASCII"]
@@ -169,7 +169,7 @@
)
(def: #export name
- (-> Char-Set Text)
+ (-> Encoding Text)
(|>> :representation))
)
diff --git a/stdlib/source/lux/type/abstract.lux b/stdlib/source/lux/type/abstract.lux
index a8be42a00..ccb6b9e18 100644
--- a/stdlib/source/lux/type/abstract.lux
+++ b/stdlib/source/lux/type/abstract.lux
@@ -196,6 +196,9 @@
primitives
(list (` ((~! ..pop!)))))))))
+(syntax: #export (:transmutation value)
+ (wrap (list (` (..:abstraction (..:representation (~ value)))))))
+
(syntax: #export (^:representation {name (s.form s.local-identifier)}
body
{branches (p.some s.any)})
diff --git a/stdlib/source/lux/type/quotient.lux b/stdlib/source/lux/type/quotient.lux
index 994383744..46f485720 100644
--- a/stdlib/source/lux/type/quotient.lux
+++ b/stdlib/source/lux/type/quotient.lux
@@ -22,31 +22,27 @@
(-> (-> t c) (Class t c q))))
(|>> :abstraction))
- (def: expose
- (All [t c q] (-> (Class t c q) (-> t c)))
- (|>> :representation))
- )
-
-(abstract: #export (Quotient t c q)
- {}
+ (abstract: #export (Quotient t c q)
+ {}
- {#value t
- #label c}
+ {#value t
+ #label c}
- (def: #export (quotient class value)
- (All [t c q]
- (-> (Class t c q) t
- (Quotient t c q)))
- (:abstraction {#value value
- #label ((expose class) value)}))
+ (def: #export (quotient class value)
+ (All [t c q]
+ (-> (Class t c q) t
+ (Quotient t c q)))
+ (:abstraction {#value value
+ #label ((:representation Class class) value)}))
- (do-template [<name> <output> <slot>]
- [(def: #export <name>
- (All [t c q] (-> (Quotient t c q) <output>))
- (|>> :representation (get@ <slot>)))]
+ (do-template [<name> <output> <slot>]
+ [(def: #export <name>
+ (All [t c q] (-> (Quotient t c q) <output>))
+ (|>> :representation (get@ <slot>)))]
- [value t #value]
- [label c #label]
+ [value t #value]
+ [label c #label]
+ )
)
)
diff --git a/stdlib/source/lux/world/internationalization/language.lux b/stdlib/source/lux/world/internationalization/language.lux
index 97a5f7463..3075eba16 100644
--- a/stdlib/source/lux/world/internationalization/language.lux
+++ b/stdlib/source/lux/world/internationalization/language.lux
@@ -1,5 +1,10 @@
(.module:
[lux #*
+ [control
+ [equivalence (#+ Equivalence)]
+ [hash (#+ Hash)]]
+ [data
+ ["." text]]
[type
abstract]
["." macro]])
@@ -509,4 +514,15 @@
["zun" zuni []]
["zza" zaza [[dimili] [dimli] [kirdki] [kirmanjki] [zazaki]]]
)
+
+ (structure: #export _ (Equivalence Language)
+ (def: (= reference sample)
+ (is? reference sample)))
+
+ (structure: #export _ (Hash Language)
+ (def: eq Equivalence<Language>)
+
+ (def: hash
+ (|>> :representation
+ (:: text.Hash<Text> hash))))
)
diff --git a/stdlib/source/lux/world/internationalization/locale.lux b/stdlib/source/lux/world/internationalization/locale.lux
index b37c9be5c..3c63f4dca 100644
--- a/stdlib/source/lux/world/internationalization/locale.lux
+++ b/stdlib/source/lux/world/internationalization/locale.lux
@@ -1,9 +1,12 @@
(.module:
[lux #*
+ [control
+ [equivalence (#+ Equivalence)]
+ [hash (#+ Hash)]]
[data
- [text
+ ["." text
format
- ["." encoding (#+ Char-Set)]]]
+ ["." encoding (#+ Encoding)]]]
[type
abstract]
["." macro]]
@@ -17,10 +20,10 @@
Text
(def: territory-separator "_")
- (def: char-set-separator ".")
+ (def: encoding-separator ".")
- (def: #export (locale language territory char-set)
- (-> Language (Maybe Territory) (Maybe Char-Set) Locale)
+ (def: #export (locale language territory encoding)
+ (-> Language (Maybe Territory) (Maybe Encoding) Locale)
(:abstraction (format (language.language language)
(case territory
(#.Some territory)
@@ -28,9 +31,9 @@
#.None
"")
- (case char-set
- (#.Some char-set)
- (format ..char-set-separator (encoding.name char-set))
+ (case encoding
+ (#.Some encoding)
+ (format ..encoding-separator (encoding.name encoding))
#.None
""))))
@@ -38,4 +41,15 @@
(def: #export code
(-> Locale Text)
(|>> :representation))
+
+ (structure: #export _ (Equivalence Locale)
+ (def: (= reference sample)
+ (:: text.Equivalence<Text> = (:representation reference) (:representation sample))))
+
+ (structure: #export _ (Hash Locale)
+ (def: eq Equivalence<Locale>)
+
+ (def: hash
+ (|>> :representation
+ (:: text.Hash<Text> hash))))
)
diff --git a/stdlib/source/lux/world/internationalization/territory.lux b/stdlib/source/lux/world/internationalization/territory.lux
index 9094fcae6..ece06b9d6 100644
--- a/stdlib/source/lux/world/internationalization/territory.lux
+++ b/stdlib/source/lux/world/internationalization/territory.lux
@@ -1,9 +1,10 @@
(.module:
[lux #*
+ [control
+ [equivalence (#+ Equivalence)]
+ [hash (#+ Hash)]]
[data
- [text
- format
- ["." encoding (#+ Char-Set)]]]
+ ["." text]]
[type
abstract]
["." macro]])
@@ -292,4 +293,16 @@
["ZM" "ZMB" 894 "Zambia" zambia []]
["ZW" "ZWE" 716 "Zimbabwe" zimbabwe []]
)
+
+ (structure: #export _ (Equivalence Territory)
+ (def: (= reference sample)
+ (is? reference sample)))
+
+ (structure: #export _ (Hash Territory)
+ (def: eq Equivalence<Territory>)
+
+ (def: hash
+ (|>> :representation
+ (get@ #long)
+ (:: text.Hash<Text> hash))))
)
diff --git a/stdlib/test/tests.lux b/stdlib/test/tests.lux
index 6d99d905a..4a6036842 100644
--- a/stdlib/test/tests.lux
+++ b/stdlib/test/tests.lux
@@ -2,7 +2,15 @@
[lux #*
[cli (#+ program:)]
["." test]
+
+ ## These modules do not need to be tested.
+ [type
+ [variance (#+)]]
+
## TODO: Test these modules
+ [data
+ [format
+ [css (#+)]]]
## [control
## ["._" contract]
## ["._" concatenative]