Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/New Features/Continue Statement.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ for i = 1, 10 do
-- continue jumps here.
end
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=--%20Print%20every%20number%20besides%20five.%0D%0Afor%20i%20%3D%201%2C%2010%20do%0D%0A%20%20%20%20if%20i%20%3D%3D%205%20then%0D%0A%20%20%20%20%20%20%20%20continue%0D%0A%20%20%20%20end%0D%0A%20%20%20%20print(i)%0D%0A%20%20%20%20--%20continue%20jumps%20here.%0D%0Aend)

:::caution
Note, `continue` will skip code. If any code within your loop will determine if the loop continues, make sure `continue` doesn't jump over it.
Expand Down
2 changes: 0 additions & 2 deletions docs/New Features/Default Arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,3 @@ end
write() --> No text provided.
write("Hello!") --> Hello!
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20function%20write(text%20%3D%20%22No%20text%20provided.%22)%0D%0A%20%20%20%20print(text)%0D%0Aend%0D%0A%0D%0Awrite()%20%20%20%20%20%20%20%20%20--%3E%20%22No%20text%20provided.%22%0D%0Awrite(%22Hello!%22)%20--%3E%20%22Hello!%22)
1 change: 0 additions & 1 deletion docs/New Features/Lambda Expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ local s1 = "123"
local s2 = s1:gsub(".", |c| -> tonumber(c) + 1)
print(s2) --> 234
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20str%20%3D%20%22123%22%0D%0Alocal%20inc_str%20%3D%20str%3Agsub(%22.%22%2C%20%7Cc%7C%20-%3E%20tonumber(c)%20%2B%201)%0D%0Aprint(inc_str)%20--%20%22234%22)

As you can see, they take an expression after the arrow, the result of which is implicitly returned.

Expand Down
4 changes: 0 additions & 4 deletions docs/New Features/Named Arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ end
process_file(file = "hello.txt", version = 2) -- "Processing hello.txt with mode 'r' and version 2"
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20function%20process_file(file%2C%20mode%20%3D%20%22r%22%2C%20version%20%3D%201)%0D%0A%20%20%20%20print(%24%22Processing%20%7Bfile%7D%20with%20mode%20'%7Bmode%7D'%20and%20version%20%7Bversion%7D%22)%0D%0Aend%0D%0Aprocess_file(file%20%3D%20%22hello.txt%22%2C%20version%20%3D%202))

Note that this example also makes use of [default arguments](Default%20Arguments.md) and [string interpolation](String%20Interpolation.md).

## Mixing arguments
Expand All @@ -25,8 +23,6 @@ end
process_file("hello.txt", version = 2) -- "Processing hello.txt with mode 'r' and version 2"
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20function%20process_file(file%2C%20mode%20%3D%20%22r%22%2C%20version%20%3D%201)%0D%0A%20%20%20%20print(%24%22Processing%20%7Bfile%7D%20with%20mode%20'%7Bmode%7D'%20and%20version%20%7Bversion%7D%22)%0D%0Aend%0D%0Aprocess_file(%22hello.txt%22%2C%20version%20%3D%202))

## Limitations

This feature is implemented entirely in the parser and therefore only works for local functions at the moment.
2 changes: 0 additions & 2 deletions docs/New Features/Named Varargs.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,3 @@ function vfunc(...args)
end
vfunc("Hello") --> Hello
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=function%20vfunc(...args)%0D%0A%20%20%20%20for%20args%20as%20arg%20do%0D%0A%20%20%20%20%20%20%20%20print(arg)%0D%0A%20%20%20%20end%0D%0Aend%0D%0Avfunc(%22Hello%22)%20--%20%22Hello%22)
12 changes: 0 additions & 12 deletions docs/New Features/Object-Oriented Programming.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ local t = {
t.say("Hello") --> Hello
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20t%20%3D%20%7B%0D%0A%20%20%20%20static%20function%20say(msg)%0D%0A%20%20%20%20%20%20%20%20print(msg)%0D%0A%20%20%20%20end%0D%0A%7D%0D%0At.say(%22Hello%22)%20--%20%22Hello%22)

## New Operator

Pluto adds an easy way to make instances with the `new` operator. This operator will also call the `__construct` method if it exists.
Expand All @@ -55,8 +53,6 @@ local john = new Human("John")
print(john.name) --> John
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20Human%20%3D%20%7B%0D%0A%20%20%20%20function%20__construct(name)%0D%0A%20%20%20%20%20%20%20%20self.name%20%3D%20name%0D%0A%20%20%20%20end%0D%0A%7D%0D%0Alocal%20john%20%3D%20new%20Human(%22John%22)%0D%0Aprint(john.name)%20--%20John)

