diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..6d36579 --- /dev/null +++ b/deno.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "preact" + }, + "imports": { + "copy-paste": "https://deno.land/x/copy_paste@v1.1.3/mod.ts", + "preact": "https://esm.sh/preact@10.16.0", + "preact/jsx-runtime": "https://esm.sh/preact@10.16.0/jsx-runtime?dts", + "preact-render-to-string": "https://esm.sh/preact-render-to-string@5.2.0?external=preact" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..5674143 --- /dev/null +++ b/deno.lock @@ -0,0 +1,122 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.149.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.149.0/bytes/bytes_list.ts": "aba5e2369e77d426b10af1de0dcc4531acecec27f9b9056f4f7bfbf8ac147ab4", + "https://deno.land/std@0.149.0/bytes/equals.ts": "3c3558c3ae85526f84510aa2b48ab2ad7bdd899e2e0f5b7a8ffc85acb3a6043a", + "https://deno.land/std@0.149.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf", + "https://deno.land/std@0.149.0/fmt/colors.ts": "6f9340b7fb8cc25a993a99e5efc56fe81bb5af284ff412129dd06df06f53c0b4", + "https://deno.land/std@0.149.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b", + "https://deno.land/std@0.149.0/streams/conversion.ts": "fc3db02026183da795fa32ac7549868e9f19c75ba029d4b4c3739af62b48517a", + "https://deno.land/std@0.149.0/testing/_diff.ts": "029a00560b0d534bc0046f1bce4bd36b3b41ada3f2a3178c85686eb2ff5f1413", + "https://deno.land/std@0.149.0/testing/_format.ts": "0d8dc79eab15b67cdc532826213bbe05bccfd276ca473a50a3fc7bbfb7260642", + "https://deno.land/std@0.149.0/testing/asserts.ts": "0ee58a557ac764e762c62bb21f00e7d897e3919e71be38b2d574fb441d721005", + "https://deno.land/std@0.176.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.176.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.176.0/encoding/hex.ts": "50f8c95b52eae24395d3dfcb5ec1ced37c5fe7610ef6fffdcc8b0fdc38e3b32f", + "https://deno.land/std@0.176.0/fmt/colors.ts": "938c5d44d889fb82eff6c358bea8baa7e85950a16c9f6dae3ec3a7a729164471", + "https://deno.land/std@0.176.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", + "https://deno.land/std@0.176.0/fs/copy.ts": "14214efd94fc3aa6db1e4af2b4b9578e50f7362b7f3725d5a14ad259a5df26c8", + "https://deno.land/std@0.176.0/fs/empty_dir.ts": "c3d2da4c7352fab1cf144a1ecfef58090769e8af633678e0f3fabaef98594688", + "https://deno.land/std@0.176.0/fs/ensure_dir.ts": "724209875497a6b4628dfb256116e5651c4f7816741368d6c44aab2531a1e603", + "https://deno.land/std@0.176.0/fs/ensure_file.ts": "c38602670bfaf259d86ca824a94e6cb9e5eb73757fefa4ebf43a90dd017d53d9", + "https://deno.land/std@0.176.0/fs/ensure_link.ts": "c0f5b2f0ec094ed52b9128eccb1ee23362a617457aa0f699b145d4883f5b2fb4", + "https://deno.land/std@0.176.0/fs/ensure_symlink.ts": "2955cc8332aeca9bdfefd05d8d3976b94e282b0f353392a71684808ed2ffdd41", + "https://deno.land/std@0.176.0/fs/eol.ts": "f1f2eb348a750c34500741987b21d65607f352cf7205f48f4319d417fff42842", + "https://deno.land/std@0.176.0/fs/exists.ts": "b8c8a457b71e9d7f29b9d2f87aad8dba2739cbe637e8926d6ba6e92567875f8e", + "https://deno.land/std@0.176.0/fs/expand_glob.ts": "45d17e89796a24bd6002e4354eda67b4301bb8ba67d2cac8453cdabccf1d9ab0", + "https://deno.land/std@0.176.0/fs/mod.ts": "bc3d0acd488cc7b42627044caf47d72019846d459279544e1934418955ba4898", + "https://deno.land/std@0.176.0/fs/move.ts": "4cb47f880e3f0582c55e71c9f8b1e5e8cfaacb5e84f7390781dd563b7298ec19", + "https://deno.land/std@0.176.0/fs/walk.ts": "ea95ffa6500c1eda6b365be488c056edc7c883a1db41ef46ec3bf057b1c0fe32", + "https://deno.land/std@0.176.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.176.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.176.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", + "https://deno.land/std@0.176.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.176.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", + "https://deno.land/std@0.176.0/path/mod.ts": "4b83694ac500d7d31b0cdafc927080a53dc0c3027eb2895790fb155082b0d232", + "https://deno.land/std@0.176.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", + "https://deno.land/std@0.176.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", + "https://deno.land/std@0.176.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.186.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.186.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.186.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8", + "https://deno.land/std@0.186.0/bytes/bytes_list.ts": "31d664f4d42fa922066405d0e421c56da89d751886ee77bbe25a88bf0310c9d0", + "https://deno.land/std@0.186.0/bytes/concat.ts": "d26d6f3d7922e6d663dacfcd357563b7bf4a380ce5b9c2bbe0c8586662f25ce2", + "https://deno.land/std@0.186.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", + "https://deno.land/std@0.186.0/encoding/base64.ts": "144ae6234c1fbe5b68666c711dc15b1e9ee2aef6d42b3b4345bf9a6c91d70d0d", + "https://deno.land/std@0.186.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/std@0.186.0/io/buf_reader.ts": "06fff3337091c49e99ebd2dd790c9a90364c087a2953ea081667400fd6c6cebb", + "https://deno.land/std@0.186.0/io/buf_writer.ts": "48c33c8f00b61dcbc7958706741cec8e59810bd307bc6a326cbd474fe8346dfd", + "https://deno.land/std@0.186.0/io/buffer.ts": "17f4410eaaa60a8a85733e8891349a619eadfbbe42e2f319283ce2b8f29723ab", + "https://deno.land/std@0.186.0/io/copy_n.ts": "0cc7ce07c75130f6fc18621ec1911c36e147eb9570664fee0ea12b1988167590", + "https://deno.land/std@0.186.0/io/limited_reader.ts": "6c9a216f8eef39c1ee2a6b37a29372c8fc63455b2eeb91f06d9646f8f759fc8b", + "https://deno.land/std@0.186.0/io/mod.ts": "2665bcccc1fd6e8627cca167c3e92aaecbd9897556b6f69e6d258070ef63fd9b", + "https://deno.land/std@0.186.0/io/multi_reader.ts": "9c2a0a31686c44b277e16da1d97b4686a986edcee48409b84be25eedbc39b271", + "https://deno.land/std@0.186.0/io/read_delim.ts": "c02b93cc546ae8caad8682ae270863e7ace6daec24c1eddd6faabc95a9d876a3", + "https://deno.land/std@0.186.0/io/read_int.ts": "7cb8bcdfaf1107586c3bacc583d11c64c060196cb070bb13ae8c2061404f911f", + "https://deno.land/std@0.186.0/io/read_lines.ts": "c526c12a20a9386dc910d500f9cdea43cba974e853397790bd146817a7eef8cc", + "https://deno.land/std@0.186.0/io/read_long.ts": "f0aaa420e3da1261c5d33c5e729f09922f3d9fa49f046258d4ff7a00d800c71e", + "https://deno.land/std@0.186.0/io/read_range.ts": "28152daf32e43dd9f7d41d8466852b0d18ad766cd5c4334c91fef6e1b3a74eb5", + "https://deno.land/std@0.186.0/io/read_short.ts": "805cb329574b850b84bf14a92c052c59b5977a492cd780c41df8ad40826c1a20", + "https://deno.land/std@0.186.0/io/read_string_delim.ts": "5dc9f53bdf78e7d4ee1e56b9b60352238ab236a71c3e3b2a713c3d78472a53ce", + "https://deno.land/std@0.186.0/io/slice_long_to_bytes.ts": "48d9bace92684e880e46aa4a2520fc3867f9d7ce212055f76ecc11b22f9644b7", + "https://deno.land/std@0.186.0/io/string_reader.ts": "da0f68251b3d5b5112485dfd4d1b1936135c9b4d921182a7edaf47f74c25cc8f", + "https://deno.land/std@0.186.0/io/string_writer.ts": "8a03c5858c24965a54c6538bed15f32a7c72f5704a12bda56f83a40e28e5433e", + "https://deno.land/std@0.186.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.186.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.186.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", + "https://deno.land/std@0.186.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.186.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", + "https://deno.land/std@0.186.0/path/mod.ts": "ee161baec5ded6510ee1d1fb6a75a0f5e4b41f3f3301c92c716ecbdf7dae910d", + "https://deno.land/std@0.186.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", + "https://deno.land/std@0.186.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", + "https://deno.land/std@0.186.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.186.0/streams/_common.ts": "f45cba84f0d813de3326466095539602364a9ba521f804cc758f7a475cda692d", + "https://deno.land/std@0.186.0/streams/buffer.ts": "d5b3d7d0299114e5b2ea895a8bf202a687fd915c5282f8096c7bae23b5a04407", + "https://deno.land/std@0.186.0/streams/byte_slice_stream.ts": "225d57263a34325d7c96cb3dafeb478eec0e6fd05cd0458d678752eadd132bb4", + "https://deno.land/std@0.186.0/streams/copy.ts": "75cbc795ff89291df22ddca5252de88b2e16d40c85d02840593386a8a1454f71", + "https://deno.land/std@0.186.0/streams/delimiter_stream.ts": "f69e849b3d1f59f02424497273f411105a6f76a9f13da92aeeb9a2d554236814", + "https://deno.land/std@0.186.0/streams/early_zip_readable_streams.ts": "4005fa74162b943f79899e5d7cb96adcbc0a6b867f9144974ed12d30e0a556e1", + "https://deno.land/std@0.186.0/streams/iterate_reader.ts": "bbec1d45c2df2c0c5920bad0549351446fdc8e0886d99e95959b259dbcdb6072", + "https://deno.land/std@0.186.0/streams/limited_bytes_transform_stream.ts": "05dc592ffaab83257494d22dd53917e56243c26e5e3129b3f13ddbbbc4785048", + "https://deno.land/std@0.186.0/streams/limited_transform_stream.ts": "d69ab790232c1b86f53621ad41ef03c235f2abb4b7a1cd51960ad6e12ee55e38", + "https://deno.land/std@0.186.0/streams/merge_readable_streams.ts": "5d6302888f4bb0616dafb5768771be0aec9bedc05fbae6b3d726d05ffbec5b15", + "https://deno.land/std@0.186.0/streams/mod.ts": "c07ec010e700b9ea887dc36ca08729828bc7912f711e4054e24d33fd46282252", + "https://deno.land/std@0.186.0/streams/read_all.ts": "ee319772fb0fd28302f97343cc48dfcf948f154fd0d755d8efe65814b70533be", + "https://deno.land/std@0.186.0/streams/readable_stream_from_iterable.ts": "cd4bb9e9bf6dbe84c213beb1f5085c326624421671473e410cfaecad15f01865", + "https://deno.land/std@0.186.0/streams/readable_stream_from_reader.ts": "bfc416c4576a30aac6b9af22c9dc292c20c6742141ee7c55b5e85460beb0c54e", + "https://deno.land/std@0.186.0/streams/reader_from_iterable.ts": "55f68110dce3f8f2c87b834d95f153bc904257fc65175f9f2abe78455cb8047c", + "https://deno.land/std@0.186.0/streams/reader_from_stream_reader.ts": "fa4971e5615a010e49492c5d1688ca1a4d17472a41e98b498ab89a64ebd7ac73", + "https://deno.land/std@0.186.0/streams/text_delimiter_stream.ts": "20e680ab8b751390e359288ce764f9c47d164af11a263870746eeca4bc7d976b", + "https://deno.land/std@0.186.0/streams/text_line_stream.ts": "0f2c4b33a5fdb2476f2e060974cba1347cefe99a4af33c28a57524b1a34750fa", + "https://deno.land/std@0.186.0/streams/to_transform_stream.ts": "7f55fc0b14cf3ed0f8d10d8f41d05bdc40726e44a65c37f58705d10a615f0159", + "https://deno.land/std@0.186.0/streams/writable_stream_from_writer.ts": "56fff5c82fb736fdd669b567cc0b2bbbe0351002cd13254eae26c366e2bed89a", + "https://deno.land/std@0.186.0/streams/write_all.ts": "aec90152978581ea62d56bb53a5cbf487e6a89c902f87c5969681ffbdf32b998", + "https://deno.land/std@0.186.0/streams/writer_from_stream_writer.ts": "07c7ee025151a190f37fc42cbb01ff93afc949119ebddc6e0d0df14df1bf6950", + "https://deno.land/std@0.186.0/streams/zip_readable_streams.ts": "a9d81aa451240f79230add674809dbee038d93aabe286e2d9671e66591fc86ca", + "https://deno.land/std@0.186.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.186.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.186.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", + "https://deno.land/x/clippy@v0.2.2/bindings/bindings.ts": "c7678a4bfa5748b77aead8f99c449c8351500783a65e2e8c0607bfe231b5b013", + "https://deno.land/x/clippy@v0.2.2/deps.ts": "6bcfee8a6054be6c52d7a51d8cf21b37bb6bfbda3bd3b7d5eda0081dde9dd4a2", + "https://deno.land/x/clippy@v0.2.2/mod.ts": "ff4966a3a21a59ae5a676a4e0737d044eac8006e93498cfbb6a8a4bdb24abab1", + "https://deno.land/x/clippy@v0.2.2/platform/darwin.ts": "ed74ede39c1e5a8a4afee2dbc5507b75d71c27049fabd8f98e7e2d595886dcc8", + "https://deno.land/x/clippy@v0.2.2/platform/helper.ts": "ba1ae4bc0905a3c21c423f83f425b654ba817fbb80341465e5338ef516ca3730", + "https://deno.land/x/clippy@v0.2.2/platform/linux.ts": "241911a15062899e697d4f7b92c213c171429aa4ba9730a909a18ceb582fd590", + "https://deno.land/x/clippy@v0.2.2/platform/mod.ts": "b7324415e824785bc29c3fdb90bf6a27fb6025f806c8cd516461cc58f2aba5dd", + "https://deno.land/x/clippy@v0.2.2/platform/windows.ts": "c83adf9f54b452a9adc84eacf9498ec5a8170274ece84c26ed93d19952cd834a", + "https://deno.land/x/copy_paste@v1.1.3/deps.ts": "89bfebe10979530b38b3be2ace3b24a7b83dbecb2a6cca7cd7b05b9a86fb1e61", + "https://deno.land/x/copy_paste@v1.1.3/mod.ts": "3b82d6c620749acb86398bbec1f2c1f472cc39921c22ca7d7a98ab682b170f20", + "https://deno.land/x/plug@1.0.1/deps.ts": "35ea2acd5e3e11846817a429b7ef4bec47b80f2d988f5d63797147134cbd35c2", + "https://deno.land/x/plug@1.0.1/download.ts": "8d6a023ade0806a0653b48cd5f6f8b15fcfaa1dbf2aa1f4bc90fc5732d27b144", + "https://deno.land/x/plug@1.0.1/mod.ts": "5dec80ee7a3a325be45c03439558531bce7707ac118f4376cebbd6740ff24bfb", + "https://deno.land/x/plug@1.0.1/types.ts": "d8eb738fc6ed883e6abf77093442c2f0b71af9090f15c7613621d4039e410ee1", + "https://deno.land/x/plug@1.0.1/util.ts": "5ba8127b9adc36e070b9e22971fb8106869eea1741f452a87b4861e574f13481", + "https://esm.sh/preact-render-to-string@5.2.0?external=preact": "834df8d191aa1435e1164e430dc68b5c42a69b1f6624e103e039a96dc702c05d", + "https://esm.sh/preact@10.16.0": "5229650cdac537f87cae81d5001e88d4e7a38cc7e77be978961d2897a733117d", + "https://esm.sh/preact@10.16.0/jsx-runtime?dts": "9e67b64a5b48299c77d30bffc213735fdcf4b3b5d4ad8ff8d4136f246de5fa34", + "https://esm.sh/stable/preact@10.16.0/denonext/jsx-runtime.js": "64770c709df77c4b64b79f84a4abf6189fd0c3ea461121870eca0cf2bcca87b0", + "https://esm.sh/stable/preact@10.16.0/denonext/preact.mjs": "01dc8bdf124926c611c0711081b9c162cf2735cccad7c2bc9914766f633ddb1d", + "https://esm.sh/v128/preact-render-to-string@5.2.0/X-ZS9wcmVhY3Q/denonext/preact-render-to-string.mjs": "b2b771d82125460bd3e5cdf20ebd662a08c4c61e34b174cd11db929dd5883966" + } +} diff --git a/html/common.tsx b/html/common.tsx index 9a1d269..cd1f5ac 100644 --- a/html/common.tsx +++ b/html/common.tsx @@ -1,28 +1,38 @@ -import { Html } from "./html.ts"; -import { Component } from "./jsx/jsx-runtime.ts"; +import { Attributes, ComponentChildren, VNode, toChildArray } from "preact"; +import { render } from "preact-render-to-string"; +import { writeText } from "copy-paste"; -export const Main: Component = (attributes, children) => ( -
- {...children} -
-); +export function Main({ + children, + ...attributes +}: { + children: ComponentChildren; + attributes?: Attributes; +}) { + return ( +
+ {...toChildArray(children)} +
+ ); +} -export const HCenter: Component = (attributes, children) => ( +export const HCenter = ({ + children, + ...attrs +}: { + children: ComponentChildren; + attrs?: Attributes; +}) => (
- {...children} + {...toChildArray(children)}
); -export const styles = (s: Record): string => - Object.entries(s) - .map(([rule, val]) => `${rule}: ${val};`) - .join(""); - -export const eggbug_emotions: Record = { +export const eggbug_emotions = { smiling: ( = { alt="eggbug, smiling" /> ), -}; +} as const; -export const EggbugImg: Component = ({ type }) => eggbug_emotions[type]; +export const EggbugImg = ({ type }: { type: keyof typeof eggbug_emotions }) => + eggbug_emotions[type]; + +export const render_and_copy = (elem: VNode) => { + const rendered = render(elem); + writeText(rendered); + console.log(rendered); +}; diff --git a/html/coq.tsx b/html/coq.tsx index 8647bb1..e97fb77 100644 --- a/html/coq.tsx +++ b/html/coq.tsx @@ -1,37 +1,55 @@ -import { Main } from "./common.tsx"; +import { Main, render_and_copy } from "./common.tsx"; import { reify_dialogue } from "./dialogue.tsx"; -import { debug_render } from "./html.ts"; -import { Component } from "./jsx/jsx-runtime.ts"; +import { ComponentChildren, toChildArray, JSX } from "preact"; -const Option: Component = ({ n }, children) => ( +const Option = ({ + n, + children, +}: { + n: number; + children: ComponentChildren; +}) => ( <> {`[${n}]`}{" "} - {...children} + {...toChildArray(children)} ); -const WaterRitual: Component = () => ( +const WaterRitual = () => ( [begin water ritual; 1 dram of{" "} water] ); -const End: Component = () => [End]; +const End = () => [End]; -const Name: Component = ({ color }, children) => ( +const Name = ({ + color, + children, +}: { + color: string; + children: ComponentChildren; +}) => (
- {...children} + {...toChildArray(children)}
); -const Speech: Component = ( - { name, name_color, portrait = <> }, - children -) => ( +const Speech = ({ + name, + name_color, + children, + portrait = <>, +}: { + name: string; + name_color: string; + children: ComponentChildren; + portrait: JSX.Element; +}) => (
{portrait}
{name} @@ -39,13 +57,19 @@ const Speech: Component = ( src="https://static.pyrope.net/coq-hr.png" alt="a snazzy horizontal rule with three central spikes, taken from caves of qud" /> -
{...children}
+
{...toChildArray(children)}
); -const Website: Component = () => website; +const Website = () => website; -const Eggbug: Component = ({ emotion }, children) => ( +const Eggbug = ({ + emotion, + children, +}: { + emotion?: "angry"; + children: ComponentChildren; +}) => ( ( /> } > - {...children} + {...toChildArray(children)} ); @@ -250,7 +274,7 @@ const dialogue = reify_dialogue([ ], ]); -debug_render( +render_and_copy(
{dialogue}
diff --git a/html/deno.json b/html/deno.json deleted file mode 100644 index ed711e5..0000000 --- a/html/deno.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "jsx": "react-jsx", - "jsxFactory": "create_element", - "jsxFragmentFactory": "create_fragment", - "jsxImportSource": "./jsx" - }, - "imports": { - "html": "./html.ts", - "./jsx/jsx-runtime": "./jsx/jsx-runtime.ts" - } -} diff --git a/html/dialogue.tsx b/html/dialogue.tsx index 44d1608..5d17028 100644 --- a/html/dialogue.tsx +++ b/html/dialogue.tsx @@ -1,13 +1,14 @@ -import { Html } from "./html.ts"; +import { JSX } from "preact"; -type DOption = [Html, Dialogue]; -type Dialogue = Html | [Html, ...DOption[]]; +type DNode = JSX.Element | string; +type DOption = [DNode, Dialogue]; +type Dialogue = DNode | [DNode, ...DOption[]]; function not_empty(arr: T[]): arr is [T, ...T[]] { return arr.length > 0; } -export function reify_dialogue(d: Dialogue): Html { +export function reify_dialogue(d: Dialogue): JSX.Element | string { if (!Array.isArray(d)) return d; const [r, ...rest] = d; diff --git a/html/eggbug-spamclick-battle.tsx b/html/eggbug-spamclick-battle.tsx index aa122a9..864537b 100644 --- a/html/eggbug-spamclick-battle.tsx +++ b/html/eggbug-spamclick-battle.tsx @@ -1,10 +1,8 @@ -import { HCenter, Main, styles } from "./common.tsx"; -import { debug_render } from "./html.ts"; -import { Component } from "./jsx/jsx-runtime.ts"; +import { EggbugImg, HCenter, Main, render_and_copy } from "./common.tsx"; -const Eggbug: Component = () => ( +const Eggbug = () => ( - + ); @@ -13,15 +11,23 @@ function health_style(current: number, last: number, max: number) { const dhealth = last - current; console.log(inc_width, dhealth); - return styles({ + return { transform: `translateX(${-(inc_width * dhealth)}%)`, width: `${last * inc_width}%`, - }); + }; } // could be generalized // might be worthwhile later since is BAN -const Health: Component = ({ current, last, max }) => ( +const Health = ({ + current, + last, + max, +}: { + current: number; + last: number; + max: number; +}) => ( console.log({ current, last, max }), (
@@ -31,7 +37,7 @@ const Health: Component = ({ current, last, max }) => ( style={health_style(current, last, max)} >
- + {Math.floor(current).toString()} @@ -42,14 +48,28 @@ const Health: Component = ({ current, last, max }) => ( ); // one-time animations of hit numbers of health flying off the screen -const BattleFrame: Component = ({ health, last_health, max_health, msg }) => ( +const BattleFrame = ({ + health, + last_health, + max_health, +}: { + health: number; + last_health: number; + max_health: number; +}) => (
); -const Defeated: Component = ({ last_health, max_health }) => ( +const Defeated = ({ + last_health, + max_health, +}: { + last_health: number; + max_health: number; +}) => (
@@ -64,35 +84,41 @@ const Defeated: Component = ({ last_health, max_health }) => (
); -const DamageNumber: Component = ({ n }) => ( +const DamageNumber = ({ n }: { n: number }) => (
{Math.round(n).toString()}
); -const Battle: Component = ({ +const Battle = ({ max_health = 100, health = max_health, last_health = health, damage_multiplier = 10, damage_bonus = 1, - ...rest -}) => +}: // ...rest +Partial<{ + max_health: number; + health: number; + last_health: number; + damage_multiplier: number; + damage_bonus: number; +}>) => health > 0 ? ( -
+
); -const Timer: Component = () => ( -
- - click this when done (HONOR SYSTEM) (EVEN AMONG EGGBUGS THERE CAN BE - HONOR) -
- {[ - ...new Array(601).fill(undefined).map((_, i) => `${i}s`), - "∞s", - ]} -
-
-
-); - // a timer would be flippin rad // (it would look like an actual scrolling clock thingie) // (because it would have to) -debug_render( +render_and_copy(
{/* */} diff --git a/html/hot_people_who_eat_croissants_are_dangerous.tsx b/html/hot_people_who_eat_croissants_are_dangerous.tsx index d603f75..818ac0a 100644 --- a/html/hot_people_who_eat_croissants_are_dangerous.tsx +++ b/html/hot_people_who_eat_croissants_are_dangerous.tsx @@ -1,6 +1,5 @@ -import { Main } from "./common.tsx"; -import { Html, debug_render, render } from "./html.ts"; -import { Component } from "./jsx/jsx-runtime.ts"; +import { JSX } from "preact"; +import { Main, render_and_copy } from "./common.tsx"; const peopleify = (...people: string[]): string[] => // non-breaking space v @@ -13,12 +12,15 @@ const wheel_style = ( width?: number, shl?: number, n?: number -): string => - `transform: translateY(calc(2rem * -${num_items})); animation: ${animation_length( +): JSX.CSSProperties => ({ + transform: `translateY(calc(2rem * -${num_items}))`, + animation: `${animation_length( num_items - )}s ease-in-out reverse none running spin; ${ - width ? `width: ${width * 100}%;` : "" - } ${shl && n ? `margin-left: -${shl * (n + 1)}px;` : ""}`; + )}s ease-in-out reverse none running spin`, + + width: width ? `width: ${width * 100}%` : undefined, + marginLeft: shl && n ? `-${shl * (n + 1)}px` : undefined, +}); const get_delays = (...lengths: number[]): number[] => { let out = [0]; @@ -28,7 +30,21 @@ const get_delays = (...lengths: number[]): number[] => { return out; }; -const Wheel: Component = ({ items, width, calc_width, shl, n, classes }, _) => ( +const Wheel = ({ + items, + width, + calc_width, + shl, + n, + classes, +}: { + items: string[]; + width?: number; + calc_width?: number; + shl?: number; + n?: number; + classes: string[]; +}) => (
{/* {...items.map((i: string) =>
{i}
)} */} @@ -38,7 +54,7 @@ const Wheel: Component = ({ items, width, calc_width, shl, n, classes }, _) => ( style={wheel_style(items.length, width)} > {/*
*/} - {...items.map((item: string, i: number) => ( + {...items.map((item, i) => (
(arr: T[]): T[][] { return arr.map(item => [...arr.filter(t => t != item), item]); } -const MultiWheel: Component = ({ items, calc_width, shl, type }, _) => ( +const MultiWheel = ({ + items, + calc_width, + shl, + type, +}: { + items: string[]; + calc_width?: number; + shl?: number; + type: string; +}) => ( {...weird_slices(items).map((sliced_items, n) => ( ( calc_width={calc_width} shl={shl} n={n} - summary_classes={[type]} + classes={[type]} /> ))} - + ); // i'll probably just hardcode the delays... lame but w/e // nope // it would be possible to have it so the final text is actually properyly selectable maybe but eh -const Take: Component = ({ subjects, objects, adjectives }, _) => ( +const Take = ({ + subjects, + objects, + adjectives, +}: { + subjects: string[]; + objects: string[]; + adjectives: string[]; +}) => (
(
); -const Checkmark: Component = () => ( +const Checkmark = () => ( ( /> ); -const Author: Component = () => ( +const Author = () => (
(
); -const Info: Component = () => ( +const Info = () => (
10:02 PM ·{" "} Feb 20, 2021 ·{" "} @@ -129,7 +163,7 @@ const Info: Component = () => (
); -const Stats: Component = () => ( +const Stats = () => (
3,228 Retweets @@ -145,7 +179,7 @@ const Stats: Component = () => ( // might want to have the final item be seperate // turned out to be unnecessary -debug_render( +render_and_copy(
; -export type Html = string | NonText; -export type NonText = { - tag: string; - attributes: Attributes; - children: Html[]; -}; - -export const Fragment = "Fragment"; - -function is_string(elem: Html): elem is string { - return typeof elem == "string"; -} - -export function fr(...children: Html[]): Html { - return { tag: Fragment, attributes: {}, children }; -} - -function div(...children: Html[]): Html { - return { tag: "div", attributes: {}, children }; -} - -function expand_fragments_in_list(children: Html[]): Html[] { - let out = []; - - for (const child of children) { - if (is_string(child)) { - out.push(child); - } else if (child.tag == Fragment) { - out.push(...child.children.map(expand_fragments)); - } else { - out.push(child); - } - } - - return out; -} - -// NOTE: if you pass a fragment to this, it won't be expanded (which makes sense if you think about it) -function expand_fragments(elem: Html): Html { - if (is_string(elem)) { - return elem; - } else { - const children = expand_fragments_in_list(elem.children ?? []); - return { ...elem, children }; - } -} - -const attr = (attrs: Attributes) => (elem: Html): Html => { - if (is_string(elem)) { - return elem; - } else { - const { tag, attributes, children } = elem; - return { tag, attributes: { ...attributes, ...attrs }, children }; - } -}; - -const escape = (unsafe: string): string => - unsafe - .replaceAll("&", "&") - .replaceAll("<", "<") - .replaceAll(">", ">") - .replaceAll('"', """) - .replaceAll("'", "'"); - -function render_attributes(attrs: Attributes): string { - return ( - (Object.keys(attrs).length > 0 ? " " : "") + - Object.entries(attrs) - .filter(([_attr, val]) => typeof val != "undefined") - .map(([attr, val]) => `${attr}="${escape((val ?? "").toString())}"`) - .join(" ") - ); -} - -function indent(str: string, amount = 4, char = " "): string { - const ind = char.repeat(amount); - return str - .split("\n") - .map((l) => ind + l) - .join("\n"); -} - -// incomplete, obviously -// i hate html -const NON_SELF_CLOSING = ["div", "p", "a", "summary"]; - -function render_elem( - { tag, attributes, children }: NonText, - mini = false, -): string { - if (children.length == 0) { - if (NON_SELF_CLOSING.includes(tag)) { - return `<${tag}${render_attributes(attributes)}>`; - } else { - return ( - `<${tag}${render_attributes(attributes)}` + (mini ? "/>" : " />") - ); - } - } else { - let inner = ""; - let string_last = false; - for (let i = 0; i < children.length; i++) { - let child = children[i]; - const rendered = render(child, mini ? "mini" : undefined); - - if (is_string(child)) { - mini && string_last && (inner += " "); - inner += rendered; - - string_last = true; - } else { - inner += rendered; - string_last = false; - } - - if (!mini && i + 1 < children.length) inner += "\n"; - } - - return [ - `<${tag}${render_attributes(attributes)}>`, - mini ? inner : indent(inner), - ``, - ].join(mini ? "" : "\n"); - } -} -// old: -// joining with " " is inefficient, but necessary for correct string behavior -// i've decided that joining with "" is worth the size savings -// THIS MEANS MINIFICATION IS SEMANTICALLY DIFFERENT -// JK I DID IT THE HARD WAY :] - -export function render(elem: Html, mini?: "mini"): string { - if (is_string(elem)) { - return escape(elem); - } else if (elem.tag == Fragment) { - // mimics react's behavior with fragments, ehhh nvm different aims - return elem.children.map((elem) => render(elem, mini)).join("\n"); - } else { - const { tag, attributes } = elem; - const expanded = expand_fragments(elem); - - if (is_string(expanded)) { - throw "impossible"; - } - - return render_elem( - { tag, attributes, children: expanded.children }, - mini == "mini", - ); - } -} - -export function debug_render(elem: Html) { - console.log(elem); - console.log(render(elem)); - const mini_render = render(elem, "mini"); - console.log(mini_render); - - writeText(mini_render); -} diff --git a/html/jsx/index.d.ts b/html/jsx/index.d.ts deleted file mode 100644 index c9af03e..0000000 --- a/html/jsx/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare namespace JSX { - export interface IntrinsicElements { - [elemName: string]: any; - } -} - -declare var React: never; diff --git a/html/jsx/jsx-runtime.ts b/html/jsx/jsx-runtime.ts deleted file mode 100644 index b8e88c4..0000000 --- a/html/jsx/jsx-runtime.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { fr, Html, Prop } from "../html.ts"; - -type SadProp = Prop | undefined | Html | Html[]; -export type Component = ( - props: CProps, - children: Html[], -) => Html; - -export type CProps = { - [key: string]: any; -}; - -interface Props { - [key: string]: typeof key extends "children" ? never : SadProp; - children: undefined | Html | Html[]; -} - -export function create_element( - type: Component | string, - props_?: Props, -): Html { - const props: Props = props_ ?? { children: [] }; - const children: Html[] = [props.children ?? []].flat().filter((c) => - typeof c == "string" || typeof c == "object" - ); - const attributes: CProps = {}; - - for (const [key, val] of Object.entries(props)) { - if ( - key == "children" || typeof val == "undefined" - ) continue; - attributes[key] = val; - } - - if (typeof type == "string") { - return { tag: type, attributes, children }; - } else { - return type(attributes, children); - } -} - -export function Fragment( - _: Record, - children: Html[], -) { - return fr(...children); -} - -export const jsx = create_element; -export const jsxs = create_element; diff --git a/html/spinny.tsx b/html/spinny.tsx index 5cd827d..421aa8d 100644 --- a/html/spinny.tsx +++ b/html/spinny.tsx @@ -1,7 +1,6 @@ -import { debug_render } from "./html.ts"; -import { Component } from "./jsx/jsx-runtime.ts"; +import { render_and_copy } from "./common.tsx"; -const Spinny: Component = ({ depth }) => ( +const Spinny = ({ depth }: { depth: number }) => (
@@ -45,7 +44,13 @@ function color(depth: number, num_squares: number): string { //TODO: MAYBE: try to get a backup pulse animation for preferes-reduced motion // low priority because it already turns off the animation thankfully // ${depth % 2 == 0 ? "cw" : "ccw"} -const Square: Component = ({ depth, num_squares }) => +const Square = ({ + depth, + num_squares, +}: { + depth: number; + num_squares: number; +}) => depth == 0 ? ( <> ) : ( @@ -57,4 +62,4 @@ const Square: Component = ({ depth, num_squares }) =>
); -debug_render(); +render_and_copy(); diff --git a/html/ttt.tsx b/html/ttt.tsx index 571fa30..691ca4f 100644 --- a/html/ttt.tsx +++ b/html/ttt.tsx @@ -1,5 +1,4 @@ -import { Html, debug_render } from "./html.ts"; -import { Component } from "./jsx/jsx-runtime.ts"; +import { render_and_copy } from "./common.tsx"; type Square = "x" | "o" | "empty"; type Row = [Square, Square, Square]; @@ -16,7 +15,7 @@ function game_over([[s1, s2, s3], [s4, s5, s6], [s7, s8, s9]]: Board): boolean { } // TODO: strike out and such -const Board: Component = ({ board, turn = 0 }) => ( +const Board = ({ board, turn = 0 }: { board: Board; turn?: number }) => (
{game_over(board) ? (
Game over!
@@ -31,35 +30,57 @@ const Board: Component = ({ board, turn = 0 }) => (
); -const Row: Component = ({ board, idx, turn }) => ( +const Row = ({ + board, + idx, + turn, +}: { + board: Board; + idx: number; + turn: number; +}) => (
- - - + + +
); -const Cell: Component = ({ board, idx, turn }) => { +const Cell = ({ + board, + idx, + turn, +}: { + board: Board; + idx: SquareIdx; + turn: number | "game over"; +}) => { + if (turn == "game over") { + return
; + } const square = get_square(board, idx); - return square == "empty" && turn != "game over" ? ( + return square == "empty" ? (
) : ( -
{square != "empty" && square}
+
{square}
); }; -const SuccBoard: Component = ({ board, idx, turn }) => { +const SuccBoard = ({ + board, + idx, + turn, +}: { + board: Board; + idx: SquareIdx; + turn: number; +}) => { const square = square_of_turn(turn); - return ( - - ); + return ; }; function get_square(board: Board, idx: SquareIdx): Square { @@ -74,4 +95,4 @@ function set_square(board: Board, idx: SquareIdx, to: Square): Board { return new_board; } -debug_render(); +render_and_copy();