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}} +