Note that for compatibility with Lua and C API classes, the `new` operator checks for the existence of a static 'new' function. If it exists, `new X(...)` will be identical to `X.new(...)`.

## Class Statement
Expand Down Expand Up @@ -107,8 +103,6 @@ print(human.age) --> 1
```
This also adds a `__parent` field to Human.

#### [Try It Yourself](https://pluto-lang.org/web/#code=class%20Entity%0D%0A%20%20%20%20age%20%3D%201%0D%0Aend%0D%0A%0D%0Aclass%20Human%20extends%20Entity%0D%0Aend%0D%0A%0D%0Alocal%20human%20%3D%20new%20Human()%0D%0Aprint(human.age)%20--%201)

## Parent Expression

The `parent` expression is a shorthand for `self.__parent`, which also supports method call syntax, in which case it's a shorthand for `self.__parent.METHOD(self, ...)`.
Expand All @@ -134,8 +128,6 @@ print(human.name) --> John

Note that if you have a local variable (or function parameter) called "parent", the `parent` expression will defer to it.

#### [Try It Yourself](https://pluto-lang.org/web/#code=class%20Entity%0D%0A%20%20%20%20function%20__construct(name)%0D%0A%20%20%20%20%20%20%20%20self.name%20%3D%20name%0D%0A%20%20%20%20end%0D%0Aend%0D%0A%0D%0Aclass%20Human%20extends%20Entity%0D%0A%20%20%20%20--%20If%20we%20don't%20define%20__construct%2C%20the%20parent-constructor%20would%20be%20called%20automatically.%0D%0A%20%20%20%20--%20However%2C%20if%20we%20overwrite%20it%2C%20we%20can%20use%20parent%3A__construct%20to%20call%20it%20manually.%0D%0A%20%20%20%20function%20__construct(name)%0D%0A%20%20%20%20%20%20%20%20parent%3A__construct(name)%0D%0A%20%20%20%20end%0D%0Aend%0D%0A%0D%0Alocal%20human%20%3D%20new%20Human(%22John%22)%0D%0Aprint(human.name)%20--%20%22John%22)

## Private Fields

Pluto allows you to specify if a field is 'public' or 'private'. Private fields can only be accessed by the class that defined them.
Expand All @@ -161,8 +153,6 @@ print(human:getAge()) -- 42
print(human.age) -- nil
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=class%20Human%0D%0A%20%20%20%20public%20name%0D%0A%20%20%20%20private%20age%0D%0A%0D%0A%20%20%20%20function%20__construct(name%2C%20age)%0D%0A%20%20%20%20%20%20%20%20self.name%20%3D%20name%0D%0A%20%20%20%20%20%20%20%20self.age%20%3D%20age%0D%0A%20%20%20%20end%0D%0A%0D%0A%20%20%20%20function%20getAge()%0D%0A%20%20%20%20%20%20%20%20return%20self.age%0D%0A%20%20%20%20end%0D%0Aend%0D%0A%0D%0Alocal%20human%20%3D%20new%20Human(%22John%22%2C%2042)%0D%0Aprint(human.name)%20--%20%22John%22%0D%0Aprint(human%3AgetAge())%20--%2042%0D%0Aprint(human.age)%20--%20nil)

## Constructor Promotion

Because a common task of `__construct` methods is to assign the value of arguments to table fields, Pluto provides a simple syntax to reduce this boilerplate:
Expand All @@ -183,8 +173,6 @@ print(human:getAge()) -- 42
print(human.age) -- nil
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=class%20Human%0D%0A%20%20%20%20function%20__construct(public%20name%2C%20private%20age)%0D%0A%20%20%20%20end%0D%0A%0D%0A%20%20%20%20function%20getAge()%0D%0A%20%20%20%20%20%20%20%20return%20self.age%0D%0A%20%20%20%20end%0D%0Aend%0D%0A%0D%0Alocal%20human%20%3D%20new%20Human(%22John%22%2C%2042)%0D%0Aprint(human.name)%20--%20%22John%22%0D%0Aprint(human%3AgetAge())%20--%2042%0D%0Aprint(human.age)%20--%20nil)

## Instanceof Operator

The `instanceof` operator can be used to check if a table is a class instance, including inherited classes:
Expand Down
2 changes: 0 additions & 2 deletions docs/New Features/String Indexing.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ print(str[-1]) -- "d"
```
Any character-intensive task — for example, a hash algorithm — will greatly benefit from this.

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20str%20%3D%20%22hello%20world%22%0D%0Aprint(str%5B5%5D)%20--%20%22o%22%0D%0Aprint(str%5B200%5D)%20--%20nil%0D%0Aprint(str%5B-1%5D)%20--%20%22d%22)

