Remove doc from compiler
0
compiler/Cargo.lock → Cargo.lock
generated
3
compiler/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
/target
|
||||
.vscode
|
||||
*.profraw
|
2
doc-generator/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
target
|
||||
static/en/**
|
507
doc-generator/Cargo.lock
generated
@ -1,507 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-wincon",
|
||||
"concolor-override",
|
||||
"concolor-query",
|
||||
"is-terminal",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6efb5f0a41b5ef5b50c5da28c07609c20091df0c1fc33d418fa2a7e693c2b624"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "671fcaa5debda4b9a84aa7fde49c907c8986c0e6ab927e04217c9cb74e7c8bc9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concolor-override"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
|
||||
|
||||
[[package]]
|
||||
name = "concolor-query"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"markdown",
|
||||
"misti",
|
||||
"toml",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "markdown"
|
||||
version = "1.0.0-alpha.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98de49c677e95e00eaa74c42a0b07ea55e1e0b1ebca5b2cbc7657f288cd714eb"
|
||||
dependencies = [
|
||||
"unicode-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "misti"
|
||||
version = "0.0.5"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"colored",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-id"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d70b6494226b36008c8366c288d77190b3fad2eb4c10533139c1c1f461127f1a"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
@ -1,13 +0,0 @@
|
||||
[package]
|
||||
name = "doc-generator"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
misti = { path = "../compiler"}
|
||||
clap = { version = "4.2.0", features = ["derive"] }
|
||||
markdown = "1.0.0-alpha.7"
|
||||
toml = "0.7.3"
|
||||
yaml-rust = "0.4.5"
|
@ -1,86 +0,0 @@
|
||||
# Doc-generator
|
||||
|
||||
Here is the documentation of the language in markdown, and a program to
|
||||
generate static HTML files from them.
|
||||
|
||||
## `src` folder
|
||||
|
||||
Rust code to generate HTML files from MD files.
|
||||
|
||||
The binary is called like:
|
||||
|
||||
```sh
|
||||
generator --input /path/to/markdown/folder/ --output /path/to/static/folder/
|
||||
```
|
||||
|
||||
## `markdown` folder
|
||||
|
||||
Contains the Markdown. All files inside are expected to be UTF-8 encoded
|
||||
markdown, and have the `.md` file extension.
|
||||
|
||||
### Indexing
|
||||
|
||||
`doc-generator` will not search for `.md` files. Instead, it will search for
|
||||
`.toml` files, which index all the markdown files. This is used to generate
|
||||
the file hierarchy and previous/next links in the documentation.
|
||||
|
||||
This file must be named `index.toml`, must be the only TOML file in its folder,
|
||||
and must follow the following schema:
|
||||
|
||||
```toml
|
||||
# Tipically index
|
||||
entry-point = "file-without-extension"
|
||||
|
||||
[folder-1]
|
||||
section-name = "Display name for the folder"
|
||||
# Markdown files, without the .md extension
|
||||
children = [
|
||||
"file1",
|
||||
"file2",
|
||||
]
|
||||
```
|
||||
|
||||
### Markdown extensions
|
||||
|
||||
The markdown follows the CommonMark specification, but certain code blocks
|
||||
contain custom behaviour:
|
||||
|
||||
#### `meta`
|
||||
|
||||
A code block with language `meta` contains text in TOML format that indicates
|
||||
metadata for the current page.
|
||||
|
||||
````toml
|
||||
```meta
|
||||
title: "Title of the page"
|
||||
description: "Description of the page"
|
||||
```
|
||||
````
|
||||
|
||||
- title: Used to create the title of the page with the format `{title} - Misti`
|
||||
- description: The description of the page, placed in a `<meta>` element in the `<head>`
|
||||
|
||||
|
||||
|
||||
## `static` folder
|
||||
|
||||
Contains CSS, JS, and HTML templates. Here the MD files are written to
|
||||
after being converted.
|
||||
|
||||
There must be a `template.html` file inside this folder. This file will be used to generate the HTML from MD files.
|
||||
|
||||
Inside `template.html` there must be a string `{{markdown}}`:
|
||||
|
||||
```html
|
||||
<!-- Some html -->
|
||||
{{markdown}}
|
||||
<!-- More html -->
|
||||
```
|
||||
|
||||
This string, `{{markdown}}`, will be replaced with the HTML generated
|
||||
from Markdown
|
||||
|
||||
## `dist` folder
|
||||
|
||||
Coming soon, this folder will contain all HTML, CSS & JS minified after
|
||||
running a script.
|
@ -1,17 +0,0 @@
|
||||
# Function calls
|
||||
|
||||
A function is called with parenthesis.
|
||||
|
||||
```misti
|
||||
// No parameters: place opening and closing paren
|
||||
debugState()
|
||||
|
||||
// 1 parameter
|
||||
val result = fibonacci(20)
|
||||
|
||||
// 2 or more parameters: separate the parameters with commas
|
||||
val remainder = substract(50, 30)
|
||||
val total = add(60, -30, 90)
|
||||
```
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
# Indentation rules
|
||||
|
||||
TBD
|
@ -1,80 +0,0 @@
|
||||
# Operators
|
||||
|
||||
Misti has similar operators to JS.
|
||||
|
||||
```md-warning
|
||||
Misti will enforce type checking in operators at compile time.
|
||||
<p>
|
||||
However, due to how JS works, automatic type casting may still occur if you combine the Misti output with JS.
|
||||
</p>
|
||||
```
|
||||
|
||||
## Basic operators
|
||||
|
||||
```misti
|
||||
4 + 2
|
||||
4 - 2
|
||||
4 * 2
|
||||
4 / 2
|
||||
4 % 2
|
||||
4 ** 2
|
||||
```
|
||||
|
||||
## Asignment operators
|
||||
|
||||
```misti
|
||||
i += 1
|
||||
i -= 1
|
||||
i *= 2
|
||||
i /= 2
|
||||
i %= 2
|
||||
i **= 2
|
||||
```
|
||||
|
||||
## Bitwise operators
|
||||
|
||||
Not considered at the moment.
|
||||
|
||||
|
||||
## Comparison
|
||||
|
||||
```misti
|
||||
1 == 2
|
||||
1 != 2
|
||||
1 > 2
|
||||
1 < 2
|
||||
1 >= 2
|
||||
1 <= 2
|
||||
```
|
||||
|
||||
```md-warning
|
||||
In Misti there's only double equals `==`.
|
||||
<br>
|
||||
<br>
|
||||
<code>x == y</code> will ALWAYS compile to <code>x === y</code>
|
||||
```
|
||||
|
||||
## Logical operators
|
||||
|
||||
```misti
|
||||
true && false
|
||||
true || false
|
||||
|
||||
!true
|
||||
```
|
||||
|
||||
```md-warning
|
||||
Multiple `!` are invalid, since there is no automatic type casting.
|
||||
<br>
|
||||
<br>
|
||||
<code>!!</code> would be considered a different operator.
|
||||
```
|
||||
|
||||
```md-warning
|
||||
There is no short-circuit like so something like:
|
||||
<br>
|
||||
<br>
|
||||
<code>true && "value"</code> will throw an error at compile time.
|
||||
```
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
# Simple datatypes
|
||||
|
||||
The following are the primitive datatypes. They have literal representations.
|
||||
|
||||
## Num
|
||||
|
||||
Equivalent to a number in JS.
|
||||
|
||||
```misti
|
||||
val f0 = 322
|
||||
val f1 = 10.304
|
||||
val f2 = -34.343223
|
||||
val f3 = 0.234234e+2
|
||||
val f4 = 1e+4
|
||||
```
|
||||
|
||||
A floating point number __must__ have a digit before and after the dot.
|
||||
|
||||
```misti
|
||||
val valid1 = 0.45
|
||||
val valid2 = 13.0
|
||||
|
||||
// Will not be considered as floating point numbers
|
||||
val invalid1 = .45 // Will be interpreted as the operator `.` and the integer 45
|
||||
val invalid2 = 13. // Will be interpreted as the integer 13 and the operator `.`
|
||||
```
|
||||
|
||||
## Bool
|
||||
|
||||
True and false
|
||||
|
||||
```
|
||||
true
|
||||
false
|
||||
```
|
@ -1,61 +0,0 @@
|
||||
# Tuples
|
||||
|
||||
Tuples contain a fixed number of values of any datatype. They are denoted with
|
||||
a hash and parenthesis.
|
||||
|
||||
```misti
|
||||
val person = #("John", "Doe", 25)
|
||||
val result = #(true, 200)
|
||||
```
|
||||
|
||||
## Signature
|
||||
|
||||
```misti
|
||||
// A tuple of Str, Str and Int
|
||||
#(Str, Str, Int)
|
||||
|
||||
// An array of tuples. These tuples have a Str, Int and Bool
|
||||
Array[#(Str, Int, Bool)]
|
||||
|
||||
// A function that takes a Str and Int, and return a tuple of Str and Int
|
||||
(Str, Int) -> #(Str, Int)
|
||||
|
||||
// A function that takes a tuple of Str and Int, and returns a Bool
|
||||
(#(Str, Int)) -> Bool
|
||||
```
|
||||
|
||||
## Destructuring
|
||||
|
||||
In variable declaration
|
||||
|
||||
```misti
|
||||
val data = #("String", 322, true)
|
||||
|
||||
val #(string, number, boolean) = data
|
||||
val #(string, _, _) = data
|
||||
```
|
||||
|
||||
In function parameters
|
||||
|
||||
```misti
|
||||
// Without parameter destructuring
|
||||
fun destructure(#(Str, Int) data) {
|
||||
val #(name, age) = data
|
||||
// Computations with name, age
|
||||
}
|
||||
|
||||
|
||||
// With parameter destructuring
|
||||
fun destructure(#(Str name, Int age)) {
|
||||
// Computations with name, age
|
||||
// Note that now there is no way to refer to the whole tuple
|
||||
}
|
||||
|
||||
|
||||
// Parameter destructuring with tuple preservation
|
||||
fun destructure(#(Str name, Int age) data) {
|
||||
// Computations with name, age
|
||||
// The tuple `data` can still be referred to
|
||||
}
|
||||
```
|
||||
|
@ -1,109 +0,0 @@
|
||||
# Variables and Constants
|
||||
|
||||
Misti uses `var` for variables and `val` for constant reference variables.
|
||||
|
||||
Variables and constants must always be initialized.
|
||||
|
||||
```misti
|
||||
// A variable, its value can be modified
|
||||
var accumulator = 0
|
||||
accumulator += 1
|
||||
```
|
||||
|
||||
```misti
|
||||
// A "constant", its value cannot be modified
|
||||
val name = "Bob"
|
||||
|
||||
// Illegal, will raise an error in compile time
|
||||
name = "Mike"
|
||||
```
|
||||
|
||||
```md-info
|
||||
If a constant's value is a primitive value, it cannot be changed.
|
||||
<br />
|
||||
However, if it is a reference value, its inner attributes can still
|
||||
be changed, but not the reference itself.
|
||||
```
|
||||
|
||||
## Identifiers
|
||||
|
||||
Identifiers start with a lower case letter or underscore,
|
||||
and then can contain letters, numbers and underscores.
|
||||
They can not start with a dollar sign.
|
||||
|
||||
```misti
|
||||
variable
|
||||
_variable
|
||||
|
||||
var1
|
||||
v4r
|
||||
```
|
||||
|
||||
If an identifier starts with an upper case letter, it is considered to be
|
||||
a Datatype.
|
||||
|
||||
```misti
|
||||
Str
|
||||
Num
|
||||
Bool
|
||||
Array
|
||||
Map
|
||||
|
||||
CustomDatatype
|
||||
```
|
||||
|
||||
## Type inference
|
||||
|
||||
Variable declarations have type inference.
|
||||
|
||||
```misti
|
||||
val anInteger = 40
|
||||
val aFloat = 10.20e+4
|
||||
var aBoolean = true
|
||||
```
|
||||
|
||||
The datatype can be optionally specified by placing it before `var` or `val`.
|
||||
|
||||
```misti
|
||||
Int val anInteger = 40
|
||||
Float val aFloat = 10.20e+4
|
||||
Bool var aBoolean = true
|
||||
```
|
||||
|
||||
However, if the variable is a constant created with `val`,
|
||||
this keyword is optional.
|
||||
|
||||
So, the following are equivalent.
|
||||
|
||||
```misti
|
||||
Str val name = "Juan"
|
||||
// is equivalent to
|
||||
Str name = "Juan"
|
||||
```
|
||||
|
||||
It is not possible to omit `var`. So the following will not mean the same.
|
||||
|
||||
```misti
|
||||
Str var age = 20
|
||||
// is not equivalent to
|
||||
Str age = 20
|
||||
|
||||
// the previous statement is equivalent to:
|
||||
// Str val age = 20
|
||||
```
|
||||
|
||||
The second statement will declare a constant, not a variable.
|
||||
|
||||
|
||||
## Assign a block to a variable
|
||||
|
||||
Assigning a block to a variable will execute the block,
|
||||
and the last expression will be the value of the variable.
|
||||
|
||||
```misti
|
||||
val roi =
|
||||
val income = someIncomeCalculation()
|
||||
val investment = 25000
|
||||
income / investment // This will be the value of `roi`
|
||||
```
|
||||
|
@ -1,15 +0,0 @@
|
||||
# Classes
|
||||
|
||||
```misti
|
||||
class Token(Str value, Int lineNumber, Int position)
|
||||
|
||||
val token1 = Token("if", 0, 0)
|
||||
val token2 = Token(value: "else", lineNumber: 1, position: 4)
|
||||
```
|
||||
|
||||
```misti
|
||||
class FunToken(Int lineNumber, Int position)
|
||||
-> Token("fun", lineNumber, position)
|
||||
|
||||
val funToken1 = FunToken(3, 0)
|
||||
```
|
@ -1,49 +0,0 @@
|
||||
# Arrays
|
||||
|
||||
Arrays in Misti don't have special syntax for declaration.
|
||||
They are created the following way instead:
|
||||
|
||||
```misti
|
||||
// Array[Int]
|
||||
val numbers = Array(10, 20, 30)
|
||||
// Array[Str]
|
||||
val names = Array("Pablo", "Kim", "Mike")
|
||||
```
|
||||
|
||||
Accessing or mutating the array use a similar syntax to other languages.
|
||||
|
||||
```misti
|
||||
// Access. Note the dot
|
||||
val secondNumber = numbers.[1]
|
||||
|
||||
// Mutation. Note the dot
|
||||
names.[2] = "Josh"
|
||||
```
|
||||
|
||||
```md-warning
|
||||
Place a dot between the array and square brackets to access or mutate an array.
|
||||
<br>
|
||||
<br>
|
||||
If you don't place a dot, it will be interpreted as a generic parameter.
|
||||
```
|
||||
|
||||
## Importance of placing a dot
|
||||
|
||||
If there is no dot between the array and square brackets, then it is parsed
|
||||
as a generic parameter.
|
||||
|
||||
```misti
|
||||
// Access or mutation
|
||||
variable.[index]
|
||||
val n = numbers.[0]
|
||||
numbers.[1] = 20
|
||||
|
||||
// Generic parameter
|
||||
arrayOf[Datatype]
|
||||
arrayOf[Str]
|
||||
arrayOf[Bool]
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
# Conditionals
|
||||
|
||||
Conditionals in Misti surround the condition with keywords,
|
||||
and the body of each condition is defined with indentation.
|
||||
|
||||
```Misti
|
||||
if condition do
|
||||
// code...
|
||||
else if anotherCondition do
|
||||
// code...
|
||||
else
|
||||
// more code...
|
||||
```
|
||||
|
||||
Conditionals are expressions, they evaluate to the last expression
|
||||
in each branch.
|
||||
|
||||
```misti
|
||||
val result = if condition do value1 else value2
|
||||
```
|
||||
|
||||
## Early return
|
||||
|
||||
If you need to return early based on a condition,
|
||||
you can use `ret` instead of `do` in a confition. The last expression of
|
||||
the block will be returned
|
||||
|
||||
```misti
|
||||
if condition ret
|
||||
// code...
|
||||
computedValue // this will be returned
|
||||
```
|
||||
|
@ -1,25 +0,0 @@
|
||||
# Loops
|
||||
|
||||
Loops are indentation-sensitive.
|
||||
|
||||
## For each
|
||||
|
||||
```misti
|
||||
// Loop through an object
|
||||
for key in object do
|
||||
print(key)
|
||||
|
||||
|
||||
// Loop through an array
|
||||
for value of array do
|
||||
print(value)
|
||||
```
|
||||
|
||||
## While
|
||||
|
||||
```misti
|
||||
while condition do
|
||||
print("loop")
|
||||
```
|
||||
|
||||
|
@ -1,89 +0,0 @@
|
||||
# Function definition
|
||||
|
||||
Functions are defined with `fun` followed by the name of the function,
|
||||
the parameters, the return type, `=` and an expression.
|
||||
|
||||
## Function with no parameters
|
||||
|
||||
To declare a function with no parameters include `()`, and call it with `()`.
|
||||
|
||||
```misti
|
||||
fun getName() =
|
||||
// code...
|
||||
|
||||
val name = getName()
|
||||
```
|
||||
|
||||
## Function that returns void/nothing
|
||||
|
||||
In Misti we return `Unit` instead of `void`, `null`, `undefined` or others.
|
||||
|
||||
So a function that doesn't return anything, would return `Unit`.
|
||||
|
||||
```misti
|
||||
// This function just prints Hello and returns
|
||||
fun printHello() -> Unit =
|
||||
print("Hello")
|
||||
```
|
||||
|
||||
This type, `Unit`, is treated like `void`, so it is ignored.
|
||||
|
||||
If a function doesn't return anything, `Unit` can be omitted.
|
||||
|
||||
```misti
|
||||
// This first declaration
|
||||
fun doSomething() -> Unit =
|
||||
something()
|
||||
|
||||
|
||||
// is equivalent to this one
|
||||
fun doSomething() =
|
||||
something()
|
||||
```
|
||||
|
||||
## Function with return
|
||||
|
||||
First, the return type must be defined in the declaration.
|
||||
|
||||
Let's say that a function `getLuckyNumber` returns a Float, then it
|
||||
would be declared like this:
|
||||
|
||||
```misti
|
||||
fun getLuckyNumber() -> Float =
|
||||
// Body of the function
|
||||
```
|
||||
|
||||
And finally, the return value is the last expression in the function.
|
||||
The following function will return 7.
|
||||
|
||||
```misti
|
||||
fun getLuckyNumber() -> Float =
|
||||
// This '7' is the last expression, so it will be returned
|
||||
7
|
||||
|
||||
|
||||
val number = getLuckyNumber() // number = 7
|
||||
```
|
||||
|
||||
## Return multiple values
|
||||
|
||||
We can use a tuple if we need to return multiple values.
|
||||
|
||||
```misti
|
||||
fun getPerson() -> #(Str, Int) =
|
||||
// Logic...
|
||||
#("Kim", 33)
|
||||
|
||||
|
||||
fun tupleContains(#(Str, Int) data, Str key) -> #(Bool, Int) =
|
||||
val #(currentKey, value) = data
|
||||
if currentKey == key do
|
||||
#(true, value)
|
||||
else
|
||||
#(false, 0)
|
||||
|
||||
|
||||
tupleContains(#("Test", 200), "Test")
|
||||
```
|
||||
|
||||
|
@ -1,67 +0,0 @@
|
||||
# Anonymous functions/Lambdas
|
||||
|
||||
```md-info
|
||||
Subject to change
|
||||
```
|
||||
|
||||
An anonymous consists of the `fn` keyword, parameters and body.
|
||||
|
||||
```misti
|
||||
fn (x, y) {
|
||||
// Body
|
||||
x + y
|
||||
}
|
||||
```
|
||||
|
||||
The following types are optional, if we can be able to infer them:
|
||||
|
||||
- The types of the parameters
|
||||
- The return type
|
||||
|
||||
If used, they would look like this:
|
||||
|
||||
```misti
|
||||
fn (Int x, Int y) -> Int {
|
||||
// Body
|
||||
x + y
|
||||
}
|
||||
```
|
||||
|
||||
## Lambdas
|
||||
|
||||
If an anonymous function doesn't have parameters, the `fn` keyword may be omitted.
|
||||
This is called a lambda.
|
||||
|
||||
```misti
|
||||
{ doSomething() }
|
||||
|
||||
// The above lambda is equivalent to:
|
||||
fn () {
|
||||
doSomething()
|
||||
}
|
||||
```
|
||||
|
||||
## Inferred arguments
|
||||
|
||||
If the arguments of the lambda don't need names, the following
|
||||
syntax can be used.
|
||||
|
||||
```misti
|
||||
{ $1 + $2 }
|
||||
```
|
||||
|
||||
Inside a short lambda you can use `$1`, `$2`, `$3`, etc. to refer to the
|
||||
parameters of the lambda.
|
||||
|
||||
So the following are the same:
|
||||
|
||||
```misti
|
||||
{ $1 + $2 }
|
||||
|
||||
// The same as:
|
||||
fn (x, y) {
|
||||
x + y
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1,101 +0,0 @@
|
||||
# Function parameters
|
||||
|
||||
## Function with 1 parameter
|
||||
|
||||
Place the parameter's datatype after the function's name, then the name of the parameter.
|
||||
|
||||
For example, a function that takes a `Str` as parameter is defined as follows:
|
||||
|
||||
```misti
|
||||
fun sayHello(Str name) =
|
||||
// Body of the function
|
||||
```
|
||||
|
||||
Then the parameter `name` can be used.
|
||||
|
||||
```misti
|
||||
fun sayHello(Str name) =
|
||||
print("Hello {name}")
|
||||
```
|
||||
|
||||
## Function with 2 or more parameters
|
||||
|
||||
The parameters are separated with commas:
|
||||
|
||||
```misti
|
||||
// 2 parameters: x and y, both Int
|
||||
fun add(Int x, Int y) -> Int =
|
||||
x + y
|
||||
```
|
||||
|
||||
```misti
|
||||
// 3 parameters
|
||||
fun substring(Str input, Int start, Int end) -> Str =
|
||||
// Logic...
|
||||
```
|
||||
|
||||
And so on.
|
||||
|
||||
## Generic parameters
|
||||
|
||||
Generic parameters consist of an uppercase letter enclosed in square brackets.
|
||||
They are placed after the function name, but before the parameters list.
|
||||
|
||||
```misti
|
||||
fun getItemAt[T](Array[T] arr, Int pos) -> T =
|
||||
// Function body
|
||||
```
|
||||
|
||||
When calling the function, the generic parameter is placed in the same position.
|
||||
|
||||
```misti
|
||||
val thirdName = getItemAt[String](names, 2)
|
||||
```
|
||||
|
||||
If the generic parameter can be inferred, it's not necessary to put it.
|
||||
|
||||
```misti
|
||||
// Will be a String, inferred
|
||||
val thirdName = getItemAt(names, 2)
|
||||
```
|
||||
|
||||
## Named parameters
|
||||
|
||||
When calling a function you can link the name of an argument to its value.
|
||||
In the following function, `substring` has 3 parameters: `string`, `start` and `end`.
|
||||
|
||||
```misti
|
||||
fun substring(Str string, Int start, Int end) =
|
||||
// Body of the function
|
||||
```
|
||||
|
||||
Then, when calling the function, you can specify each parameter and their values.
|
||||
|
||||
```misti
|
||||
// Without named parameters
|
||||
substring("Hello, world!", 7, 12)
|
||||
|
||||
// With named parameters
|
||||
substring(string: "Hello, world!", start: 7, end: 12)
|
||||
|
||||
substring(
|
||||
string: "Hello, world!",
|
||||
start: 7,
|
||||
end: 12,
|
||||
)
|
||||
```
|
||||
|
||||
This will return `"world"`.
|
||||
|
||||
You can do computations with named parameters as well.
|
||||
|
||||
```misti
|
||||
substring(string: "Hello, world!", start: 12 - 5, end: 48 / 4)
|
||||
|
||||
substring(
|
||||
string: "Hello, world!",
|
||||
start: 12 - 5,
|
||||
end: 48 / 4,
|
||||
)
|
||||
```
|
||||
|
@ -1,396 +0,0 @@
|
||||
# Welcome
|
||||
|
||||
Misti is _yet another_ toy language to replace JavaScript.
|
||||
|
||||
__Misti is indentation based.__
|
||||
|
||||
It's objectives are:
|
||||
|
||||
- Reduce compilation times using Rust.
|
||||
|
||||
- Improve code quality by making the language more expressive.
|
||||
- Make the language easy to understand by using a consistent syntax (at the expense of familiarity).
|
||||
- Integrate with existing TypeScript definitions by importing and exporting `.d.ts` files.
|
||||
- Serve as a side project.
|
||||
|
||||
The purpose of the language is to address many of the limitations of JS.
|
||||
To serve that end, __many concepts from JS may be completely omitted
|
||||
or replaced with different syntax/semantics__.
|
||||
|
||||
Such things will be noted in the documentation where neccesary.
|
||||
|
||||
## Syntax summary
|
||||
|
||||
## Variables and constants
|
||||
|
||||
```misti
|
||||
//
|
||||
// Variables and constants
|
||||
//
|
||||
var aVariable = 20
|
||||
val aConstant = 30
|
||||
aVariable = 40
|
||||
// | semi colons not required
|
||||
|
||||
|
||||
// Specify the datatype of a constant
|
||||
Num aConstant = 30 // <- `val` is optional
|
||||
|
||||
// Specify the datatype of a variable
|
||||
Num var aVariable = 20 // <- `var` required
|
||||
|
||||
// You can assign the result of many operations to a variable
|
||||
val roi = do {
|
||||
val income = someIncomeCalculation()
|
||||
val investment = 25000
|
||||
income / investment // This will be the value of `roi`
|
||||
}
|
||||
```
|
||||
|
||||
## Basic datatypes
|
||||
|
||||
```misti
|
||||
//
|
||||
// Basic datatypes
|
||||
//
|
||||
Num number = 40.12345
|
||||
Bool boolean = true
|
||||
Str string = "John Doe"
|
||||
```
|
||||
|
||||
## Conditionals
|
||||
|
||||
```misti
|
||||
//
|
||||
// Conditionals
|
||||
//
|
||||
if name == "John Doe" {
|
||||
val message = "Hello John"
|
||||
console.log(message)
|
||||
} else if name == "Mark" {
|
||||
console.log("Hi Mark!")
|
||||
} else {
|
||||
console.log("Hello there")
|
||||
}
|
||||
|
||||
|
||||
// You can use conditionals as expressions
|
||||
val response = if risk < 0.2 { "Go ahead" } else { "Don't" }
|
||||
|
||||
// There is no ternary conditional
|
||||
```
|
||||
|
||||
## Arrays
|
||||
|
||||
```misti
|
||||
//
|
||||
// Arrays
|
||||
//
|
||||
val dates = Array(1990, 1995, 2014, 2015, 2017)
|
||||
// | There isn't special syntax for array declaration
|
||||
// so you can't do `[1990, 1995, ...]`
|
||||
|
||||
val firstDate = dates.[0]
|
||||
// | Notice the dot for access
|
||||
|
||||
dates.[4] = 2018
|
||||
// | Dot for mutation
|
||||
|
||||
// Array signature
|
||||
Array[Num] dates = Array(1990, 1995, 2014, 2015, 2017)
|
||||
// | Square brackets are used for generics
|
||||
// instead of angle brackes.
|
||||
```
|
||||
|
||||
## Tuples
|
||||
|
||||
```misti
|
||||
//
|
||||
// Tuples
|
||||
//
|
||||
val person = #("John", 30, true)
|
||||
|
||||
// Destructuring
|
||||
var #(name, age, isMarried) = person
|
||||
|
||||
// Tuple signature
|
||||
#(Str, Num, Bool) signature = #("John", 30, true)
|
||||
```
|
||||
|
||||
## Loops
|
||||
|
||||
```misti
|
||||
//
|
||||
// Loops
|
||||
//
|
||||
for #(key, value) in object {
|
||||
console.log("key: {key}, value: {value}")
|
||||
}
|
||||
|
||||
for value of array {
|
||||
console.log("value: {value}")
|
||||
}
|
||||
|
||||
|
||||
while condition {
|
||||
print("while")
|
||||
}
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
```misti
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
console.log("Enclose the parameters in parens")
|
||||
|
||||
add(10, 20)
|
||||
|
||||
// Named parameters
|
||||
substring(input: "Hello, world!", start: 7, end: 12)
|
||||
|
||||
// Funtion declaration
|
||||
fun add(Num x, Num y) -> Num {
|
||||
x + y
|
||||
}
|
||||
|
||||
// Function with default value
|
||||
fun calculate(Num price, Num discount = 0.0) {
|
||||
val total = price * (1.0 - discount)
|
||||
console.log("Your total is {total}$")
|
||||
}
|
||||
|
||||
calculate(100, 0.25) // "Your total is 75$"
|
||||
calculate(100) // "Your total is 100$"
|
||||
```
|
||||
|
||||
## Objects
|
||||
|
||||
```misti
|
||||
//
|
||||
// Objects
|
||||
//
|
||||
|
||||
type Person = #{
|
||||
Str name,
|
||||
Num age,
|
||||
}
|
||||
|
||||
val john = Person #{
|
||||
name: "John",
|
||||
age: 21,
|
||||
}
|
||||
|
||||
// An object with arbitrary keys/values
|
||||
val randomObject = #{
|
||||
key1: "Any value"
|
||||
key2: 322,
|
||||
key3: true,
|
||||
key4: #{
|
||||
key5: "zzz",
|
||||
},
|
||||
key6: Person #{
|
||||
name: "Sarah",
|
||||
age: 20,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Classes
|
||||
|
||||
```misti
|
||||
//
|
||||
// Classes
|
||||
//
|
||||
|
||||
// Declare a simple class
|
||||
class Shape
|
||||
|
||||
|
||||
// Classes can not be extended by default.
|
||||
// To allow inheritance, use @open
|
||||
@open
|
||||
class Shape =
|
||||
// By default methods can not be overrided.
|
||||
// To allow it, use @open
|
||||
@open
|
||||
fun printName() =
|
||||
print("Generic Shape")
|
||||
|
||||
|
||||
val shape = Shape()
|
||||
// | There's no `new` keyword, just call the class
|
||||
|
||||
shape.printName() // "Generic Shape"
|
||||
|
||||
|
||||
@open
|
||||
class Rectangle(Num height, Num length) -> Shape() =
|
||||
// | Constructor parameters
|
||||
|
||||
// Properties are always private
|
||||
val vertexCount = 4
|
||||
|
||||
// Methods are private by default
|
||||
fun perimeter() -> Num =
|
||||
(height + length) * 2
|
||||
|
||||
|
||||
// To make a method public add @pub
|
||||
@pub
|
||||
fun area() -> Num =
|
||||
height * length
|
||||
|
||||
|
||||
// Method override
|
||||
@override
|
||||
fun printName() =
|
||||
print("A rectangle")
|
||||
|
||||
|
||||
val rectangle = Rectangle(10, 20)
|
||||
rectangle.area() // 200
|
||||
rectangle.printName() // "A rectangle"
|
||||
|
||||
|
||||
class Square(Num length) -> Rectangle(length, length) =
|
||||
// | Inheritance
|
||||
|
||||
@override
|
||||
fun printName() =
|
||||
console.log("A square")
|
||||
|
||||
|
||||
fun printInfo() =
|
||||
// Use $ to refer to methods/properties of the parent class
|
||||
console.log("A square with perimeter = {$perimeter()} and area = {$area()}")
|
||||
```
|
||||
|
||||
## Null safety
|
||||
|
||||
```misti
|
||||
//
|
||||
// Null safety
|
||||
//
|
||||
|
||||
// Operations that may fail return an Option value
|
||||
fun divide(Int numerator, Int denominator) -> Option[Num] =
|
||||
if denominator == 0 do
|
||||
None // Equivalent to `null`
|
||||
else
|
||||
Some(numerator / denominator)
|
||||
|
||||
|
||||
val possibleResult = divide(10, 5)
|
||||
|
||||
if val Some(result) = possibleResult do
|
||||
print("The result of the division is {result}")
|
||||
else
|
||||
print("Division by zero")
|
||||
|
||||
|
||||
// `Type?` is syntax sugar for Option[Type]
|
||||
Num? roi = divide(income, investment)
|
||||
```
|
||||
|
||||
## Error handling
|
||||
|
||||
```misti
|
||||
//
|
||||
// Error handling
|
||||
//
|
||||
|
||||
// A recoverable error
|
||||
fun testVersionNumber(Str version) -> Result[Int, Str] =
|
||||
if version == "10" do
|
||||
Ok(10)
|
||||
else if version == "11" do
|
||||
Ok(11)
|
||||
else
|
||||
Err("Invalid version")
|
||||
|
||||
|
||||
// Legacy try-catch (may change)
|
||||
try problematicExpression() with
|
||||
| Error(e) ->
|
||||
// do something
|
||||
// must return an expression
|
||||
10
|
||||
```
|
||||
|
||||
## Pattern matching
|
||||
|
||||
```misti
|
||||
//
|
||||
// Pattern matching
|
||||
//
|
||||
|
||||
match age with
|
||||
| 10 ->
|
||||
// executes when age == 10
|
||||
| 11 | 12 | 13 ->
|
||||
// when age == 11, 12 or 13
|
||||
| _ ->
|
||||
// when none of the conditions match
|
||||
|
||||
|
||||
Str? result = someOperation()
|
||||
match result with
|
||||
| Some(value) ->
|
||||
// value is a Str
|
||||
// do operations with v
|
||||
| None ->
|
||||
// Handle empty return
|
||||
|
||||
|
||||
Result[Num, Str] result = someOtherOperation()
|
||||
match result with
|
||||
| Ok(number) ->
|
||||
// number is Num
|
||||
| Err(reason) ->
|
||||
// reason is Str
|
||||
|
||||
|
||||
Result[Num, Str] result = someOtherOperation()
|
||||
match result with
|
||||
| Ok(number) if number > 18 ->
|
||||
// This matches if number > 18
|
||||
| Ok(number) ->
|
||||
// This matches if number <= 18
|
||||
| Err(reason) ->
|
||||
// reason is Str
|
||||
```
|
||||
|
||||
## JSX
|
||||
|
||||
```misti
|
||||
use Solid.{createSignal}
|
||||
use Search
|
||||
use Person
|
||||
use Registers
|
||||
use NewRegister
|
||||
|
||||
pub fun 'Certs() {
|
||||
val #(person, setPerson) = createSignal[Person?](None)
|
||||
val #(lastUpdate, setLastUpdate) = createSignal(0)
|
||||
|
||||
<div>
|
||||
<h1
|
||||
class="px-4 py-2 text-2xl font-bold"
|
||||
>
|
||||
Registrar certificado
|
||||
</h1>
|
||||
<Search setPerson={setPerson}/>
|
||||
<Registers person={person()} lastUpdate={lastUpdate()} />
|
||||
<NewRegister
|
||||
personId={person()?.id ?? -1}
|
||||
onSuccess={{setLastUpdate {$ + 1}}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
path: ""
|
||||
name: ""
|
||||
has_index: true
|
||||
children:
|
||||
- path: index
|
||||
name: Index
|
||||
|
||||
- path: basics
|
||||
name: Basics
|
||||
children:
|
||||
- path: variables-and-constants
|
||||
name: Variables and constants
|
||||
- path: simple-datatypes
|
||||
name: Simple datatypes
|
||||
- path: function-calls
|
||||
name: Function calls
|
||||
- path: operators
|
||||
name: Operators
|
||||
- path: tuples
|
||||
name: Tuples
|
||||
- path: indentation-rules
|
||||
name: Indentation rules
|
||||
|
||||
- path: flow-control
|
||||
name: Flow control
|
||||
children:
|
||||
- path: conditionals
|
||||
name: Conditionals
|
||||
- path: arrays
|
||||
name: Arrays
|
||||
- path: loops
|
||||
name: Loops
|
||||
|
||||
- path: functions
|
||||
name: Functions
|
||||
children:
|
||||
- path: definition
|
||||
name: Definition
|
||||
- path: lambdas
|
||||
name: Lambdas
|
||||
- path: parameters
|
||||
name: Parameters
|
||||
|
||||
- path: objects
|
||||
name: Objects
|
||||
children:
|
||||
- path: definition
|
||||
name: Definition
|
||||
|
||||
- path: classes
|
||||
name: Classes
|
||||
children:
|
||||
- path: definition
|
||||
name: Definition
|
||||
|
||||
- path: modules
|
||||
name: Modules
|
||||
children:
|
||||
- path: import
|
||||
name: Import
|
@ -1,34 +0,0 @@
|
||||
# Modules
|
||||
|
||||
```md-info
|
||||
Subject to change
|
||||
```
|
||||
|
||||
## Idea 1: Copy ES2015 modules
|
||||
|
||||
```misti
|
||||
import React, {useState} from "react"
|
||||
import "./utils/math"
|
||||
```
|
||||
|
||||
## Idea 2: Python-like ES2015 modules
|
||||
|
||||
```misti
|
||||
from "react" import React, {useState}
|
||||
import "./utils/math"
|
||||
```
|
||||
|
||||
## Idea 3: F#-like modules
|
||||
|
||||
```misti
|
||||
use React
|
||||
use Math
|
||||
```
|
||||
|
||||
## Idea 4: Java-like modules
|
||||
|
||||
```misti
|
||||
use React
|
||||
use utils.Math
|
||||
```
|
||||
|
@ -1,34 +0,0 @@
|
||||
# Definition
|
||||
|
||||
Objects are defined with the syntax `#{}`
|
||||
|
||||
Objects should have a definition that specifies which fields it accepts.
|
||||
|
||||
```misti
|
||||
type Position = #{
|
||||
Num latitude,
|
||||
Num longitude,
|
||||
}
|
||||
|
||||
val position = Position #{
|
||||
latitude: -93.0838749,
|
||||
longitude: 80.2847561,
|
||||
}
|
||||
|
||||
// Destructure
|
||||
val Position #{latitude: lat, longitude: long} = position
|
||||
|
||||
```
|
||||
|
||||
## Arbitrary keys and values
|
||||
|
||||
|
||||
```misti
|
||||
val object2 = #{
|
||||
key1: "sample",
|
||||
key2: "text",
|
||||
key3: 322,
|
||||
}
|
||||
|
||||
object2.key1
|
||||
```
|
@ -1 +0,0 @@
|
||||
# Stdlib index
|
@ -1,10 +0,0 @@
|
||||
path: ""
|
||||
name: ""
|
||||
children:
|
||||
- path: prelude
|
||||
name: Prelude
|
||||
children:
|
||||
- path: String
|
||||
name: String
|
||||
- path: Console
|
||||
name: Console
|
@ -1,26 +0,0 @@
|
||||
# Console
|
||||
|
||||
## Overview
|
||||
|
||||
The console module contains functions useful for debugging.
|
||||
|
||||
## Functions
|
||||
|
||||
### `fun log(Any ...objects)`
|
||||
|
||||
Outputs a message to the console of the system, with a new line.
|
||||
|
||||
When called without parameters, it prints just the new line.
|
||||
|
||||
```
|
||||
Console.log() // Prints: `\n`
|
||||
```
|
||||
|
||||
When called with one or more parameters, it first converts those
|
||||
parameters to strings, joins them with white space, then prints them.
|
||||
|
||||
```
|
||||
Console.log("message") // Prints: `message\n`
|
||||
|
||||
Console.log("message", "value") // Prints: `message value\n`
|
||||
```
|
@ -1,421 +0,0 @@
|
||||
# String
|
||||
|
||||
A collection of UTF-16 characters.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Strings are a primitive datatype that contain a series of UTF-16 encoded characters.
|
||||
|
||||
To create a string use double quotes:
|
||||
|
||||
```misti
|
||||
val greeting = "Hello there!"
|
||||
|
||||
// With type annotation
|
||||
Str greeting = "Hello there!"
|
||||
```
|
||||
|
||||
```md-warning
|
||||
Misti doesn't allow string creation with single quotes <code>''</code>.
|
||||
```
|
||||
|
||||
Strings can be concatenated with the plus `+` operator:
|
||||
|
||||
```misti
|
||||
val name = "John"
|
||||
val greeting = "Hello"
|
||||
|
||||
val fullGreeting = greeting + " " + name + "!"
|
||||
// fullGreeting = "Hello John!"
|
||||
```
|
||||
|
||||
In the future, the language will support string concatenation and multi-line strings.
|
||||
|
||||
## String comparison
|
||||
|
||||
To check if two strings are the same use the equal-to `==` operator.
|
||||
|
||||
```misti
|
||||
"Hello" == "Hello" //: true
|
||||
"Hello" == "hello" //: false
|
||||
```
|
||||
|
||||
To check if two strings are different use the not-equal-to `!=` operator.
|
||||
|
||||
```misti
|
||||
"abc" != "123" //: true
|
||||
"xyz" != "xyz" //: false
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
Comparing strings with `<`, `<=`, `>` & `>=` will compare each character of the string,
|
||||
based on the UTF-16 value.
|
||||
|
||||
```misti
|
||||
"a" < "b" //: true
|
||||
"a" < "A" //: false
|
||||
|
||||
"aab" > "aac" //: false
|
||||
"aab" < "aac" //: true
|
||||
```
|
||||
|
||||
## Automatic String conversion
|
||||
|
||||
Misti __does not__ automatically convert other datatypes to String.
|
||||
|
||||
```misti
|
||||
val sentence = "My age is: " + 20 // This will throw an error
|
||||
// ^
|
||||
// Cannot concatenate a String and a Number.
|
||||
```
|
||||
|
||||
To do so use the method `.toStr()` to explicitly convert to String.
|
||||
|
||||
```misti
|
||||
val sentence = "My age is: " + 20.toStr() // ok
|
||||
```
|
||||
|
||||
In the future, string interpolation will coerce datatypes into strings.
|
||||
|
||||
|
||||
## Escape characters
|
||||
|
||||
Misti supports the following escape characters:
|
||||
|
||||
- `\"`
|
||||
|
||||
- `\\`
|
||||
- `\n`
|
||||
- `\r`
|
||||
- `\t`
|
||||
- `\b`
|
||||
|
||||
---
|
||||
|
||||
## API
|
||||
|
||||
Prelude's `Str` contains methods and functions created for their usage within Misti.
|
||||
|
||||
To access the underlying JavaScript methods, use the `js.String` module.
|
||||
|
||||
|
||||
### Constructor
|
||||
|
||||
```misti
|
||||
class String[T](T value)
|
||||
where T -> Printable
|
||||
```
|
||||
|
||||
Creates a string from `value`, by calling its `toStr` method.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- `T value`: Any value that implements `Printable`, and therefore has a `toStr` method.
|
||||
|
||||
#### Examples
|
||||
|
||||
```misti
|
||||
val age = String(20) //: "20"
|
||||
val condition = String(false) //: "false"
|
||||
val numbers = Array(1, 2, 3) |> String //: "1,2,3"
|
||||
```
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
### length
|
||||
|
||||
```misti
|
||||
Num length
|
||||
```
|
||||
|
||||
Returns the number of UTF-16 code units in the string.
|
||||
|
||||
#### Example
|
||||
|
||||
```misti
|
||||
val name = "John"
|
||||
name.length //: 4
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
---
|
||||
|
||||
## Methods
|
||||
|
||||
### charAt
|
||||
|
||||
```misti
|
||||
fun charAt(Num position) -> Str?
|
||||
```
|
||||
|
||||
Returns the UTF-16 code unit located at `position`.
|
||||
|
||||
<div class="padded">
|
||||
|
||||
#### Parameters
|
||||
|
||||
- `Num position`: An integer between `0` and the string's `length - 1`.
|
||||
|
||||
#### Return
|
||||
|
||||
- `Str?`: The character at `position`, or `None` if it's invalid
|
||||
|
||||
#### Description
|
||||
|
||||
In a string with `length` characters, this method returns the character (UTF-16 code point)
|
||||
located at `position`, if it is true that `0 <= position < length`.
|
||||
|
||||
If `position` is out of range, this method will return `None`.
|
||||
|
||||
#### Examples
|
||||
|
||||
```misti
|
||||
val name = "John Doe"
|
||||
|
||||
name.charAt(0) //: Some("J")
|
||||
name.charAt(1) //: Some("o")
|
||||
name.charAt(7) //: Some("e")
|
||||
|
||||
name.charAt(-1) //: None
|
||||
name.charAt(8) //: None
|
||||
```
|
||||
|
||||
If you are sure that the position is valid, you can use the `!!` operator to get
|
||||
the value directly, instead of a `Maybe`.
|
||||
|
||||
```misti
|
||||
val greeting = "Hello!"
|
||||
|
||||
name.charAt(4)!! //: "o"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### charCodeAt
|
||||
|
||||
```misti
|
||||
fun charCodeAt(Num position) -> Num?
|
||||
```
|
||||
|
||||
Returns an integer between `0` and `65535` representing the UTF-16
|
||||
code unit at `position`.
|
||||
|
||||
|
||||
<div class="padded">
|
||||
|
||||
#### Parameters
|
||||
|
||||
- `Num position`: A number between `0` and the string's `length - 1`
|
||||
|
||||
#### Return
|
||||
|
||||
- `Num?`: The code unit at `position` if it's valid, or `None` if it's invalid.
|
||||
|
||||
#### Description
|
||||
|
||||
Description
|
||||
|
||||
#### Examples
|
||||
|
||||
```misti
|
||||
val letters = "ABC"
|
||||
|
||||
letters.charCodeAt(0) //: Some(65)
|
||||
letters.charCodeAt(1) //: Some(66)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### codePointAt
|
||||
|
||||
|
||||
### concat
|
||||
|
||||
```misti
|
||||
fun concat[any T](T... values) -> Str
|
||||
where T -> Printable
|
||||
```
|
||||
|
||||
Concatenates the calling string and `values`, and returns the result
|
||||
as a new `Str`
|
||||
|
||||
<div class="padded">
|
||||
|
||||
#### Type parameters
|
||||
|
||||
- `any T`: Any datatype that implements `Printable`
|
||||
|
||||
#### Parameters
|
||||
|
||||
- `T... values`: Zero or more values of type `T`
|
||||
|
||||
#### Return
|
||||
|
||||
- `Str`: A new string with the values concatenated
|
||||
|
||||
#### Description
|
||||
|
||||
`concat` concatenates the callee, and any arguments passed to it in
|
||||
a new string. The callee is not modified.
|
||||
|
||||
If the arguments don't have type `Str`, they are converted with their
|
||||
`toStr` method.
|
||||
|
||||
#### Examples
|
||||
|
||||
```misti
|
||||
val greeting = "Hello "
|
||||
|
||||
greeting.concat("world", "!") //: "Hello world!"
|
||||
greeting.concat(123) //: "Hello 123"
|
||||
greeting.concat(3, 2, 2) //: "Hello 322"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### endsWith
|
||||
|
||||
|
||||
|
||||
### includes
|
||||
|
||||
```misti
|
||||
fun includes(Str searchString, Num pos = 0) -> Bool
|
||||
```
|
||||
|
||||
Returns whether the current string contains `searchString`,
|
||||
searching from position `pos`
|
||||
|
||||
<div class="padded">
|
||||
|
||||
#### Parameters
|
||||
|
||||
- `Str searchString`: The string to search for
|
||||
- `Num pos = 0`: The position from where to start searching.
|
||||
|
||||
#### Return
|
||||
|
||||
`Bool`: `true` if searchString is found, `false` otherwise
|
||||
|
||||
#### Additional
|
||||
|
||||
If `searchString` is the empty string `""` this method returns `true`.
|
||||
|
||||
If `pos` is negative, the search starts from the first character.
|
||||
|
||||
#### Examples
|
||||
|
||||
```misti
|
||||
val loremIpsum = "Lorem ipsum dolor sit amet"
|
||||
|
||||
loremIpsum.includes("ipsum") //: true
|
||||
loremIpsum.includes("ipsum", 10) //: false
|
||||
loremIpsum.includes("ipsum", -5) //: true
|
||||
```
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
### indexOf
|
||||
|
||||
```misti
|
||||
fun indexOf(Str searchValue, Num position = 0) -> Num
|
||||
```
|
||||
|
||||
### lastIndexOf
|
||||
|
||||
fun lastIndexOf(Str searchValue, Num position = Infinity) -> Num
|
||||
|
||||
### match
|
||||
|
||||
```misti
|
||||
fun match(RegExp pattern) -> RegExpResult
|
||||
```
|
||||
|
||||
|
||||
### matchAll
|
||||
|
||||
```misti
|
||||
fun matchAll(RegExp pattern) -> Iterator[RegExpResult]
|
||||
```
|
||||
|
||||
|
||||
### normalize
|
||||
|
||||
```misti
|
||||
fun normalize(Str form = "NFC") -> String
|
||||
```
|
||||
|
||||
|
||||
### padEnd
|
||||
|
||||
```misti
|
||||
fun padEnd(Num targetLength, Str padValue = " ") -> String
|
||||
```
|
||||
|
||||
|
||||
### padStart
|
||||
|
||||
```misti
|
||||
fun padStart(Num targetLength, Str padValue = " ") -> String
|
||||
```
|
||||
|
||||
### repeat
|
||||
|
||||
```misti
|
||||
fun repeat(Num count) -> String
|
||||
```
|
||||
|
||||
### replace
|
||||
|
||||
```misti
|
||||
fun replaceAll([RegExp | Str] pattern, Str replacement) -> String
|
||||
```
|
||||
|
||||
|
||||
### replaceAll
|
||||
|
||||
```misti
|
||||
fun replaceAll([RegExp | Str] pattern, Str replacement) -> String
|
||||
```
|
||||
|
||||
|
||||
### search
|
||||
|
||||
```misti
|
||||
fun search([RegExp | Str] pattern) -> Num
|
||||
```
|
||||
|
||||
|
||||
### slice
|
||||
|
||||
```misti
|
||||
fun slice(Num start, Num? end) -> String
|
||||
```
|
||||
|
||||
|
||||
### split
|
||||
|
||||
```misti
|
||||
fun split(Str separator, Num? limit) -> Array<Str>
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,88 +0,0 @@
|
||||
use markdown::mdast::Code;
|
||||
|
||||
use super::highlighter::highlight;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for Code {
|
||||
fn to_html(&self) -> String {
|
||||
let code = highlight(&self.value);
|
||||
|
||||
if let Some(lang) = &self.lang {
|
||||
if lang == "nav" {
|
||||
return generate_nav_html(&self.value);
|
||||
}
|
||||
|
||||
format!("<pre class=\"language-{}\">{}</pre>", lang, code)
|
||||
} else {
|
||||
format!("<pre class=\"language-none\">{}</pre>", code)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
panic!("Code cannot return its raw text")
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_nav_html(data: &String) -> String {
|
||||
use toml::{Table, Value};
|
||||
|
||||
let table = data.parse::<Table>().unwrap();
|
||||
|
||||
let previous = match table.get("previous") {
|
||||
Some(Value::Table(t)) => match (t.get("href"), t.get("title")) {
|
||||
(Some(Value::String(href)), Some(Value::String(title))) => {
|
||||
format!(
|
||||
"
|
||||
<a
|
||||
class=\"inline-block px-4 py-2 transition-colors
|
||||
border border-border-color hover:border-c2-primary
|
||||
hover:text-c2-primary
|
||||
rounded-md\"
|
||||
href=\"{}\"
|
||||
>
|
||||
<span class=\"text-xs\">Previous</span>
|
||||
<br>
|
||||
<span class=\"font-bold\">{}</span>
|
||||
</a>
|
||||
",
|
||||
href, title
|
||||
)
|
||||
}
|
||||
_ => panic!("TOML error: `previous` doesn't have a href and title string."),
|
||||
},
|
||||
Some(_) => panic!("TOML error: `previous` is not a table."),
|
||||
_ => String::from("<div></div>"),
|
||||
};
|
||||
|
||||
let next = match table.get("next") {
|
||||
Some(Value::Table(t)) => match (t.get("href"), t.get("title")) {
|
||||
(Some(Value::String(href)), Some(Value::String(title))) => {
|
||||
format!(
|
||||
"
|
||||
<a
|
||||
class=\"inline-block px-4 py-2 transition-colors
|
||||
border border-border-color hover:border-c2-primary
|
||||
hover:text-c2-primary
|
||||
rounded-md text-right\"
|
||||
href=\"{}\"
|
||||
>
|
||||
<span class=\"text-xs\">Next</span>
|
||||
<br>
|
||||
<span class=\"font-bold\">{}</span>
|
||||
</a>
|
||||
",
|
||||
href, title
|
||||
)
|
||||
}
|
||||
_ => panic!("TOML error: `next` doesn't have a href and title string."),
|
||||
},
|
||||
Some(_) => panic!("TOML error: `next` is not a table."),
|
||||
_ => String::from("<div></div>"),
|
||||
};
|
||||
|
||||
format!(
|
||||
"<div class=\"grid grid-cols-2 gap-4 my-16\">{}{}</div>",
|
||||
previous, next
|
||||
)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
use markdown::mdast::Emphasis;
|
||||
|
||||
use crate::utils;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for Emphasis {
|
||||
fn to_html(&self) -> String {
|
||||
let html = utils::collect_children_html(&self.children);
|
||||
|
||||
format!("<em>{}</em>", html)
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
utils::collect_children_text(&self.children)
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
use markdown::mdast::Heading;
|
||||
|
||||
use crate::utils;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for Heading {
|
||||
fn to_html(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
result.push(node.to_html())
|
||||
}
|
||||
|
||||
let text: String = result.into_iter().collect();
|
||||
|
||||
if self.depth < 4 {
|
||||
let html_fragment_text = utils::to_html_fragment(&self.get_text());
|
||||
|
||||
format!(
|
||||
"<h{} id=\"{}\" class=\"heading-linked\"><a href=\"#{}\">{}</a></h{}>",
|
||||
self.depth, html_fragment_text, html_fragment_text, text, self.depth
|
||||
)
|
||||
} else {
|
||||
format!("<h{}>{}</h{}>", self.depth, text, self.depth)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
result.push(node.get_text())
|
||||
}
|
||||
|
||||
result.join("-")
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
use misti::TokenType;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! replace {
|
||||
($classes:literal, $token:ident, $offset:ident, $output:ident) => {{
|
||||
let start_pos = $token.position;
|
||||
let end_pos = $token.get_end_position();
|
||||
|
||||
let range = (start_pos + $offset)..(end_pos + $offset);
|
||||
let html = format!("<span class=\"token {}\">{}</span>", $classes, $token.value);
|
||||
|
||||
$offset += 28 + $classes.len();
|
||||
|
||||
$output.replace_range(range, html.as_str());
|
||||
}};
|
||||
}
|
||||
|
||||
pub fn highlight(input: &String) -> String {
|
||||
// The tokens come in order
|
||||
let tokens = misti::tokenize(&input);
|
||||
|
||||
if tokens.is_err() {
|
||||
// eprintln!("Found a lexical error processing code.\n{:?}", tokens);
|
||||
return input.clone();
|
||||
}
|
||||
|
||||
let mut output = input.clone();
|
||||
// Offset to the position of the tokens in the string, to allow
|
||||
// several tokens to be highlighted
|
||||
let mut offset = 0;
|
||||
|
||||
for token in tokens.unwrap() {
|
||||
match &token.token_type {
|
||||
TokenType::Datatype => replace!("class-name", token, offset, output),
|
||||
TokenType::Number => replace!("number", token, offset, output),
|
||||
TokenType::Identifier if token.value == "true" || token.value == "false" => {
|
||||
replace!("keyword", token, offset, output)
|
||||
}
|
||||
TokenType::String => replace!("string", token, offset, output),
|
||||
TokenType::Comment => replace!("comment", token, offset, output),
|
||||
TokenType::VAL | TokenType::VAR => replace!("keyword", token, offset, output),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_return_simple_string() {
|
||||
assert_eq!("sample", highlight(&String::from("sample")))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_highlight_datatype() {
|
||||
assert_eq!(
|
||||
"<span class=\"token class-name\">Num</span>",
|
||||
highlight(&String::from("Num"))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_highlight_number() {
|
||||
assert_eq!(
|
||||
"<span class=\"token number\">322</span>",
|
||||
highlight(&String::from("322"))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_highlight_string() {
|
||||
assert_eq!(
|
||||
"<span class=\"token string\">\"Hello\"</span>",
|
||||
highlight(&String::from("\"Hello\""))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_highlight_multiple_tokens() {
|
||||
assert_eq!(
|
||||
"<span class=\"token class-name\">Str</span> x = <span class=\"token number\">322</span>",
|
||||
highlight(&String::from("Str x = 322"))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"<span class=\"token class-name\">Str</span> x = <span class=\"token string\">\"hello\"</span> <span class=\"token number\">322</span>",
|
||||
highlight(&String::from("Str x = \"hello\" 322"))
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
use markdown::mdast::InlineCode;
|
||||
|
||||
use super::highlighter::highlight;
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for InlineCode {
|
||||
fn to_html(&self) -> String {
|
||||
/*
|
||||
let tokens = misti::tokenize(&self.value);
|
||||
println!("INLINE CODE ==== tokens ====\n\n{:?}\n\n==== code ====\n\n{}\n\n", tokens, self.value);
|
||||
|
||||
let s = self.value
|
||||
.replace("<", "<")
|
||||
.replace(">", ">");
|
||||
*/
|
||||
|
||||
format!(
|
||||
"<code class=\"border border-border-color dark:border-transparent\">{}</code>",
|
||||
highlight(&self.value)
|
||||
)
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
self.value.clone()
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
use markdown::mdast::{List, ListItem, Node};
|
||||
|
||||
use crate::utils;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for List {
|
||||
fn to_html(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
result.push(format!("<li class=\"py-2\">{}</li>", node.to_html()))
|
||||
}
|
||||
|
||||
let str: String = result.into_iter().collect();
|
||||
|
||||
if self.ordered {
|
||||
format!("<ol class=\"list-decimal list-inside\">{}</ol>", str)
|
||||
} else {
|
||||
format!("<ul class=\"list-disc list-inside\">{}</ul>", str)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
panic!("List cannot return it's raw text")
|
||||
}
|
||||
}
|
||||
|
||||
impl Printable for ListItem {
|
||||
fn to_html(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
let s = match node {
|
||||
Node::Paragraph(p) => utils::collect_children_html(&p.children),
|
||||
_ => panic!("A thing other than Paragraph inside ListItem (?)"),
|
||||
};
|
||||
result.push(format!("{}", s))
|
||||
}
|
||||
|
||||
result.into_iter().collect()
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
panic!("ListItem cannot return it's raw text")
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
use markdown::mdast::Node;
|
||||
|
||||
mod code;
|
||||
mod emphasis;
|
||||
mod heading;
|
||||
mod inline_code;
|
||||
mod list;
|
||||
mod paragraph;
|
||||
mod root;
|
||||
mod strong;
|
||||
mod text;
|
||||
|
||||
mod highlighter;
|
||||
|
||||
pub trait Printable {
|
||||
fn to_html(&self) -> String;
|
||||
fn get_text(&self) -> String;
|
||||
}
|
||||
|
||||
impl Printable for Node {
|
||||
fn to_html(&self) -> String {
|
||||
match self {
|
||||
Node::Root(root) => root.to_html(),
|
||||
Node::Heading(heading) => heading.to_html(),
|
||||
Node::Text(text) => text.to_html(),
|
||||
Node::Paragraph(p) => p.to_html(),
|
||||
Node::ThematicBreak(_) => String::from("<hr />"),
|
||||
Node::InlineCode(i) => i.to_html(),
|
||||
Node::Code(c) => c.to_html(),
|
||||
Node::Html(h) => h.value.clone(),
|
||||
Node::Strong(s) => s.to_html(),
|
||||
Node::Emphasis(e) => e.to_html(),
|
||||
Node::List(l) => l.to_html(),
|
||||
Node::ListItem(l) => l.to_html(),
|
||||
_ => format!(
|
||||
"<div style=\"background-color: red\">Not implemented<br>{:?}</div>",
|
||||
self
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
match self {
|
||||
Node::Root(root) => root.get_text(),
|
||||
Node::Heading(heading) => heading.get_text(),
|
||||
Node::Text(text) => text.get_text(),
|
||||
Node::Paragraph(p) => p.get_text(),
|
||||
Node::ThematicBreak(_) => panic!("<hr> cannot return its raw text"),
|
||||
Node::InlineCode(i) => i.get_text(),
|
||||
Node::Code(c) => c.get_text(),
|
||||
Node::Html(_) => panic!("Html cannot return its raw text"),
|
||||
Node::Strong(s) => s.get_text(),
|
||||
Node::Emphasis(e) => e.get_text(),
|
||||
Node::List(l) => l.get_text(),
|
||||
Node::ListItem(l) => l.get_text(),
|
||||
_ => String::from(""),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
use markdown::mdast::Paragraph;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for Paragraph {
|
||||
fn to_html(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
result.push(node.to_html())
|
||||
}
|
||||
|
||||
let text: String = result.into_iter().collect();
|
||||
|
||||
format!("<p>{}</p>", text)
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
panic!("Paragraph cannot return its raw text")
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
use markdown::mdast;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for mdast::Root {
|
||||
fn to_html(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
result.push(node.to_html())
|
||||
}
|
||||
|
||||
result.into_iter().collect()
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in &self.children {
|
||||
result.push(node.get_text())
|
||||
}
|
||||
|
||||
result.join("-")
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
use markdown::mdast::Strong;
|
||||
|
||||
use crate::utils;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for Strong {
|
||||
fn to_html(&self) -> String {
|
||||
let text = utils::collect_children_html(&self.children);
|
||||
|
||||
format!("<b>{}</b>", text)
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
utils::collect_children_text(&self.children)
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
use markdown::mdast::Text;
|
||||
|
||||
use super::Printable;
|
||||
|
||||
impl Printable for Text {
|
||||
fn to_html(&self) -> String {
|
||||
self.value.clone()
|
||||
}
|
||||
|
||||
fn get_text(&self) -> String {
|
||||
self.value.clone()
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
use clap::Parser;
|
||||
use std::path::Path;
|
||||
|
||||
mod generator;
|
||||
mod pages;
|
||||
mod processor;
|
||||
mod sidebar;
|
||||
mod utils;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Input folder
|
||||
#[arg(short, long)]
|
||||
input: String,
|
||||
/// Output folder
|
||||
#[arg(short, long)]
|
||||
output: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let input_folder = Path::new(&args.input);
|
||||
let output_folder = Path::new(&args.output);
|
||||
|
||||
if input_folder.is_dir() && output_folder.is_dir() {
|
||||
processor::search_config_file(&input_folder, input_folder, output_folder);
|
||||
// process_folder(&input_folder, input_folder, output_folder);
|
||||
} else {
|
||||
eprint!("Input folder is not a valid path to a folder")
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::{generator::Printable, sidebar::SidebarGenerator};
|
||||
|
||||
/// ## Parameters
|
||||
///
|
||||
/// - `file`: Path to the MD file to compile
|
||||
/// - `input_folder`: Path to the input folder passed as parameter of the program
|
||||
/// - `output_folder`: Path to the output folder passed as parameter of the program
|
||||
/// - `file_tree_html`: HTML code of the file tree to be inserted into the generated HTML
|
||||
pub fn compile(file: &PathBuf, input_folder: &Path, output_folder: &Path, file_tree_html: &String) {
|
||||
// /home/fernando/misti/docs/markdown
|
||||
let input_folder = input_folder.canonicalize().unwrap();
|
||||
|
||||
// /home/fernando/misti/docs/markdown/en/docs/latest/index.md
|
||||
let input_file = file
|
||||
.canonicalize()
|
||||
.expect(format!("Expected file {:?} to exist", file).as_str());
|
||||
|
||||
// /home/fernando/misti/docs/static
|
||||
let output_folder = output_folder.canonicalize().unwrap();
|
||||
|
||||
// en/docs/latests/index.md
|
||||
let relative_input_file = input_file.strip_prefix(input_folder).unwrap();
|
||||
|
||||
let mut output_file = output_folder.clone();
|
||||
output_file.push(relative_input_file);
|
||||
output_file.set_extension("html");
|
||||
|
||||
//
|
||||
// Read MD from disk
|
||||
//
|
||||
let file_content_bytes = fs::read(&input_file).unwrap();
|
||||
let markdown_text = String::from_utf8(file_content_bytes).unwrap();
|
||||
|
||||
//
|
||||
// Compile MD
|
||||
//
|
||||
let md_ast = markdown::to_mdast(&markdown_text, &markdown::ParseOptions::gfm()).unwrap();
|
||||
let html_text = md_ast.to_html();
|
||||
let sidebar_html = md_ast.generate_sidebar();
|
||||
|
||||
// Read template.html
|
||||
let mut template_path = output_folder.clone();
|
||||
template_path.push("template.html");
|
||||
|
||||
let template_contents = fs::read(template_path).unwrap();
|
||||
let template_contents = String::from_utf8(template_contents).unwrap();
|
||||
|
||||
// Insert the markdown, sidebar and file tree into the template
|
||||
let final_output = template_contents
|
||||
.replace("{{markdown}}", &html_text)
|
||||
.replace("{{sidebar}}", &sidebar_html)
|
||||
.replace("{{pages}}", &file_tree_html);
|
||||
|
||||
//
|
||||
// Write to disk
|
||||
//
|
||||
File::create(&output_file)
|
||||
.expect(format!("MD: Output file should be valid {:?}", &output_file).as_str())
|
||||
.write_all(final_output.as_bytes())
|
||||
.unwrap();
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
use std::path::Path;
|
||||
|
||||
use yaml_rust::Yaml;
|
||||
|
||||
use crate::utils;
|
||||
|
||||
mod md_compiler;
|
||||
|
||||
pub enum Node<'a> {
|
||||
File(File<'a>),
|
||||
Folder(Folder<'a>),
|
||||
}
|
||||
|
||||
pub struct File<'a> {
|
||||
/// Name of the file
|
||||
path: &'a String,
|
||||
/// Display name of the file
|
||||
name: &'a String,
|
||||
}
|
||||
|
||||
pub struct Folder<'a> {
|
||||
/// Name of the folder
|
||||
path: &'a String,
|
||||
/// Display name of the folder
|
||||
name: &'a String,
|
||||
/// If true, then there MUST be a `File {path: "index"}` in the `children` field
|
||||
has_index: bool,
|
||||
/// Sub files or folders
|
||||
children: Box<Vec<Node<'a>>>,
|
||||
}
|
||||
|
||||
/// Creates a `YAML::String` from a `&str`
|
||||
macro_rules! y_str {
|
||||
($str:literal) => {
|
||||
&Yaml::String(String::from($str))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parse_yaml(values: &Yaml) -> Node {
|
||||
let Yaml::Hash(table) = values
|
||||
else {panic!("YAML: input MUST be an object")};
|
||||
|
||||
// Node path
|
||||
let Yaml::String(path) = table.get(y_str!("path")).expect("YAML: Node MUST have a `path` key")
|
||||
else { panic!("YAML: `path` MUST be a String") };
|
||||
|
||||
let Yaml::String(name) = table.get(y_str!("name")).expect("YAML: Node MUST have a `name` key")
|
||||
else { panic!("YAML: `name` MUST be a String") };
|
||||
|
||||
let input_data = (
|
||||
table.get(y_str!("has_index")),
|
||||
table.get(y_str!("children")),
|
||||
);
|
||||
|
||||
match input_data {
|
||||
(None, None) => Node::File(File { path, name }),
|
||||
(has_index, Some(children)) => {
|
||||
let has_index = match has_index {
|
||||
Some(Yaml::Boolean(v)) => *v,
|
||||
Some(_) => panic!("YAML: if key `has_index` exists, it MUST be a Boolean"),
|
||||
None => false,
|
||||
};
|
||||
|
||||
let Yaml::Array(children) = children
|
||||
else {panic!("YAML: `children` MUST be an Array")};
|
||||
|
||||
let children_nodes: Vec<Node> = children
|
||||
.into_iter()
|
||||
.map(|values| parse_yaml(values))
|
||||
.collect();
|
||||
|
||||
Node::Folder(Folder {
|
||||
path,
|
||||
name,
|
||||
has_index,
|
||||
children: Box::new(children_nodes),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
panic!("YAML: A Node is missing a `name` or `children` key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_pages_html(file_tree: &Node, current_path: &Path) -> String {
|
||||
match file_tree {
|
||||
Node::File(file) => {
|
||||
if file.path == "index" {
|
||||
format!(
|
||||
"<li class=\"my-1\">
|
||||
<a class=\"inline-block rounded-md w-full hover:text-c2-primary p-1\" href=\"/{}\">Index</a>
|
||||
</li>",
|
||||
current_path.to_str().unwrap()
|
||||
)
|
||||
} else if file.path == "" {
|
||||
String::from("")
|
||||
} else {
|
||||
format!(
|
||||
"<li class=\"my-1\">
|
||||
<a class=\"inline-block rounded-md w-full hover:text-c2-primary p-1\" href=\"/{}/{}.html\">{}</a>
|
||||
</li>",
|
||||
current_path.to_str().unwrap(),
|
||||
file.path,
|
||||
file.name
|
||||
)
|
||||
}
|
||||
}
|
||||
Node::Folder(folder) => {
|
||||
let mut new_path = current_path.to_path_buf();
|
||||
new_path.push(folder.path);
|
||||
|
||||
let sub_nodes_html: Vec<String> = folder
|
||||
.children
|
||||
.iter()
|
||||
.map(|n| generate_pages_html(n, &new_path))
|
||||
.collect();
|
||||
|
||||
// This is true for the root of the YAML file
|
||||
if folder.path == "" {
|
||||
format!("<ul>{}</ul>", sub_nodes_html.join(""))
|
||||
} else {
|
||||
format!(
|
||||
"<li class=\"my-1\">
|
||||
<div class=\"uppercase opacity-80 mt-6 font-semibold\">{}</div>
|
||||
<ul>{}</ul>
|
||||
</li>",
|
||||
folder.name,
|
||||
sub_nodes_html.join("")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile_md_to_html(
|
||||
file_tree: &Node,
|
||||
current_path: &Path,
|
||||
input_folder: &Path,
|
||||
output_folder: &Path,
|
||||
file_tree_html: &String,
|
||||
) {
|
||||
match file_tree {
|
||||
Node::File(file) if file.path != "" => {
|
||||
let mut file_path = current_path.canonicalize().unwrap();
|
||||
file_path.push(format!("{}.md", file.path));
|
||||
|
||||
md_compiler::compile(&file_path, input_folder, output_folder, file_tree_html);
|
||||
}
|
||||
Node::File(_) => {
|
||||
panic!("YAML: A file cannot have an empty `path` key")
|
||||
}
|
||||
Node::Folder(folder) if folder.path != "" => {
|
||||
let mut new_path = current_path.canonicalize().unwrap();
|
||||
new_path.push(folder.path);
|
||||
utils::ensure_folder_exists(&new_path, input_folder, output_folder)
|
||||
.expect("SHOULD be able to create folder");
|
||||
|
||||
for node in folder.children.iter() {
|
||||
compile_md_to_html(node, &new_path, input_folder, output_folder, file_tree_html);
|
||||
}
|
||||
}
|
||||
Node::Folder(folder) => {
|
||||
for node in folder.children.iter() {
|
||||
compile_md_to_html(
|
||||
node,
|
||||
¤t_path,
|
||||
input_folder,
|
||||
output_folder,
|
||||
file_tree_html,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
use crate::pages::{compile_md_to_html, generate_pages_html, parse_yaml};
|
||||
use crate::utils;
|
||||
use std::{
|
||||
fs,
|
||||
path::Path,
|
||||
};
|
||||
use yaml_rust::YamlLoader;
|
||||
|
||||
enum EntryFound {
|
||||
YamlFile,
|
||||
OtherFile,
|
||||
None,
|
||||
}
|
||||
|
||||
// Traverses the current path searching for a YAML file
|
||||
pub fn search_config_file(current_path: &Path, input_folder: &Path, output_folder: &Path) {
|
||||
// Iterate over all the files searching for a YAML file
|
||||
let result = current_path
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.fold(&EntryFound::None, |acc, next| {
|
||||
let p = next.unwrap().path();
|
||||
let is_file = p.is_file();
|
||||
let ext = p.extension();
|
||||
|
||||
match (acc, is_file, ext) {
|
||||
(EntryFound::YamlFile, true, Some(x)) if x == "yaml" => {
|
||||
panic!("FOUND A SECOND YAML FILE!!!")
|
||||
}
|
||||
(EntryFound::YamlFile, _, _) => acc,
|
||||
(EntryFound::OtherFile, true, Some(x)) if x == "yaml" => &EntryFound::YamlFile,
|
||||
(EntryFound::None, true, Some(x)) if x == "yaml" => &EntryFound::YamlFile,
|
||||
(EntryFound::None, true, Some(_)) => &EntryFound::OtherFile,
|
||||
_ => acc,
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
// If a file other than a YAML file is found, panic
|
||||
EntryFound::OtherFile => panic!(
|
||||
"Found an orphan file without a YAML parent at {:?}",
|
||||
current_path
|
||||
),
|
||||
// Process the YAML file
|
||||
EntryFound::YamlFile => process_yaml(current_path, input_folder, output_folder),
|
||||
// No files found, recursively read children folders
|
||||
EntryFound::None => {
|
||||
for entry in current_path.read_dir().unwrap() {
|
||||
// Should always succeed, and countain a folder
|
||||
let x = entry.unwrap();
|
||||
let path = x.path();
|
||||
|
||||
utils::ensure_folder_exists(&path, input_folder, output_folder).unwrap();
|
||||
search_config_file(&path, input_folder, output_folder);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn process_yaml(current_path: &Path, input_folder: &Path, output_folder: &Path) {
|
||||
//
|
||||
// Read YAML file
|
||||
//
|
||||
let mut yaml_path = current_path.canonicalize().unwrap();
|
||||
yaml_path.push("index.yaml");
|
||||
|
||||
let yaml_bytes = fs::read(yaml_path).expect("File index.yaml MUST exist");
|
||||
let yaml = String::from_utf8(yaml_bytes).expect("YAML index file MUST be valid UTF-8");
|
||||
|
||||
let yaml_docs =
|
||||
YamlLoader::load_from_str(yaml.as_str()).expect("YAML file MUST contain valid YAML");
|
||||
let yaml = &yaml_docs[0];
|
||||
|
||||
//
|
||||
// Parse YAML
|
||||
//
|
||||
let file_tree = parse_yaml(&yaml);
|
||||
|
||||
//
|
||||
// Generate File Tree HTML
|
||||
//
|
||||
let tree_html = {
|
||||
let input_folder = input_folder.canonicalize().unwrap();
|
||||
let yaml_folder_temp = current_path.canonicalize().unwrap();
|
||||
let web_absolute_path = yaml_folder_temp.strip_prefix(input_folder).unwrap();
|
||||
|
||||
generate_pages_html(&file_tree, web_absolute_path)
|
||||
};
|
||||
|
||||
//
|
||||
// Compile MD to HTML
|
||||
//
|
||||
compile_md_to_html(
|
||||
&file_tree,
|
||||
current_path,
|
||||
input_folder,
|
||||
output_folder,
|
||||
&tree_html,
|
||||
);
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
use markdown::mdast::{Heading, Node};
|
||||
|
||||
use crate::{generator::Printable, utils};
|
||||
|
||||
pub trait SidebarGenerator {
|
||||
fn generate_sidebar(&self) -> String;
|
||||
}
|
||||
|
||||
impl SidebarGenerator for Node {
|
||||
fn generate_sidebar(&self) -> String {
|
||||
match self {
|
||||
Node::Root(root) => {
|
||||
let children_nodes = root
|
||||
.children
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter_map(|x| match x {
|
||||
Node::Heading(h) if h.depth <= 3 => Some(h),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// A top level topic that contains other topics
|
||||
let topic = extract_topics(&children_nodes, 0, 1);
|
||||
|
||||
match topic {
|
||||
Some((t, _)) => {
|
||||
let html: String = t.children.iter().map(|x| x.get_html()).collect();
|
||||
format!("<ul>{}</ul>", html)
|
||||
}
|
||||
None => String::from("D:"),
|
||||
}
|
||||
}
|
||||
_ => panic!("??"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Topic {
|
||||
text: String,
|
||||
children: Box<Vec<Topic>>,
|
||||
}
|
||||
|
||||
impl Topic {
|
||||
pub fn get_html(&self) -> String {
|
||||
let extra = if self.children.len() > 0 {
|
||||
let children_html: String = self.children.iter().map(|x| x.get_html()).collect();
|
||||
|
||||
format!("<ol class=\"px-4\">{}</ol>", children_html)
|
||||
} else {
|
||||
String::from("")
|
||||
};
|
||||
|
||||
let html_fragment_link = utils::to_html_fragment(&self.text);
|
||||
format!(
|
||||
"<li class=\"m-2\"><a href=\"#{}\" class=\"inline-block w-full hover:text-c2-primary\">{}</a>{}</li>",
|
||||
html_fragment_link, self.text, extra
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Return the next heading and all its children
|
||||
// current_level: the depth of the heading to match
|
||||
fn extract_topics<'a>(
|
||||
headings: &'a Vec<Heading>,
|
||||
current_pos: usize,
|
||||
current_level: u8,
|
||||
) -> Option<(Topic, usize)> {
|
||||
match headings.get(current_pos) {
|
||||
Some(h) if h.depth == current_level => {
|
||||
let mut new_vec = Vec::new();
|
||||
let mut next_pos = current_pos + 1;
|
||||
|
||||
while let Some((topic, next)) = extract_topics(headings, next_pos, current_level + 1) {
|
||||
new_vec.push(topic);
|
||||
next_pos = next;
|
||||
}
|
||||
|
||||
let title = h.get_text();
|
||||
let topic = Topic {
|
||||
text: title,
|
||||
children: Box::new(new_vec),
|
||||
};
|
||||
|
||||
Some((topic, next_pos))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use markdown::mdast::Node;
|
||||
|
||||
use crate::generator::Printable;
|
||||
|
||||
pub fn to_html_fragment(text: &String) -> String {
|
||||
text.clone().replace(" ", "-")
|
||||
}
|
||||
|
||||
pub fn collect_children_html(vec: &Vec<Node>) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in vec {
|
||||
result.push(node.to_html())
|
||||
}
|
||||
|
||||
result.into_iter().collect()
|
||||
}
|
||||
|
||||
pub fn collect_children_text(vec: &Vec<Node>) -> String {
|
||||
let mut result = Vec::<String>::new();
|
||||
|
||||
for node in vec {
|
||||
result.push(node.get_text())
|
||||
}
|
||||
|
||||
result.join("-")
|
||||
}
|
||||
|
||||
pub fn ensure_folder_exists(
|
||||
folder: &Path,
|
||||
input_folder: &Path,
|
||||
output_folder: &Path,
|
||||
) -> Result<(), String> {
|
||||
// /home/fernando/misti/docs/markdown
|
||||
let input_folder = input_folder.canonicalize().unwrap();
|
||||
|
||||
// /home/fernando/misti/docs/static
|
||||
let output_folder = output_folder.canonicalize().unwrap();
|
||||
|
||||
// /home/fernando/misti/docs/markdown/en/
|
||||
let full_input_folder = folder.canonicalize().unwrap();
|
||||
|
||||
let relative_new_folder = full_input_folder.strip_prefix(input_folder).unwrap();
|
||||
|
||||
let mut full_output_folder = output_folder.clone();
|
||||
full_output_folder.push(relative_new_folder);
|
||||
|
||||
// println!("Ensuring that folder exists:\n{:?}", full_output_folder);
|
||||
|
||||
// If this is a "top-level" folder, remove all its contents, if it exists
|
||||
if full_output_folder.is_dir() {
|
||||
// println!("| Removing...");
|
||||
let _ = fs::remove_dir_all(&full_output_folder);
|
||||
}
|
||||
|
||||
// Create folder
|
||||
match fs::create_dir(&full_output_folder) {
|
||||
Ok(_) => {
|
||||
// println!("| done\n\n");
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(format!("Error creating folder {:?}", full_output_folder)),
|
||||
}
|
||||
}
|
3
doc-generator/static/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
tailwind/output.css
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 15 KiB |
@ -1,107 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="/tailwind/output.css" rel="stylesheet">
|
||||
|
||||
<link href="/styles/global.css" rel="stylesheet" />
|
||||
<link href="/styles/xcode-colors.css" rel="stylesheet" />
|
||||
<title>Misti</title>
|
||||
|
||||
<!-- Google fonts - Inter -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
<div class="py-6 pt-12 flex justify-center">
|
||||
<img src="/svg/logo_color.svg" alt="Misti logo" height="200" />
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="grid" style="grid-template-columns: 12rem calc(100vw - 12rem);">
|
||||
<div class="text-sm p-4 h-screen py-8 sticky top-0 overflow-y-scroll overflow-x-hidden border-r border-border-color">
|
||||
<a
|
||||
href="/"
|
||||
class="inline-block border border-transparent mb-8
|
||||
hover:border-c2-primary hover:text-c2-primary transition-colors rounded-md"
|
||||
>
|
||||
<svg style="width: 100%" viewBox="0 0 10240 10240">
|
||||
<g id="l4bTekyh7yd5nSqF0diaM2" fill="var(--c2-primary)" style="transform: none;">
|
||||
<g style="transform: none;">
|
||||
<path id="pEcfct8KT" d="M10103 9031 c-296 -154 -525 -301 -823 -526 -522 -397 -1153 -1070 -1467 -1565 -232 -367 -424 -755 -643 -1300 -193 -481 -298 -764 -440 -1182 l-98 -287 -147 302 c-143 293 -302 581 -548 992 -66 110 -156 272 -200 360 -44 88 -101 192 -127 230 -26 39 -57 90 -69 113 -55 109 -182 189 -314 199 -100 8 -171 -14 -272 -82 -83 -57 -118 -90 -225 -215 -35 -41 -85 -97 -111 -125 -139 -149 -331 -451 -594 -940 -21 -38 -55 -99 -75 -135 -21 -36 -55 -103 -77 -150 -22 -47 -51 -110 -65 -140 l-26 -55 -38 85 c-20 47 -84 177 -142 290 -57 113 -132 268 -167 346 -35 77 -169 352 -298 610 -364 727 -529 1000 -781 1289 -169 194 -438 463 -544 545 -117 90 -121 92 -217 157 -225 150 -441 285 -595 370 -408 227 -532 286 -775 373 -104 38 -198 71 -208 75 -16 7 -17 -15 -15 -411 l3 -418 48 -18 c61 -23 227 -103 337 -163 47 -26 119 -65 160 -87 128 -69 209 -117 395 -236 304 -195 395 -264 560 -429 284 -282 429 -469 612 -788 92 -160 509 -990 613 -1220 38 -84 104 -219 147 -301 215 -412 352 -790 413 -1144 31 -182 77 -357 104 -405 35 -58 117 -132 184 -163 50 -24 70 -27 157 -27 88 0 107 3 158 27 73 34 160 116 192 182 14 28 32 85 40 126 47 247 387 1087 555 1375 9 17 31 55 47 85 147 272 323 573 371 635 l18 23 69 -117 c38 -64 101 -170 141 -236 354 -595 583 -1059 774 -1570 135 -360 215 -532 327 -702 96 -145 263 -210 436 -169 117 28 194 76 252 161 57 83 66 122 75 317 13 274 19 302 166 828 167 599 604 1736 859 2234 264 517 484 816 945 1290 314 322 641 591 983 807 l97 61 0 444 c0 244 -1 444 -2 444 -2 0 -62 -31 -135 -69z">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<p class="font-extrabold text-6xl text-center">Misti</p>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
<a href="/en/docs/latest/">Docs</a>
|
||||
</p>
|
||||
|
||||
<p class="mb-8">
|
||||
<a href="/en/stdlib/latest">Stdlib</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
<div class="px-8 max-w-screen-lg">
|
||||
<h2 class="text-6xl px-4 py-6 font-bold leading-snug">
|
||||
Typed.
|
||||
<br>
|
||||
Expressive.
|
||||
<br>
|
||||
Consistent.
|
||||
<br>
|
||||
Friendly.
|
||||
</h2>
|
||||
|
||||
<p class="p-4" style="color: #ffdf90;">
|
||||
Misti is <i>yet another</i> programming language that compiles to <b>JavaScript</b>.
|
||||
</p>
|
||||
|
||||
<!-- Demo code -->
|
||||
|
||||
<div class="px-4 py-4">
|
||||
<a class="inline-block py-4 px-12 my-1 border-2 border-c5-primary
|
||||
bg-js-color
|
||||
text-dark-color
|
||||
rounded-xl cursor-pointer select-none font-medium shadow-md hover:shadow-2xl"
|
||||
href="/en/docs/latest/"
|
||||
>
|
||||
Get started
|
||||
</a>
|
||||
|
||||
<br>
|
||||
|
||||
<a class="inline-block py-4 px-12 my-1 border-2 border-c2-primary
|
||||
bg-c2-primary-container hover:bg-c2-primary
|
||||
text-c2-on-primary-container hover:text-c2-on-primary
|
||||
rounded-xl cursor-pointer select-none transition-colors"
|
||||
href="/en/stdlib/latest/"
|
||||
>
|
||||
StdLib
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Inter - Google fonts - load here as to not interrupt the page
|
||||
const linkEl = document.createElement("link");
|
||||
linkEl.href = "https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;700&display=swap";
|
||||
linkEl.rel = "stylesheet";
|
||||
|
||||
document.head.appendChild(linkEl);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,8 +0,0 @@
|
||||
<svg class="img-fluid" id="outputsvg" xmlns="http://www.w3.org/2000/svg" style="transform: matrix(1.3, 0, 0, 1.3, 0, 0); transform-origin: 50% 50% 0px; cursor: move; max-height: none; transition: none 0s ease 0s;" width="1024" height="1024" viewBox="0 0 10240 10240">
|
||||
<g id="l4bTekyh7yd5nSqF0diaM2" fill="var(--c2)" style="transform: none;">
|
||||
<g style="transform: none;">
|
||||
<path id="pEcfct8KT" d="M10103 9031 c-296 -154 -525 -301 -823 -526 -522 -397 -1153 -1070 -1467 -1565 -232 -367 -424 -755 -643 -1300 -193 -481 -298 -764 -440 -1182 l-98 -287 -147 302 c-143 293 -302 581 -548 992 -66 110 -156 272 -200 360 -44 88 -101 192 -127 230 -26 39 -57 90 -69 113 -55 109 -182 189 -314 199 -100 8 -171 -14 -272 -82 -83 -57 -118 -90 -225 -215 -35 -41 -85 -97 -111 -125 -139 -149 -331 -451 -594 -940 -21 -38 -55 -99 -75 -135 -21 -36 -55 -103 -77 -150 -22 -47 -51 -110 -65 -140 l-26 -55 -38 85 c-20 47 -84 177 -142 290 -57 113 -132 268 -167 346 -35 77 -169 352 -298 610 -364 727 -529 1000 -781 1289 -169 194 -438 463 -544 545 -117 90 -121 92 -217 157 -225 150 -441 285 -595 370 -408 227 -532 286 -775 373 -104 38 -198 71 -208 75 -16 7 -17 -15 -15 -411 l3 -418 48 -18 c61 -23 227 -103 337 -163 47 -26 119 -65 160 -87 128 -69 209 -117 395 -236 304 -195 395 -264 560 -429 284 -282 429 -469 612 -788 92 -160 509 -990 613 -1220 38 -84 104 -219 147 -301 215 -412 352 -790 413 -1144 31 -182 77 -357 104 -405 35 -58 117 -132 184 -163 50 -24 70 -27 157 -27 88 0 107 3 158 27 73 34 160 116 192 182 14 28 32 85 40 126 47 247 387 1087 555 1375 9 17 31 55 47 85 147 272 323 573 371 635 l18 23 69 -117 c38 -64 101 -170 141 -236 354 -595 583 -1059 774 -1570 135 -360 215 -532 327 -702 96 -145 263 -210 436 -169 117 28 194 76 252 161 57 83 66 122 75 317 13 274 19 302 166 828 167 599 604 1736 859 2234 264 517 484 816 945 1290 314 322 641 591 983 807 l97 61 0 444 c0 244 -1 444 -2 444 -2 0 -62 -31 -135 -69z">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 44 KiB |
@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "static",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"watch": "concurrently -k \"tailwindcss -i ./tailwind/input.css -o ./tailwind/output.css --watch\" \"live-server . --port=3333\"",
|
||||
"start": "live-server . --port=3333",
|
||||
"styles": "tailwindcss -i ./tailwind/input.css -o ./tailwind/output.css --watch"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"concurrently": "^7.6.0",
|
||||
"live-server": "^1.2.2",
|
||||
"serve": "^14.2.0",
|
||||
"tailwindcss": "^3.2.7"
|
||||
}
|
||||
}
|
@ -1,308 +0,0 @@
|
||||
:root {
|
||||
--js-color: #FFE70B;
|
||||
--dark-color: #0f0f0f;
|
||||
--light-color: white;
|
||||
--error-color: #ff3b3b;
|
||||
--error-text-color: #410002;
|
||||
--error-bg-color: #ffdad6;
|
||||
|
||||
--c1: #e7b711;
|
||||
--c2: #038dce;
|
||||
--c3: #ffaed7;
|
||||
--c4: #f44336;
|
||||
--c5: #39b487;
|
||||
--c3-transparent: #772957; /* rgba(252, 168, 209, 0.35); */
|
||||
|
||||
--bg-color: var(--dark-color);
|
||||
--color: #dedede;
|
||||
--code-bg-color: #151515;
|
||||
--code-color: #bababa;
|
||||
--border-color: #72787e;
|
||||
|
||||
/* C1 Material Colors */
|
||||
--c1-primary: #f1c01f;
|
||||
|
||||
/* C2 Material Colors */
|
||||
--c2-primary: #90ccff;
|
||||
--c2-on-primary: #003351;
|
||||
--c2-primary-container: #004b72;
|
||||
--c2-on-primary-container: #cce5ff;
|
||||
--c2-surface-variant: #41474d;
|
||||
--c2-on-surface-variant: #c1c7ce;
|
||||
|
||||
/* C3 Material Colors */
|
||||
--c3-primary: #ffaed7;
|
||||
--c3-on-primary: #5b113f;
|
||||
--c3-primary-container: #782957;
|
||||
--c3-on-primary-container: #ffd8e9;
|
||||
|
||||
/* C4 Material Colors */
|
||||
--c4-primary: #ffb4a8;
|
||||
|
||||
|
||||
/* C5 Material Colors */
|
||||
--c5-primary: #66dcac;
|
||||
--c5-on-primary: #003825;
|
||||
--c5-primary-container: #005137;
|
||||
--c5-on-primary-container: #83f9c7;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--c2: #038dce;
|
||||
|
||||
--bg-color: #fffdfc;
|
||||
--color: #202020;
|
||||
--code-bg-color: #fdf6e3;
|
||||
--code-color: #073642;
|
||||
--border-color: rgba(64, 64, 64, 0.25);
|
||||
|
||||
--c3-transparent: #ffd8ea;
|
||||
|
||||
/* C1 Material Colors */
|
||||
--c1-primary: #765b00;
|
||||
|
||||
/* C2 Material Colors */
|
||||
--c2-primary: #006397;
|
||||
--c2-on-primary: #ffffff;
|
||||
--c2-primary-container: #cce5ff;
|
||||
--c2-on-primary-container: #001e31;
|
||||
--c2-surface-variant: #dde3ea;
|
||||
--c2-on-surface-variant: #41474d;
|
||||
|
||||
/* C3 Material Colors */
|
||||
--c3-primary: #954170;
|
||||
--c3-on-primary: #ffffff;
|
||||
--c3-primary-container: #ffd8e9;
|
||||
--c3-on-primary-container: #3c0027;
|
||||
|
||||
/* C4 Material Colors */
|
||||
--c4-primary: #bc1714;
|
||||
|
||||
/* C5 Material Colors */
|
||||
--c5-primary: #006c4b;
|
||||
--c5-on-primary: #ffffff;
|
||||
--c5-primary-container: #83f9c7;
|
||||
--c5-on-primary-container: #002114;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.padded {
|
||||
padding-left: 2rem;
|
||||
border-left: solid 1px var(--border-color);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
html {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Inter, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
svg.railroad-diagram {
|
||||
background-color: rgba(0,0,0,0) !important;
|
||||
}
|
||||
|
||||
svg.railroad-diagram path {
|
||||
stroke: var(--c1) !important;
|
||||
}
|
||||
|
||||
svg.railroad-diagram rect {
|
||||
stroke: var(--c2) !important;
|
||||
fill: var(--c2) !important;
|
||||
}
|
||||
|
||||
svg.railroad-diagram g.non-terminal rect {
|
||||
stroke: var(--c4) !important;
|
||||
fill: var(--c4) !important;
|
||||
}
|
||||
|
||||
svg.railroad-diagram text {
|
||||
font-family: Inter, sans-serif !important;
|
||||
font-weight: normal !important;
|
||||
fill: white;
|
||||
}
|
||||
|
||||
g.terminal text {
|
||||
font-family: Iosevka, sans-serif !important;
|
||||
}
|
||||
|
||||
.railroad-code {
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.railroad-code svg {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
pre {
|
||||
border: solid 1px rgba(150, 150, 150, 0.5);
|
||||
}
|
||||
|
||||
code, pre {
|
||||
font-family: "SF Mono", Iosevka, "Source Code Pro", monospace !important;
|
||||
font-variant-ligatures: discretionary-ligatures;
|
||||
}
|
||||
|
||||
.marked pre {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.marked p {
|
||||
line-height: 1.5rem;
|
||||
text-align: justify;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.marked h1 {
|
||||
font-weight: 900;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 2rem;
|
||||
font-size: 2.25rem;
|
||||
}
|
||||
|
||||
.marked h2 {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
|
||||
.marked h3 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 500;
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1.25rem;
|
||||
text-decoration: underline;
|
||||
|
||||
/*
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--bg-color);
|
||||
*/
|
||||
}
|
||||
|
||||
.marked h4 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 300;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.marked table {
|
||||
text-align: center;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.marked table, th, td {
|
||||
border: solid 1px rgba(150, 150, 150, 1);
|
||||
}
|
||||
|
||||
.marked table td, th {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.md-modifier {
|
||||
border-radius: 0.75rem;
|
||||
padding: 1rem;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.md-modifier > div {
|
||||
padding-bottom: 1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.md-info {
|
||||
border: solid 2px var(--js-color);
|
||||
}
|
||||
|
||||
.md-info > div {
|
||||
color: var(--js-color);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.md-info {
|
||||
background-color: var(--js-color);
|
||||
}
|
||||
|
||||
.md-info > div {
|
||||
color: var(--dark-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.md-warning {
|
||||
border: solid 3px var(--c4);
|
||||
}
|
||||
|
||||
.md-warning > div {
|
||||
color: var(--c4);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.md-warning {
|
||||
background-color: var(--error-bg-color);
|
||||
color: var(--error-text-color);
|
||||
}
|
||||
|
||||
.md-warning > div {
|
||||
color: var(--c4);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.md-implemented {
|
||||
border: solid 3px var(--c2-primary);
|
||||
}
|
||||
|
||||
.md-implemented > div {
|
||||
color: var(--c2-primary);
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.marked p {
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.marked h1 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
pre[class*="language-"].line-numbers {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.railroad-code svg {
|
||||
display: none;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Used by headers generated at src/generator/heading.rs */
|
||||
.heading-linked :hover::after{
|
||||
color: var(--c2-primary);
|
||||
content: "#";
|
||||
display: inline-block;
|
||||
font-size: 0.7em;
|
||||
line-height: 1;
|
||||
margin-left: 4px;
|
||||
text-decoration: none;
|
||||
}
|
@ -1,263 +0,0 @@
|
||||
/* colors from: https://raw.githubusercontent.com/WhiteVermouth/XcodeTheme/master/assets/color-palette.png */
|
||||
:root {
|
||||
--code-theme-color: #dedede;
|
||||
--code-theme-bg-color: #1f1f24;
|
||||
--code-theme-bg-color_selection: #515b70;
|
||||
--code-theme-color_selection: inherit;
|
||||
|
||||
--code-theme-comment: #6c7986;
|
||||
|
||||
/* number */
|
||||
--code-theme-c1: #d0bf69;
|
||||
/* keyword */
|
||||
--code-theme-c2: #fc5fa3;
|
||||
/* ? */
|
||||
--code-theme-c3: #39adb5;
|
||||
/* string */
|
||||
--code-theme-c4: #fc6a5d;
|
||||
/* declaration */
|
||||
--code-theme-c5: #5dd8ff;
|
||||
/* proyect function */
|
||||
--code-theme-c6: #67b7a4; /*#e53935;*/
|
||||
|
||||
--code-theme-punctuation: #dedede;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--code-theme-color: #3a3a3a;
|
||||
--code-theme-bg-color: #ffffff;
|
||||
--code-theme-bg-color_selection: #a4cdff;
|
||||
--code-theme-color_selection: inherit;
|
||||
|
||||
--code-theme-comment: #5d6c79;
|
||||
|
||||
/* number */
|
||||
--code-theme-c1: #1c00cf;
|
||||
/* keyword */
|
||||
--code-theme-c2: #9b2393;
|
||||
--code-theme-c3: #39adb5;
|
||||
/* string */
|
||||
--code-theme-c4: #c41a16;
|
||||
/* declaration */
|
||||
--code-theme-c5: #0f68a0;
|
||||
--code-theme-c6: #326d74; /*#e53935;*/
|
||||
|
||||
--code-theme-punctuation: #202020;
|
||||
}
|
||||
}
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
color: var(--code-theme-color);
|
||||
background: var(--code-theme-bg-color);
|
||||
font-size: 0.8em;
|
||||
line-height: 1.5em;
|
||||
border-radius: 0.3em;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
code[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection {
|
||||
background: var(--code-theme-bg-color_selection);
|
||||
color: var(--code-theme-color_selection);
|
||||
}
|
||||
|
||||
code[class*="language-"]::selection,
|
||||
pre[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection,
|
||||
pre[class*="language-"] ::selection {
|
||||
background: var(--code-theme-bg-color_selection);
|
||||
color: var(--code-theme-color_selection);
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"] {
|
||||
white-space: normal;
|
||||
border-radius: 0.2em;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
:not(pre) > code {
|
||||
/* border: solid 1px var(--border-color); */
|
||||
background-color: var(--code-theme-bg-color);
|
||||
padding: 0 0.25rem;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
pre[class*="language-"] {
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
margin: 0.5em 0;
|
||||
padding: 0.75em 0.75em;
|
||||
}
|
||||
|
||||
.language-css > code,
|
||||
.language-sass > code,
|
||||
.language-scss > code {
|
||||
color: var(--code-theme-c1);
|
||||
}
|
||||
|
||||
[class*="language-"] .namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.token.atrule {
|
||||
color: var(--code-theme-c2);
|
||||
}
|
||||
|
||||
.token.attr-name {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.attr-value {
|
||||
color: var(--code-theme-c4);
|
||||
}
|
||||
|
||||
.token.attribute {
|
||||
color: var(--code-theme-c4);
|
||||
}
|
||||
|
||||
.token.boolean {
|
||||
color: var(--code-theme-c2);
|
||||
}
|
||||
|
||||
.token.builtin {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.cdata {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.char {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.class {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.class-name {
|
||||
color: var(--code-theme-c5);
|
||||
}
|
||||
|
||||
.token.comment {
|
||||
color: var(--code-theme-comment);
|
||||
}
|
||||
|
||||
.token.constant {
|
||||
color: var(--code-theme-c2);
|
||||
}
|
||||
|
||||
.token.deleted {
|
||||
color: var(--code-theme-c6);
|
||||
}
|
||||
|
||||
.token.doctype {
|
||||
color: var(--code-theme-comment);
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
color: var(--code-theme-c6);
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: var(--code-theme-c2);
|
||||
}
|
||||
|
||||
.token.hexcode {
|
||||
color: var(--code-theme-c1);
|
||||
}
|
||||
|
||||
.token.id {
|
||||
color: var(--code-theme-c2);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.important {
|
||||
color: var(--code-theme-c2);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.inserted {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: var(--code-theme-c2);
|
||||
}
|
||||
|
||||
.token.number {
|
||||
color: var(--code-theme-c1);
|
||||
}
|
||||
|
||||
.token.operator {
|
||||
color: var(--code-theme-punctuation);
|
||||
}
|
||||
|
||||
.token.prolog {
|
||||
color: var(--code-theme-comment);
|
||||
}
|
||||
|
||||
.token.property {
|
||||
color: var(--code-theme-c3);
|
||||
}
|
||||
|
||||
.token.pseudo-class {
|
||||
color: var(--code-theme-c4);
|
||||
}
|
||||
|
||||
.token.pseudo-element {
|
||||
color: var(--code-theme-c4);
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: var(--code-theme-punctuation);
|
||||
}
|
||||
|
||||
.token.regex {
|
||||
color: var(--code-theme-c5);
|
||||
}
|
||||
|
||||
.token.selector {
|
||||
color: var(--code-theme-c6);
|
||||
}
|
||||
|
||||
.token.string {
|
||||
color: var(--code-theme-c4);
|
||||
}
|
||||
|
||||
.token.symbol {
|
||||
color: var(--code-theme-c2);
|
||||
}
|
||||
|
||||
.token.tag {
|
||||
color: var(--code-theme-c6);
|
||||
}
|
||||
|
||||
.token.unit {
|
||||
color: var(--code-theme-c1);
|
||||
}
|
||||
|
||||
.token.url {
|
||||
color: var(--code-theme-c6);
|
||||
}
|
||||
|
||||
.token.variable {
|
||||
color: var(--code-theme-c6);
|
||||
}
|
@ -1 +0,0 @@
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="184.0pt" height="72.0pt" viewBox="0 0 184.000000 72.000000" preserveAspectRatio="xMidYMid meet"> <g transform="translate(0.000000,72.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none"> <path d="M520 680 c-41 -41 -13 -112 45 -112 58 0 86 71 45 112 -11 11 -31 20 -45 20 -14 0 -34 -9 -45 -20z"/> <path d="M40 683 c0 -5 7 -17 15 -27 22 -29 22 -413 0 -442 -8 -10 -15 -22 -15 -26 0 -5 41 -8 92 -8 87 0 90 1 75 18 -26 29 -24 232 2 232 4 0 34 -55 67 -122 l59 -123 157 -3 c87 -1 158 -1 158 2 0 2 -7 17 -15 32 -11 22 -15 66 -15 183 l0 153 -22 -5 c-13 -3 -44 -9 -70 -12 -52 -8 -56 -14 -32 -50 13 -19 15 -47 12 -144 -5 -183 -28 -186 -108 -16 -46 98 -89 155 -116 155 -28 0 -12 24 80 116 l94 94 -63 0 c-60 0 -62 -1 -58 -24 4 -18 -11 -41 -68 -104 -41 -45 -75 -79 -78 -77 -2 3 -3 41 -3 86 1 62 5 86 18 100 17 18 15 19 -74 19 -51 0 -92 -3 -92 -7z"/> <path d="M1132 678 c-41 -9 -42 -10 -27 -31 22 -32 22 -412 -1 -445 l-15 -22 90 0 c50 0 91 3 91 8 0 4 -7 16 -15 26 -16 21 -22 156 -7 156 5 0 21 -33 37 -72 45 -118 44 -118 125 -118 73 0 84 6 50 28 -11 6 -33 40 -48 75 -26 56 -79 117 -103 117 -23 0 -3 22 71 76 44 32 80 63 80 67 0 4 -26 7 -57 5 -53 -3 -58 -5 -58 -27 0 -16 -17 -38 -52 -68 l-53 -46 0 142 0 141 -32 -1 c-18 -1 -52 -5 -76 -11z"/> <path d="M1728 559 c-21 -12 -24 -62 -5 -77 6 -5 21 -12 32 -14 17 -3 20 -10 17 -53 -7 -109 -51 -185 -109 -185 -35 0 -43 34 -43 186 l0 134 -75 0 c-75 0 -86 -5 -62 -28 8 -9 14 -59 17 -142 6 -147 18 -174 85 -199 33 -13 43 -13 81 1 43 15 43 15 32 -6 -27 -52 -96 -116 -125 -116 -8 0 -10 11 -6 35 7 43 -9 65 -48 65 -70 0 -83 -92 -18 -125 75 -39 164 5 230 115 119 196 116 479 -3 409z"/> <path d="M728 538 c-60 -11 -67 -20 -43 -52 21 -28 21 -244 0 -272 -8 -10 -15 -22 -15 -26 0 -5 38 -8 85 -8 47 0 85 2 85 4 0 2 -7 17 -15 32 -18 35 -20 185 -4 233 18 51 56 64 89 31 18 -18 20 -33 20 -140 0 -117 1 -122 26 -147 21 -21 32 -24 61 -20 36 6 63 23 63 38 0 5 -7 9 -15 9 -12 0 -15 19 -15 115 0 128 -12 173 -54 200 -35 23 -113 16 -155 -14 l-31 -22 0 25 c0 15 -5 25 -12 25 -7 -1 -39 -6 -70 -11z"/> </g> </svg>
|
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 172 KiB |
Before Width: | Height: | Size: 172 KiB |
@ -1,10 +0,0 @@
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="300pt" height="100pt"
|
||||
viewBox="0 0 300.000000 100.000000" preserveAspectRatio="xMidYMid meet">
|
||||
<g transform="translate(-30.000000,140.000000) scale(0.100000,-0.100000)" fill="#ffffff" stroke="none">
|
||||
<path d="M310 1300 c0 -79 0 -80 25 -80 l25 0 0 -215 0 -215 -25 0 c-25 0 -25 -1 -25 -80 l0 -80 190 0 190 0 0 80 0 80 -30 0 -30 0 0 80 c0 79 0 80 26 80 28 0 65 -16 76 -34 4 -6 8 -73 8 -148 l0 -138 155 0 155 0 0 80 c0 79 0 80 -25 80 -24 0 -25 3 -25 54 0 73 -13 103 -54 122 l-34 17 38 36 c78 74 81 222 6 297 -56 56 -106 64 -393 64 l-253 0 0 -80z m414 -96 c18 -18 21 -85 6 -115 -8 -14 -21 -19 -55 -19 l-45 0 0 75 0 75 39 0 c23 0 46 -7 55 -16z"/>
|
||||
<path d="M2310 1256 c0 -46 -18 -76 -50 -82 l-30 -6 0 -79 c0 -78 0 -79 25 -79 l25 0 0 -128 c0 -113 3 -133 23 -172 33 -67 72 -85 182 -85 50 0 107 6 128 13 l38 14 -3 71 -3 72 -51 -3 c-75 -5 -84 7 -84 124 l0 94 65 0 65 0 0 80 0 80 -65 0 -65 0 0 55 0 55 -100 0 c-99 0 -100 0 -100 -24z"/>
|
||||
<path d="M1905 1183 c-105 -14 -165 -58 -185 -134 -17 -61 -3 -108 44 -154 42 -41 73 -54 179 -75 46 -9 57 -15 55 -28 -3 -15 -19 -17 -131 -15 l-127 1 0 -64 0 -63 38 -11 c62 -18 222 -24 281 -11 62 13 114 48 136 91 24 46 20 140 -8 181 -28 43 -93 76 -165 84 -32 3 -68 11 -81 16 -20 8 -21 12 -10 26 12 14 30 15 131 9 l118 -6 0 64 0 65 -52 10 c-66 12 -183 20 -223 14z"/>
|
||||
<path d="M1050 1090 c0 -72 2 -80 19 -80 17 0 19 -11 23 -127 3 -108 7 -136 27 -175 29 -61 72 -88 139 -88 62 0 98 13 135 48 l27 26 0 -32 0 -32 135 0 135 0 0 80 c0 79 0 80 -25 80 l-25 0 0 190 0 190 -135 0 -135 0 0 -80 c0 -79 0 -80 25 -80 25 0 25 0 25 -98 0 -106 -7 -122 -49 -122 -54 0 -56 5 -59 200 l-3 180 -130 0 -129 0 0 -80z"/>
|
||||
<path d="M2670 1090 c0 -72 2 -80 19 -80 17 0 19 -11 23 -127 6 -183 36 -241 134 -263 49 -11 128 10 165 46 l29 28 0 -41 c0 -49 -17 -70 -66 -79 -34 -6 -176 2 -221 13 -22 5 -23 3 -23 -75 l0 -81 58 -12 c31 -7 109 -13 172 -14 108 0 119 2 175 30 64 32 97 71 115 134 5 20 10 160 10 319 l0 282 -135 0 -135 0 0 -80 c0 -79 0 -80 25 -80 25 0 25 0 25 -98 0 -106 -7 -122 -49 -122 -54 0 -56 5 -59 200 l-3 180 -130 0 -129 0 0 -80z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
@ -1,50 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./**/*.html"],
|
||||
theme: {
|
||||
colors: {
|
||||
transparent: 'transparent',
|
||||
current: 'currentColor',
|
||||
white: "#ffffff",
|
||||
|
||||
"js-color": "var(--js-color)",
|
||||
"dark-color": "var(--dark-color)",
|
||||
"light-color": "var(--light-color)",
|
||||
"error-color": "var(--error-color)",
|
||||
"error-text-color": "var(--error-text-color)",
|
||||
"error-bg-color": "var(--error-bg-color)",
|
||||
"c1": "var(--c1)",
|
||||
"c2": "var(--c2)",
|
||||
"c3": "var(--c3)",
|
||||
"c4": "var(--c4)",
|
||||
"c5": "var(--c5)",
|
||||
"c3-transparent": "var(--c3-transparent)",
|
||||
"main-color": "var(--color)",
|
||||
"code-bg-color": "var(--code-bg-color)",
|
||||
"code-color": "var(--code-color)",
|
||||
"border-color": "var(--border-color)",
|
||||
|
||||
"c1-primary": "var(--c1-primary)",
|
||||
|
||||
"c2-primary": "var(--c2-primary)",
|
||||
"c2-on-primary": "var(--c2-on-primary)",
|
||||
"c2-primary-container": "var(--c2-primary-container)",
|
||||
"c2-on-primary-container": "var(--c2-on-primary-container)",
|
||||
"c2-surface-variant": "var(--c2-surface-variant)",
|
||||
"c2-on-surface-variant": "var(--c2-on-surface-variant)",
|
||||
|
||||
"c3-primary": "var(--c3-primary)",
|
||||
"c3-on-primary": "var(--c3-on-primary)",
|
||||
"c3-primary-container": "var(--c3-primary-container)",
|
||||
"c3-on-primary-container": "var(--c3-on-primary-container)",
|
||||
"c4-primary": "var(--c4-primary)",
|
||||
"c5-primary": "var(--c5-primary)",
|
||||
"c5-on-primary": "var(--c5-on-primary)",
|
||||
"c5-primary-container": "var(--c5-primary-container)",
|
||||
"c5-on-primary-container": "var(--c5-on-primary-container)",
|
||||
"bg-color": "var(--bg-color)",
|
||||
},
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
@ -1,121 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="/tailwind/output.css" rel="stylesheet">
|
||||
|
||||
<link href="/styles/global.css" rel="stylesheet" />
|
||||
<link href="/styles/xcode-colors.css" rel="stylesheet" />
|
||||
<title>Misti</title>
|
||||
|
||||
<!-- Google fonts - Inter -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="grid" style="grid-template-columns: 12rem 12rem calc(100vw - 24rem);">
|
||||
<div class="text-sm p-4 h-screen py-8 sticky top-0 overflow-y-scroll overflow-x-hidden border-r border-border-color">
|
||||
<a
|
||||
href="/"
|
||||
class="inline-block border border-transparent mb-8
|
||||
hover:border-c2-primary hover:text-c2-primary transition-colors rounded-md"
|
||||
>
|
||||
<svg style="width: 100%" viewBox="0 0 10240 10240">
|
||||
<g id="l4bTekyh7yd5nSqF0diaM2" fill="var(--c2-primary)" style="transform: none;">
|
||||
<g style="transform: none;">
|
||||
<path id="pEcfct8KT" d="M10103 9031 c-296 -154 -525 -301 -823 -526 -522 -397 -1153 -1070 -1467 -1565 -232 -367 -424 -755 -643 -1300 -193 -481 -298 -764 -440 -1182 l-98 -287 -147 302 c-143 293 -302 581 -548 992 -66 110 -156 272 -200 360 -44 88 -101 192 -127 230 -26 39 -57 90 -69 113 -55 109 -182 189 -314 199 -100 8 -171 -14 -272 -82 -83 -57 -118 -90 -225 -215 -35 -41 -85 -97 -111 -125 -139 -149 -331 -451 -594 -940 -21 -38 -55 -99 -75 -135 -21 -36 -55 -103 -77 -150 -22 -47 -51 -110 -65 -140 l-26 -55 -38 85 c-20 47 -84 177 -142 290 -57 113 -132 268 -167 346 -35 77 -169 352 -298 610 -364 727 -529 1000 -781 1289 -169 194 -438 463 -544 545 -117 90 -121 92 -217 157 -225 150 -441 285 -595 370 -408 227 -532 286 -775 373 -104 38 -198 71 -208 75 -16 7 -17 -15 -15 -411 l3 -418 48 -18 c61 -23 227 -103 337 -163 47 -26 119 -65 160 -87 128 -69 209 -117 395 -236 304 -195 395 -264 560 -429 284 -282 429 -469 612 -788 92 -160 509 -990 613 -1220 38 -84 104 -219 147 -301 215 -412 352 -790 413 -1144 31 -182 77 -357 104 -405 35 -58 117 -132 184 -163 50 -24 70 -27 157 -27 88 0 107 3 158 27 73 34 160 116 192 182 14 28 32 85 40 126 47 247 387 1087 555 1375 9 17 31 55 47 85 147 272 323 573 371 635 l18 23 69 -117 c38 -64 101 -170 141 -236 354 -595 583 -1059 774 -1570 135 -360 215 -532 327 -702 96 -145 263 -210 436 -169 117 28 194 76 252 161 57 83 66 122 75 317 13 274 19 302 166 828 167 599 604 1736 859 2234 264 517 484 816 945 1290 314 322 641 591 983 807 l97 61 0 444 c0 244 -1 444 -2 444 -2 0 -62 -31 -135 -69z">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<p class="font-extrabold text-6xl text-center">Misti</p>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
<a href="/en/docs/latest/">Docs</a>
|
||||
</p>
|
||||
|
||||
<p class="mb-8">
|
||||
<a href="/en/stdlib/latest">Stdlib</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<nav id="secondary-nav">
|
||||
{{pages}}
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
<nav id="primary-nav" class="text-sm p-4 h-screen py-12 sticky top-0 overflow-y-scroll overflow-x-hidden border-r border-border-color">
|
||||
<div class="mx-2 my-4 uppercase opacity-80 font-semibold">On this page</div>
|
||||
|
||||
{{sidebar}}
|
||||
</nav>
|
||||
<div class="marked px-8 max-w-screen-lg">
|
||||
{{markdown}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Inter - Google fonts - load here to avoid interrupting the page
|
||||
const linkEl = document.createElement("link");
|
||||
linkEl.href = "https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;700&display=swap";
|
||||
linkEl.rel = "stylesheet";
|
||||
|
||||
document.head.appendChild(linkEl);
|
||||
</script>
|
||||
<script>
|
||||
/* Highlight current topic in sidebar */
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const anchors = document.querySelectorAll('h2, h3');
|
||||
const links = document.querySelectorAll('nav#primary-nav > ul > li a');
|
||||
|
||||
window.addEventListener('scroll', (event) => {
|
||||
if (anchors && links) {
|
||||
let scrollTop = window.scrollY;
|
||||
let scrollBottom = scrollTop + window.innerHeight;
|
||||
|
||||
// highlight the last scrolled-to: set everything inactive first
|
||||
links.forEach((link, index) => {
|
||||
link.classList.remove("text-c2-primary");
|
||||
});
|
||||
|
||||
// then iterate backwards, on the first match highlight it and break
|
||||
for (let i = 0; i < anchors.length; i++) {
|
||||
let anchorPos = anchors[i].offsetTop + 30;
|
||||
|
||||
if (anchorPos > scrollTop && anchorPos < scrollBottom) {
|
||||
links[i].classList.add('text-c2-primary');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
/* Highlight current page in secondary navbar */
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const links = document.querySelectorAll("nav#secondary-nav > ul a");
|
||||
|
||||
let currentUrl = window.location.href;
|
||||
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
let el = links[i];
|
||||
if (currentUrl === el.href) {
|
||||
el.classList.add("bg-c2-primary-container");
|
||||
el.classList.add("text-c2-on-primary-container");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|