1
Fork 0
mirror of https://github.com/RGBCube/HTMNIX synced 2025-07-25 23:17:44 +00:00

Rework everything

This commit is contained in:
RGBCube 2024-02-28 09:37:09 +03:00
parent 274cd1f747
commit 01fbf8f629
No known key found for this signature in database

View file

@ -1,41 +1,71 @@
{ {
outputs = { self }: let outputs = { self }: let
firstChar = builtins.substring 0 1; first = n: builtins.substring 0 n;
dropFirstChar = string: builtins.substring 1 (builtins.stringLength string) string; dropFirst = n: string: builtins.substring n (builtins.stringLength string - n) string;
lastChar = string: builtins.substring (builtins.stringLength string - 1) 1 string; last = n: string: builtins.substring (builtins.stringLength string - n) n string;
dropLastChar = string: builtins.substring 0 (builtins.stringLength string - 1) string; dropLast = n: string: builtins.substring 0 (builtins.stringLength string - n) string;
getType = item: item._type or null; escape = string: string; # TODO
escape = s: s; # TODO attrsetToHtmlAttrs = attrs:
builtins.concatStringsSep " "
(builtins.attrValues
(builtins.mapAttrs (k: v: ''${k}="${escape (toString v)}"'') attrs));
domListToString = _: escape "TODO"; dottedNameToTag = name:
if first 1 name == "."
then "</${dropFirst 1 name}>"
else if last 1 name == "."
then "<${dropLast 1 name}/>"
else "<${name}>";
in { in {
__findFile = _: name: {
outPath = dottedNameToTag name;
__findFile = _: name: if firstChar name == "." then { __functor = this: next:
_type = "end"; # Not an attrset. Just escape and add it onto the HTML.
_name = dropFirstChar name; if !builtins.isAttrs next
} else if lastChar name == "." then { then this // {
_type = "lone"; outPath = (toString this) + escape (toString next);
_name = dropLastChar name; }
} else {
_type = "start"; # An attrset. But not a tag. This means it must be HTML attributes.
_name = name; # We need to insert it right before the '>' or '/>' at the end of our string
# and error if it doesn't end with a tag.
_accum = []; #
__functor = let # Due to how it is implemented, passing multiple attrsets to a single
impl = this: next: if # tag to combine them works. Here is an example:
getType next == "end" && #
next._name == this._name # <foo>{bar="baz";}{fizz="fuzz";}
then #
domListToString this # This will output the following HTML:
#
# <foo bar="baz" fizz="fuzz">
else if builtins.isAttrs next && !(next ? outPath)
then let
lastElementIsTag = last 1 (toString this) == ">";
lastElementIsSelfClosing = last 2 (toString this) == "/>";
in this // {
outPath = let
attrs = attrsetToHtmlAttrs next;
in if !lastElementIsTag then
throw "Attributes must come right after a tag: '${if attrs != "" then attrs else "<empty attrs>"}'"
else
(dropLast (if lastElementIsSelfClosing then 2 else 1) (toString this))
+ (if attrs != "" then " " else "") # Keep it pretty.
+ attrs
+ (if lastElementIsSelfClosing then "/>" else ">");
}
# The next element is a tag with the `outPath` attribute which means it's a
# start, closing or self closing tag. Just append it onto our string.
else this // { else this // {
_accum = this._accum ++ [ next ]; outPath = "${this}${next}";
__functor = impl;
}; };
in impl; };
};
result = let inherit (self) __findFile; in result = let inherit (self) __findFile; in
<html> <html>