diff --git a/arturo.html.markdown b/arturo.html.markdown
new file mode 100644
index 00000000..c3c4dc43
--- /dev/null
+++ b/arturo.html.markdown
@@ -0,0 +1,432 @@
+---
+language: arturo
+filename: learnarturo.art
+contributors:
+ - ["Dr.Kameleon", "https://github.com/drkameleon"]
+---
+
+```red
+; this is a comment
+; this is another comment
+
+;---------------------------------
+; VARIABLES & VALUES
+;---------------------------------
+
+; numbers
+a1: 2
+a2: 3.14
+a3: to :complex [1 2.0] ; 1.0+2.0i
+
+; strings
+c1: "this is a string"
+c2: {
+ this is a multiline string
+ that is indentation-agnostic
+}
+c3: {:
+ this is
+ a verbatim
+ multiline string
+ which will remain exactly
+ as the original
+:}
+
+; characters
+ch: `c`
+
+; blocks/arrays
+d: [1 2 3]
+
+; dictionaries
+e: #[
+ name: "John"
+ surname: "Doe"
+ age: 34
+ likes: [pizza spaghetti]
+]
+
+; yes, functions are values too
+f: function [x][
+ 2 * x
+]
+
+; dates
+g: now ; 2021-05-03T17:10:48+02:00
+
+; booleans
+h1: true
+h2: false
+
+;---------------------------------
+; BASIC OPERATORS
+;---------------------------------
+
+; simple arithmetic
+1 + 1 ; => 2
+8 - 1 ; => 7
+4.2 - 1.1 ; => 3.1
+10 * 2 ; => 20
+35 / 4 ; => 8
+35 // 4 ; => 8.75
+2 ^ 5 ; => 32
+5 % 3 ; => 2
+
+; bitwise operators
+and 3 5 ; => 1
+or 3 5 ; => 7
+xor 3 5 ; => 6
+
+; pre-defined constants
+pi ; => 3.141592653589793
+epsilon ; => 2.718281828459045
+null ; => null
+true ; => true
+false ; => false
+
+;---------------------------------
+; COMPARISON OPERATORS
+;---------------------------------
+
+; equality
+1 = 1 ; => true
+2 = 1 ; => false
+
+; inequality
+1 <> 1 ; => false
+2 <> 1 ; => true
+
+; more comparisons
+1 < 10 ; => true
+1 =< 10 ; => true
+10 =< 10 ; => true
+1 > 10 ; => false
+1 >= 10 ; => false
+11 >= 10 ; => true
+
+;---------------------------------
+; CONDITIONALS
+;---------------------------------
+
+; logical operators
+and? true true ; => true
+and? true false ; => false
+or? true false ; => true
+or? false false ; => false
+
+and? [1=2][2<3] ; => false
+ ; (the second block will not be evaluated)
+
+; simple if statements
+if 2 > 1 [ print "yes!"] ; yes!
+if 3 <> 2 -> print "true!" ; true!
+
+; if/else statements
+if? 2 > 3 -> print "2 is greater than 3"
+else -> print "2 is not greater than 3" ; 2 is not greater than 3
+
+; switch statements
+switch 2 > 3 -> print "2 is greater than 3"
+ -> print "2 is not greater than 3" ; 2 is not greater than 3
+
+a: (2 > 3)["yes"]["no"] ; a: "no"
+a: (2 > 3)? -> "yes" -> "no" ; a: "no" (exactly the same as above)
+
+; case/when statements
+case [1]
+ when? [>2] -> print "1 is greater than 2. what?!"
+ when? [<0] -> print "1 is less than 0. nope..."
+ else -> print "here we are!" ; here we are!
+
+;---------------------------------
+; LOOPS
+;---------------------------------
+
+; with `loop`
+arr: [1 4 5 3]
+loop arr 'x [
+ print ["x =" x]
+]
+; x = 1
+; x = 4
+; x = 5
+; x = 3
+
+; with loop and custom index
+loop.with:'i arr 'x [
+ print ["item at position" i "=>" x]
+]
+; item at position 0 => 1
+; item at position 1 => 4
+; item at position 2 => 5
+; item at position 3 => 3
+
+; using ranges
+loop 1..3 'x -> ; since it's a single statement
+ print x ; there's no need for [block] notation
+ ; we can wrap it up using the `->` syntactic sugar
+
+loop `a`..`c` 'ch ->
+ print ch
+; a
+; b
+; c
+
+; picking multiple items
+loop 1..10 [x y] ->
+ print ["x =" x ", y =" y]
+; x = 1 , y = 2
+; x = 3 , y = 4
+; x = 5 , y = 6
+; x = 7 , y = 8
+; x = 9 , y = 10
+
+; looping through a dictionary
+dict: #[name: "John", surname: "Doe", age: 34]
+loop dict [key value][
+ print [key "->" value]
+]
+; name -> John
+; surname -> Doe
+; age -> 34
+
+; while loops
+i: new 0
+while [i<3][
+ print ["i =" i]
+ inc 'i
+]
+; i = 0
+; i = 1
+; i = 2
+
+;---------------------------------
+; STRINGS
+;---------------------------------
+
+; case
+a: "tHis Is a stRinG"
+print upper a ; THIS IS A STRING
+print lower a ; this is a string
+print capitalize a ; tHis Is a stRinG
+
+; concatenation
+a: "Hello " ++ "World!" ; a: "Hello World!"
+
+; strings as an array
+split "hello" ; => [h e l l o]
+split.words "hello world" ; => [hello world]
+
+print first "hello" ; h
+print last "hello" ; o
+
+; conversion
+to :string 123 ; => "123"
+to :integer "123" ; => 123
+
+; joining strings together
+join ["hello" "world"] ; => "helloworld"
+join.with:"-" ["hello" "world"] ; => "hello-world"
+
+; string interpolation
+x: 2
+print ~"x = |x|" ; x = 2
+
+; interpolation with `print`
+print ["x =" x] ; x = 2
+ ; (`print` works by calculating the given block
+ ; and joining the different values as strings
+ ; with a single space between them)
+
+; templates
+print render.template {
+ <||= switch x=2 [ ||>
+ Yes, x = 2
+ <||][||>
+ No, x is not 2
+ <||]||>
+} ; Yes, x = 2
+
+; matching
+prefix? "hello" "he" ; => true
+suffix? "hello" "he" ; => false
+
+contains? "hello" "ll" ; => true
+contains? "hello" "he" ; => true
+contains? "hello" "x" ; => false
+
+in? "ll" "hello" ; => true
+in? "x" "hello" ; => false
+
+;---------------------------------
+; BLOCKS
+;---------------------------------
+
+; calculate a block
+arr: [1 1+1 1+1+1]
+@arr ; => [1 2 3]
+
+; execute a block
+sth: [print "Hello world"] ; this is perfectly valid,
+ ; could contain *anything*
+ ; and will not be executed...
+
+do sth ; Hello world
+ ; (...until we tell it to)
+
+; array indexing
+arr: ["zero" "one" "two" "three"]
+print first arr ; zero
+print arr\0 ; zero
+print last arr ; three
+print arr\3 ; three
+
+x: 2
+print get arr x ; two
+print arr \ 2 ; two
+ ; (using the `\` infix alias for get -
+ ; notice space between the operands!
+ ; otherwise, it'll be parsed as a path)
+
+; setting an array element
+arr\0: "nada"
+set arr 2 "dos"
+print arr ; nada one dos three
+
+; adding elements to an array
+arr: new []
+'arr ++ "one"
+'arr ++ "two"
+print arr ; one two
+
+; remove elements from an array
+arr: new ["one" "two" "three" "four"]
+'arr -- "two" ; arr: ["one" "three" "four"]
+remove 'arr .index 0 ; arr: ["three" "four"]
+
+; getting the size of an array
+arr: ["one" 2 "three" 4]
+print size arr ; 4
+
+; getting a slice of an array
+print slice ["one" "two" "three" "four"] 0 1 ; one two
+
+; check if array contains a specific element
+print contains? arr "one" ; true
+print contains? arr "five" ; false
+
+; sorting array
+arr: [1 5 3 2 4]
+sort arr ; => [1 2 3 4 5]
+sort.descending arr ; => [5 4 3 2 1]
+
+; mapping values
+map 1..10 [x][2*x] ; => [2 4 6 8 10 12 14 16 18 20]
+map 1..10 'x -> 2*x ; same as above
+map 1..10 => [2*&] ; same as above
+map 1..10 => [2*] ; same as above
+
+; selecting/filtering array values
+select 1..10 [x][odd? x] ; => [1 3 5 7 9]
+select 1..10 => odd? ; same as above
+
+filter 1..10 => odd? ; => [2 4 6 8 10]
+ ; (now, we leave out all odd numbers -
+ ; while select keeps them)
+
+; misc operations
+arr: ["one" 2 "three" 4]
+reverse arr ; => [4 "three" 2 "one"]
+shuffle arr ; => [2 4 "three" "one"]
+unique [1 2 3 2 3 1] ; => [1 2 3]
+permutate [1 2 3] ; => [[1 2 3] [1 3 2] [3 1 2] [2 1 3] [2 3 1] [3 2 1]]
+take 1..10 3 ; => [1 2 3]
+repeat [1 2] 3 ; => [1 2 1 2 1 2]
+
+;---------------------------------
+; FUNCTIONS
+;---------------------------------
+
+; declaring a function
+f: function [x][ 2*x ]
+f: function [x]-> 2*x ; same as above
+f: $[x]->2*x ; same as above (only using the `$` alias
+ ; for the `function`... function)
+
+; calling a function
+f 10 ; => 20
+
+; returning a value
+g: function [x][
+ if x < 2 -> return 0
+
+ res: 0
+ loop 0..x 'z [
+ res: res + z
+ ]
+ return res
+]
+
+;---------------------------------
+; CUSTOM TYPES
+;---------------------------------
+
+; defining a custom type
+define :person [ ; define a new custom type "Person"
+ name ; with fields: name, surname, age
+ surname
+ age
+][
+ ; with custom post-construction initializer
+ init: [
+ this\name: capitalize this\name
+ ]
+
+ ; custom print function
+ print: [
+ render "NAME: |this\name|, SURNAME: |this\surname|, AGE: |this\age|"
+ ]
+
+ ; custom comparison operator
+ compare: 'age
+]
+
+; create a method for our custom type
+sayHello: function [this][
+ ensure -> is? :person this
+
+ print ["Hello" this\name]
+]
+
+; create new objects of our custom type
+a: to :person ["John" "Doe" 34] ; let's create 2 "Person"s
+b: to :person ["jane" "Doe" 33] ; and another one
+
+; call pseudo-inner method
+sayHello a ; Hello John
+sayHello b ; Hello Jane
+
+; access object fields
+print ["The first person's name is:" a\name] ; The first person's name is: John
+print ["The second person's name is:" b\name] ; The second person's name is: Jane
+
+; changing object fields
+a\name: "Bob"
+sayHello a ; Hello Bob
+
+; verifying object type
+print type a ; :person
+print is? :person a ; true
+
+; printing objects
+print a ; NAME: John, SURNAME: Doe, AGE: 34
+
+; sorting user objects (using custom comparator)
+sort @[a b] ; Jane..., John...
+sort.descending @[a b] ; John..., Jane...
+```
+
+## Additional resources
+
+- [Official documentation](https://arturo-lang.io/documentation/) - Arturo official documentation & reference.
+- [Online playground](https://arturo-lang.io/playground/) - Online REPL for the Arturo programming language.