:::caution
The bytecode of this feature is not backwards-compatible with Lua.
:::
1 change: 0 additions & 1 deletion docs/New Features/String Interpolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ local label = "meaning of life"
local data = { value = 42 }
print($"The {label} is {data.value}") --> The meaning of life is 42
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20label%20%3D%20%22meaning%20of%20life%22%0D%0Alocal%20data%20%3D%20%7B%20value%20%3D%2042%20%7D%0D%0Aprint(%24%22The%20%7Blabel%7D%20is%20%7Bdata.value%7D%22)%20--%20%22The%20meaning%20of%20life%20is%2042%22)

As you can see, you declare a string interpolated by prefixing it with the "$" symbol. Brackets can contain any expression. The result of expressions will be converted to a string as with normal concatenation, although note that Pluto supports [boolean concatenation](../QoL%20Improvements/Boolean%20Concatenation) unlike Lua.
6 changes: 0 additions & 6 deletions docs/New Features/Switch Blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ end
```
The `default` case can be placed anywhere in the block. It also supports fallthrough, so remember to use `break` if you place it above any cases.

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20value%20%3D%203%0D%0Aswitch%20value%20do%0D%0A%20%20case%201%3A%0D%0A%20%20case%202%3A%0D%0A%20%20case%203%3A%0D%0A%20%20case%204%3A%0D%0A%20%20case%205%3A%0D%0A%20%20%20%20print%20%22Got%201-5.%22%0D%0A%20%20%20%20break%0D%0A%20%20default%3A%0D%0A%20%20%20%20print%20%22Value%20is%20greater%20than%205.%22%0D%0Aend%0D%0A--%20Break%20jumps%20here.)

## Case Blocks

Any expression can be used for the case condition:
Expand Down Expand Up @@ -128,8 +126,6 @@ print(place) --> 1st

Note that the case blocks here have their conditions delimited by an arrow (->) instead of a colon (:).

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20place%20%3D%201%0D%0Aplace%20%3D%20switch%20place%20do%0D%0A%20%20%20%20case%201%20-%3E%20%221st%22%0D%0A%20%20%20%20case%202%20-%3E%20%222nd%22%0D%0A%20%20%20%20case%203%20-%3E%20%223rd%22%0D%0A%20%20%20%20default%20-%3E%20%24%22%7Bplace%7Dth%22%0D%0Aend%0D%0Aprint(place))

Despite not being able to manually fall through, the shorthand fallthrough syntax still works:

```pluto
Expand All @@ -146,7 +142,5 @@ print_range(9) --> nil

Notice how the `default` case was omitted in this example, so it was implicitly set to `default -> nil`.

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20function%20print_range(value)%0D%0A%20%20%20%20print(switch%20value%20do%0D%0A%20%20%20%20%20%20%20%20case%201%2C%202%2C%203%20-%3E%20%221-3%22%0D%0A%20%20%20%20%20%20%20%20case%204%2C%205%2C%206%20-%3E%20%224-6%22%0D%0A%20%20%20%20end)%0D%0Aend%0D%0Aprint_range(1)%20--%3E%20%221-3%22%0D%0Aprint_range(6)%20--%3E%20%224-6%22%0D%0Aprint_range(9)%20--%3E%20nil)

