Remove doc from compiler

master
Araozu 2023-09-07 20:18:35 -05:00
parent 349f466283
commit 4f1fc93ceb
97 changed files with 0 additions and 6564 deletions

View File

3
compiler/.gitignore vendored
View File

@ -1,3 +0,0 @@
/target
.vscode
*.profraw

View File

@ -1,2 +0,0 @@
target
static/en/**

507
doc-generator/Cargo.lock generated
View File

@ -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",
]

View File

@ -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"

View File

@ -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.

View File

@ -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)
```

View File

@ -1,3 +0,0 @@
# Indentation rules
TBD

View File

@ -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.
```

View File

@ -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
```

View File

@ -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
}
```

View File

@ -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`
```

View File

@ -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)
```

View File

@ -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]
```

View File

@ -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
```

View File

@ -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")
```

View File

@ -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")
```

View File

@ -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
}
```

View File

@ -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,
)
```

View File

@ -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>
}
```

View File

@ -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

View File

@ -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
```

View File

@ -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
```

View File

@ -1 +0,0 @@
# Stdlib index

View File

@ -1,10 +0,0 @@
path: ""
name: ""
children:
- path: prelude
name: Prelude
children:
- path: String
name: String
- path: Console
name: Console

View File

@ -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`
```

View File

@ -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>
```

View File

@ -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
)
}

View File

@ -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)
}
}

View File

@ -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("-")
}
}

View File

@ -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"))
);
}
}

View File

@ -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("<", "&lt;")
.replace(">", "&gt;");
*/
format!(
"<code class=\"border border-border-color dark:border-transparent\">{}</code>",
highlight(&self.value)
)
}
fn get_text(&self) -> String {
self.value.clone()
}
}

View File

@ -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")
}
}

View File

@ -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(""),
}
}
}

View File

@ -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")
}
}

View File

@ -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("-")
}
}

View File

@ -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)
}
}

View File

@ -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()
}
}

View File

@ -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")
}
}

View File

@ -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();
}

View File

@ -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,
&current_path,
input_folder,
output_folder,
file_tree_html,
);
}
}
}
}

View File

@ -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,
);
}

View File

@ -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,
}
}

View File

@ -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)),
}
}

View File

@ -1,3 +0,0 @@
node_modules
tailwind/output.css

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -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>

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@ -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"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 172 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 172 KiB

View File

@ -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

View File

@ -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: [],
}

View File

@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -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>