diff options
Diffstat (limited to 'stdlib/source/library/lux/web/css')
-rw-r--r-- | stdlib/source/library/lux/web/css/class.lux | 34 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/font.lux | 24 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/id.lux | 34 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/property.lux | 517 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/query.lux | 135 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/selector.lux | 213 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/style.lux | 39 | ||||
-rw-r--r-- | stdlib/source/library/lux/web/css/value.lux | 1422 |
8 files changed, 2418 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/web/css/class.lux b/stdlib/source/library/lux/web/css/class.lux new file mode 100644 index 000000000..46e980a47 --- /dev/null +++ b/stdlib/source/library/lux/web/css/class.lux @@ -0,0 +1,34 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [data + ["[0]" text (.use "[1]#[0]" hash) + ["%" \\format (.only format)]]] + ["[0]" meta (.only) + ["[0]" code] + [macro + [syntax (.only syntax)]] + [type + ["[0]" nominal (.except def)]]]]]) + +(nominal.def .public Class + Text + + (def .public class + (-> Class Text) + (|>> representation)) + + (def .public custom + (-> Text Class) + (|>> abstraction)) + + (def .public generic + (syntax (_ []) + (do meta.monad + [module meta.current_module_name + class meta.seed] + (in (list (` (..custom (, (code.text (format "c" (%.nat_16 class) + "_" (%.nat_16 (text#hash module)))))))))))) + ) diff --git a/stdlib/source/library/lux/web/css/font.lux b/stdlib/source/library/lux/web/css/font.lux new file mode 100644 index 000000000..f69a8f602 --- /dev/null +++ b/stdlib/source/library/lux/web/css/font.lux @@ -0,0 +1,24 @@ +(.require + [library + [lux (.except #source) + [meta + [code + ["s" \\parser]]] + [world + [net (.only URL)]]]] + ["[0]" // + ["[1][0]" value (.only Value Font_Stretch Font_Style Font_Weight)]]) + +(type .public Unicode_Range + (Record + [#start Nat + #end Nat])) + +(type .public Font + (Record + [#family Text + #source URL + #stretch (Maybe (Value Font_Stretch)) + #style (Maybe (Value Font_Style)) + #weight (Maybe (Value Font_Weight)) + #unicode_range (Maybe Unicode_Range)])) diff --git a/stdlib/source/library/lux/web/css/id.lux b/stdlib/source/library/lux/web/css/id.lux new file mode 100644 index 000000000..fc93ec1bb --- /dev/null +++ b/stdlib/source/library/lux/web/css/id.lux @@ -0,0 +1,34 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [data + ["[0]" text (.use "[1]#[0]" hash) + ["%" \\format (.only format)]]] + ["[0]" meta (.only) + ["[0]" code] + [macro + [syntax (.only syntax)]] + [type + ["[0]" nominal (.except def)]]]]]) + +(nominal.def .public ID + Text + + (def .public id + (-> ID Text) + (|>> representation)) + + (def .public custom + (-> Text ID) + (|>> abstraction)) + + (def .public generic + (syntax (_ []) + (do meta.monad + [module meta.current_module_name + id meta.seed] + (in (list (` (..custom (, (code.text (format "i" (%.nat_16 id) + "_" (%.nat_16 (text#hash module)))))))))))) + ) diff --git a/stdlib/source/library/lux/web/css/property.lux b/stdlib/source/library/lux/web/css/property.lux new file mode 100644 index 000000000..192f0395a --- /dev/null +++ b/stdlib/source/library/lux/web/css/property.lux @@ -0,0 +1,517 @@ +(.require + [library + [lux (.except All Location all left right) + [data + ["[0]" text]] + [meta + ["[0]" code (.only) + ["s" \\parser]] + [macro + [syntax (.only syntax)] + ["[0]" template]] + [type + ["[0]" nominal (.except def)]]]]] + [// + [value (.only All + Number + Length Thickness Time + Color + Location Fit + Slice + Alignment Animation_Direction + Animation Animation_Fill + Column_Fill Column_Span + Iteration Count + Play + Timing Visibility Attachment + Blend Span Image + Angle Repeat Border + Collapse Box_Decoration_Break Caption + Float Clear + Content + Cursor + Shadow Clip + Text_Direction + Display Empty + Filter + Flex_Direction Flex_Wrap + Font Font_Kerning Font_Size Font_Stretch Font_Style Font_Weight Font_Variant + Grid Grid_Content Grid_Flow Grid_Span Grid_Template + Hanging_Punctuation Hyphens Isolation + List_Style_Position List_Style_Type + Overflow Page_Break Pointer_Events + Position + Quotes + Resize Scroll_Behavior Table_Layout + Text_Align Text_Align_Last + Text_Decoration_Line Text_Decoration_Style + Text_Justification Text_Overflow Text_Transform + Transform Transform_Origin Transform_Style + Transition + Bidi User_Select + Vertical_Align + White_Space Word_Break Word_Wrap Writing_Mode + Z_Index)]]) + +(def text_symbol + (syntax (_ [symbol s.text]) + (in (list (code.local (text.replaced "-" "_" symbol)))))) + +(nominal.def .public (Property brand) + Text + + (def .public name + (-> (Property Any) Text) + (|>> representation)) + + (with_template [<brand> <alias>+ <property>+] + [(`` (with_template [<alias> <property>] + [(def .public <alias> + (Property <brand>) + (abstraction <property>))] + + (,, (template.spliced <alias>+)))) + + (with_expansions [<rows> (template.spliced <property>+)] + (with_template [<property>] + [(`` (def .public (,, (text_symbol <property>)) + (Property <brand>) + (abstraction <property>)))] + + <rows>))] + + [All + [] + [["all"]]] + + [Length + [] + [["border-image-outset"] + ["border-image-width"] + ["bottom"] + ["column-gap"] + ["column-width"] + ["flex-basis"] + ["grid-column-gap"] + ["grid-gap"] + ["grid-row-gap"] + ["height"] + ["left"] + ["letter-spacing"] + ["line-height"] + ["margin"] + ["margin-bottom"] + ["margin-left"] + ["margin-right"] + ["margin-top"] + ["max-height"] + ["max-width"] + ["min-height"] + ["min-width"] + ["outline-offset"] + ["padding"] + ["padding-bottom"] + ["padding-left"] + ["padding-right"] + ["padding-top"] + ["perspective"] + ["right"] + ["text-indent"] + ["top"] + ["width"] + ["word-spacing"]]] + + [Time + [] + [["animation-delay"] + ["animation-duration"] + ["transition-delay"] + ["transition-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"] + ["outline-color"] + ["text-decoration-color"]]] + + [Alignment + [] + [["align-content"] + ["align-items"] + ["align-self"] + ["justify-content"]]] + + [Animation + [] + [["animation-name"]]] + + [Animation_Direction + [] + [["animation-direction"]]] + + [Animation_Fill + [] + [["animation-fill-mode"]]] + + [Column_Fill + [] + [["column-fill"]]] + + [Column_Span + [] + [["column-span"]]] + + [Iteration + [] + [["animation-iteration-count"]]] + + [Count + [] + [["column-count"] + ["flex-grow"] + ["flex-shrink"] + ["order"] + ["tab-size"]]] + + [Play + [] + [["animation-play-state"]]] + + [Timing + [] + [["animation-timing-function"] + ["transition-timing-function"]]] + + [Visibility + [] + [["backface-visibility"] + ["visibility"]]] + + [Attachment + [] + [["background-attachment"]]] + + [Blend + [] + [["background-blend-mode"] + ["mix-blend-mode"]]] + + [Image + [] + [["background-image"] + ["border-image-source"] + ["list-style-image"]]] + + [Span + [] + [["background-clip"] + ["background-origin"] + ["box-sizing"]]] + + [Location + [] + [["background-position"] + ["object-position"] + ["perspective-origin"]]] + + [Repeat + [] + [["background-repeat"] + ["border-image-repeat"]]] + + [Fit + [] + [["background-size"] + ["border-radius"] + ["border-bottom-left-radius"] + ["border-bottom-right-radius"] + ["border-top-left-radius"] + ["border-top-right-radius"] + ["border-spacing"] + ["object-fit"]]] + + [Border + [] + [["border-style"] + ["border-bottom-style"] + ["border-left-style"] + ["border-right-style"] + ["border-top-style"] + ["column-rule-style"] + ["outline-style"]]] + + [Thickness + [] + [["border-width"] + ["border-bottom-width"] + ["border-left-width"] + ["border-right-width"] + ["border-top-width"] + ["column-rule-width"] + ["outline-width"]]] + + [Collapse + [] + [["border-collapse"]]] + + [Box_Decoration_Break + [] + [["box-decoration-break"]]] + + [Caption + [] + [["caption-side"]]] + + [Clear + [] + [["clear"]]] + + [Shadow + [] + [["box-shadow"] + ["text-shadow"]]] + + [Clip + [] + [["clip"]]] + + [Content + [] + [["counter-reset"] + ["counter-increment"]]] + + [Cursor + [] + [["cursor"]]] + + [Text_Direction + [[text_direction "direction"]] + []] + + [Display + [] + [["display"]]] + + [Empty + [] + [["empty-cells"]]] + + [Filter + [] + [["filter"]]] + + [Flex_Direction + [] + [["flex-direction"]]] + + [Flex_Wrap + [] + [["flex-wrap"]]] + + [Float + [] + [["float"]]] + + [Font + [] + [["font-family"]]] + + [Font_Kerning + [] + [["font-kerning"]]] + + [Font_Size + [] + [["font-size"]]] + + [Font_Stretch + [] + [["font-stretch"]]] + + [Font_Style + [] + [["font-style"]]] + + [Font_Weight + [] + [["font-weight"]]] + + [Font_Variant + [] + [["font-variant"]]] + + [Grid + [] + [["grid-area"]]] + + [Grid_Content + [] + [["grid-auto-columns"] + ["grid-auto-rows"] + ["grid-template-columns"] + ["grid-template-rows"]]] + + [Grid_Flow + [] + [["grid-auto-flow"]]] + + [Grid_Span + [] + [["grid-column-end"] + ["grid-column-start"] + ["grid-row-end"] + ["grid-row-start"]]] + + [Grid_Template + [] + [["grid-template-areas"]]] + + [Hanging_Punctuation + [] + [["hanging-punctuation"]]] + + [Hyphens + [] + [["hyphens"]]] + + [Isolation + [] + [["isolation"]]] + + [List_Style_Position + [] + [["list-style-position"]]] + + [List_Style_Type + [] + [["list-style-type"]]] + + [Number + [] + [["font-size-adjust"] + ["opacity"]]] + + [Overflow + [] + [["overflow"] + ["overflow-x"] + ["overflow-y"]]] + + [Page_Break + [] + [["page-break-after"] + ["page-break-before"] + ["page-break-inside"]]] + + [Pointer_Events + [] + [["pointer-events"]]] + + [Position + [] + [["position"]]] + + [Quotes + [] + [["quotes"]]] + + [Resize + [] + [["resize"]]] + + [Scroll_Behavior + [] + [["scroll-behavior"]]] + + [Table_Layout + [] + [["table-layout"]]] + + [Text_Align + [] + [["text-align"]]] + + [Text_Align_Last + [] + [["text-align-last"]]] + + [Text_Decoration_Line + [] + [["text-decoration-line"]]] + + [Text_Decoration_Style + [] + [["text-decoration-style"]]] + + [Text_Justification + [] + [["text-justify"]]] + + [Text_Overflow + [] + [["text-overflow"]]] + + [Text_Transform + [] + [["text-transform"]]] + + [Transform + [] + [["transform"]]] + + [Transform_Origin + [] + [["transform-origin"]]] + + [Transform_Style + [] + [["transform-style"]]] + + [Transition + [] + [["transition-property"]]] + + [Bidi + [] + [["unicode-bidi"]]] + + [User_Select + [] + [["user-select"]]] + + [Vertical_Align + [] + [["vertical-align"]]] + + [White_Space + [] + [["white-space"]]] + + [Word_Break + [] + [["word-break"]]] + + [Word_Wrap + [] + [["word-wrap"]]] + + [Writing_Mode + [] + [["writing-mode"]]] + + [Z_Index + [] + [["z-index"]]] + ) + ) diff --git a/stdlib/source/library/lux/web/css/query.lux b/stdlib/source/library/lux/web/css/query.lux new file mode 100644 index 000000000..de3defe3b --- /dev/null +++ b/stdlib/source/library/lux/web/css/query.lux @@ -0,0 +1,135 @@ +(.require + [library + [lux (.except and or not all only except) + [data + ["[0]" text (.only) + ["%" \\format (.only format)]]] + [meta + ["[0]" code (.only) + ["s" \\parser]] + [macro + [syntax (.only syntax)] + ["[0]" template]] + [type + ["[0]" nominal (.except def)]]]]] + ["[0]" // + ["[1][0]" value (.only Value Length Count Resolution Ratio + Orientation Scan Boolean Update + Block_Overflow Inline_Overflow + Display_Mode Color_Gamut Inverted_Colors + Pointer Hover + Light Scripting Motion Color_Scheme)]]) + +(def text_symbol + (syntax (_ [symbol s.text]) + (in (list (code.local (text.replaced "-" "_" symbol)))))) + +(nominal.def .public Media + Text + + (def .public media + (-> Media Text) + (|>> representation)) + + (with_template [<media>] + [(`` (def .public (,, (text_symbol <media>)) + Media + (abstraction <media>)))] + + ["all"] + ["print"] + ["screen"] + ["speech"] + )) + +(nominal.def .public Feature + Text + + (def .public feature + (-> Feature Text) + (|>> representation)) + + (with_template [<feature> <brand>] + [(`` (def .public ((,, (text_symbol <feature>)) input) + (-> (Value <brand>) Feature) + (abstraction (format "(" <feature> ": " (//value.value input) ")"))))] + + ["min-color" Count] + ["color" Count] + ["max-color" Count] + + ["min-color-index" Count] + ["color-index" Count] + ["max-color-index" Count] + + ["min-monochrome" Count] + ["monochrome" Count] + ["max-monochrome" Count] + + ["min-height" Length] + ["height" Length] + ["max-height" Length] + + ["min-width" Length] + ["width" Length] + ["max-width" Length] + + ["min-resolution" Resolution] + ["resolution" Resolution] + ["max-resolution" Resolution] + + ["aspect-ratio" Ratio] + ["max-aspect-ratio" Ratio] + ["min-aspect-ratio" Ratio] + + ["display-mode" Display_Mode] + ["color-gamut" Color_Gamut] + ["grid" Boolean] + ["orientation" Orientation] + ["overflow-block" Block_Overflow] + ["overflow-inline" Inline_Overflow] + ["scan" Scan] + ["update" Update] + ["inverted-colors" Inverted_Colors] + ["pointer" Pointer] + ["any-pointer" Pointer] + ["hover" Hover] + ["any-hover" Hover] + ["light-level" Light] + ["scripting" Scripting] + ["prefers-reduced-motion" Motion] + ["prefers-color-scheme" Color_Scheme] + ) + ) + +(nominal.def .public Query + Text + + (def .public query + (-> Query Text) + (|>> representation)) + + (with_template [<name> <operator>] + [(def .public <name> + (-> Media Query) + (|>> ..media (format <operator>) abstraction))] + + [except "not "] + [only "only "] + ) + + (def .public not + (-> Feature Query) + (|>> ..feature (format "not ") abstraction)) + + (with_template [<name> <operator>] + [(def .public (<name> left right) + (-> Query Query Query) + (abstraction (format (representation left) + <operator> + (representation right))))] + + [and " and "] + [or " or "] + ) + ) diff --git a/stdlib/source/library/lux/web/css/selector.lux b/stdlib/source/library/lux/web/css/selector.lux new file mode 100644 index 000000000..292e27300 --- /dev/null +++ b/stdlib/source/library/lux/web/css/selector.lux @@ -0,0 +1,213 @@ +(.require + [library + [lux (.except Label Tag or and for same? not) + [data + ["[0]" text (.only) + ["%" \\format (.only format)]]] + [math + [number + ["i" int]]] + [meta + [macro + ["[0]" template]] + [type + ["[0]" nominal (.except def)]]] + [world + ["[0]" locale (.only Locale)]]]] + ["[0]" // + ["[1][0]" id (.only ID)] + ["[1][0]" class (.only Class)]]) + +(type .public Label Text) + +(type .public Tag Label) +(type .public Attribute Label) + +(nominal.def .public (Generic brand) Any) + +(with_template [<generic> <brand>] + [(nominal.def <brand> Any) + (type .public <generic> (Generic <brand>))] + + [Can_Chain Can_Chain'] + [Cannot_Chain Cannot_Chain'] + ) + +(nominal.def .public Unique Any) +(nominal.def .public Specific Any) +(nominal.def .public Composite Any) + +(nominal.def .public (Selector kind) + Text + + (def .public selector + (-> (Selector Any) Text) + (|>> representation)) + + (def .public any + (Selector Cannot_Chain) + (abstraction "*")) + + (def .public tag + (-> Tag (Selector Cannot_Chain)) + (|>> abstraction)) + + (with_template [<name> <type> <prefix> <kind> <out>] + [(def .public <name> + (-> <type> (Selector <kind>)) + (|>> <out> (format <prefix>) abstraction))] + + [id ID "#" Unique //id.id] + [class Class "." Can_Chain //class.class] + ) + + (with_template [<right> <left> <combinator>+] + [(`` (with_template [<combinator> <name>] + [(def .public (<name> right left) + (-> (Selector <right>) (Selector <left>) (Selector Composite)) + (abstraction (format (representation left) + <combinator> + (representation right))))] + + (,, (template.spliced <combinator>+))))] + + [Can_Chain (Generic Any) + [["" and]]] + [Specific (Generic Any) + [["" at]]] + [Unique (Generic Any) + [["" for]]] + [Any Any + [["," or] + [" " in] + [">" sub] + ["+" next] + ["~" later]]] + ) + + (type .public (Specializer kind) + (-> (Selector kind) (Selector (Generic Any)) (Selector Composite))) + + (type .public Combinator + (-> (Selector Any) (Selector Any) (Selector Composite))) + + (def .public (with? attribute) + (-> Attribute (Selector Can_Chain)) + (abstraction (format "[" attribute "]"))) + + (with_template [<check> <name>] + [(def .public (<name> attribute value) + (-> Attribute Text (Selector Can_Chain)) + (abstraction (format "[" attribute <check> value "]")))] + + ["=" same?] + ["~=" has?] + ["|=" has_start?] + ["^=" starts?] + ["$=" ends?] + ["*=" contains?] + ) + + (with_template [<kind> <pseudo>+] + [(`` (with_template [<name> <pseudo>] + [(def .public <name> + (Selector <kind>) + (abstraction <pseudo>))] + + (,, (template.spliced <pseudo>+))))] + + [Can_Chain + [[active ":active"] + [checked ":checked"] + [default ":default"] + [disabled ":disabled"] + [empty ":empty"] + [enabled ":enabled"] + [first_child ":first-child"] + [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"] + [read_only ":read-only"] + [read_write ":read-write"] + [required ":required"] + [root ":root"] + [target ":target"] + [valid ":valid"] + [visited ":visited"]]] + + [Specific + [[after "::after"] + [before "::before"] + [first_letter "::first-letter"] + [first_line "::first-line"] + [placeholder "::placeholder"] + [selection "::selection"]]] + ) + + (def .public (language locale) + (-> Locale (Selector Can_Chain)) + (|> locale + locale.code + (text.enclosed ["(" ")"]) + (format ":lang") + abstraction)) + + (def .public not + (-> (Selector Any) (Selector Can_Chain)) + (|>> representation + (text.enclosed ["(" ")"]) + (format ":not") + abstraction)) + + (nominal.def .public Index + Text + + (def .public index + (-> Nat Index) + (|>> %.nat abstraction)) + + (with_template [<name> <index>] + [(def .public <name> Index (abstraction <index>))] + + [odd "odd"] + [even "even"] + ) + + (type .public Formula + (Record + [#constant Int + #variable Int])) + + (def .public (formula input) + (-> Formula Index) + (let [(open "_[0]") input] + (abstraction (format (if (i.< +0 _#variable) + (%.int _#variable) + (%.nat (.nat _#variable))) + (%.int _#constant))))) + + (with_template [<name> <pseudo>] + [(def .public (<name> index) + (-> Index (Selector Can_Chain)) + (|> (representation index) + (text.enclosed ["(" ")"]) + (format <pseudo>) + (abstraction Selector)))] + + [nth_child ":nth-child"] + [nth_last_child ":nth-last-child"] + [nth_of_type ":nth-of-type"] + [nth_last_of_type ":nth-last-of-type"] + ) + ) + ) diff --git a/stdlib/source/library/lux/web/css/style.lux b/stdlib/source/library/lux/web/css/style.lux new file mode 100644 index 000000000..d1bd1899d --- /dev/null +++ b/stdlib/source/library/lux/web/css/style.lux @@ -0,0 +1,39 @@ +(.require + [library + [lux (.except with) + [data + [text + ["%" \\format (.only format)]] + [collection + ["[0]" list (.use "[1]#[0]" mix)]]] + [meta + [type + ["[0]" nominal (.except def)]]]]] + ["[0]" // + ["[1][0]" value (.only Value)] + ["[1][0]" property (.only Property)]]) + +(nominal.def .public Style + Text + + (def .public empty + Style + (abstraction "")) + + (def .public (with [property value]) + (All (_ brand) + (-> [(Property brand) (Value brand)] + (-> Style Style))) + (|>> representation + (format (//property.name property) ": " (//value.value value) ";") + abstraction)) + + (def .public inline + (-> Style Text) + (|>> representation)) + + (def .public (style config) + (-> (List (Ex (_ brand) [(Property brand) (Value brand)])) + Style) + (list#mix ..with ..empty config)) + ) diff --git a/stdlib/source/library/lux/web/css/value.lux b/stdlib/source/library/lux/web/css/value.lux new file mode 100644 index 000000000..37c8580a0 --- /dev/null +++ b/stdlib/source/library/lux/web/css/value.lux @@ -0,0 +1,1422 @@ +(.require + [library + [lux (.except Label All Location and static false true all) + [control + ["[0]" maybe]] + [data + ["[0]" product] + ["[0]" color (.only) + [pigment (.only Pigment)] + ["[0]" rgb]] + ["[0]" text (.only) + ["%" \\format (.only Format format)]] + [collection + ["[0]" list (.use "[1]#[0]" functor)]]] + [math + [number + ["n" nat] + ["i" int] + ["r" rev] + ["f" frac]]] + [meta + ["[0]" code (.only) + ["<[1]>" \\parser]] + [macro + [syntax (.only syntax)] + ["[0]" template]] + [type + ["[0]" nominal (.except def)]]] + [world + [net (.only URL)]]]] + [// + [selector (.only Label)]]) + +(def text_symbol + (syntax (_ [symbol <code>.text]) + (in (list (code.local (text.replaced "-" "_" symbol)))))) + +(def enumeration + (template (_ <abstraction> <representation> <out> <sample>+ <definition>+) + [(nominal.def .public <abstraction> + <representation> + + (def .public <out> + (-> <abstraction> <representation>) + (|>> representation)) + + (`` (with_template [<name> <value>] + [(def .public <name> <abstraction> (abstraction <value>))] + + (,, (template.spliced <sample>+)) + )) + + (template.spliced <definition>+))])) + +(def (%number value) + (Format Frac) + (let [raw (%.frac value)] + (if (f.< +0.0 value) + raw + (|> raw (text.split_at 1) maybe.trusted product.right)))) + +(nominal.def .public (Value brand) + Text + + (def .public value + (-> (Value Any) + Text) + (|>> representation)) + + (with_template [<name> <value>] + [(def .public <name> + Value + (abstraction <value>))] + + [initial "initial"] + [inherit "inherit"] + [unset "unset"] + ) + + (nominal.def .public (Numeric kind) Any) + + (with_template [<name>] + [(with_expansions [<name>' (template.symbol [<name> "'"])] + (nominal.def .public <name>' Any) + (type .public <name> + (Numeric <name>')))] + + [Number] + [Length] + [Time] + [Percentage] + ) + + (with_template [<brand> <alias>+ <value>+] + [(nominal.def .public <brand> Any) + + (`` (with_template [<name> <value>] + [(def .public <name> + (Value <brand>) + (abstraction <value>))] + + (,, (template.spliced <alias>+)))) + + (with_expansions [<rows> (template.spliced <value>+)] + (with_template [<value>] + [(`` (def .public (,, (..text_symbol <value>)) + (Value <brand>) + (abstraction <value>)))] + + <rows>))] + + [All + [] + []] + + [Thickness + [] + [["medium"] + ["thin"] + ["thick"]]] + + [Slice + [[full_slice "fill"]] + []] + + [Alignment + [[auto_alignment "auto"]] + [["stretch"] + ["center"] + ["flex-start"] + ["flex-end"] + ["baseline"] + ["space-between"] + ["space-around"]]] + + [Animation + [] + []] + + [Animation_Direction + [[normal_direction "normal"]] + [["reverse"] + ["alternate"] + ["alternate-reverse"]]] + + [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"] + [collapse_visibility "collapse"]] + [["visible"]]] + + [Attachment + [[scroll_attachment "scroll"] + [fixed_attachment "fixed"] + [local_attachment "local"]] + []] + + [Blend + [[normal_blend "normal"]] + [["multiply"] + ["screen"] + ["overlay"] + ["darken"] + ["lighten"] + ["color-dodge"] + ["color-burn"] + ["difference"] + ["exclusion"] + ["hue"] + ["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"]] + []] + + [Fit + [[no_fit "none"]] + [["fill"] + ["cover"] + ["contain"] + ["scale-down"]]] + + [Border + [] + [["hidden"] + ["dotted"] + ["dashed"] + ["solid"] + ["double"] + ["groove"] + ["ridge"] + ["inset"] + ["outset"]]] + + [Collapse + [] + [["separate"] + ["collapse"]]] + + [Box_Decoration_Break + [] + [["slice"] + ["clone"]]] + + [Caption + [] + [["top"] + ["bottom"]]] + + [Float + [[float_left "left"] + [float_right "right"]] + []] + + [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"] + [no_cursor "none"]] + [["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"] + ["not-allowed"] + ["pointer"] + ["progress"] + ["row-resize"] + ["s-resize"] + ["se-resize"] + ["sw-resize"] + ["vertical-text"] + ["w-resize"] + ["wait"] + ["zoom-in"] + ["zoom-out"]]] + + [Shadow + [] + []] + + [Clip + [] + []] + + [Text_Direction + [[left_to_right "ltr"] + [right_to_left "rtl"]] + []] + + [Display + [[grid_display "grid"] + [no_display "none"]] + [["inline"] + ["block"] + ["contents"] + ["flex"] + ["inline-block"] + ["inline-flex"] + ["inline-grid"] + ["inline-table"] + ["list-item"] + ["run-in"] + ["table"] + ["table-caption"] + ["table-column-group"] + ["table-header-group"] + ["table-footer-group"] + ["table-row-group"] + ["table-cell"] + ["table-column"] + ["table-row"]]] + + [Empty + [] + [["show"] + ["hide"]]] + + [Filter + [] + []] + + [Flex_Direction + [] + [["row"] + ["row-reverse"] + ["column"] + ["column-reverse"]]] + + [Flex_Wrap + [[no_wrap "nowrap"]] + [["wrap"] + ["wrap_reverse"]]] + + [Font_Kerning + [[auto_kerning "auto"] + [normal_kerning "normal"] + [no_kerning "none"]] + []] + + [Font_Size + [[medium_size "medium"] + [xx_small_size "xx-small"] + [x_small_size "x-small"] + [small_size "small"] + [large_size "large"] + [x_large_size "x-large"] + [xx_large_size "xx-large"] + [smaller_size "smaller"] + [larger_size "larger"]] + []] + + [Font_Stretch + [[normal_stretch "normal"]] + [["condensed"] + ["ultra-condensed"] + ["extra-condensed"] + ["semi-condensed"] + ["expanded"] + ["semi-expanded"] + ["extra-expanded"] + ["ultra-expanded"]]] + + [Font_Style + [[normal_style "normal"]] + [["italic"] + ["oblique"]]] + + [Font_Weight + [[normal_weight "normal"] + [weight_100 "100"] + [weight_200 "200"] + [weight_300 "300"] + [weight_400 "400"] + [weight_500 "500"] + [weight_600 "600"] + [weight_700 "700"] + [weight_800 "800"] + [weight_900 "900"]] + [["bold"]]] + + [Font_Variant + [[normal_font "normal"]] + [["small-caps"]]] + + [Grid + [] + []] + + [Grid_Content + [[auto_content "auto"]] + [["max-content"] + ["min-content"]]] + + [Grid_Flow + [[row_flow "row"] + [column_flow "column"] + [dense_flow "dense"] + [row_dense_flow "row dense"] + [column_dense_flow "column dense"]] + []] + + [Grid_Span + [[auto_span "auto"]] + []] + + [Grid_Template + [] + []] + + [Hanging_Punctuation + [[no_hanging_punctuation "none"]] + [["first"] + ["last"] + ["allow-end"] + ["force-end"]]] + + [Hyphens + [[no_hyphens "none"] + [manual_hyphens "manual"] + [auto_hyphens "auto"]] + []] + + [Orientation + [] + [["portrait"] + ["landscape"]]] + + [Resolution + [] + []] + + [Scan + [] + [["interlace"] + ["progressive"]]] + + [Boolean + [[false "0"] + [true "1"]] + []] + + [Update + [[no_update "none"] + [slow_update "slow"] + [fast_update "fast"]] + []] + + [Block_Overflow + [[no_block_overflow "none"] + [scroll_block_overflow "scroll"] + [optional_paged_block_overflow "optional-paged"] + [paged_block_overflow "paged"]] + []] + + [Inline_Overflow + [[no_inline_overflow "none"] + [scroll_inline_overflow "scroll"]] + []] + + [Display_Mode + [] + [["fullscreen"] + ["standalone"] + ["minimal-ui"] + ["browser"]]] + + [Color_Gamut + [] + [["srgb"] + ["p3"] + ["rec2020"]]] + + [Inverted_Colors + [[no_inverted_colors "none"] + [inverted_colors "inverted"]] + []] + + [Pointer + [[no_pointer "none"] + [coarse_pointer "coarse"] + [fine_pointer "fine"]] + []] + + [Hover + [[no_hover "none"]] + [["hover"]]] + + [Light + [[dim_light "dim"] + [normal_light "normal"] + [washed_light "washed"]] + []] + + [Ratio + [] + []] + + [Scripting + [[no_scripting "none"] + [initial_scripting_only "initial-only"] + [scripting_enabled "enabled"]] + []] + + [Motion + [[no_motion_preference "no-preference"] + [reduced_motion "reduce"]] + []] + + [Color_Scheme + [[no_color_scheme_preference "no-preference"] + [light_color_scheme "light"] + [dark_color_scheme "dark"]] + []] + + [Isolation + [[auto_isolation "auto"]] + [["isolate"]]] + + [List_Style_Position + [] + [["inside"] + ["outside"]]] + + [List_Style_Type + [[no_list_style "none"]] + [["disc"] + ["armenian"] + ["circle"] + ["cjk-ideographic"] + ["decimal"] + ["decimal-leading-zero"] + ["georgian"] + ["hebrew"] + ["hiragana"] + ["hiragana-iroha"] + ["katakana"] + ["katakana-iroha"] + ["lower-alpha"] + ["lower-greek"] + ["lower-latin"] + ["lower-roman"] + ["square"] + ["upper-alpha"] + ["upper-greek"] + ["upper-latin"] + ["upper-roman"]]] + + [Color + [] + []] + + [Overflow + [[visible_overflow "visible"] + [hidden_overflow "hidden"] + [scroll_overflow "scroll"] + [auto_overflow "auto"]] + []] + + [Page_Break + [[auto_page_break "auto"] + [always_page_break "always"] + [avoid_page_break "avoid"] + [left_page_break "left"] + [right_page_break "right"]] + []] + + [Pointer_Events + [[auto_pointer_events "auto"] + [no_pointer_events "none"]] + []] + + [Position + [] + [["static"] + ["absolute"] + ["fixed"] + ["relative"] + ["sticky"]]] + + [Quotes + [[no_quotes "none"]] + []] + + [Resize + [[resize_none "none"] + [resize_both "both"] + [resize_horizontal "horizontal"] + [resize_vertical "vertical"]] + []] + + [Scroll_Behavior + [[auto_scroll_behavior "auto"] + [smooth_scroll_behavior "smooth"]] + []] + + [Table_Layout + [[auto_table_layout "auto"] + [fixed_table_layout "fixed"]] + []] + + [Text_Align + [[left_text_align "left"] + [right_text_align "right"] + [center_text_align "center"] + [justify_text_align "justify"]] + []] + + [Text_Align_Last + [[auto_text_align_last "auto"] + [left_text_align_last "left"] + [right_text_align_last "right"] + [center_text_align_last "center"] + [justify_text_align_last "justify"] + [start_text_align_last "start"] + [end_text_align_last "end"]] + []] + + [Text_Decoration_Line + [[no_text_decoration_line "none"] + [underline_text_decoration_line "underline"] + [overline_text_decoration_line "overline"] + [line_through_text_decoration_line "line-through"]] + []] + + [Text_Decoration_Style + [[solid_text_decoration_style "solid"] + [double_text_decoration_style "double"] + [dotted_text_decoration_style "dotted"] + [dashed_text_decoration_style "dashed"] + [wavy_text_decoration_style "wavy"]] + []] + + [Text_Justification + [[auto_text_justification "auto"] + [inter_word_text_justification "inter-word"] + [inter_character_text_justification "inter-character"] + [no_text_justification "none"]] + []] + + [Text_Overflow + [[clip_text_overflow "clip"] + [ellipsis_text_overflow "ellipsis"]] + []] + + [Text_Transform + [[no_text_transform "none"]] + [["capitalize"] + ["uppercase"] + ["lowercase"]]] + + [Transform + [[no_transform "none"]] + []] + + [Transform_Origin + [] + []] + + [Transform_Style + [] + [["flat"] + ["preserve_3d"]]] + + [Transition + [[transition_none "none"] + [transition_all "all"]] + []] + + [Bidi + [[bidi_normal "normal"] + [bidi_embed "embed"] + [bidi_isolate "isolate"] + [bidi_isolate_override "isolate-override"] + [bidi_plaintext "plaintext"]] + [["bidi-override"]]] + + [User_Select + [[user_select_auto "auto"] + [user_select_none "none"] + [user_select_text "text"] + [user_select_all "all"]] + []] + + [Vertical_Align + [[vertical_align_baseline "baseline"] + [vertical_align_sub "sub"] + [vertical_align_super "super"] + [vertical_align_top "top"] + [vertical_align_text_top "text-top"] + [vertical_align_middle "middle"] + [vertical_align_bottom "bottom"] + [vertical_align_text_bottom "text-bottom"]] + []] + + [White_Space + [[normal_white_space "normal"] + [no_wrap_white_space "nowrap"] + [pre_white_space "pre"] + [pre_line_white_space "pre-line"] + [pre_wrap_white_space "pre-wrap"]] + []] + + [Word_Break + [[normal_word_break "normal"]] + [["break-all"] + ["keep-all"] + ["break-word"]]] + + [Word_Wrap + [[normal_word_wrap "normal"] + [break_word_word_wrap "break-word"]] + []] + + [Writing_Mode + [[top_to_bottom_writing_mode "horizontal-tb"] + [left_to_right_writing_mode "vertical-rl"] + [right_to_left_writing_mode "vertical-lr"]] + []] + + [Z_Index + [] + []] + ) + + (def value_separator + ",") + + (def (apply name inputs) + (-> Text (List Text) + Value) + (|> inputs + (text.interposed ..value_separator) + (text.enclosed ["(" ")"]) + (format name) + abstraction)) + + (enumeration + Step + Text + step + [[start "start"] + [end "end"]] + []) + + (def .public (steps intervals step) + (-> Nat Step + (Value Timing)) + (..apply "steps" (list (%.nat intervals) (..step step)))) + + (def .public (cubic_bezier p0 p1 p2 p3) + (-> Frac Frac Frac Frac + (Value Timing)) + (|> (list p0 p1 p2 p3) + (list#each %number) + (..apply "cubic-bezier"))) + + (with_template [<name> <brand>] + [(def .public <name> + (-> Nat + (Value <brand>)) + (|>> %.nat abstraction))] + + [iteration Iteration] + [count Count] + [slice_number/1 Slice] + [span_line Grid_Span] + ) + + (def .public animation + (-> Label + (Value Animation)) + (|>> abstraction)) + + (def .public (rgb color) + (-> color.Color + (Value Color)) + (let [color (color.rgb color)] + (..apply "rgb" (list (%.nat (rgb.red color)) + (%.nat (rgb.green color)) + (%.nat (rgb.blue color)))))) + + (def .public (rgba pigment) + (-> Pigment + (Value Color)) + (let [(open "/[0]") pigment] + (..apply "rgba" (list (%.nat (rgb.red /#color)) + (%.nat (rgb.green /#color)) + (%.nat (rgb.blue /#color)) + (if (r.= (of r.interval top) /#alpha) + "1.0" + (format "0" (%.rev /#alpha))))))) + + (with_template [<name> <suffix>] + [(def .public (<name> value) + (-> Frac + (Value Length)) + (abstraction (format (%number 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"] + [fr "fr"] + ) + + (def (%int value) + (Format Int) + (if (i.< +0 value) + (%.int value) + (%.nat (.nat value)))) + + (with_template [<name> <suffix>] + [(def .public (<name> value) + (-> Int + (Value Time)) + (abstraction (format (if (i.< +0 value) + (%.int value) + (%.nat (.nat value))) + <suffix>)))] + + + [seconds "s"] + [milli_seconds "ms"] + ) + + (def .public thickness + (-> (Value Length) + (Value Thickness)) + (|>> transmutation)) + + (def slice_separator " ") + + (def .public (slice_number/2 horizontal vertical) + (-> Nat Nat + (Value Slice)) + (abstraction (format (%.nat horizontal) ..slice_separator + (%.nat vertical)))) + + (nominal.def .public Stop + Text + + (def .public stop + (-> (Value Color) + Stop) + (|>> (representation Value) (abstraction Stop))) + + (def stop_separator + " ") + + (def .public (single_stop length color) + (-> (Value Length) (Value Color) + Stop) + (abstraction (format (representation Value color) ..stop_separator + (representation Value length)))) + + (def .public (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)))) + + (nominal.def .public Hint + Text + + (def .public hint + (-> (Value Length) + Hint) + (|>> (representation Value) (abstraction Hint))) + + (def (with_hint [hint stop]) + (-> [(Maybe Hint) Stop] + Text) + (when hint + {.#None} + (representation Stop stop) + + {.#Some hint} + (format (representation Hint hint) ..value_separator (representation Stop stop)))))) + + (type .public (List/1 a) + [a (List a)]) + + (nominal.def .public Angle + Text + + (def .public angle + (-> Angle + Text) + (|>> representation)) + + (def .public (turn value) + (-> Rev + Angle) + (abstraction (format (%.rev value) "turn"))) + + (def degree_limit + Nat + 360) + + (def .public (degree value) + (-> Nat + Angle) + (abstraction (format (%.nat (n.% ..degree_limit value)) "deg"))) + + (with_template [<degree> <name>] + [(def .public <name> + Angle + (..degree <degree>))] + + [000 to_top] + [090 to_right] + [180 to_bottom] + [270 to_left] + ) + + (with_template [<name> <function>] + [(def .public (<name> angle start next) + (-> Angle Stop (List/1 [(Maybe Hint) Stop]) + (Value Image)) + (let [[now after] next] + (..apply <function> (list.partial (representation Angle angle) + (with_hint now) + (list#each with_hint after)))))] + + [linear_gradient "linear-gradient"] + [repeating_linear_gradient "repeating-linear-gradient"] + ) + ) + + (def percentage_limit + Nat + (.++ 100)) + + (def .public (%% value) + (-> Nat + (Value Percentage)) + (abstraction (format (%.nat (n.% percentage_limit value)) "%"))) + + (def .public slice_percent/1 + (-> (Value Percentage) + (Value Slice)) + (|>> transmutation)) + + (def .public (slice_percent/2 horizontal vertical) + (-> (Value Percentage) (Value Percentage) + (Value Slice)) + (abstraction (format (representation horizontal) ..slice_separator + (representation vertical)))) + + (with_template [<input> <pre> <function>+] + [(`` (with_template [<name> <function>] + [(def .public <name> + (-> <input> + (Value Filter)) + (|>> <pre> (list) (..apply <function>)))] + + (,, (template.spliced <function>+))))] + + [Nat (<| representation ..px n.frac) + [[blur "blur"]]] + [Nat (<| ..angle ..degree) + [[hue_rotate "hue-rotate"]]] + [(Value Percentage) representation + [[brightness "brightness"] + [contrast "contrast"] + [grayscale "grayscale"] + [invert "invert"] + [opacity "opacity"] + [saturate "saturate"] + [sepia "sepia"]]] + ) + + (def .public svg_filter + (-> URL + (Value Filter)) + (|>> (list) (..apply "url"))) + + (def default_shadow_length + (px +0.0)) + + (def .public (drop_shadow horizontal vertical blur spread color) + (-> (Value Length) (Value Length) + (Maybe (Value Length)) (Maybe (Value Length)) + (Value Color) + (Value Filter)) + (|> (list (representation horizontal) + (representation vertical) + (|> blur (maybe.else ..default_shadow_length) representation) + (|> spread (maybe.else ..default_shadow_length) representation) + (representation color)) + (text.interposed " ") + (list) + (..apply "drop-shadow"))) + + (def length_separator + " ") + + (with_template [<name> <type>] + [(def .public (<name> horizontal vertical) + (-> (Value Length) (Value Length) + (Value <type>)) + (abstraction (format (representation horizontal) + ..length_separator + (representation vertical))))] + + [location Location] + [fit Fit] + ) + + (def .public (fit/1 length) + (-> (Value Length) + (Value Fit)) + (..fit length length)) + + (def .public image + (-> URL + (Value Image)) + (|>> %.text + (list) + (..apply "url"))) + + (enumeration + Shape + Text + shape + [[ellipse_shape "ellipse"] + [circle_shape "circle"]] + []) + + (enumeration + Extent + Text + extent + [[closest_side "closest-side"] + [closest_corner "closest-corner"] + [farthest_side "farthest-side"] + [farthest_corner "farthest-corner"]] + []) + + (with_template [<name> <function>] + [(def .public (<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 (when extent + {.#Some extent} + (format (..extent extent) " " after_extent) + + {.#None} + after_extent) + where (format (..shape shape) " " with_extent) + [now after] next] + (..apply <function> (list.partial (..shape shape) + (with_hint now) + (list#each with_hint after)))))] + + [radial_gradient "radial-gradient"] + [repeating_radial_gradient "repeating-radial-gradient"] + ) + + (def .public (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.partial (representation horizontal) + (representation vertical) + (|> blur (maybe.else ..default_shadow_length) representation) + (|> spread (maybe.else ..default_shadow_length) representation) + (representation color) + with_inset) + (text.interposed " ") + abstraction))) + + (type .public Rectangle + (Record + [#top (Value Length) + #right (Value Length) + #bottom (Value Length) + #left (Value Length)])) + + (def .public (clip rectangle) + (-> Rectangle + (Value Clip)) + (`` (..apply "rect" (list (,, (with_template [<side>] + [(representation (the <side> rectangle))] + + [#top] [#right] [#bottom] [#left])))))) + + (def .public counter + (-> Label + (Value Counter)) + (|>> abstraction)) + + (def .public current_count + (-> (Value Counter) + (Value Content)) + (|>> representation (list) (..apply "counter"))) + + (def .public text + (-> Text + (Value Content)) + (|>> %.text abstraction)) + + (def .public attribute + (-> Label + (Value Content)) + (|>> (list) (..apply "attr"))) + + (def .public media + (-> URL + (Value Content)) + (|>> (list) (..apply "url"))) + + (enumeration + Font + Text + font_name + [[serif "serif"] + [sans_serif "sans-serif"] + [cursive "cursive"] + [fantasy "fantasy"] + [monospace "monospace"]] + [(def .public font + (-> Text Font) + (|>> %.text abstraction)) + + (def .public (font_family options) + (-> (List Font) (Value Font)) + (when options + {.#Item _} + (|> options + (list#each ..font_name) + (text.interposed ",") + (abstraction Value)) + + {.#End} + ..initial))]) + + (def .public font_size + (-> (Value Length) + (Value Font_Size)) + (|>> transmutation)) + + (def .public number + (-> Frac + (Value Number)) + (|>> %number abstraction)) + + (def .public grid + (-> Label + (Value Grid)) + (|>> abstraction)) + + (def .public fit_content + (-> (Value Length) + (Value Grid_Content)) + (|>> representation (list) (..apply "fit-content"))) + + (def .public (min_max min max) + (-> (Value Grid_Content) (Value Grid_Content) + (Value Grid_Content)) + (..apply "minmax" (list (representation min) + (representation max)))) + + (def .public grid_span + (-> Nat + (Value Grid_Span)) + (|>> %.nat (format "span ") abstraction)) + + (def grid_column_separator " ") + (def grid_row_separator " ") + + (def .public grid_template + (-> (List (List (Maybe (Value Grid)))) + (Value Grid_Template)) + (let [empty (is (Value Grid) + (abstraction "."))] + (|>> (list#each (|>> (list#each (|>> (maybe.else empty) + representation)) + (text.interposed ..grid_column_separator) + (text.enclosed ["'" "'"]))) + (text.interposed ..grid_row_separator) + abstraction))) + + (def .public (resolution dpi) + (-> Nat + (Value Resolution)) + (abstraction (format (%.nat dpi) "dpi"))) + + (def .public (ratio numerator denominator) + (-> Nat Nat + (Value Ratio)) + (abstraction (format (%.nat numerator) "/" (%.nat denominator)))) + + (enumeration + Quote + Text + quote_text + [[double_quote "\0022"] + [single_quote "\0027"] + [single_left_angle_quote "\2039"] + [single_right_angle_quote "\203A"] + [double_left_angle_quote "\00AB"] + [double_right_angle_quote "\00BB"] + [single_left_quote "\2018"] + [single_right_quote "\2019"] + [double_left_quote "\201C"] + [double_right_quote "\201D"] + [low_double_quote "\201E"]] + [(def .public quote + (-> Text Quote) + (|>> abstraction))]) + + (def quote_separator " ") + + (def .public (quotes [left0 right0] [left1 right1]) + (-> [Quote Quote] [Quote Quote] + (Value Quotes)) + (|> (list left0 right0 left1 right1) + (list#each (|>> ..quote_text %.text)) + (text.interposed ..quote_separator) + abstraction)) + + (def .public (matrix_2d [a b] [c d] [tx ty]) + (-> [Frac Frac] + [Frac Frac] + [Frac Frac] + (Value Transform)) + (|> (list a b c d tx ty) + (list#each %number) + (..apply "matrix"))) + + (def .public (matrix_3d [a0 b0 c0 d0] [a1 b1 c1 d1] [a2 b2 c2 d2] [a3 b3 c3 d3]) + (-> [Frac Frac Frac Frac] + [Frac Frac Frac Frac] + [Frac Frac Frac Frac] + [Frac Frac Frac Frac] + (Value Transform)) + (|> (list a0 b0 c0 d0 a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3) + (list#each %number) + (..apply "matrix3d"))) + + (with_template [<name> <function> <input_types> <input_values>] + [(`` (def .public (<name> [(,, (template.spliced <input_values>))]) + (-> [(,, (template.spliced <input_types>))] + (Value Transform)) + (|> (list (,, (template.spliced <input_values>))) + (list#each %number) + (..apply <function>))))] + + [translate_2d "translate" [Frac Frac] [x y]] + [translate_3d "translate3d" [Frac Frac Frac] [x y z]] + [translate_x "translateX" [Frac] [value]] + [translate_y "translateY" [Frac] [value]] + [translate_z "translateZ" [Frac] [value]] + + [scale_2d "scale" [Frac Frac] [x y]] + [scale_3d "scale3d" [Frac Frac Frac] [x y z]] + [scale_x "scaleX" [Frac] [value]] + [scale_y "scaleY" [Frac] [value]] + [scale_z "scaleZ" [Frac] [value]] + + [perspective "perspective" [Frac] [value]] + ) + + (with_template [<name> <function> <input_types> <input_values>] + [(`` (def .public (<name> [(,, (template.spliced <input_values>))]) + (-> [(,, (template.spliced <input_types>))] + (Value Transform)) + (|> (list (,, (template.spliced <input_values>))) + (list#each ..angle) + (..apply <function>))))] + + [rotate_2d "rotate" [Angle] [angle]] + [rotate_x "rotateX" [Angle] [angle]] + [rotate_y "rotateY" [Angle] [angle]] + [rotate_z "rotateZ" [Angle] [angle]] + + [skew "skew" [Angle Angle] [x_angle y_angle]] + [skew_x "skewX" [Angle] [angle]] + [skew_y "skewY" [Angle] [angle]] + ) + + (def .public (rotate_3d [x y z angle]) + (-> [Frac Frac Frac Angle] + (Value Transform)) + (..apply "rotate3d" + (list (%number x) (%number y) (%number z) (..angle angle)))) + + (def origin_separator " ") + + (def .public (origin_2d x y) + (-> (Value Length) (Value Length) + (Value Transform_Origin)) + (abstraction (format (representation x) ..origin_separator + (representation y)))) + + (def .public (origin_3d x y z) + (-> (Value Length) (Value Length) (Value Length) + (Value Transform_Origin)) + (abstraction (format (representation x) ..origin_separator + (representation y) ..origin_separator + (representation z)))) + + (def .public vertical_align + (-> (Value Length) + (Value Vertical_Align)) + (|>> transmutation)) + + (def .public (z_index index) + (-> Int + (Value Z_Index)) + (abstraction (if (i.< +0 index) + (%.int index) + (%.nat (.nat index))))) + + (with_template [<separator> <type> <multi>] + [(def .public (<multi> pre post) + (-> (Value <type>) (Value <type>) + (Value <type>)) + (abstraction (format (representation pre) + <separator> + (representation post))))] + + ["," Image multi_image] + ["," Shadow multi_shadow] + [" " Content multi_content] + ) + + ... https://developer.mozilla.org/en-US/docs/Web/CSS/calc() + (with_template [<name> <parameter>] + [(def .public (<name> parameter subject) + (.All (_ kind) + (-> (Value <parameter>) (Value (Numeric kind)) + (Value (Numeric kind)))) + (|> (format (representation subject) + (template.text [" " <name> " "]) + (representation parameter)) + (text.enclosed ["calc(" ")"]) + abstraction))] + + [+ (Numeric kind)] + [- (Numeric kind)] + [* Number] + [/ Number] + ) + ) |