## Using Compatibility Mode?
You may need to use `pluto_switch` instead of `switch`. Alternatively, `pluto_use switch` will enable the keyword independently of environment settings.
4 changes: 2 additions & 2 deletions docs/New Features/Ternary Expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
sidebar_position: 1
---
Ternary expressions behave identical as to how they would in C. They introduce no new keywords.
```pluto title="Old Code"
```pluto norun title="Old Code"
local max
if a > b then
max = a
else
max = b
end
```
```pluto title="New Code"
```pluto norun title="New Code"
local max = a > b ? a : b
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20a%20%3D%206%0Alocal%20b%20%3D%209%0A%0Alocal%20max%20%3D%20a%20%3E%20b%20%3F%20a%20%3A%20b%0A%0Aprint(max))
Expand Down
2 changes: 0 additions & 2 deletions docs/New Features/Try-Catch Statement.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ print(try_get_fruit_rating("cucumber")) --> -10
print(try_get_fruit_rating("car")) --> nil
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20function%20get_fruit_rating(fruit)%0D%0A%20%20%20%20return%20switch%20fruit%20do%0D%0A%20%20%20%20%20%20%20%20case%20%22apple%22%20-%3E%208%0D%0A%20%20%20%20%20%20%20%20case%20%22banana%22%20-%3E%207%0D%0A%20%20%20%20%20%20%20%20case%20%22orange%22%20-%3E%209%0D%0A%20%20%20%20%20%20%20%20case%20%22mango%22%20-%3E%2010%0D%0A%20%20%20%20%20%20%20%20case%20%22grape%22%20-%3E%206%0D%0A%20%20%20%20%20%20%20%20case%20%22strawberry%22%20-%3E%209%0D%0A%20%20%20%20%20%20%20%20case%20%22cucumber%22%2C%20%22tomato%22%20-%3E%20error(%22What%20are%20you%2C%20a%20botanist%3F%22)%0D%0A%20%20%20%20end%0D%0Aend%0D%0A%0D%0Alocal%20function%20try_get_fruit_rating(fruit)%0D%0A%20%20%20%20try%0D%0A%20%20%20%20%20%20%20%20return%20get_fruit_rating(fruit)%0D%0A%20%20%20%20catch%20e%20then%0D%0A%20%20%20%20%20%20%20%20if%20e%3Afind(%22What%20are%20you%2C%20a%20botanist%3F%22)%20then%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20-10%0D%0A%20%20%20%20%20%20%20%20end%0D%0A%20%20%20%20end%0D%0Aend%0D%0A%0D%0Aprint(try_get_fruit_rating(%22apple%22))%20--%3E%208%0D%0Aprint(try_get_fruit_rating(%22cucumber%22))%20--%3E%20-10%0D%0Aprint(try_get_fruit_rating(%22car%22))%20--%3E%20nil)

## Using Compatibility Mode?

You may need to use `pluto_try` and `pluto_catch` instead. Alternatively, `pluto_use try, catch` will enable both keywords independently of the environment settings.
16 changes: 6 additions & 10 deletions docs/New Operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ This operator does not implement any metamethods.
## Walrus Operator
The Walrus operator allows you to perform assignments inside of conditional expresssions.

```pluto
```pluto norun
if a := get_value() then
-- 'a' was assigned a truthy value.
else
-- 'a' was assigned a falsy value.
end
```
You can imagine it like this, but note they're not always the same:
```pluto
```pluto norun
do
local a = get_value()
if a then
Expand All @@ -103,12 +103,12 @@ end
```

Note that for while-loops, it will be executed as many times as the condition:
```pluto title="Pluto Way"
```pluto norun title="Pluto Way"
while a := next_value() do
-- ...
end
```
```pluto title="Lua Way"
```pluto norun title="Lua Way"
while true do
local a = next_value()
if not a then break end
Expand All @@ -128,7 +128,7 @@ print(eq, lt, gt) --> 0, -1, 1

It works with any type that supports `__eq` and `__lt`, making it well-suited for usage in generic algorithms like sorting. The return values are designed such that you can compare them to `0`, e.g. with the values from above:

