diff --git a/doc-generator/markdown/en/stdlib/latest/prelude/Console.md b/doc-generator/markdown/en/stdlib/latest/prelude/Console.md
new file mode 100644
index 0000000..6de7020
--- /dev/null
+++ b/doc-generator/markdown/en/stdlib/latest/prelude/Console.md
@@ -0,0 +1,26 @@
+# 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`
+```
diff --git a/doc-generator/markdown/en/stdlib/latest/prelude/String.md b/doc-generator/markdown/en/stdlib/latest/prelude/String.md
new file mode 100644
index 0000000..f52cd8a
--- /dev/null
+++ b/doc-generator/markdown/en/stdlib/latest/prelude/String.md
@@ -0,0 +1,294 @@
+# 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 ''
.
+```
+
+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
+```
+
+
+
+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
+```
+
+
+
+---
+
+## Methods
+
+### charAt
+
+```misti
+fun charAt(Num position) -> Str?
+```
+
+Returns the UTF-16 code unit located at `position`.
+
+
+
+#### 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"
+```
+
+
+
+
+### 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`
+
+
+
+#### 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"
+```
+
+
+
+
+
+### includes
+
+```misti
+fun includes(Str searchString, Num pos = 0) -> Bool
+```
+
+Returns whether the current string contains `searchString`,
+searching from position `pos`
+
+
+
+#### 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
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc-generator/src/generator/heading.rs b/doc-generator/src/generator/heading.rs
new file mode 100644
index 0000000..98b9626
--- /dev/null
+++ b/doc-generator/src/generator/heading.rs
@@ -0,0 +1,21 @@
+use std::fmt::format;
+
+use markdown::mdast::Heading;
+
+use super::Printable;
+
+
+impl Printable for Heading {
+ fn to_html(&self) -> String {
+ let mut result = Vec::::new();
+
+ for node in &self.children {
+ result.push(node.to_html())
+ }
+
+ let text: String = result.into_iter().collect();
+
+ format!("{}", self.depth, text, self.depth)
+ }
+}
+
diff --git a/doc-generator/src/generator/mod.rs b/doc-generator/src/generator/mod.rs
new file mode 100644
index 0000000..56b61de
--- /dev/null
+++ b/doc-generator/src/generator/mod.rs
@@ -0,0 +1,19 @@
+use markdown::mdast::Node;
+
+mod root;
+mod heading;
+
+pub trait Printable {
+ fn to_html(&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(),
+ _ => format!("Not implemented
{:?}", self),
+ }
+ }
+}
+
diff --git a/doc-generator/src/generator/root.rs b/doc-generator/src/generator/root.rs
new file mode 100644
index 0000000..7f10778
--- /dev/null
+++ b/doc-generator/src/generator/root.rs
@@ -0,0 +1,16 @@
+use markdown::mdast;
+
+use super::Printable;
+
+
+impl Printable for mdast::Root {
+ fn to_html(&self) -> String {
+ let mut result = Vec::::new();
+
+ for node in &self.children {
+ result.push(node.to_html())
+ }
+
+ result.into_iter().collect()
+ }
+}
diff --git a/doc-generator/src/main.rs b/doc-generator/src/main.rs
index 7d61ee3..344f28d 100644
--- a/doc-generator/src/main.rs
+++ b/doc-generator/src/main.rs
@@ -1,4 +1,5 @@
use clap::Parser;
+use generator::Printable;
use markdown::to_html;
use std::fs::File;
use std::io::Write;
@@ -7,6 +8,8 @@ use std::{
path::Path,
};
+mod generator;
+
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
@@ -67,18 +70,18 @@ fn ensure_folder_exists(folder: &Path, input_folder: &Path, output_folder: &Path
let mut full_output_folder = output_folder.clone();
full_output_folder.push(relative_new_folder);
- println!("Ensuring that folder exists:\n{:?}", full_output_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...");
+ // println!("| Removing...");
let _ = fs::remove_dir_all(&full_output_folder);
}
// Create folder
match fs::create_dir(&full_output_folder) {
Ok(_) => {
- println!("| done\n\n");
+ // println!("| done\n\n");
Ok(())
}
Err(_) => Err(format!("Error creating folder {:?}", full_output_folder)),
@@ -102,15 +105,16 @@ fn process_markdown(file: &Path, input_folder: &Path, output_folder: &Path) -> R
output_file.push(relative_input_file);
output_file.set_extension("html");
-
+ //
+ // Compilation
+ //
let file_content_bytes = fs::read(&input_file).unwrap();
let markdown_text = String::from_utf8(file_content_bytes).unwrap();
- let html_text = to_html(markdown_text.as_str());
+ // let html_text = to_html(markdown_text.as_str());
+ let md_ast = markdown::to_mdast(&markdown_text, &markdown::ParseOptions::gfm()).unwrap();
+ let html_text = md_ast.to_html();
- // Write the HTML to disk
-
- println!("Compiling: from -> to\n{:?}\n{:?}\n", input_file, output_file);
// Read template.html
let mut template_path = output_folder.clone();
@@ -121,6 +125,7 @@ fn process_markdown(file: &Path, input_folder: &Path, output_folder: &Path) -> R
let final_output = template_contents.replace("{{markdown}}", &html_text);
+ // Write to disk
let _ = File::create(&output_file)
.unwrap()
.write_all(final_output.as_bytes())
diff --git a/doc-generator/static/styles/global.css b/doc-generator/static/styles/global.css
index 40a9521..1ebb250 100644
--- a/doc-generator/static/styles/global.css
+++ b/doc-generator/static/styles/global.css
@@ -98,8 +98,6 @@ html {
font-size: 20px;
}
-.hide-on-small {}
-
.padded {
padding-left: 2rem;
border-left: solid 1px var(--border-color);
@@ -109,10 +107,6 @@ html {
html {
font-size: 18px;
}
-
- .hide-on-small {
- display: none;
- }
}
body {
@@ -158,25 +152,6 @@ g.terminal text {
transform: scale(1.5);
}
-.main-container {
- margin: 0 auto;
- max-width: 1400px;
- width: 90%;
-}
-
-.rainbow-separator {
- background-color: var(--js-color);
-}
-
-h2 {
- font-weight: normal;
- font-size: 2rem;
-}
-
-code {
-
-}
-
pre {
border: solid 1px rgba(150, 150, 150, 0.5);
}
@@ -193,17 +168,19 @@ code, pre {
.marked p {
line-height: 1.5rem;
text-align: justify;
+ margin: 1rem 0;
}
.marked h1 {
- font-weight: 600;
+ font-weight: 900;
margin-top: 3rem;
margin-bottom: 2rem;
+ font-size: 2.25rem;
}
.marked h2 {
- font-size: 1.75rem;
- font-weight: 500;
+ font-size: 2rem;
+ font-weight: bold;
margin-top: 3rem;
margin-bottom: 1.5rem;
}
@@ -213,9 +190,23 @@ code, pre {
text-decoration-color: var(--c5);
}
-.marked h3, .marked h4, .marked h5 {
- font-size: 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 {
@@ -302,11 +293,6 @@ code, pre {
margin-bottom: 0.75rem;
}
- .marked h2 {
- margin-top: 2rem;
- margin-bottom: 1.25rem;
- }
-
pre[class*="language-"].line-numbers {
font-size: 0.8rem;
}
diff --git a/doc-generator/static/template.html b/doc-generator/static/template.html
index 2d5f35e..f724acd 100644
--- a/doc-generator/static/template.html
+++ b/doc-generator/static/template.html
@@ -16,7 +16,9 @@
- {{markdown}}
+
+ {{markdown}}
+