```pluto
```pluto norun
print(eq <= 0) --> true
print(lt <= 0) --> true
print(gt <= 0) --> false
Expand Down Expand Up @@ -156,9 +156,8 @@ http.request("https://httpbin.org/get")
--> ["url"] = string(23) "https://httpbin.org/get",
--> }
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20%7B%20http%2C%20json%20%7D%20%3D%20require%20%22pluto%3A*%22%0D%0A%0D%0Ahttp.request(%22https%3A%2F%2Fhttpbin.org%2Fget%22)%0D%0A%7C%3E%20json.decode%0D%0A%7C%3E%20dumpvar%0D%0A%7C%3E%20print%0D%0A)
The HTTP-to-print pipeline here would otherwise be written like this:
```pluto
```pluto norun
print(dumpvar(json.decode((http.request("https://httpbin.org/get")))))
```
Note that the pipe operator only passes on the first return value, which is classically achieved by wrapping the expression in an extra pair of parentheses.
Expand All @@ -172,7 +171,6 @@ producer()
|> tonumber|16|
|> print --> 16
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20producer%20%3D%20%7C%7C%20-%3E%20%2210%22%0D%0A%0D%0Aproducer()%0D%0A%7C%3E%20tonumber%7C16%7C%0D%0A%7C%3E%20print%20--%3E%2016%0D%0A)

### Methods Calls
There is specialized syntax for method calls with the pipe operator, too:
Expand All @@ -190,7 +188,6 @@ producer()
|> obj:multiply
|> print --> 42
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20producer%20%3D%20%7C%7C%20-%3E%2021%0D%0A%0D%0Alocal%20obj%20%3D%20%7B%0D%0A%20%20%20%20function%20multiply(value)%0D%0A%20%20%20%20%20%20%20%20return%20value%20*%20self.factor%0D%0A%20%20%20%20end%0D%0A%7D%0D%0Aobj.factor%20%3D%202%0D%0A%0D%0Aproducer()%0D%0A%7C%3E%20obj%3Amultiply%0D%0A%7C%3E%20print%20--%3E%2042%0D%0A)

### Anonymous Functions
The righthand side of the pipe operator can also be an anonymous function, allowing for more advanced usage like this:
Expand All @@ -202,4 +199,3 @@ producer()

--> The result was 42
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20producer%20%3D%20%7C%7C%20-%3E%2042%0D%0A%0D%0Aproducer()%0D%0A%7C%3E%20%7Cres%7C%20-%3E%20print(%24%22The%20result%20was%20%7Bres%7D%22)%0D%0A%0D%0A--%3E%20The%20result%20was%2042%0D%0A)
2 changes: 0 additions & 2 deletions docs/Runtime Environment/Exception.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,3 @@ script.pluto:2: Not implemented
Not implemented
script.pluto:2
```

#### [Try It Yourself](https://pluto-lang.org/web/#code=try%0A%20%20%20%20new%20exception(%22Not%20implemented%22)%0Acatch%20e%20then%0A%20%20%20%20print(e)%20--%20same%20as%20error(%22Not%20implemented%22)%0A%20%20%20%20print(e.what)%0A%20%20%20%20print(e.where)%0Aend)
1 change: 0 additions & 1 deletion docs/Runtime Environment/HTTP.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ if os.platform != "wasm" then
end
print(body)
```
#### [Try It Yourself](https://pluto-lang.org/web/#code=local%20http%20%3D%20require%20%22pluto%3Ahttp%22%0D%0Alocal%20body%2C%20status_code%2C%20headers%2C%20status_text%20%3D%20http.request(%22https%3A%2F%2Fhttpbin.org%2Fanything%22)%0D%0Aprint(status_code..%22%20%22..status_text)%0D%0Aif%20os.platform%20!%3D%20%22wasm%22%20then%0D%0A%20%20%20%20print(dumpvar(headers))%0D%0Aend%0D%0Aprint(body))

---
### `http.hasconnection`
Expand Down
5 changes: 4 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ const config = {
respectPrefersColorScheme: false,
},
}),
trailingSlash: false
trailingSlash: false,
scripts: [
{ src: '/custom.js', async: true }
]
};

module.exports = config;
16 changes: 16 additions & 0 deletions src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,19 @@ p, h1, h2, h3, h4, a {
text-align: right;
color: rgba(115,138,148,.4)
}

.copy-button {
background: none !important;
cursor: auto !important;
padding: 0 !important;
}

.copy-button button {
appearance: none;
border: none;
background: rgba(0, 0, 0, 0.3);
border-radius: var(--ifm-global-radius);
cursor: pointer;
padding: 0.4rem 0.5rem;
margin-left: 0.3rem;
}
29 changes: 29 additions & 0 deletions static/custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var observer = new MutationObserver(() => {
observer.disconnect();
patchCodeblocks();
observer.observe(document, { childList: true, subtree: true });
});

function patchCodeblocks() {
document.querySelectorAll(".shiki.monokai:has(button.copy-button)").forEach(code => {
code.removeAttribute("title");

const div = document.createElement("div");
div.className = "copy-button";
code.appendChild(div);

if (!code.hasAttribute("norun")) {
const button = document.createElement("button");
button.textContent = "Try It";
button.onclick = () => {
window.open("https://pluto-lang.org/web/#code=" + encodeURIComponent([...code.querySelectorAll(".code-container .line")].map(x => x.textContent).join("\n")));
};
div.appendChild(button);
}

div.appendChild(code.querySelector(".copy-button")).className = "";
});
}

patchCodeblocks();
observer.observe(document, { childList: true, subtree: true });