feat: add cJSON and SQLite amalgamation source files under deps/

Add the cJSON library (cJSON.c, cJSON.h) and SQLite amalgamation
(sqlite3.c, sqlite3.h, sqlite3ext.h, shell.c) as vendored dependencies
in the deps/ directory for use by the project build system.
This commit is contained in:
2026-01-24 18:35:43 +00:00
parent 8f1d13a86b
commit fdd61cc90c
118 changed files with 315687 additions and 6 deletions
+68
View File
@@ -0,0 +1,68 @@
// retoor <retoor@molodetz.nl>
import "base64" for Base64
System.print("=== Base64 Module Demo ===\n")
System.print("--- Basic Encoding ---")
var text = "Hello, World!"
var encoded = Base64.encode(text)
System.print("Original: %(text)")
System.print("Encoded: %(encoded)")
System.print("\n--- Basic Decoding ---")
var decoded = Base64.decode(encoded)
System.print("Decoded: %(decoded)")
System.print("\n--- Various Strings ---")
var samples = [
"Hello",
"The quick brown fox jumps over the lazy dog",
"12345",
"Special chars: !@#^&*()",
"Unicode: cafe resume naive"
]
for (sample in samples) {
var enc = Base64.encode(sample)
var dec = Base64.decode(enc)
System.print("%(sample)")
System.print(" -> %(enc)")
System.print(" <- %(dec)")
System.print("")
}
System.print("--- URL-Safe Encoding ---")
var urlData = "Hello+World/Test=End"
var urlEncoded = Base64.encodeUrl(urlData)
var standardEncoded = Base64.encode(urlData)
System.print("Original: %(urlData)")
System.print("Standard Base64: %(standardEncoded)")
System.print("URL-Safe Base64: %(urlEncoded)")
System.print("\n--- URL-Safe Decoding ---")
var urlDecoded = Base64.decodeUrl(urlEncoded)
System.print("Decoded from URL-safe: %(urlDecoded)")
System.print("\n--- Binary-like Data ---")
var binaryText = "Binary: \x00\x01\x02\xFF"
var binaryEncoded = Base64.encode(binaryText)
System.print("Binary-like string encoded: %(binaryEncoded)")
System.print("\n--- Empty String ---")
System.print("Empty encoded: %(Base64.encode(""))")
System.print("Empty decoded: %(Base64.decode(""))")
System.print("\n--- Practical Example: Basic Auth Header ---")
var username = "admin"
var password = "secret123"
var credentials = "%(username):%(password)"
var authHeader = "Basic " + Base64.encode(credentials)
System.print("Credentials: %(credentials)")
System.print("Authorization header: %(authHeader)")
System.print("\n--- Practical Example: Data URI ---")
var jsonData = "{\"message\":\"Hello\"}"
var dataUri = "data:application/json;base64," + Base64.encode(jsonData)
System.print("JSON: %(jsonData)")
System.print("Data URI: %(dataUri)")
+89
View File
@@ -0,0 +1,89 @@
// retoor <retoor@molodetz.nl>
import "crypto" for Crypto, Hash
System.print("=== Crypto Module Demo ===\n")
System.print("--- Random Bytes ---")
var bytes = Crypto.randomBytes(16)
System.print("16 random bytes: %(bytes)")
System.print("As hex: %(Hash.toHex(bytes))")
System.print("\n--- Random Integers ---")
System.print("Random integers between 1 and 100:")
for (i in 0...5) {
var num = Crypto.randomInt(1, 101)
System.print(" %(num)")
}
System.print("\n--- Random Integers (different ranges) ---")
System.print("1-10: %(Crypto.randomInt(1, 11))")
System.print("0-255: %(Crypto.randomInt(0, 256))")
System.print("1000-9999: %(Crypto.randomInt(1000, 10000))")
System.print("\n--- MD5 Hashing ---")
var text = "Hello, World!"
var md5Bytes = Hash.md5(text)
var md5Hex = Hash.toHex(md5Bytes)
System.print("Text: %(text)")
System.print("MD5: %(md5Hex)")
System.print("\n--- SHA1 Hashing ---")
var sha1Bytes = Hash.sha1(text)
var sha1Hex = Hash.toHex(sha1Bytes)
System.print("SHA1: %(sha1Hex)")
System.print("\n--- SHA256 Hashing ---")
var sha256Bytes = Hash.sha256(text)
var sha256Hex = Hash.toHex(sha256Bytes)
System.print("SHA256: %(sha256Hex)")
System.print("\n--- Hashing Different Inputs ---")
var inputs = [
"",
"test",
"The quick brown fox jumps over the lazy dog",
"password123"
]
for (input in inputs) {
var hash = Hash.toHex(Hash.sha256(input))
var displayInput = input
if (input == "") displayInput = "(empty string)"
if (input.count > 30) displayInput = input[0...30] + "..."
System.print("%(displayInput)")
System.print(" -> %(hash)")
}
System.print("\n--- Password Hashing Example ---")
var password = "mysecretpassword"
var passwordHash = Hash.toHex(Hash.sha256(password))
System.print("Password: %(password)")
System.print("Hash: %(passwordHash)")
System.print("\n--- Generating Random Token ---")
var tokenBytes = Crypto.randomBytes(32)
var token = Hash.toHex(tokenBytes)
System.print("Random token (64 hex chars): %(token)")
System.print("\n--- Generating Random Session ID ---")
var sessionBytes = Crypto.randomBytes(16)
var sessionId = Hash.toHex(sessionBytes)
System.print("Session ID: %(sessionId)")
System.print("\n--- Hash Comparison (constant input) ---")
var data = "consistent input"
var hash1 = Hash.toHex(Hash.sha256(data))
var hash2 = Hash.toHex(Hash.sha256(data))
System.print("Same input produces same hash: %(hash1 == hash2)")
System.print("\n--- Practical Example: File Checksum ---")
var fileContent = "This is the content of a file.\nLine 2.\nLine 3."
var checksum = Hash.toHex(Hash.sha256(fileContent))
System.print("File content checksum (SHA256):")
System.print(" %(checksum)")
System.print("\n--- Practical Example: API Key Generation ---")
var apiKeyBytes = Crypto.randomBytes(24)
var apiKey = Hash.toHex(apiKeyBytes)
System.print("Generated API key: %(apiKey)")
+86
View File
@@ -0,0 +1,86 @@
// retoor <retoor@molodetz.nl>
import "datetime" for DateTime, Duration
System.print("=== DateTime Module Demo ===\n")
System.print("--- Current Date/Time ---")
var now = DateTime.now()
System.print("Now: %(now)")
System.print("Timestamp: %(now.timestamp)")
System.print("\n--- Date Components ---")
System.print("Year: %(now.year)")
System.print("Month: %(now.month)")
System.print("Day: %(now.day)")
System.print("Hour: %(now.hour)")
System.print("Minute: %(now.minute)")
System.print("Second: %(now.second)")
System.print("Day of Week: %(now.dayOfWeek) (0=Sunday)")
System.print("Day of Year: %(now.dayOfYear)")
System.print("Is DST: %(now.isDst)")
System.print("\n--- Creating from Timestamp ---")
var epoch = DateTime.fromTimestamp(0)
System.print("Unix Epoch: %(epoch)")
var specificTime = DateTime.fromTimestamp(1704067200)
System.print("Jan 1, 2024 00:00 UTC: %(specificTime)")
System.print("\n--- Formatting with strftime ---")
System.print("ISO 8601: %(now.toIso8601)")
System.print("Date (Y-m-d): %(now.format("\%Y-\%m-\%d"))")
System.print("Time (H:M:S): %(now.format("\%H:\%M:\%S"))")
System.print("Full date: %(now.format("\%A, \%B \%d, \%Y"))")
System.print("Time with AM/PM: %(now.format("\%I:\%M \%p"))")
System.print("\n--- Duration Class ---")
var oneHour = Duration.fromHours(1)
var twoMinutes = Duration.fromMinutes(2)
var thirtySeconds = Duration.fromSeconds(30)
var oneDay = Duration.fromDays(1)
System.print("1 hour in seconds: %(oneHour.seconds)")
System.print("2 minutes in milliseconds: %(twoMinutes.milliseconds)")
System.print("30 seconds in minutes: %(thirtySeconds.minutes)")
System.print("1 day in hours: %(oneDay.hours)")
System.print("\n--- Duration Arithmetic ---")
var combined = oneHour + twoMinutes + thirtySeconds
System.print("1 hour + 2 minutes + 30 seconds: %(combined)")
System.print(" in seconds: %(combined.seconds)")
var doubled = oneHour * 2
System.print("1 hour * 2: %(doubled)")
var diff = oneHour - twoMinutes
System.print("1 hour - 2 minutes: %(diff)")
System.print("\n--- DateTime Arithmetic ---")
var tomorrow = now + Duration.fromDays(1)
System.print("Now: %(now)")
System.print("Tomorrow: %(tomorrow)")
var nextHour = now + Duration.fromHours(1)
System.print("Next hour: %(nextHour)")
var yesterday = now - Duration.fromDays(1)
System.print("Yesterday: %(yesterday)")
System.print("\n--- DateTime Comparison ---")
System.print("tomorrow > now: %(tomorrow > now)")
System.print("yesterday < now: %(yesterday < now)")
System.print("now == now: %(now == now)")
System.print("\n--- Difference Between DateTimes ---")
var timeDiff = tomorrow - now
System.print("Difference (tomorrow - now): %(timeDiff)")
System.print("\n--- Practical Example: Event Timing ---")
var eventStart = DateTime.now()
var eventDuration = Duration.fromHours(2) + Duration.fromMinutes(30)
var eventEnd = eventStart + eventDuration
System.print("Event starts: %(eventStart.format("\%H:\%M"))")
System.print("Event duration: %(eventDuration)")
System.print("Event ends: %(eventEnd.format("\%H:\%M"))")
+47
View File
@@ -0,0 +1,47 @@
// retoor <retoor@molodetz.nl>
import "dns" for Dns
System.print("=== DNS Module Demo ===\n")
System.print("--- Basic DNS Lookup ---")
var hostname = "example.com"
System.print("Looking up: %(hostname)")
var addresses = Dns.lookup(hostname)
System.print("Addresses: %(addresses)")
System.print("\n--- IPv4 Only Lookup ---")
System.print("Looking up %(hostname) (IPv4 only)")
var ipv4Addresses = Dns.lookup(hostname, 4)
System.print("IPv4 addresses: %(ipv4Addresses)")
System.print("\n--- IPv6 Only Lookup ---")
System.print("Looking up %(hostname) (IPv6 only)")
var ipv6Addresses = Dns.lookup(hostname, 6)
System.print("IPv6 addresses: %(ipv6Addresses)")
System.print("\n--- Multiple Hostname Lookups ---")
var hosts = ["google.com", "github.com", "cloudflare.com"]
for (host in hosts) {
var addrs = Dns.lookup(host, 4)
if (addrs.count > 0) {
System.print("%(host) -> %(addrs[0])")
} else {
System.print("%(host) -> (no addresses found)")
}
}
System.print("\n--- Localhost Lookup ---")
var localhost = Dns.lookup("localhost", 4)
System.print("localhost (IPv4): %(localhost)")
System.print("\n--- Practical Example: Server Connection ---")
var serverHost = "httpbin.org"
System.print("Resolving server: %(serverHost)")
var serverAddrs = Dns.lookup(serverHost, 4)
if (serverAddrs.count > 0) {
System.print("Server IP: %(serverAddrs[0])")
System.print("Ready to connect to %(serverAddrs[0]):80")
} else {
System.print("Could not resolve %(serverHost)")
}
+51
View File
@@ -0,0 +1,51 @@
// retoor <retoor@molodetz.nl>
import "env" for Environment
System.print("=== Environment Module Demo ===\n")
System.print("--- Reading Environment Variables ---")
var home = Environment.get("HOME")
var path = Environment.get("PATH")
var user = Environment.get("USER")
System.print("HOME: %(home)")
System.print("USER: %(user)")
System.print("PATH (first 80 chars): %(path[0...80])...")
System.print("\n--- Reading Non-existent Variable ---")
var missing = Environment.get("WREN_NONEXISTENT_VAR_12345")
System.print("Missing variable: %(missing)")
System.print("\n--- Setting Environment Variables ---")
Environment.set("WREN_DEMO_VAR", "Hello from Wren!")
var demoVar = Environment.get("WREN_DEMO_VAR")
System.print("WREN_DEMO_VAR: %(demoVar)")
Environment.set("WREN_DEMO_NUMBER", "42")
System.print("WREN_DEMO_NUMBER: %(Environment.get("WREN_DEMO_NUMBER"))")
System.print("\n--- Updating Environment Variables ---")
Environment.set("WREN_DEMO_VAR", "Updated value")
System.print("WREN_DEMO_VAR (updated): %(Environment.get("WREN_DEMO_VAR"))")
System.print("\n--- Deleting Environment Variables ---")
Environment.delete("WREN_DEMO_VAR")
var afterDelete = Environment.get("WREN_DEMO_VAR")
System.print("WREN_DEMO_VAR (after delete): %(afterDelete)")
System.print("\n--- Listing All Environment Variables ---")
var all = Environment.all
System.print("Total environment variables: %(all.count)")
System.print("\nFirst 10 environment variables:")
var count = 0
for (entry in all) {
if (count >= 10) break
var value = entry.value
if (value.count > 40) value = value[0...40] + "..."
System.print(" %(entry.key) = %(value)")
count = count + 1
}
Environment.delete("WREN_DEMO_NUMBER")
+2
View File
@@ -36,7 +36,9 @@ var host = "127.0.0.1"
var port = 8080 // Try to connect to our own http_server example
var path = "/"
while(true) {
var result = HttpClient.get(host, port, path)
System.print("\n--- Response Received ---
")
System.print(result)
}
+94
View File
@@ -0,0 +1,94 @@
// retoor <retoor@molodetz.nl>
import "http" for Http, HttpResponse, Url
System.print("=== HTTP Module Demo ===\n")
System.print("--- URL Parsing ---")
var urls = [
"http://example.com",
"http://example.com:8080",
"http://example.com/path/to/resource",
"http://example.com/search?q=hello&limit=10"
]
for (urlStr in urls) {
var url = Url.parse(urlStr)
System.print("URL: %(urlStr)")
System.print(" scheme: %(url.scheme), host: %(url.host), port: %(url.port)")
System.print(" path: %(url.path), query: %(url.query)")
System.print("")
}
System.print("--- Simple GET Request ---")
System.print("Fetching http://httpbin.org/get...")
var response = Http.get("http://httpbin.org/get")
System.print("Status: %(response.statusCode) %(response.statusText)")
System.print("OK: %(response.ok)")
System.print("\n--- Response Headers ---")
var count = 0
for (header in response.headers) {
if (count < 5) System.print(" %(header.key): %(header.value)")
count = count + 1
}
System.print("\n--- Response Body (first 300 chars) ---")
var body = response.body
if (body.count > 300) body = body[0...300] + "..."
System.print(body)
System.print("\n--- Getting Specific Header ---")
var contentType = response.header("Content-Type")
System.print("Content-Type: %(contentType)")
System.print("\n--- GET with Query Parameters ---")
var searchResponse = Http.get("http://httpbin.org/get?name=wren&version=1.0")
System.print("Status: %(searchResponse.statusCode)")
System.print("Body contains 'wren': %(searchResponse.body.contains("wren"))")
System.print("\n--- POST Request ---")
System.print("Posting to httpbin.org...")
var postResponse = Http.post("http://httpbin.org/post", "Hello from Wren!")
System.print("Status: %(postResponse.statusCode)")
System.print("Body contains 'Hello': %(postResponse.body.contains("Hello"))")
System.print("\n--- Custom Headers ---")
var headersResponse = Http.get("http://httpbin.org/headers", {
"X-Custom-Header": "WrenTest",
"Accept": "application/json"
})
System.print("Status: %(headersResponse.statusCode)")
System.print("Body contains 'WrenTest': %(headersResponse.body.contains("WrenTest"))")
System.print("\n--- Checking Response Status ---")
var notFoundResponse = Http.get("http://httpbin.org/status/404")
System.print("404 response OK: %(notFoundResponse.ok)")
System.print("Status code: %(notFoundResponse.statusCode)")
var okResponse = Http.get("http://httpbin.org/status/200")
System.print("200 response OK: %(okResponse.ok)")
System.print("\n--- HTTP Response Object ---")
System.print(response.toString)
System.print("\n--- Practical Example: Get UUID ---")
var uuidResponse = Http.get("http://httpbin.org/uuid")
System.print("Status: %(uuidResponse.statusCode)")
var uuidBody = uuidResponse.body
if (uuidBody.contains("uuid")) {
System.print("UUID response received successfully")
System.print("Body: %(uuidBody)")
}
System.print("\n--- HTTPS Request ---")
System.print("Fetching https://httpbin.org/get...")
var httpsResponse = Http.get("https://httpbin.org/get")
System.print("Status: %(httpsResponse.statusCode) %(httpsResponse.statusText)")
System.print("OK: %(httpsResponse.ok)")
System.print("Body contains 'origin': %(httpsResponse.body.contains("origin"))")
System.print("\n--- HTTPS POST Request ---")
var httpsPost = Http.post("https://httpbin.org/post", {"message": "Hello from Wren over HTTPS!"})
System.print("Status: %(httpsPost.statusCode)")
System.print("Body contains 'Hello': %(httpsPost.body.contains("Hello"))")
+161
View File
@@ -0,0 +1,161 @@
// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=" * 60)
System.print("JINJA BASICS - Variables, Filters, and Expressions")
System.print("=" * 60)
var templates = {
"variable_simple": "Hello, {{ name }}!",
"variable_nested": "User: {{ user.name }}, Age: {{ user.age }}, City: {{ user.address.city }}",
"variable_subscript": "First item: {{ items[0] }}, Last item: {{ items[-1] }}",
"variable_default": "Name: {{ name|default(\"Anonymous\") }}, Role: {{ role|default(\"Guest\") }}",
"literal_string": "String: {{ \"hello world\" }}",
"literal_number": "Number: {{ 42 }}, Float: {{ 3.14159 }}",
"literal_bool": "True: {{ true }}, False: {{ false }}",
"literal_list": "List: {{ [1, 2, 3]|join(\", \") }}",
"expr_math": "Addition: {{ 10 + 5 }}, Subtraction: {{ 10 - 5 }}, Multiplication: {{ 10 * 5 }}, Division: {{ 10 / 4 }}",
"expr_modulo": "Modulo: {{ 17 \% 5 }}",
"expr_negative": "Negative: {{ -42 }}, Double negative: {{ --42 }}",
"expr_parens": "With parens: {{ (2 + 3) * 4 }}, Without: {{ 2 + 3 * 4 }}",
"expr_concat": "Concat: {{ first ~ \" \" ~ last }}",
"expr_compare": "Equal: {{ 5 == 5 }}, Not equal: {{ 5 != 3 }}, Less: {{ 3 < 5 }}, Greater: {{ 5 > 3 }}",
"expr_logic": "And: {{ true and false }}, Or: {{ true or false }}, Not: {{ not false }}",
"expr_in": "In list: {{ 2 in [1, 2, 3] }}, In string: {{ \"o\" in \"hello\" }}",
"filter_upper": "{{ text|upper }}",
"filter_lower": "{{ text|lower }}",
"filter_capitalize": "{{ text|capitalize }}",
"filter_title": "{{ text|title }}",
"filter_trim": "[{{ text|trim }}]",
"filter_length": "Length: {{ items|length }}",
"filter_first": "First: {{ items|first }}",
"filter_last": "Last: {{ items|last }}",
"filter_reverse": "Reversed: {{ items|reverse|join(\", \") }}",
"filter_sort": "Sorted: {{ items|sort|join(\", \") }}",
"filter_unique": "Unique: {{ items|unique|join(\", \") }}",
"filter_join": "Joined: {{ items|join(\" | \") }}",
"filter_replace": "{{ text|replace(\"world\", \"universe\") }}",
"filter_truncate": "{{ text|truncate(20) }}",
"filter_abs": "Absolute: {{ num|abs }}",
"filter_round": "Rounded: {{ num|round(2) }}",
"filter_int": "Integer: {{ num|int }}",
"filter_chain": "{{ text|trim|upper|replace(\"HELLO\", \"HI\") }}",
"filter_batch": "{\% for row in items|batch(3) \%}[{\% for i in row \%}{{ i }}{\% endfor \%}]{\% endfor \%}",
"filter_map": "Names: {{ users|map(\"name\")|join(\", \") }}",
"filter_sum": "Sum: {{ numbers|sum }}",
"filter_min": "Min: {{ numbers|min }}",
"filter_max": "Max: {{ numbers|max }}",
"filter_striptags": "{{ html|striptags }}",
"filter_urlencode": "{{ text|urlencode }}",
"filter_wordcount": "Word count: {{ text|wordcount }}",
"filter_center": "[{{ text|center(20) }}]",
"escape_auto": "Auto-escaped: {{ html }}",
"escape_safe": "Safe (no escape): {{ html|safe }}",
"tojson_simple": "{{ data|tojson }}",
"tojson_complex": "{{ complex|tojson }}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("\n--- Simple Variables ---")
System.print(env.getTemplate("variable_simple").render({"name": "World"}))
System.print(env.getTemplate("variable_nested").render({
"user": {
"name": "Alice",
"age": 28,
"address": {"city": "New York", "zip": "10001"}
}
}))
System.print(env.getTemplate("variable_subscript").render({"items": ["apple", "banana", "cherry", "date"]}))
System.print(env.getTemplate("variable_default").render({"name": "Bob"}))
System.print("\n--- Literals ---")
System.print(env.getTemplate("literal_string").render({}))
System.print(env.getTemplate("literal_number").render({}))
System.print(env.getTemplate("literal_bool").render({}))
System.print(env.getTemplate("literal_list").render({}))
System.print("\n--- Mathematical Expressions ---")
System.print(env.getTemplate("expr_math").render({}))
System.print(env.getTemplate("expr_modulo").render({}))
System.print(env.getTemplate("expr_negative").render({}))
System.print(env.getTemplate("expr_parens").render({}))
System.print(env.getTemplate("expr_concat").render({"first": "John", "last": "Doe"}))
System.print("\n--- Comparison and Logic ---")
System.print(env.getTemplate("expr_compare").render({}))
System.print(env.getTemplate("expr_logic").render({}))
System.print(env.getTemplate("expr_in").render({}))
System.print("\n--- String Filters ---")
System.print(env.getTemplate("filter_upper").render({"text": "hello world"}))
System.print(env.getTemplate("filter_lower").render({"text": "HELLO WORLD"}))
System.print(env.getTemplate("filter_capitalize").render({"text": "hello world"}))
System.print(env.getTemplate("filter_title").render({"text": "hello world"}))
System.print(env.getTemplate("filter_trim").render({"text": " padded string "}))
System.print(env.getTemplate("filter_replace").render({"text": "hello world"}))
System.print(env.getTemplate("filter_truncate").render({"text": "This is a very long string that should be truncated"}))
System.print(env.getTemplate("filter_chain").render({"text": " hello world "}))
System.print("\n--- List Filters ---")
System.print(env.getTemplate("filter_length").render({"items": [1, 2, 3, 4, 5]}))
System.print(env.getTemplate("filter_first").render({"items": ["a", "b", "c"]}))
System.print(env.getTemplate("filter_last").render({"items": ["a", "b", "c"]}))
System.print(env.getTemplate("filter_reverse").render({"items": ["a", "b", "c"]}))
System.print(env.getTemplate("filter_sort").render({"items": ["cherry", "apple", "banana"]}))
System.print(env.getTemplate("filter_unique").render({"items": ["a", "b", "a", "c", "b", "d"]}))
System.print(env.getTemplate("filter_join").render({"items": ["one", "two", "three"]}))
System.print(env.getTemplate("filter_batch").render({"items": [1, 2, 3, 4, 5, 6, 7, 8, 9]}))
System.print("\n--- Numeric Filters ---")
System.print(env.getTemplate("filter_abs").render({"num": -42}))
System.print(env.getTemplate("filter_round").render({"num": 3.14159}))
System.print(env.getTemplate("filter_int").render({"num": 3.99}))
System.print(env.getTemplate("filter_sum").render({"numbers": [1, 2, 3, 4, 5]}))
System.print(env.getTemplate("filter_min").render({"numbers": [5, 2, 8, 1, 9]}))
System.print(env.getTemplate("filter_max").render({"numbers": [5, 2, 8, 1, 9]}))
System.print("\n--- Object Filters ---")
System.print(env.getTemplate("filter_map").render({
"users": [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 35}
]
}))
System.print("\n--- HTML/Text Filters ---")
System.print(env.getTemplate("filter_striptags").render({"html": "<p>Hello <b>World</b></p>"}))
System.print(env.getTemplate("filter_urlencode").render({"text": "hello world & more"}))
System.print(env.getTemplate("filter_wordcount").render({"text": "The quick brown fox jumps"}))
System.print(env.getTemplate("filter_center").render({"text": "Hi"}))
System.print("\n--- HTML Escaping ---")
System.print(env.getTemplate("escape_auto").render({"html": "<script>alert('XSS')</script>"}))
System.print(env.getTemplate("escape_safe").render({"html": "<b>Bold text</b>"}))
System.print("\n--- JSON Output ---")
System.print(env.getTemplate("tojson_simple").render({"data": {"name": "Test", "value": 42}}))
System.print(env.getTemplate("tojson_complex").render({
"complex": {
"string": "hello",
"number": 123,
"bool": true,
"null_val": null,
"array": [1, 2, 3],
"nested": {"a": 1, "b": 2}
}
}))
System.print("\n" + "=" * 60)
System.print("End of Basics Demo")
System.print("=" * 60)
+188
View File
@@ -0,0 +1,188 @@
// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=" * 60)
System.print("JINJA CONTROL FLOW - Conditionals, Loops, and Tests")
System.print("=" * 60)
var templates = {
"if_simple": "{\% if show \%}Visible{\% endif \%}",
"if_else": "{\% if logged_in \%}Welcome back!{\% else \%}Please log in{\% endif \%}",
"if_elif": "{\% if score >= 90 \%}A{\% elif score >= 80 \%}B{\% elif score >= 70 \%}C{\% elif score >= 60 \%}D{\% else \%}F{\% endif \%}",
"if_nested": "{\% if user \%}{\% if user.admin \%}Admin: {{ user.name }}{\% else \%}User: {{ user.name }}{\% endif \%}{\% else \%}Guest{\% endif \%}",
"if_and": "{\% if a and b \%}Both true{\% else \%}At least one false{\% endif \%}",
"if_or": "{\% if a or b \%}At least one true{\% else \%}Both false{\% endif \%}",
"if_not": "{\% if not hidden \%}Shown{\% else \%}Hidden{\% endif \%}",
"if_complex": "{\% if (a > 5 and b < 10) or c == \"special\" \%}Match!{\% else \%}No match{\% endif \%}",
"if_in_list": "{\% if item in items \%}Found '{{ item }}'{\% else \%}'{{ item }}' not found{\% endif \%}",
"if_in_string": "{\% if char in text \%}Contains '{{ char }}'{\% else \%}Does not contain '{{ char }}'{\% endif \%}",
"if_not_in": "{\% if item not in items \%}Not in list{\% else \%}In list{\% endif \%}",
"test_defined": "{\% if var is defined \%}Defined: {{ var }}{\% else \%}Undefined{\% endif \%}",
"test_undefined": "{\% if var is undefined \%}Undefined{\% else \%}Defined: {{ var }}{\% endif \%}",
"test_none": "{\% if var is none \%}Is none{\% else \%}Not none: {{ var }}{\% endif \%}",
"test_even": "{\% if num is even \%}{{ num }} is even{\% else \%}{{ num }} is odd{\% endif \%}",
"test_odd": "{\% if num is odd \%}{{ num }} is odd{\% else \%}{{ num }} is even{\% endif \%}",
"test_divisible": "{\% if num is divisibleby 3 \%}{{ num }} is divisible by 3{\% else \%}{{ num }} is not divisible by 3{\% endif \%}",
"test_sequence": "{\% if items is sequence \%}Is a sequence{\% else \%}Not a sequence{\% endif \%}",
"test_string": "{\% if val is string \%}Is a string{\% else \%}Not a string{\% endif \%}",
"test_number": "{\% if val is number \%}Is a number{\% else \%}Not a number{\% endif \%}",
"test_mapping": "{\% if val is mapping \%}Is a mapping{\% else \%}Not a mapping{\% endif \%}",
"ternary": "Status: {{ \"Active\" if active else \"Inactive\" }}",
"ternary_complex": "{{ user.name if user else \"Anonymous\" }} ({{ \"Admin\" if user and user.admin else \"User\" }})",
"for_simple": "{\% for item in items \%}{{ item }} {\% endfor \%}",
"for_index": "{\% for item in items \%}{{ loop.index }}. {{ item }}\n{\% endfor \%}",
"for_index0": "{\% for item in items \%}[{{ loop.index0 }}] {{ item }}\n{\% endfor \%}",
"for_first_last": "{\% for item in items \%}{{ \"[\" if loop.first else \"\" }}{{ item }}{{ \"]\" if loop.last else \", \" }}{\% endfor \%}",
"for_length": "{\% for item in items \%}Item {{ loop.index }} of {{ loop.length }}: {{ item }}\n{\% endfor \%}",
"for_revindex": "{\% for item in items \%}{{ loop.revindex }} remaining: {{ item }}\n{\% endfor \%}",
"for_else": "{\% for item in items \%}{{ item }}{\% else \%}No items found{\% endfor \%}",
"for_nested": "{\% for row in matrix \%}Row {{ loop.index }}: {\% for col in row \%}{{ col }}{\% if not loop.last \%}, {\% endif \%}{\% endfor \%}\n{\% endfor \%}",
"for_dict": "{\% for key, value in data \%}{{ key }}: {{ value }}\n{\% endfor \%}",
"for_dict_items": "{\% for key in data \%}{{ key }} = {{ data[key] }}\n{\% endfor \%}",
"for_range": "{\% for i in range(5) \%}{{ i }} {\% endfor \%}",
"for_range_start": "{\% for i in range(1, 6) \%}{{ i }} {\% endfor \%}",
"for_range_step": "{\% for i in range(0, 10, 2) \%}{{ i }} {\% endfor \%}",
"for_string": "{\% for char in text \%}{{ char }}-{\% endfor \%}",
"for_filtered": "{\% for item in items|sort \%}{{ item }} {\% endfor \%}",
"for_reversed": "{\% for item in items|reverse \%}{{ item }} {\% endfor \%}",
"for_conditional": "{\% for item in items \%}{\% if item > 5 \%}{{ item }} is greater than 5\n{\% endif \%}{\% endfor \%}",
"set_simple": "{\% set x = 10 \%}x = {{ x }}",
"set_expression": "{\% set result = a + b * c \%}Result: {{ result }}",
"set_from_filter": "{\% set upper_name = name|upper \%}Upper: {{ upper_name }}",
"set_in_loop": "{\% set total = 0 \%}{\% for n in numbers \%}{\% set total = total + n \%}{\% endfor \%}Total: {{ total }}",
"combined_example": "{\% for user in users \%}{\% if user.active \%}{{ loop.index }}. {{ user.name|title }} ({{ \"Admin\" if user.admin else \"User\" }})\n{\% endif \%}{\% else \%}No active users{\% endfor \%}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("\n--- Simple Conditionals ---")
System.print("show=true: " + env.getTemplate("if_simple").render({"show": true}))
System.print("show=false: " + env.getTemplate("if_simple").render({"show": false}))
System.print("logged_in=true: " + env.getTemplate("if_else").render({"logged_in": true}))
System.print("logged_in=false: " + env.getTemplate("if_else").render({"logged_in": false}))
System.print("\n--- If-Elif-Else Chain ---")
for (score in [95, 85, 75, 65, 50]) {
System.print("Score %(score): " + env.getTemplate("if_elif").render({"score": score}))
}
System.print("\n--- Nested Conditionals ---")
System.print(env.getTemplate("if_nested").render({"user": {"name": "Alice", "admin": true}}))
System.print(env.getTemplate("if_nested").render({"user": {"name": "Bob", "admin": false}}))
System.print(env.getTemplate("if_nested").render({"user": null}))
System.print("\n--- Logical Operators ---")
System.print("a=true, b=true: " + env.getTemplate("if_and").render({"a": true, "b": true}))
System.print("a=true, b=false: " + env.getTemplate("if_and").render({"a": true, "b": false}))
System.print("a=false, b=false: " + env.getTemplate("if_or").render({"a": false, "b": false}))
System.print("a=true, b=false: " + env.getTemplate("if_or").render({"a": true, "b": false}))
System.print("hidden=false: " + env.getTemplate("if_not").render({"hidden": false}))
System.print("hidden=true: " + env.getTemplate("if_not").render({"hidden": true}))
System.print("\n--- Complex Conditions ---")
System.print(env.getTemplate("if_complex").render({"a": 10, "b": 5, "c": "normal"}))
System.print(env.getTemplate("if_complex").render({"a": 3, "b": 5, "c": "special"}))
System.print(env.getTemplate("if_complex").render({"a": 3, "b": 15, "c": "normal"}))
System.print("\n--- In Operator ---")
System.print(env.getTemplate("if_in_list").render({"item": "banana", "items": ["apple", "banana", "cherry"]}))
System.print(env.getTemplate("if_in_list").render({"item": "grape", "items": ["apple", "banana", "cherry"]}))
System.print(env.getTemplate("if_in_string").render({"char": "o", "text": "hello"}))
System.print(env.getTemplate("if_not_in").render({"item": "x", "items": ["a", "b", "c"]}))
System.print("\n--- Tests ---")
System.print(env.getTemplate("test_defined").render({"var": "Hello"}))
System.print(env.getTemplate("test_defined").render({}))
System.print(env.getTemplate("test_none").render({"var": null}))
System.print(env.getTemplate("test_none").render({"var": "something"}))
System.print(env.getTemplate("test_even").render({"num": 4}))
System.print(env.getTemplate("test_even").render({"num": 7}))
System.print(env.getTemplate("test_divisible").render({"num": 9}))
System.print(env.getTemplate("test_divisible").render({"num": 10}))
System.print(env.getTemplate("test_sequence").render({"items": [1, 2, 3]}))
System.print(env.getTemplate("test_string").render({"val": "hello"}))
System.print(env.getTemplate("test_number").render({"val": 42}))
System.print(env.getTemplate("test_mapping").render({"val": {"a": 1}}))
System.print("\n--- Ternary Expressions ---")
System.print(env.getTemplate("ternary").render({"active": true}))
System.print(env.getTemplate("ternary").render({"active": false}))
System.print(env.getTemplate("ternary_complex").render({"user": {"name": "Alice", "admin": true}}))
System.print(env.getTemplate("ternary_complex").render({"user": null}))
System.print("\n--- Basic For Loops ---")
System.print(env.getTemplate("for_simple").render({"items": ["a", "b", "c", "d"]}))
System.print("\n--- Loop Variables ---")
System.print("loop.index:")
System.print(env.getTemplate("for_index").render({"items": ["Apple", "Banana", "Cherry"]}))
System.print("loop.index0:")
System.print(env.getTemplate("for_index0").render({"items": ["Apple", "Banana", "Cherry"]}))
System.print("loop.first/last:")
System.print(env.getTemplate("for_first_last").render({"items": ["Apple", "Banana", "Cherry"]}))
System.print("loop.length:")
System.print(env.getTemplate("for_length").render({"items": ["A", "B", "C"]}))
System.print("loop.revindex:")
System.print(env.getTemplate("for_revindex").render({"items": ["A", "B", "C"]}))
System.print("\n--- For-Else ---")
System.print("With items: " + env.getTemplate("for_else").render({"items": ["x", "y", "z"]}))
System.print("Empty: " + env.getTemplate("for_else").render({"items": []}))
System.print("\n--- Nested Loops ---")
System.print(env.getTemplate("for_nested").render({
"matrix": [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
}))
System.print("\n--- Dictionary Iteration ---")
System.print(env.getTemplate("for_dict").render({"data": {"name": "Alice", "age": 30, "city": "NYC"}}))
System.print("\n--- Range Function ---")
System.print("range(5): " + env.getTemplate("for_range").render({}))
System.print("range(1, 6): " + env.getTemplate("for_range_start").render({}))
System.print("range(0, 10, 2): " + env.getTemplate("for_range_step").render({}))
System.print("\n--- Iterating Strings ---")
System.print(env.getTemplate("for_string").render({"text": "Hello"}))
System.print("\n--- Filtered Loops ---")
System.print("Sorted: " + env.getTemplate("for_filtered").render({"items": ["cherry", "apple", "banana"]}))
System.print("Reversed: " + env.getTemplate("for_reversed").render({"items": [1, 2, 3, 4, 5]}))
System.print("\n--- Conditionals in Loops ---")
System.print(env.getTemplate("for_conditional").render({"items": [3, 7, 2, 9, 4, 8]}))
System.print("\n--- Set Variable ---")
System.print(env.getTemplate("set_simple").render({}))
System.print(env.getTemplate("set_expression").render({"a": 2, "b": 3, "c": 4}))
System.print(env.getTemplate("set_from_filter").render({"name": "alice"}))
System.print("\n--- Combined Example ---")
System.print(env.getTemplate("combined_example").render({
"users": [
{"name": "alice smith", "active": true, "admin": true},
{"name": "bob jones", "active": false, "admin": false},
{"name": "charlie brown", "active": true, "admin": false},
{"name": "diana ross", "active": true, "admin": true}
]
}))
System.print("\n" + "=" * 60)
System.print("End of Control Flow Demo")
System.print("=" * 60)
+107
View File
@@ -0,0 +1,107 @@
// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=== Jinja2-like Templating Demo ===\n")
var templates = {
"base.html": "<!DOCTYPE html>\n<html>\n<head><title>{\% block title \%}Default{\% endblock \%}</title></head>\n<body>\n{\% block content \%}{\% endblock \%}\n</body>\n</html>",
"page.html": "{\% extends \"base.html\" \%}{\% block title \%}{{ page_title }}{\% endblock \%}{\% block content \%}<h1>{{ heading }}</h1>\n<p>{{ message }}</p>{\% endblock \%}",
"list.html": "<ul>\n{\% for item in items \%}<li>{{ loop.index }}. {{ item }}</li>\n{\% else \%}<li>No items</li>\n{\% endfor \%}</ul>",
"user_card.html": "{\% macro user_card(user) \%}<div class=\"card\">\n <h3>{{ user.name|title }}</h3>\n <p>Email: {{ user.email|default(\"N/A\") }}</p>\n <p>Age: {{ user.age|default(\"Unknown\") }}</p>\n</div>{\% endmacro \%}{\% for u in users \%}{{ user_card(u) }}\n{\% endfor \%}",
"table.html": "<table>\n{\% for row in data|batch(3) \%}<tr>{\% for cell in row \%}<td>{{ cell }}</td>{\% endfor \%}</tr>\n{\% endfor \%}</table>",
"conditional.html": "{\% if user.role == \"admin\" \%}Admin Panel{\% elif user.role == \"moderator\" \%}Mod Panel{\% else \%}User Panel{\% endif \%}",
"filters.html": "Original: {{ text }}\nUpper: {{ text|upper }}\nTrimmed: {{ text|trim }}\nLength: {{ text|length }}\nTruncated: {{ text|truncate(10) }}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("--- Template Inheritance ---")
var page = env.getTemplate("page.html")
System.print(page.render({
"page_title": "Welcome",
"heading": "Hello, World!",
"message": "This demonstrates template inheritance."
}))
System.print("\n--- Loop with Index ---")
var list = env.getTemplate("list.html")
System.print(list.render({"items": ["Apple", "Banana", "Cherry"]}))
System.print("\n--- Empty List (else clause) ---")
System.print(list.render({"items": []}))
System.print("\n--- Macros ---")
var cards = env.getTemplate("user_card.html")
System.print(cards.render({
"users": [
{"name": "alice smith", "email": "alice@example.com", "age": 28},
{"name": "bob jones", "age": 35}
]
}))
System.print("\n--- Batch Filter ---")
var table = env.getTemplate("table.html")
System.print(table.render({"data": [1, 2, 3, 4, 5, 6, 7, 8, 9]}))
System.print("\n--- Conditionals ---")
var cond = env.getTemplate("conditional.html")
System.print("Admin: " + cond.render({"user": {"role": "admin"}}))
System.print("Mod: " + cond.render({"user": {"role": "moderator"}}))
System.print("User: " + cond.render({"user": {"role": "guest"}}))
System.print("\n--- Filters Demo ---")
var filters = env.getTemplate("filters.html")
System.print(filters.render({"text": " Hello World! "}))
System.print("\n--- From String ---")
var inline = env.fromString("{\% for n in range(5) \%}{{ n }}{\% if not loop.last \%}, {\% endif \%}{\% endfor \%}")
System.print(inline.render({}))
System.print("\n--- Nested Data Access ---")
var nested = env.fromString("{{ users[0].address.city }}")
System.print(nested.render({
"users": [
{"name": "Test", "address": {"city": "New York", "zip": "10001"}}
]
}))
System.print("\n--- Expression Tests ---")
var tests = env.fromString("{\% if items is sequence \%}Sequence{\% endif \%} {\% if count is even \%}Even{\% endif \%} {\% if name is defined \%}Defined{\% endif \%}")
System.print(tests.render({"items": [1, 2, 3], "count": 4, "name": "test"}))
System.print("\n--- JSON Output ---")
var json = env.fromString("{{ data|tojson }}")
System.print(json.render({"data": {"name": "Test", "values": [1, 2, 3]}}))
System.print("\n--- Whitespace Control ---")
var ws = env.fromString("Items:{\% for i in items \%}\n {{- i -}}\n{\% endfor \%}")
System.print(ws.render({"items": ["a", "b", "c"]}))
System.print("\n--- Raw Block ---")
var raw = env.fromString("{\% raw \%}Use {{ variable }} for output{\% endraw \%}")
System.print(raw.render({}))
System.print("\n--- Set Variable ---")
var setVar = env.fromString("{\% set greeting = \"Hello\" \%}{\% set name = \"World\" \%}{{ greeting }}, {{ name }}!")
System.print(setVar.render({}))
System.print("\n--- Comments ---")
var comments = env.fromString("Visible{# This is hidden #}Text")
System.print(comments.render({}))
System.print("\n--- Complex Example ---")
var complex = env.fromString("{\% for product in products \%}{{ product.name|title }}: ${{ product.price|round(2) }}{\% if product.sale \%} (SALE!){\% endif \%}\n{\% endfor \%}Total: {{ products|map(\"price\")|sum|round(2) }}")
System.print(complex.render({
"products": [
{"name": "widget", "price": 9.99, "sale": true},
{"name": "gadget", "price": 24.50, "sale": false},
{"name": "gizmo", "price": 15.75, "sale": true}
]
}))
+367
View File
@@ -0,0 +1,367 @@
// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=" * 60)
System.print("JINJA TEMPLATE INHERITANCE - Extends, Blocks, and Includes")
System.print("=" * 60)
var templates = {
"base.html": "<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>{\% block title \%}Default Title{\% endblock \%}</title>
<style>
{\% block styles \%}
body { font-family: sans-serif; margin: 20px; }
{\% endblock \%}
</style>
</head>
<body>
<header>
{\% block header \%}
<h1>My Website</h1>
<nav>{\% block nav \%}<a href=\"/\">Home</a>{\% endblock \%}</nav>
{\% endblock \%}
</header>
<main>
{\% block content \%}
<p>Default content goes here.</p>
{\% endblock \%}
</main>
<footer>
{\% block footer \%}
<p>Copyright 2024</p>
{\% endblock \%}
</footer>
</body>
</html>",
"page.html": "{\% extends \"base.html\" \%}
{\% block title \%}{{ page_title }} - My Website{\% endblock \%}
{\% block content \%}
<article>
<h2>{{ heading }}</h2>
<p>{{ content }}</p>
</article>
{\% endblock \%}",
"blog_base.html": "{\% extends \"base.html\" \%}
{\% block nav \%}
{{ super() }}
| <a href=\"/blog\">Blog</a>
| <a href=\"/about\">About</a>
{\% endblock \%}
{\% block styles \%}
{{ super() }}
.blog-post { border: 1px solid #ccc; padding: 10px; margin: 10px 0; }
.blog-meta { color: #666; font-size: 0.9em; }
{\% endblock \%}
{\% block content \%}
<section class=\"blog\">
{\% block blog_content \%}
<p>Blog posts will appear here.</p>
{\% endblock \%}
</section>
{\% endblock \%}",
"blog_post.html": "{\% extends \"blog_base.html\" \%}
{\% block title \%}{{ post.title }} - Blog{\% endblock \%}
{\% block blog_content \%}
<article class=\"blog-post\">
<h2>{{ post.title }}</h2>
<p class=\"blog-meta\">By {{ post.author }} on {{ post.date }}</p>
<div class=\"blog-body\">
{{ post.body }}
</div>
{\% if post.tags \%}
<p class=\"blog-tags\">Tags: {{ post.tags|join(\", \") }}</p>
{\% endif \%}
</article>
{\% endblock \%}",
"blog_list.html": "{\% extends \"blog_base.html\" \%}
{\% block title \%}All Posts - Blog{\% endblock \%}
{\% block blog_content \%}
<h2>Recent Posts</h2>
{\% for post in posts \%}
<article class=\"blog-post\">
<h3>{{ post.title }}</h3>
<p class=\"blog-meta\">{{ post.date }} by {{ post.author }}</p>
<p>{{ post.excerpt }}</p>
<a href=\"/blog/{{ post.slug }}\">Read more...</a>
</article>
{\% else \%}
<p>No posts yet.</p>
{\% endfor \%}
{\% endblock \%}",
"admin_base.html": "{\% extends \"base.html\" \%}
{\% block header \%}
<h1>Admin Panel</h1>
<nav>
<a href=\"/admin\">Dashboard</a> |
<a href=\"/admin/users\">Users</a> |
<a href=\"/admin/posts\">Posts</a> |
<a href=\"/admin/settings\">Settings</a>
</nav>
{\% endblock \%}
{\% block styles \%}
{{ super() }}
.admin-panel { background: #f5f5f5; padding: 20px; }
.admin-table { width: 100\%; border-collapse: collapse; }
.admin-table th, .admin-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
{\% endblock \%}
{\% block content \%}
<div class=\"admin-panel\">
{\% block admin_content \%}
<p>Welcome to the admin panel.</p>
{\% endblock \%}
</div>
{\% endblock \%}
{\% block footer \%}
<p>Admin Panel v1.0 | <a href=\"/\">Back to site</a></p>
{\% endblock \%}",
"admin_users.html": "{\% extends \"admin_base.html\" \%}
{\% block title \%}User Management - Admin{\% endblock \%}
{\% block admin_content \%}
<h2>User Management</h2>
<table class=\"admin-table\">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{\% for user in users \%}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.role|title }}</td>
<td>{{ \"Active\" if user.active else \"Inactive\" }}</td>
</tr>
{\% endfor \%}
</tbody>
</table>
<p>Total users: {{ users|length }}</p>
{\% endblock \%}",
"sidebar.html": "<aside class=\"sidebar\">
<h3>{{ title|default(\"Sidebar\") }}</h3>
{\% if items \%}
<ul>
{\% for item in items \%}
<li><a href=\"{{ item.url }}\">{{ item.label }}</a></li>
{\% endfor \%}
</ul>
{\% endif \%}
</aside>",
"alert.html": "<div class=\"alert alert-{{ type|default(\"info\") }}\">
{\% if dismissible \%}<button class=\"close\">&times;</button>{\% endif \%}
<strong>{{ title }}:</strong> {{ message }}
</div>",
"page_with_includes.html": "{\% extends \"base.html\" \%}
{\% block title \%}Page with Includes{\% endblock \%}
{\% block content \%}
<div class=\"container\">
<div class=\"main-content\">
{\% include \"alert.html\" \%}
<h2>Main Content</h2>
<p>{{ content }}</p>
</div>
{\% include \"sidebar.html\" \%}
</div>
{\% endblock \%}",
"email_base.html": "From: {{ from_email }}
To: {{ to_email }}
Subject: {\% block subject \%}No Subject{\% endblock \%}
{\% block greeting \%}Hello,{\% endblock \%}
{\% block body \%}
This is the email body.
{\% endblock \%}
{\% block signature \%}
Best regards,
{{ sender_name }}
{\% endblock \%}",
"welcome_email.html": "{\% extends \"email_base.html\" \%}
{\% block subject \%}Welcome to Our Service, {{ user.name }}!{\% endblock \%}
{\% block greeting \%}Dear {{ user.name }},{\% endblock \%}
{\% block body \%}
Thank you for signing up for our service!
Your account details:
- Username: {{ user.username }}
- Email: {{ user.email }}
- Plan: {{ user.plan|title }}
To get started, please verify your email by clicking the link below:
{{ verification_url }}
If you have any questions, feel free to contact our support team.
{\% endblock \%}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("\n" + "-" * 60)
System.print("1. BASIC PAGE (extends base.html)")
System.print("-" * 60)
System.print(env.getTemplate("page.html").render({
"page_title": "Welcome",
"heading": "Welcome to Our Website",
"content": "This is a simple page that extends the base template."
}))
System.print("\n" + "-" * 60)
System.print("2. BLOG POST (three-level inheritance: blog_post -> blog_base -> base)")
System.print("-" * 60)
System.print(env.getTemplate("blog_post.html").render({
"post": {
"title": "Getting Started with Jinja Templates",
"author": "Alice Smith",
"date": "2024-01-15",
"body": "Template inheritance is a powerful feature that allows you to build a base skeleton template containing common elements of your site and defines blocks that child templates can override.",
"tags": ["jinja", "templates", "tutorial"]
}
}))
System.print("\n" + "-" * 60)
System.print("3. BLOG LIST (loops within inherited template)")
System.print("-" * 60)
System.print(env.getTemplate("blog_list.html").render({
"posts": [
{"title": "First Post", "date": "2024-01-15", "author": "Alice", "excerpt": "This is my first post...", "slug": "first-post"},
{"title": "Second Post", "date": "2024-01-14", "author": "Bob", "excerpt": "Another great article...", "slug": "second-post"},
{"title": "Third Post", "date": "2024-01-13", "author": "Charlie", "excerpt": "More content here...", "slug": "third-post"}
]
}))
System.print("\n" + "-" * 60)
System.print("4. ADMIN USERS PAGE (admin template hierarchy)")
System.print("-" * 60)
System.print(env.getTemplate("admin_users.html").render({
"users": [
{"id": 1, "name": "Alice Smith", "email": "alice@example.com", "role": "admin", "active": true},
{"id": 2, "name": "Bob Jones", "email": "bob@example.com", "role": "editor", "active": true},
{"id": 3, "name": "Charlie Brown", "email": "charlie@example.com", "role": "user", "active": false},
{"id": 4, "name": "Diana Ross", "email": "diana@example.com", "role": "user", "active": true}
]
}))
System.print("\n" + "-" * 60)
System.print("5. PAGE WITH INCLUDES")
System.print("-" * 60)
System.print(env.getTemplate("page_with_includes.html").render({
"type": "warning",
"title": "Notice",
"message": "This page demonstrates the include feature.",
"dismissible": true,
"content": "This is the main content of the page.",
"title": "Quick Links",
"items": [
{"label": "Home", "url": "/"},
{"label": "About", "url": "/about"},
{"label": "Contact", "url": "/contact"}
]
}))
System.print("\n" + "-" * 60)
System.print("6. STANDALONE INCLUDE (sidebar)")
System.print("-" * 60)
System.print(env.getTemplate("sidebar.html").render({
"title": "Navigation",
"items": [
{"label": "Dashboard", "url": "/dashboard"},
{"label": "Profile", "url": "/profile"},
{"label": "Settings", "url": "/settings"},
{"label": "Logout", "url": "/logout"}
]
}))
System.print("\n" + "-" * 60)
System.print("7. EMAIL TEMPLATE (text-based inheritance)")
System.print("-" * 60)
System.print(env.getTemplate("welcome_email.html").render({
"from_email": "noreply@example.com",
"to_email": "newuser@example.com",
"sender_name": "The Example Team",
"user": {
"name": "John Doe",
"username": "johndoe",
"email": "newuser@example.com",
"plan": "premium"
},
"verification_url": "https://example.com/verify?token=abc123"
}))
System.print("\n" + "-" * 60)
System.print("8. SUPER() DEMONSTRATION")
System.print("-" * 60)
var superDemo = {
"level1": "[L1-START]{\% block content \%}Level1-Content{\% endblock \%}[L1-END]",
"level2": "{\% extends \"level1\" \%}{\% block content \%}{{ super() }}+Level2{\% endblock \%}",
"level3": "{\% extends \"level2\" \%}{\% block content \%}{{ super() }}+Level3{\% endblock \%}"
}
var superEnv = Environment.new(DictLoader.new(superDemo))
System.print("Level 1: " + superEnv.getTemplate("level1").render({}))
System.print("Level 2: " + superEnv.getTemplate("level2").render({}))
System.print("Level 3: " + superEnv.getTemplate("level3").render({}))
System.print("\n" + "-" * 60)
System.print("9. MULTIPLE BLOCKS INHERITANCE")
System.print("-" * 60)
var multiBlock = {
"base": "A:{\% block a \%}base-a{\% endblock \%} B:{\% block b \%}base-b{\% endblock \%} C:{\% block c \%}base-c{\% endblock \%}",
"override_a": "{\% extends \"base\" \%}{\% block a \%}OVERRIDE-A{\% endblock \%}",
"override_bc": "{\% extends \"base\" \%}{\% block b \%}OVERRIDE-B{\% endblock \%}{\% block c \%}OVERRIDE-C{\% endblock \%}",
"override_all": "{\% extends \"base\" \%}{\% block a \%}NEW-A{\% endblock \%}{\% block b \%}NEW-B{\% endblock \%}{\% block c \%}NEW-C{\% endblock \%}"
}
var multiEnv = Environment.new(DictLoader.new(multiBlock))
System.print("Base: " + multiEnv.getTemplate("base").render({}))
System.print("Override A: " + multiEnv.getTemplate("override_a").render({}))
System.print("Override BC:" + multiEnv.getTemplate("override_bc").render({}))
System.print("Override All:" + multiEnv.getTemplate("override_all").render({}))
System.print("\n" + "=" * 60)
System.print("End of Inheritance Demo")
System.print("=" * 60)
+363
View File
@@ -0,0 +1,363 @@
// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=" * 60)
System.print("JINJA MACROS - Reusable Template Components")
System.print("=" * 60)
var templates = {
"macro_simple": "{\% macro greet(name) \%}Hello, {{ name }}!{\% endmacro \%}
{{ greet(\"World\") }}
{{ greet(\"Alice\") }}
{{ greet(\"Bob\") }}",
"macro_default_args": "{\% macro button(text, type=\"primary\", size=\"medium\", disabled=false) \%}
<button class=\"btn btn-{{ type }} btn-{{ size }}\"{{ \" disabled\" if disabled else \"\" }}>{{ text }}</button>
{\% endmacro \%}
{{ button(\"Submit\") }}
{{ button(\"Cancel\", \"secondary\") }}
{{ button(\"Delete\", \"danger\", \"small\") }}
{{ button(\"Disabled\", \"primary\", \"medium\", true) }}",
"macro_with_content": "{\% macro card(title, footer=\"\") \%}
<div class=\"card\">
<div class=\"card-header\">{{ title }}</div>
<div class=\"card-body\">
{\% for item in content \%}{{ item }}{\% endfor \%}
</div>
{\% if footer \%}<div class=\"card-footer\">{{ footer }}</div>{\% endif \%}
</div>
{\% endmacro \%}
{{ card(\"My Card\", \"Footer text\") }}",
"macro_input": "{\% macro input(name, type, value, placeholder, required, label) \%}
<div class=\"form-group\">
{\% if label \%}<label for=\"{{ name }}\">{{ label }}{\% if required \%} *{\% endif \%}</label>{\% endif \%}
<input type=\"{{ type|default(\"text\") }}\" id=\"{{ name }}\" name=\"{{ name }}\" value=\"{{ value }}\" placeholder=\"{{ placeholder }}\"{\% if required \%} required{\% endif \%} class=\"form-control\">
</div>
{\% endmacro \%}
{{ input(\"username\", \"text\", \"\", \"Enter username\", true, \"Username\") }}
{{ input(\"email\", \"email\", \"\", \"\", true, \"Email Address\") }}
{{ input(\"password\", \"password\", \"\", \"\", true, \"Password\") }}
{{ input(\"bio\", \"text\", \"\", \"Tell us about yourself\", false, \"\") }}",
"macro_select": "{\% macro select(name, options, selected=\"\", label=\"\", required=false) \%}
<div class=\"form-group\">
{\% if label \%}<label for=\"{{ name }}\">{{ label }}{\% if required \%} *{\% endif \%}</label>{\% endif \%}
<select id=\"{{ name }}\" name=\"{{ name }}\" class=\"form-control\"{\% if required \%} required{\% endif \%}>
<option value=\"\">-- Select --</option>
{\% for opt in options \%}
<option value=\"{{ opt.value }}\"{{ \" selected\" if opt.value == selected else \"\" }}>{{ opt.label }}</option>
{\% endfor \%}
</select>
</div>
{\% endmacro \%}
{{ select(\"country\", countries, \"us\", \"Country\", true) }}",
"macro_table": "{\% macro table(headers, rows, striped=true, bordered=true) \%}
<table class=\"table{\% if striped \%} table-striped{\% endif \%}{\% if bordered \%} table-bordered{\% endif \%}\">
<thead>
<tr>
{\% for header in headers \%}
<th>{{ header }}</th>
{\% endfor \%}
</tr>
</thead>
<tbody>
{\% for row in rows \%}
<tr>
{\% for cell in row \%}
<td>{{ cell }}</td>
{\% endfor \%}
</tr>
{\% else \%}
<tr><td colspan=\"{{ headers|length }}\">No data available</td></tr>
{\% endfor \%}
</tbody>
</table>
{\% endmacro \%}
{{ table(headers, data) }}",
"macro_pagination": "{\% macro pagination(current, total, url_pattern=\"?page=\") \%}
<nav class=\"pagination\">
{\% if current > 1 \%}
<a href=\"{{ url_pattern }}{{ current - 1 }}\" class=\"prev\">&laquo; Previous</a>
{\% endif \%}
{\% for page in range(1, total + 1) \%}
{\% if page == current \%}
<span class=\"current\">{{ page }}</span>
{\% else \%}
<a href=\"{{ url_pattern }}{{ page }}\">{{ page }}</a>
{\% endif \%}
{\% endfor \%}
{\% if current < total \%}
<a href=\"{{ url_pattern }}{{ current + 1 }}\" class=\"next\">Next &raquo;</a>
{\% endif \%}
</nav>
{\% endmacro \%}
{{ pagination(3, 5) }}",
"macro_breadcrumb": "{\% macro breadcrumb(items) \%}
<nav class=\"breadcrumb\">
{\% for item in items \%}
{\% if loop.last \%}
<span class=\"current\">{{ item.label }}</span>
{\% else \%}
<a href=\"{{ item.url }}\">{{ item.label }}</a>
<span class=\"separator\">/</span>
{\% endif \%}
{\% endfor \%}
</nav>
{\% endmacro \%}
{{ breadcrumb(crumbs) }}",
"macro_alert": "{\% macro alert(message, type=\"info\", title=\"\", dismissible=true) \%}
<div class=\"alert alert-{{ type }}{\% if dismissible \%} alert-dismissible{\% endif \%}\" role=\"alert\">
{\% if dismissible \%}<button type=\"button\" class=\"close\">&times;</button>{\% endif \%}
{\% if title \%}<strong>{{ title }}:</strong> {\% endif \%}{{ message }}
</div>
{\% endmacro \%}
{{ alert(\"Operation completed successfully!\", \"success\", \"Success\") }}
{{ alert(\"Please check your input.\", \"warning\", \"Warning\") }}
{{ alert(\"An error occurred.\", \"danger\", \"Error\") }}
{{ alert(\"Here is some helpful information.\", \"info\") }}",
"macro_user_card": "{\% macro user_card(user) \%}
<div class=\"user-card\">
<div class=\"avatar\">
<img src=\"{{ user.avatar|default(\"/default-avatar.png\") }}\" alt=\"{{ user.name }}\">
</div>
<div class=\"info\">
<h4>{{ user.name|title }}</h4>
<p class=\"role\">{{ user.role|default(\"Member\")|title }}</p>
{\% if user.email \%}<p class=\"email\">{{ user.email }}</p>{\% endif \%}
{\% if user.bio \%}<p class=\"bio\">{{ user.bio|truncate(100) }}</p>{\% endif \%}
<div class=\"stats\">
<span>{{ user.posts|default(0) }} posts</span>
<span>{{ user.followers|default(0) }} followers</span>
</div>
</div>
</div>
{\% endmacro \%}
{\% for user in users \%}
{{ user_card(user) }}
{\% endfor \%}",
"macro_nav_menu": "{\% macro nav_menu(items, current_path) \%}
<nav class=\"main-nav\">
<ul class=\"nav-list\">
{\% for item in items \%}
<li class=\"nav-item{\% if item.url == current_path \%} active{\% endif \%}{\% if item.children \%} has-children{\% endif \%}\">
<a href=\"{{ item.url }}\" class=\"nav-link\">
{\% if item.icon \%}<i class=\"icon-{{ item.icon }}\"></i> {\% endif \%}
{{ item.label }}
</a>
{\% if item.children \%}
<ul class=\"sub-menu\">
{\% for child in item.children \%}
<li class=\"nav-item{\% if child.url == current_path \%} active{\% endif \%}\">
<a href=\"{{ child.url }}\" class=\"nav-link\">{{ child.label }}</a>
</li>
{\% endfor \%}
</ul>
{\% endif \%}
</li>
{\% endfor \%}
</ul>
</nav>
{\% endmacro \%}
{{ nav_menu(menu_items, \"/products\") }}",
"macro_form": "{\% macro form_start(action, method=\"POST\", id=\"\", classes=\"\") \%}
<form action=\"{{ action }}\" method=\"{{ method }}\"{\% if id \%} id=\"{{ id }}\"{\% endif \%}{\% if classes \%} class=\"{{ classes }}\"{\% endif \%}>
{\% endmacro \%}
{\% macro form_end() \%}
</form>
{\% endmacro \%}
{\% macro hidden(name, value) \%}
<input type=\"hidden\" name=\"{{ name }}\" value=\"{{ value }}\">
{\% endmacro \%}
{\% macro submit(text=\"Submit\", type=\"primary\") \%}
<button type=\"submit\" class=\"btn btn-{{ type }}\">{{ text }}</button>
{\% endmacro \%}
{{ form_start(\"/api/contact\", \"POST\", \"contact-form\", \"contact-form\") }}
{{ hidden(\"csrf_token\", token) }}
<div class=\"form-row\">
<label>Name: <input type=\"text\" name=\"name\" required></label>
</div>
<div class=\"form-row\">
<label>Email: <input type=\"email\" name=\"email\" required></label>
</div>
<div class=\"form-row\">
<label>Message: <textarea name=\"message\" rows=\"4\"></textarea></label>
</div>
{{ submit(\"Send Message\", \"success\") }}
{{ form_end() }}",
"macro_star_rating": "{\% macro stars(rating, max=5) \%}
<div class=\"star-rating\" title=\"{{ rating }}/{{ max }}\">
{\% for i in range(1, max + 1) \%}
{\% if i <= rating \%}
<span class=\"star filled\">&#9733;</span>
{\% else \%}
<span class=\"star empty\">&#9734;</span>
{\% endif \%}
{\% endfor \%}
</div>
{\% endmacro \%}
Rating 1: {{ stars(1) }}
Rating 3: {{ stars(3) }}
Rating 5: {{ stars(5) }}
Rating 4/10: {{ stars(4, 10) }}",
"macro_progress": "{\% macro progress(value, max=100, label=\"\", color=\"primary\") \%}
{\% set percentage = (value / max * 100)|round \%}
<div class=\"progress-container\">
{\% if label \%}<label>{{ label }}: {{ value }}/{{ max }}</label>{\% endif \%}
<div class=\"progress\">
<div class=\"progress-bar bg-{{ color }}\" style=\"width: {{ percentage }}\%\">
{{ percentage }}\%
</div>
</div>
</div>
{\% endmacro \%}
{{ progress(25, 100, \"Downloads\") }}
{{ progress(75, 100, \"Upload\", \"success\") }}
{{ progress(50, 100, \"Processing\", \"warning\") }}
{{ progress(3, 10, \"Steps\", \"info\") }}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("\n" + "-" * 60)
System.print("1. SIMPLE MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_simple").render({}))
System.print("\n" + "-" * 60)
System.print("2. MACRO WITH DEFAULT ARGUMENTS")
System.print("-" * 60)
System.print(env.getTemplate("macro_default_args").render({}))
System.print("\n" + "-" * 60)
System.print("3. FORM INPUT MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_input").render({}))
System.print("\n" + "-" * 60)
System.print("4. SELECT DROPDOWN MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_select").render({
"countries": [
{"value": "us", "label": "United States"},
{"value": "uk", "label": "United Kingdom"},
{"value": "ca", "label": "Canada"},
{"value": "au", "label": "Australia"}
]
}))
System.print("\n" + "-" * 60)
System.print("5. TABLE MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_table").render({
"headers": ["ID", "Name", "Email", "Status"],
"data": [
[1, "Alice", "alice@example.com", "Active"],
[2, "Bob", "bob@example.com", "Active"],
[3, "Charlie", "charlie@example.com", "Inactive"]
]
}))
System.print("\n" + "-" * 60)
System.print("6. PAGINATION MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_pagination").render({}))
System.print("\n" + "-" * 60)
System.print("7. BREADCRUMB MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_breadcrumb").render({
"crumbs": [
{"label": "Home", "url": "/"},
{"label": "Products", "url": "/products"},
{"label": "Electronics", "url": "/products/electronics"},
{"label": "Laptops", "url": "/products/electronics/laptops"}
]
}))
System.print("\n" + "-" * 60)
System.print("8. ALERT MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_alert").render({}))
System.print("\n" + "-" * 60)
System.print("9. USER CARD MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_user_card").render({
"users": [
{
"name": "alice smith",
"role": "admin",
"email": "alice@example.com",
"avatar": "/avatars/alice.jpg",
"bio": "Software engineer with 10 years of experience in web development and cloud architecture.",
"posts": 42,
"followers": 1250
},
{
"name": "bob jones",
"email": "bob@example.com",
"posts": 15,
"followers": 300
}
]
}))
System.print("\n" + "-" * 60)
System.print("10. NAVIGATION MENU MACRO (RECURSIVE)")
System.print("-" * 60)
System.print(env.getTemplate("macro_nav_menu").render({
"menu_items": [
{"label": "Home", "url": "/", "icon": "home"},
{
"label": "Products",
"url": "/products",
"icon": "box",
"children": [
{"label": "Electronics", "url": "/products/electronics"},
{"label": "Clothing", "url": "/products/clothing"},
{"label": "Books", "url": "/products/books"}
]
},
{"label": "About", "url": "/about", "icon": "info"},
{"label": "Contact", "url": "/contact", "icon": "envelope"}
]
}))
System.print("\n" + "-" * 60)
System.print("11. FORM HELPERS")
System.print("-" * 60)
System.print(env.getTemplate("macro_form").render({
"token": "abc123xyz789"
}))
System.print("\n" + "-" * 60)
System.print("12. STAR RATING MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_star_rating").render({}))
System.print("\n" + "-" * 60)
System.print("13. PROGRESS BAR MACRO")
System.print("-" * 60)
System.print(env.getTemplate("macro_progress").render({}))
System.print("\n" + "=" * 60)
System.print("End of Macros Demo")
System.print("=" * 60)
+698
View File
@@ -0,0 +1,698 @@
// retoor <retoor@molodetz.nl>
import "jinja" for Environment, DictLoader
System.print("=" * 60)
System.print("JINJA REAL-WORLD EXAMPLES")
System.print("=" * 60)
var templates = {
"invoice.html": "<!DOCTYPE html>
<html>
<head>
<title>Invoice #{{ invoice.number }}</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.header { border-bottom: 2px solid #333; padding-bottom: 20px; }
.company-info { float: left; }
.invoice-info { float: right; text-align: right; }
.clear { clear: both; }
.addresses { margin: 30px 0; }
.from, .to { width: 45\%; display: inline-block; vertical-align: top; }
table { width: 100\%; border-collapse: collapse; margin: 20px 0; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
th { background: #f5f5f5; }
.amount { text-align: right; }
.totals { width: 300px; float: right; }
.totals td { border: none; padding: 5px 10px; }
.totals .total { font-weight: bold; font-size: 1.2em; border-top: 2px solid #333; }
.footer { margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 0.9em; color: #666; }
</style>
</head>
<body>
<div class=\"header\">
<div class=\"company-info\">
<h1>{{ company.name }}</h1>
<p>{{ company.address }}<br>
{{ company.city }}, {{ company.country }}<br>
Tel: {{ company.phone }}<br>
Email: {{ company.email }}</p>
</div>
<div class=\"invoice-info\">
<h2>INVOICE</h2>
<p><strong>Invoice #:</strong> {{ invoice.number }}<br>
<strong>Date:</strong> {{ invoice.date }}<br>
<strong>Due Date:</strong> {{ invoice.due_date }}<br>
<strong>Status:</strong> {{ invoice.status|upper }}</p>
</div>
<div class=\"clear\"></div>
</div>
<div class=\"addresses\">
<div class=\"from\">
<h3>From:</h3>
<p>{{ company.name }}<br>
{{ company.address }}<br>
{{ company.city }}, {{ company.country }}</p>
</div>
<div class=\"to\">
<h3>Bill To:</h3>
<p><strong>{{ client.name }}</strong><br>
{{ client.address }}<br>
{{ client.city }}, {{ client.country }}<br>
{\% if client.vat \%}VAT: {{ client.vat }}{\% endif \%}</p>
</div>
</div>
<table>
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Quantity</th>
<th class=\"amount\">Unit Price</th>
<th class=\"amount\">Amount</th>
</tr>
</thead>
<tbody>
{\% for item in invoice.items \%}
<tr>
<td>{{ loop.index }}</td>
<td>{{ item.description }}</td>
<td>{{ item.quantity }}</td>
<td class=\"amount\">${{ item.price|round(2) }}</td>
<td class=\"amount\">${{ (item.quantity * item.price)|round(2) }}</td>
</tr>
{\% endfor \%}
</tbody>
</table>
<table class=\"totals\">
<tr>
<td>Subtotal:</td>
<td class=\"amount\">${{ invoice.subtotal|round(2) }}</td>
</tr>
{\% if invoice.discount \%}
<tr>
<td>Discount ({{ invoice.discount_percent }}\%):</td>
<td class=\"amount\">-${{ invoice.discount|round(2) }}</td>
</tr>
{\% endif \%}
<tr>
<td>Tax ({{ invoice.tax_rate }}\%):</td>
<td class=\"amount\">${{ invoice.tax|round(2) }}</td>
</tr>
<tr class=\"total\">
<td>Total:</td>
<td class=\"amount\">${{ invoice.total|round(2) }}</td>
</tr>
</table>
<div class=\"clear\"></div>
{\% if invoice.notes \%}
<div class=\"notes\">
<h3>Notes:</h3>
<p>{{ invoice.notes }}</p>
</div>
{\% endif \%}
<div class=\"footer\">
<p>Payment Terms: {{ invoice.payment_terms|default(\"Net 30\") }}</p>
<p>Please make payment to: {{ company.bank_account }}</p>
<p>Thank you for your business!</p>
</div>
</body>
</html>",
"report.md": "# {{ report.title }}
**Generated:** {{ report.date }}
**Author:** {{ report.author }}
**Period:** {{ report.period_start }} to {{ report.period_end }}
---
## Executive Summary
{{ report.summary }}
## Key Metrics
| Metric | Value | Change |
|--------|-------|--------|
{\% for metric in report.metrics \%}
| {{ metric.name }} | {{ metric.value }} | {{ \"+\" if metric.change > 0 else \"\" }}{{ metric.change }}\% |
{\% endfor \%}
## Performance by Category
{\% for category in report.categories \%}
### {{ category.name }}
- **Revenue:** ${{ category.revenue|round(2) }}
- **Units Sold:** {{ category.units }}
- **Growth:** {{ category.growth }}\%
{\% if category.top_products \%}
Top products:
{\% for product in category.top_products \%}
{{ loop.index }}. {{ product.name }} (${{ product.revenue|round(2) }})
{\% endfor \%}
{\% endif \%}
{\% endfor \%}
## Recommendations
{\% for rec in report.recommendations \%}
{{ loop.index }}. **{{ rec.priority|upper }}**: {{ rec.text }}
{\% endfor \%}
---
*This report was automatically generated.*",
"api_response.json": "{
\"status\": \"{{ response.status }}\",
\"code\": {{ response.code }},
\"message\": \"{{ response.message }}\",
\"timestamp\": \"{{ response.timestamp }}\",
\"data\": {
{\% if response.data.user \%}
\"user\": {
\"id\": {{ response.data.user.id }},
\"name\": \"{{ response.data.user.name }}\",
\"email\": \"{{ response.data.user.email }}\",
\"role\": \"{{ response.data.user.role }}\",
\"created_at\": \"{{ response.data.user.created_at }}\"
},
{\% endif \%}
{\% if response.data.items \%}
\"items\": [
{\% for item in response.data.items \%}
{
\"id\": {{ item.id }},
\"name\": \"{{ item.name }}\",
\"price\": {{ item.price }},
\"available\": {{ \"true\" if item.available else \"false\" }}
}{{ \",\" if not loop.last else \"\" }}
{\% endfor \%}
],
\"total\": {{ response.data.items|length }},
{\% endif \%}
\"pagination\": {
\"page\": {{ response.pagination.page }},
\"per_page\": {{ response.pagination.per_page }},
\"total_pages\": {{ response.pagination.total_pages }},
\"total_items\": {{ response.pagination.total_items }}
}
}
}",
"config.yaml": "# Application Configuration
# Generated: {{ timestamp }}
app:
name: {{ config.app.name }}
version: {{ config.app.version }}
environment: {{ config.app.environment }}
debug: {{ \"true\" if config.app.debug else \"false\" }}
server:
host: {{ config.server.host }}
port: {{ config.server.port }}
workers: {{ config.server.workers }}
timeout: {{ config.server.timeout }}
database:
driver: {{ config.database.driver }}
host: {{ config.database.host }}
port: {{ config.database.port }}
name: {{ config.database.name }}
user: {{ config.database.user }}
pool_size: {{ config.database.pool_size }}
cache:
driver: {{ config.cache.driver }}
host: {{ config.cache.host }}
port: {{ config.cache.port }}
ttl: {{ config.cache.ttl }}
logging:
level: {{ config.logging.level }}
format: \"{{ config.logging.format }}\"
handlers:
{\% for handler in config.logging.handlers \%}
- type: {{ handler.type }}
{\% if handler.path \%}path: {{ handler.path }}{\% endif \%}
{\% if handler.max_size \%}max_size: {{ handler.max_size }}{\% endif \%}
{\% endfor \%}
features:
{\% for feature, enabled in config.features \%}
{{ feature }}: {{ \"true\" if enabled else \"false\" }}
{\% endfor \%}",
"sitemap.xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">
{\% for page in pages \%}
<url>
<loc>{{ base_url }}{{ page.url }}</loc>
<lastmod>{{ page.last_modified }}</lastmod>
<changefreq>{{ page.change_freq|default(\"weekly\") }}</changefreq>
<priority>{{ page.priority|default(\"0.5\") }}</priority>
</url>
{\% endfor \%}
</urlset>",
"dockerfile": "# Dockerfile for {{ app.name }}
# Generated automatically - do not edit manually
FROM {{ app.base_image }}
LABEL maintainer=\"{{ app.maintainer }}\"
LABEL version=\"{{ app.version }}\"
# Set environment variables
{\% for key, value in app.env_vars \%}
ENV {{ key }}={{ value }}
{\% endfor \%}
# Set working directory
WORKDIR {{ app.workdir }}
# Install system dependencies
{\% if app.system_packages \%}
RUN apt-get update && apt-get install -y \\
{\% for pkg in app.system_packages \%}
{{ pkg }}{\% if not loop.last \%} \\{\% endif \%}
{\% endfor \%}
&& rm -rf /var/lib/apt/lists/*
{\% endif \%}
# Copy dependency files
{\% for file in app.dependency_files \%}
COPY {{ file }} .
{\% endfor \%}
# Install application dependencies
{\% if app.install_cmd \%}
RUN {{ app.install_cmd }}
{\% endif \%}
# Copy application code
COPY . .
# Expose port
EXPOSE {{ app.port }}
# Health check
{\% if app.healthcheck \%}
HEALTHCHECK --interval={{ app.healthcheck.interval }} --timeout={{ app.healthcheck.timeout }} \\
CMD {{ app.healthcheck.cmd }}
{\% endif \%}
# Run the application
CMD [\"{{ app.cmd }}\"]",
"readme.md": "# {{ project.name }}
{{ project.description }}
## Features
{\% for feature in project.features \%}
- {{ feature }}
{\% endfor \%}
## Installation
```bash
{{ project.install_cmd }}
```
## Quick Start
```{{ project.code_lang }}
{{ project.quick_start }}
```
## Configuration
| Option | Type | Default | Description |
|--------|------|---------|-------------|
{\% for opt in project.config_options \%}
| `{{ opt.name }}` | {{ opt.type }} | {{ opt.default|default(\"N/A\") }} | {{ opt.description }} |
{\% endfor \%}
## API Reference
{\% for endpoint in project.api_endpoints \%}
### {{ endpoint.method }} {{ endpoint.path }}
{{ endpoint.description }}
**Parameters:**
{\% for param in endpoint.params \%}
- `{{ param.name }}` ({{ param.type }}{\% if param.required \%}, required{\% endif \%}): {{ param.description }}
{\% endfor \%}
**Response:**
```json
{{ endpoint.response_example }}
```
{\% endfor \%}
## License
{{ project.license }}
## Author
{{ project.author }} - {{ project.author_email }}",
"changelog.md": "# Changelog
All notable changes to {{ project_name }} will be documented in this file.
{\% for release in releases \%}
## [{{ release.version }}] - {{ release.date }}
{\% if release.breaking \%}
### Breaking Changes
{\% for item in release.breaking \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% if release.added \%}
### Added
{\% for item in release.added \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% if release.changed \%}
### Changed
{\% for item in release.changed \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% if release.deprecated \%}
### Deprecated
{\% for item in release.deprecated \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% if release.removed \%}
### Removed
{\% for item in release.removed \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% if release.fixed \%}
### Fixed
{\% for item in release.fixed \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% if release.security \%}
### Security
{\% for item in release.security \%}
- {{ item }}
{\% endfor \%}
{\% endif \%}
{\% endfor \%}"
}
var env = Environment.new(DictLoader.new(templates))
System.print("\n" + "-" * 60)
System.print("1. INVOICE (HTML)")
System.print("-" * 60)
System.print(env.getTemplate("invoice.html").render({
"company": {
"name": "Acme Corporation",
"address": "123 Business Street",
"city": "New York, NY 10001",
"country": "USA",
"phone": "+1 (555) 123-4567",
"email": "billing@acme.com",
"bank_account": "Bank of America - 1234567890"
},
"client": {
"name": "TechStart Inc.",
"address": "456 Innovation Ave",
"city": "San Francisco, CA 94102",
"country": "USA",
"vat": "US123456789"
},
"invoice": {
"number": "INV-2024-001",
"date": "2024-01-15",
"due_date": "2024-02-14",
"status": "pending",
"items": [
{"description": "Web Development Services", "quantity": 40, "price": 150},
{"description": "UI/UX Design", "quantity": 20, "price": 125},
{"description": "Server Setup & Configuration", "quantity": 8, "price": 200},
{"description": "Monthly Maintenance (Jan)", "quantity": 1, "price": 500}
],
"subtotal": 9600,
"discount": 480,
"discount_percent": 5,
"tax_rate": 8.5,
"tax": 775.2,
"total": 9895.2,
"notes": "Thank you for choosing Acme Corporation. Payment is due within 30 days.",
"payment_terms": "Net 30"
}
}))
System.print("\n" + "-" * 60)
System.print("2. BUSINESS REPORT (Markdown)")
System.print("-" * 60)
System.print(env.getTemplate("report.md").render({
"report": {
"title": "Q4 2024 Sales Report",
"date": "2024-01-05",
"author": "Analytics Team",
"period_start": "2024-10-01",
"period_end": "2024-12-31",
"summary": "Q4 2024 showed strong performance with overall revenue growth of 15\% compared to Q3. The Electronics category led growth while we saw moderate decline in Accessories.",
"metrics": [
{"name": "Total Revenue", "value": "$1.2M", "change": 15},
{"name": "Orders", "value": "8,450", "change": 12},
{"name": "Avg Order Value", "value": "$142", "change": 3},
{"name": "Customer Retention", "value": "78\%", "change": -2}
],
"categories": [
{
"name": "Electronics",
"revenue": 650000,
"units": 4200,
"growth": 22,
"top_products": [
{"name": "Laptop Pro X", "revenue": 180000},
{"name": "Wireless Headphones", "revenue": 95000},
{"name": "Smart Watch V3", "revenue": 72000}
]
},
{
"name": "Clothing",
"revenue": 380000,
"units": 12500,
"growth": 8,
"top_products": [
{"name": "Winter Jacket", "revenue": 65000},
{"name": "Running Shoes", "revenue": 48000}
]
}
],
"recommendations": [
{"priority": "high", "text": "Increase inventory for Electronics category to meet Q1 demand"},
{"priority": "medium", "text": "Launch targeted campaign for Accessories to reverse decline"},
{"priority": "low", "text": "Consider expanding Clothing line with spring collection"}
]
}
}))
System.print("\n" + "-" * 60)
System.print("3. API RESPONSE (JSON)")
System.print("-" * 60)
System.print(env.getTemplate("api_response.json").render({
"response": {
"status": "success",
"code": 200,
"message": "Data retrieved successfully",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"user": {
"id": 12345,
"name": "John Doe",
"email": "john@example.com",
"role": "admin",
"created_at": "2023-06-15T08:00:00Z"
},
"items": [
{"id": 1, "name": "Widget A", "price": 29.99, "available": true},
{"id": 2, "name": "Widget B", "price": 49.99, "available": true},
{"id": 3, "name": "Widget C", "price": 19.99, "available": false}
]
},
"pagination": {
"page": 1,
"per_page": 10,
"total_pages": 5,
"total_items": 47
}
}
}))
System.print("\n" + "-" * 60)
System.print("4. CONFIG FILE (YAML)")
System.print("-" * 60)
System.print(env.getTemplate("config.yaml").render({
"timestamp": "2024-01-15 10:30:00",
"config": {
"app": {
"name": "MyApp",
"version": "2.1.0",
"environment": "production",
"debug": false
},
"server": {
"host": "0.0.0.0",
"port": 8080,
"workers": 4,
"timeout": 30
},
"database": {
"driver": "postgresql",
"host": "db.example.com",
"port": 5432,
"name": "myapp_prod",
"user": "app_user",
"pool_size": 20
},
"cache": {
"driver": "redis",
"host": "cache.example.com",
"port": 6379,
"ttl": 3600
},
"logging": {
"level": "INFO",
"format": "\%(asctime)s - \%(name)s - \%(levelname)s - \%(message)s",
"handlers": [
{"type": "console"},
{"type": "file", "path": "/var/log/myapp.log", "max_size": "100MB"}
]
},
"features": {
"new_dashboard": true,
"beta_api": false,
"analytics": true
}
}
}))
System.print("\n" + "-" * 60)
System.print("5. SITEMAP (XML)")
System.print("-" * 60)
System.print(env.getTemplate("sitemap.xml").render({
"base_url": "https://example.com",
"pages": [
{"url": "/", "last_modified": "2024-01-15", "change_freq": "daily", "priority": "1.0"},
{"url": "/about", "last_modified": "2024-01-10", "change_freq": "monthly", "priority": "0.8"},
{"url": "/products", "last_modified": "2024-01-14", "change_freq": "weekly", "priority": "0.9"},
{"url": "/blog", "last_modified": "2024-01-15", "change_freq": "daily", "priority": "0.7"},
{"url": "/contact", "last_modified": "2024-01-01", "change_freq": "yearly", "priority": "0.5"}
]
}))
System.print("\n" + "-" * 60)
System.print("6. DOCKERFILE")
System.print("-" * 60)
System.print(env.getTemplate("dockerfile").render({
"app": {
"name": "my-python-app",
"base_image": "python:3.11-slim",
"maintainer": "dev@example.com",
"version": "1.0.0",
"workdir": "/app",
"port": 8000,
"env_vars": {
"PYTHONUNBUFFERED": "1",
"PYTHONDONTWRITEBYTECODE": "1",
"APP_ENV": "production"
},
"system_packages": ["gcc", "libpq-dev", "curl"],
"dependency_files": ["requirements.txt", "setup.py"],
"install_cmd": "pip install --no-cache-dir -r requirements.txt",
"healthcheck": {
"interval": "30s",
"timeout": "10s",
"cmd": "curl -f http://localhost:8000/health || exit 1"
},
"cmd": "gunicorn -w 4 -b 0.0.0.0:8000 app:app"
}
}))
System.print("\n" + "-" * 60)
System.print("7. CHANGELOG")
System.print("-" * 60)
System.print(env.getTemplate("changelog.md").render({
"project_name": "MyAwesomeLib",
"releases": [
{
"version": "2.0.0",
"date": "2024-01-15",
"breaking": [
"Removed deprecated `oldMethod()` function",
"Changed default timeout from 30s to 60s"
],
"added": [
"New async API support",
"Plugin system for extensibility",
"TypeScript type definitions"
],
"changed": [
"Improved error messages",
"Updated dependencies to latest versions"
],
"fixed": [
"Memory leak in connection pool",
"Race condition in concurrent requests"
]
},
{
"version": "1.5.0",
"date": "2023-12-01",
"added": [
"Caching layer for improved performance",
"Retry mechanism with exponential backoff"
],
"deprecated": [
"`oldMethod()` - use `newMethod()` instead"
],
"fixed": [
"Timeout handling in slow networks",
"Unicode encoding issues"
],
"security": [
"Updated crypto library to patch CVE-2023-XXXXX"
]
}
]
}))
System.print("\n" + "=" * 60)
System.print("End of Real-World Examples")
System.print("=" * 60)
+61
View File
@@ -0,0 +1,61 @@
// retoor <retoor@molodetz.nl>
import "json" for Json
System.print("=== Json Module Demo ===\n")
System.print("--- Parsing JSON ---")
var jsonString = "{\"name\":\"Alice\",\"age\":30,\"active\":true}"
var obj = Json.parse(jsonString)
System.print("Parsed: %(obj)")
System.print("Name: %(obj["name"])")
System.print("Age: %(obj["age"])")
System.print("Active: %(obj["active"])")
System.print("\n--- Parsing Arrays ---")
var arrayJson = "[1, 2, 3, \"four\", true, null]"
var arr = Json.parse(arrayJson)
System.print("Parsed array: %(arr)")
System.print("Third element: %(arr[2])")
System.print("\n--- Nested Objects ---")
var nestedJson = "{\"user\":{\"name\":\"Bob\",\"address\":{\"city\":\"New York\",\"zip\":\"10001\"}},\"tags\":[\"admin\",\"user\"]}"
var nested = Json.parse(nestedJson)
System.print("City: %(nested["user"]["address"]["city"])")
System.print("First tag: %(nested["tags"][0])")
System.print("\n--- Stringify (compact) ---")
var data = {
"name": "Charlie",
"scores": [85, 92, 78],
"metadata": {
"created": "2024-01-15",
"version": 1
}
}
System.print(Json.stringify(data))
System.print("\n--- Stringify (pretty, 2 spaces) ---")
System.print(Json.stringify(data, 2))
System.print("\n--- Stringify (pretty, 4 spaces) ---")
System.print(Json.stringify(data, 4))
System.print("\n--- Special Values ---")
var special = {
"string": "Hello\nWorld",
"number": 42.5,
"boolean": false,
"null": null,
"empty_array": [],
"empty_object": {}
}
System.print(Json.stringify(special, 2))
System.print("\n--- Round-trip ---")
var original = {"key": "value", "list": [1, 2, 3]}
var jsonified = Json.stringify(original)
var restored = Json.parse(jsonified)
System.print("Original: %(original)")
System.print("JSON: %(jsonified)")
System.print("Restored: %(restored)")
+78
View File
@@ -0,0 +1,78 @@
// retoor <retoor@molodetz.nl>
import "math" for Math
System.print("=== Math Module Demo ===\n")
System.print("--- Constants ---")
System.print("pi: %(Math.pi)")
System.print("e: %(Math.e)")
System.print("tau: %(Math.tau)")
System.print("infinity: %(Math.infinity)")
System.print("nan: %(Math.nan)")
System.print("\n--- Trigonometric Functions ---")
var angle = Math.pi / 4
System.print("Angle: pi/4 radians (45 degrees)")
System.print("sin(pi/4): %(Math.sin(angle))")
System.print("cos(pi/4): %(Math.cos(angle))")
System.print("tan(pi/4): %(Math.tan(angle))")
System.print("\n--- Inverse Trigonometric Functions ---")
System.print("asin(0.5): %(Math.asin(0.5)) radians")
System.print("acos(0.5): %(Math.acos(0.5)) radians")
System.print("atan(1): %(Math.atan(1)) radians")
System.print("atan2(1, 1): %(Math.atan2(1, 1)) radians")
System.print("\n--- Hyperbolic Functions ---")
System.print("sinh(1): %(Math.sinh(1))")
System.print("cosh(1): %(Math.cosh(1))")
System.print("tanh(1): %(Math.tanh(1))")
System.print("\n--- Logarithmic Functions ---")
System.print("log(e): %(Math.log(Math.e))")
System.print("log10(100): %(Math.log10(100))")
System.print("log2(8): %(Math.log2(8))")
System.print("exp(1): %(Math.exp(1))")
System.print("\n--- Power and Roots ---")
System.print("pow(2, 10): %(Math.pow(2, 10))")
System.print("sqrt(16): %(Math.sqrt(16))")
System.print("cbrt(27): %(Math.cbrt(27))")
System.print("\n--- Rounding Functions ---")
System.print("ceil(4.3): %(Math.ceil(4.3))")
System.print("floor(4.7): %(Math.floor(4.7))")
System.print("round(4.5): %(Math.round(4.5))")
System.print("abs(-42): %(Math.abs(-42))")
System.print("\n--- Min, Max, Clamp ---")
System.print("min(5, 3): %(Math.min(5, 3))")
System.print("max(5, 3): %(Math.max(5, 3))")
System.print("clamp(15, 0, 10): %(Math.clamp(15, 0, 10))")
System.print("clamp(5, 0, 10): %(Math.clamp(5, 0, 10))")
System.print("clamp(-5, 0, 10): %(Math.clamp(-5, 0, 10))")
System.print("\n--- Sign Function ---")
System.print("sign(42): %(Math.sign(42))")
System.print("sign(-42): %(Math.sign(-42))")
System.print("sign(0): %(Math.sign(0))")
System.print("\n--- Linear Interpolation ---")
System.print("lerp(0, 100, 0.0): %(Math.lerp(0, 100, 0))")
System.print("lerp(0, 100, 0.5): %(Math.lerp(0, 100, 0.5))")
System.print("lerp(0, 100, 1.0): %(Math.lerp(0, 100, 1))")
System.print("\n--- Angle Conversion ---")
System.print("degrees(pi): %(Math.degrees(Math.pi))")
System.print("degrees(pi/2): %(Math.degrees(Math.pi / 2))")
System.print("radians(180): %(Math.radians(180))")
System.print("radians(90): %(Math.radians(90))")
System.print("\n--- Practical Example: Distance Calculation ---")
var x1 = 0
var y1 = 0
var x2 = 3
var y2 = 4
var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
System.print("Distance from (%(x1),%(y1)) to (%(x2),%(y2)): %(distance)")
+138
View File
@@ -0,0 +1,138 @@
// retoor <retoor@molodetz.nl>
import "http" for Http
import "json" for Json
import "env" for Environment
import "io" for Stdin, Stdout
class Chat {
construct new(model) {
_model = model
_messages = []
_apiKey = Environment.get("OPENROUTER_API_KEY")
if (_apiKey == null || _apiKey.count == 0) {
Fiber.abort("OPENROUTER_API_KEY environment variable not set")
}
}
addSystem(content) {
_messages.add({"role": "system", "content": content})
}
send(content) {
_messages.add({"role": "user", "content": content})
var requestBody = {
"model": _model,
"messages": _messages,
"stream": false
}
var headers = {
"Authorization": "Bearer " + _apiKey,
"Content-Type": "application/json"
}
var response = Http.post("https://openrouter.ai/api/v1/chat/completions", requestBody, headers)
if (!response.ok) {
var error = "API error: %(response.statusCode)"
if (response.body.count > 0) {
var data = Json.parse(response.body)
if (data["error"] != null && data["error"]["message"] != null) {
error = data["error"]["message"]
}
}
return {"error": error}
}
var data = Json.parse(response.body)
if (data["choices"] != null && data["choices"].count > 0) {
var message = data["choices"][0]["message"]
if (message != null) {
_messages.add(message)
return {
"content": message["content"],
"model": data["model"],
"usage": data["usage"]
}
}
}
return {"error": "Invalid response format"}
}
clear() {
var system = _messages.count > 0 && _messages[0]["role"] == "system" ? _messages[0] : null
_messages = []
if (system != null) _messages.add(system)
}
model { _model }
model=(value) { _model = value }
messageCount { _messages.count }
}
var model = "x-ai/grok-code-fast-1"
var chat = Chat.new(model)
chat.addSystem("You are a helpful assistant. Be concise in your responses.")
System.print("OpenRouter Chat")
System.print("Model: %(model)")
System.print("Commands: /quit, /clear, /model <name>, /history")
System.print("-" * 50)
while (true) {
System.write("\nYou: ")
Stdout.flush()
var input = Stdin.readLine()
if (input == null || input.trim() == "/quit" || input.trim() == "/exit") {
System.print("Goodbye!")
break
}
input = input.trim()
if (input.count == 0) continue
if (input == "/clear") {
chat.clear()
System.print("[Conversation cleared]")
continue
}
if (input == "/history") {
System.print("[%(chat.messageCount) messages in history]")
continue
}
if (input.startsWith("/model ")) {
var newModel = input[7..-1].trim()
if (newModel.count > 0) {
chat.model = newModel
System.print("[Model changed to: %(newModel)]")
}
continue
}
if (input.startsWith("/")) {
System.print("[Unknown command: %(input)]")
continue
}
System.write("\nAssistant: ")
Stdout.flush()
var result = chat.send(input)
if (result["error"] != null) {
System.print("[Error: %(result["error"])]")
} else {
System.print(result["content"])
if (result["usage"] != null) {
var usage = result["usage"]
System.print("\n[tokens: %(usage["prompt_tokens"]) prompt, %(usage["completion_tokens"]) completion]")
}
}
}
+55
View File
@@ -0,0 +1,55 @@
// retoor <retoor@molodetz.nl>
import "http" for Http
import "json" for Json
import "env" for Environment
var apiKey = Environment.get("OPENROUTER_API_KEY")
if (apiKey == null || apiKey.count == 0) {
System.print("Error: OPENROUTER_API_KEY environment variable not set")
Fiber.abort("Missing API key")
}
System.print("=== OpenRouter API Demo ===\n")
var model = "x-ai/grok-code-fast-1"
var prompt = "What is 2 + 2? Reply with just the number."
System.print("Model: %(model)")
System.print("Prompt: %(prompt)")
System.print("")
var requestBody = {
"model": model,
"messages": [
{"role": "user", "content": prompt}
]
}
var headers = {
"Authorization": "Bearer " + apiKey,
"Content-Type": "application/json"
}
System.print("Sending request to OpenRouter...")
var response = Http.post("https://openrouter.ai/api/v1/chat/completions", requestBody, headers)
System.print("Status: %(response.statusCode)")
System.print("")
if (response.ok) {
var data = Json.parse(response.body)
if (data != null && data["choices"] != null && data["choices"].count > 0) {
var message = data["choices"][0]["message"]
if (message != null && message["content"] != null) {
System.print("Response: %(message["content"])")
}
}
System.print("\nModel used: %(data["model"])")
if (data["usage"] != null) {
System.print("Tokens - prompt: %(data["usage"]["prompt_tokens"]), completion: %(data["usage"]["completion_tokens"])")
}
} else {
System.print("Error: %(response.body)")
}
+130
View File
@@ -0,0 +1,130 @@
// retoor <retoor@molodetz.nl>
import "regex" for Regex
System.print("=== Regex Module Demo ===\n")
System.print("--- Basic Pattern Matching ---")
var pattern = Regex.new("hello")
System.print("Pattern: %(pattern.pattern)")
System.print("Test 'hello world': %(pattern.test("hello world"))")
System.print("Test 'HELLO world': %(pattern.test("HELLO world"))")
System.print("Test 'goodbye': %(pattern.test("goodbye"))")
System.print("\n--- Case Insensitive Matching ---")
var insensitive = Regex.new("hello", "i")
System.print("Pattern: %(insensitive.pattern) (flags: %(insensitive.flags))")
System.print("Test 'HELLO world': %(insensitive.test("HELLO world"))")
System.print("Test 'HeLLo': %(insensitive.test("HeLLo"))")
System.print("\n--- Digit Patterns ---")
var digitPattern = Regex.new("[0-9]+")
System.print("Pattern: [0-9]+")
System.print("Test '123': %(digitPattern.test("123"))")
System.print("Test 'abc': %(digitPattern.test("abc"))")
System.print("Test 'abc123': %(digitPattern.test("abc123"))")
System.print("\n--- Replace First Match ---")
var text = "hello hello hello"
var helloPattern = Regex.new("hello")
var replaced = helloPattern.replace(text, "hi")
System.print("Original: %(text)")
System.print("Replaced first: %(replaced)")
System.print("\n--- Replace All Matches ---")
var replacedAll = helloPattern.replaceAll(text, "hi")
System.print("Replaced all: %(replacedAll)")
System.print("\n--- Split by Pattern ---")
var csv = "apple,banana,cherry,date"
var commaPattern = Regex.new(",")
var parts = commaPattern.split(csv)
System.print("CSV: %(csv)")
System.print("Split parts: %(parts)")
System.print("\n--- Split by Multiple Commas ---")
var csvMultiple = "apple,,banana,,,cherry"
var multiComma = Regex.new(",+")
var cleanParts = multiComma.split(csvMultiple)
System.print("CSV: %(csvMultiple)")
System.print("Split parts: %(cleanParts)")
System.print("\n--- Word Pattern ---")
var wordPattern = Regex.new("[a-zA-Z]+")
System.print("Test 'hello123': %(wordPattern.test("hello123"))")
System.print("Test '12345': %(wordPattern.test("12345"))")
System.print("\n--- Whitespace Handling ---")
var whitespace = Regex.new("\\s+")
var messy = "too many spaces"
var cleaned = whitespace.replaceAll(messy, " ")
System.print("Original: '%(messy)'")
System.print("Cleaned: '%(cleaned)'")
System.print("\n--- Special Character Escapes ---")
var digitEscape = Regex.new("\\d+")
System.print("Pattern: \\d+ (digits)")
System.print("Test 'abc123def': %(digitEscape.test("abc123def"))")
var wordEscape = Regex.new("\\w+")
System.print("Pattern: \\w+ (word chars)")
System.print("Test 'hello_world': %(wordEscape.test("hello_world"))")
var spaceEscape = Regex.new("\\s")
System.print("Pattern: \\s (whitespace)")
System.print("Test 'hello world': %(spaceEscape.test("hello world"))")
System.print("\n--- Anchors ---")
var startAnchor = Regex.new("^hello")
System.print("Pattern: ^hello (start anchor)")
System.print("Test 'hello world': %(startAnchor.test("hello world"))")
System.print("Test 'say hello': %(startAnchor.test("say hello"))")
var endAnchor = Regex.new("world$")
System.print("Pattern: world$ (end anchor)")
System.print("Test 'hello world': %(endAnchor.test("hello world"))")
System.print("Test 'world hello': %(endAnchor.test("world hello"))")
System.print("\n--- Quantifiers ---")
var optional = Regex.new("colou?r")
System.print("Pattern: colou?r (optional u)")
System.print("Test 'color': %(optional.test("color"))")
System.print("Test 'colour': %(optional.test("colour"))")
var oneOrMore = Regex.new("a+")
System.print("Pattern: a+ (one or more a)")
System.print("Test 'aaa': %(oneOrMore.test("aaa"))")
System.print("Test 'bbb': %(oneOrMore.test("bbb"))")
var zeroOrMore = Regex.new("ba*b")
System.print("Pattern: ba*b (zero or more a)")
System.print("Test 'bb': %(zeroOrMore.test("bb"))")
System.print("Test 'bab': %(zeroOrMore.test("bab"))")
System.print("Test 'baaab': %(zeroOrMore.test("baaab"))")
System.print("\n--- Character Classes ---")
var vowels = Regex.new("[aeiou]")
System.print("Pattern: [aeiou] (vowels)")
System.print("Test 'hello': %(vowels.test("hello"))")
System.print("Test 'xyz': %(vowels.test("xyz"))")
var notDigit = Regex.new("[^0-9]+")
System.print("Pattern: [^0-9]+ (non-digits)")
var numbersRemoved = notDigit.replaceAll("abc123def456", "")
System.print("Remove non-digits from 'abc123def456': '%(numbersRemoved)'")
System.print("\n--- Practical: Trim Whitespace ---")
var leadingSpace = Regex.new("^\\s+")
var trailingSpace = Regex.new("\\s+$")
var padded = " hello world "
var trimmed = leadingSpace.replace(padded, "")
trimmed = trailingSpace.replace(trimmed, "")
System.print("Original: '[%(padded)]'")
System.print("Trimmed: '[%(trimmed)]'")
System.print("\n--- Practical: Simple Tokenizer ---")
var tokenSeparator = Regex.new("[\\s,;]+")
var sentence = "hello, world; foo bar"
var tokens = tokenSeparator.split(sentence)
System.print("Input: %(sentence)")
System.print("Tokens: %(tokens)")
+39
View File
@@ -0,0 +1,39 @@
// retoor <retoor@molodetz.nl>
import "signal" for Signal
System.print("=== Signal Module Demo ===\n")
System.print("--- Available Signal Constants ---")
System.print("SIGHUP: %(Signal.SIGHUP)")
System.print("SIGINT: %(Signal.SIGINT)")
System.print("SIGQUIT: %(Signal.SIGQUIT)")
System.print("SIGTERM: %(Signal.SIGTERM)")
System.print("SIGUSR1: %(Signal.SIGUSR1)")
System.print("SIGUSR2: %(Signal.SIGUSR2)")
System.print("\n--- Signal API Overview ---")
System.print("The Signal module provides:")
System.print(" Signal.trap(signum, fn) - Set a handler for a signal")
System.print(" Signal.ignore(signum) - Ignore a signal")
System.print(" Signal.reset(signum) - Reset to default behavior")
System.print("\n--- Example Usage ---")
System.print("To handle SIGINT (Ctrl+C):")
System.print(" Signal.trap(Signal.SIGINT) {")
System.print(" System.print(\"Interrupted!\")")
System.print(" }")
System.print("\nTo ignore SIGTERM:")
System.print(" Signal.ignore(Signal.SIGTERM)")
System.print("\nTo reset SIGHUP to default:")
System.print(" Signal.reset(Signal.SIGHUP)")
System.print("\n--- Notes ---")
System.print("Signal handling is useful for:")
System.print(" - Graceful shutdown on SIGTERM/SIGINT")
System.print(" - Reloading configuration on SIGHUP")
System.print(" - Custom actions on SIGUSR1/SIGUSR2")
System.print("\n--- Demo Complete ---")
+112
View File
@@ -0,0 +1,112 @@
// retoor <retoor@molodetz.nl>
import "sqlite" for Database
System.print("=== SQLite Module Demo ===\n")
System.print("--- Creating In-Memory Database ---")
var db = Database.memory()
System.print("Database opened successfully")
System.print("\n--- Creating Table ---")
db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, age INTEGER)")
System.print("Table 'users' created")
System.print("\n--- Inserting Data ---")
db.execute("INSERT INTO users (name, email, age) VALUES ('Alice', 'alice@example.com', 30)")
System.print("Last insert ID: %(db.lastInsertId)")
db.execute("INSERT INTO users (name, email, age) VALUES ('Bob', 'bob@example.com', 25)")
System.print("Last insert ID: %(db.lastInsertId)")
db.execute("INSERT INTO users (name, email, age) VALUES ('Charlie', 'charlie@example.com', 35)")
System.print("Last insert ID: %(db.lastInsertId)")
System.print("Rows changed: %(db.changes)")
System.print("\n--- Parameterized Insert ---")
db.execute("INSERT INTO users (name, email, age) VALUES (?, ?, ?)", ["Diana", "diana@example.com", 28])
System.print("Inserted Diana with ID: %(db.lastInsertId)")
System.print("\n--- Querying All Data ---")
var allUsers = db.query("SELECT * FROM users")
System.print("All users:")
for (user in allUsers) {
System.print(" %(user["id"]): %(user["name"]) <%(user["email"])> age %(user["age"])")
}
System.print("\n--- Parameterized Query ---")
var olderUsers = db.query("SELECT * FROM users WHERE age > ?", [27])
System.print("Users older than 27:")
for (user in olderUsers) {
System.print(" %(user["name"]) (age %(user["age"]))")
}
System.print("\n--- Single Result Query ---")
var singleUser = db.query("SELECT * FROM users WHERE name = ?", ["Alice"])
if (singleUser.count > 0) {
System.print("Found Alice: %(singleUser[0]["email"])")
}
System.print("\n--- Aggregate Query ---")
var avgAge = db.query("SELECT AVG(age) as avg_age, COUNT(*) as count FROM users")
System.print("Average age: %(avgAge[0]["avg_age"])")
System.print("Total users: %(avgAge[0]["count"])")
System.print("\n--- Updating Data ---")
db.execute("UPDATE users SET age = ? WHERE name = ?", [31, "Alice"])
System.print("Rows updated: %(db.changes)")
var updated = db.query("SELECT age FROM users WHERE name = 'Alice'")
System.print("Alice's new age: %(updated[0]["age"])")
System.print("\n--- Deleting Data ---")
db.execute("DELETE FROM users WHERE name = ?", ["Charlie"])
System.print("Rows deleted: %(db.changes)")
System.print("\n--- Remaining Users ---")
var remaining = db.query("SELECT name FROM users ORDER BY name")
System.print("Users: %(remaining)")
System.print("\n--- Creating Another Table ---")
db.execute("CREATE TABLE orders (id INTEGER PRIMARY KEY, user_id INTEGER, product TEXT, amount REAL)")
db.execute("INSERT INTO orders (user_id, product, amount) VALUES (1, 'Widget', 19.99)")
db.execute("INSERT INTO orders (user_id, product, amount) VALUES (1, 'Gadget', 29.99)")
db.execute("INSERT INTO orders (user_id, product, amount) VALUES (2, 'Widget', 19.99)")
System.print("\n--- Join Query ---")
var ordersWithUsers = db.query("SELECT u.name, o.product, o.amount FROM users u JOIN orders o ON u.id = o.user_id")
System.print("Orders with user names:")
for (row in ordersWithUsers) {
System.print(" %(row["name"]) ordered %(row["product"]) for $%(row["amount"])")
}
System.print("\n--- Transaction Example ---")
db.execute("BEGIN TRANSACTION")
db.execute("INSERT INTO users (name, email, age) VALUES (?, ?, ?)", ["Eve", "eve@example.com", 22])
db.execute("INSERT INTO users (name, email, age) VALUES (?, ?, ?)", ["Frank", "frank@example.com", 45])
db.execute("COMMIT")
System.print("Transaction committed")
var afterTransaction = db.query("SELECT COUNT(*) as count FROM users")
System.print("Total users after transaction: %(afterTransaction[0]["count"])")
System.print("\n--- Closing Database ---")
db.close()
System.print("Database closed")
System.print("\n--- File-based Database Example ---")
var fileDb = Database.open("/tmp/wren_demo.db")
fileDb.execute("CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT)")
fileDb.execute("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", ["version", "1.0.0"])
fileDb.execute("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", ["theme", "dark"])
var settings = fileDb.query("SELECT * FROM settings")
System.print("Settings:")
for (s in settings) {
System.print(" %(s["key"]) = %(s["value"])")
}
fileDb.close()
System.print("File database closed")
System.print("Database saved to: /tmp/wren_demo.db")
+70
View File
@@ -0,0 +1,70 @@
// retoor <retoor@molodetz.nl>
import "subprocess" for Subprocess, ProcessResult
System.print("=== Subprocess Module Demo ===\n")
System.print("--- Running Shell Commands ---")
var result = Subprocess.run("echo 'Hello from subprocess!'")
System.print("stdout: %(result.stdout.trim())")
System.print("exit code: %(result.exitCode)")
System.print("success: %(result.success)")
System.print("\n--- Running with Arguments List ---")
var lsResult = Subprocess.run(["/bin/ls", "-la", "/tmp"])
System.print("Directory listing (first 200 chars):")
var output = lsResult.stdout
if (output.count > 200) output = output[0...200] + "..."
System.print(output)
System.print("\n--- Getting Current Directory ---")
var pwdResult = Subprocess.run("pwd")
System.print("Current directory: %(pwdResult.stdout.trim())")
System.print("\n--- Environment Variables ---")
var envResult = Subprocess.run("echo $USER@$HOSTNAME")
System.print("User info: %(envResult.stdout.trim())")
System.print("\n--- Piped Commands ---")
var pipeResult = Subprocess.run("echo 'apple\nbanana\ncherry' | sort -r")
System.print("Sorted output:")
System.print(pipeResult.stdout)
System.print("--- Command with Stderr ---")
var errResult = Subprocess.run("ls /nonexistent_directory_12345 2>&1")
System.print("Output: %(errResult.stdout.trim())")
System.print("Exit code: %(errResult.exitCode)")
System.print("Success: %(errResult.success)")
System.print("\n--- Capturing Both Stdout and Stderr ---")
var mixedResult = Subprocess.run("echo 'stdout message' && echo 'stderr message' >&2")
System.print("stdout: %(mixedResult.stdout.trim())")
System.print("stderr: %(mixedResult.stderr.trim())")
System.print("\n--- Running Python (if available) ---")
var pyResult = Subprocess.run("python3 -c \"print('Hello from Python!')\" 2>/dev/null || echo 'Python not available'")
System.print("Python: %(pyResult.stdout.trim())")
System.print("\n--- Getting System Info ---")
var unameResult = Subprocess.run("uname -a")
System.print("System: %(unameResult.stdout.trim())")
System.print("\n--- Date and Time ---")
var dateResult = Subprocess.run("date '+\%Y-\%m-\%d \%H:\%M:\%S'")
System.print("Current time: %(dateResult.stdout.trim())")
System.print("\n--- Checking Exit Codes ---")
var trueResult = Subprocess.run("true")
var falseResult = Subprocess.run("false")
System.print("'true' exit code: %(trueResult.exitCode)")
System.print("'false' exit code: %(falseResult.exitCode)")
System.print("\n--- Practical Example: Git Status ---")
var gitResult = Subprocess.run("git status --short 2>/dev/null || echo 'Not a git repository'")
System.print("Git status:")
var gitOutput = gitResult.stdout.trim()
if (gitOutput.count == 0) {
System.print(" (clean working directory)")
} else {
System.print(gitOutput)
}
+49
View File
@@ -0,0 +1,49 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket
import "scheduler" for Scheduler
import "timer" for Timer
import "io" for Stdin
var host = "ws://127.0.0.1:8080"
System.print("=== WebSocket Chat Client ===")
System.print("Connecting to %(host)...")
var ws = WebSocket.connect(host)
System.print("Connected!")
System.print("Commands: /name <name>, /who, /quit")
System.print("Type a message and press Enter to send.\n")
var running = true
Scheduler.add {
while (running && ws.isOpen) {
var msg = ws.receive()
if (msg == null || msg.isClose) {
running = false
System.print("\nConnection closed.")
break
}
if (msg.isText) {
System.print(msg.text)
}
}
}
Timer.sleep(100)
while (running && ws.isOpen) {
System.write("> ")
var line = Stdin.readLine()
if (line == null || line == "/quit") {
running = false
break
}
if (line.count > 0) {
ws.send(line)
}
}
ws.close()
System.print("Disconnected.")
+95
View File
@@ -0,0 +1,95 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket, WebSocketServer
import "scheduler" for Scheduler
import "timer" for Timer
var port = 8080
var clients = []
var clientId = 0
System.print("=== WebSocket Chat Server ===")
System.print("Listening on ws://0.0.0.0:%(port)")
System.print("Clients can send messages that get broadcast to all others.\n")
var broadcast = Fn.new { |sender, message|
var i = 0
while (i < clients.count) {
var client = clients[i]
if (client["ws"].isOpen && client["id"] != sender) {
client["ws"].send(message)
}
i = i + 1
}
}
var removeClient = Fn.new { |id|
var i = 0
while (i < clients.count) {
if (clients[i]["id"] == id) {
clients.removeAt(i)
break
}
i = i + 1
}
}
var handleClient = Fn.new { |ws, id|
var client = {"ws": ws, "id": id, "name": "User%(id)"}
clients.add(client)
System.print("[%(client["name"])] Connected (%(clients.count) clients online)")
broadcast.call(id, "*** %(client["name"]) joined the chat ***")
while (ws.isOpen) {
var msg = ws.receive()
if (msg == null || msg.isClose) {
break
}
if (msg.isText) {
var text = msg.text
if (text.startsWith("/name ")) {
var oldName = client["name"]
client["name"] = text[6..-1]
broadcast.call(-1, "*** %(oldName) is now known as %(client["name"]) ***")
ws.send("Name changed to %(client["name"])")
} else if (text == "/who") {
var names = []
for (c in clients) {
names.add(c["name"])
}
ws.send("Online: " + names.join(", "))
} else if (text == "/quit") {
ws.send("Goodbye!")
break
} else {
var chatMsg = "[%(client["name"])]: %(text)"
System.print(chatMsg)
broadcast.call(id, chatMsg)
ws.send(chatMsg)
}
}
}
removeClient.call(id)
System.print("[%(client["name"])] Disconnected (%(clients.count) clients online)")
broadcast.call(id, "*** %(client["name"]) left the chat ***")
}
var server = WebSocketServer.bind("0.0.0.0", port)
while (true) {
var ws = server.accept()
if (ws != null) {
clientId = clientId + 1
var id = clientId
Scheduler.add {
handleClient.call(ws, id)
}
}
}
+69
View File
@@ -0,0 +1,69 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket, WebSocketServer
import "scheduler" for Scheduler
import "timer" for Timer
var port = 8080
var clientCount = 0
var messageCount = 0
System.print("=== Concurrent WebSocket Server ===")
System.print("Listening on ws://0.0.0.0:%(port)")
System.print("Each client connection runs in its own fiber.\n")
var server = WebSocketServer.bind("0.0.0.0", port)
var handleClient = Fn.new { |ws, clientId|
System.print("[Client %(clientId)] Connected")
while (ws.isOpen) {
var msg = ws.receive()
if (msg == null) {
System.print("[Client %(clientId)] Connection lost")
break
}
if (msg.isClose) {
System.print("[Client %(clientId)] Sent close frame")
break
}
if (msg.isText) {
messageCount = messageCount + 1
var text = msg.text
System.print("[Client %(clientId)] Received: %(text) (total messages: %(messageCount))")
if (text == "ping") {
ws.send("pong")
} else if (text == "stats") {
ws.send("clients: %(clientCount), messages: %(messageCount)")
} else if (text == "broadcast") {
ws.send("broadcast not implemented in this example")
} else {
ws.send("echo: %(text)")
}
} else if (msg.isBinary) {
messageCount = messageCount + 1
System.print("[Client %(clientId)] Received binary: %(msg.bytes.count) bytes")
ws.sendBinary(msg.bytes)
}
}
clientCount = clientCount - 1
System.print("[Client %(clientId)] Disconnected (%(clientCount) clients remaining)")
}
while (true) {
var ws = server.accept()
if (ws != null) {
clientCount = clientCount + 1
var clientId = clientCount
Scheduler.add {
handleClient.call(ws, clientId)
}
}
}
+23
View File
@@ -0,0 +1,23 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket
System.print("=== WebSocket Client Demo ===\n")
System.print("Connecting to ws://127.0.0.1:8080...")
var ws = WebSocket.connect("ws://127.0.0.1:8080")
System.print("Connected\n")
System.print("--- Sending Text Message ---")
ws.send("Hello WebSocket!")
var msg = ws.receive()
System.print("Received: %(msg.text)")
System.print("\n--- Sending Binary Message ---")
ws.sendBinary([72, 101, 108, 108, 111])
msg = ws.receive()
System.print("Received bytes: %(msg.bytes)")
System.print("\n--- Closing Connection ---")
ws.close(1000, "Client closing")
System.print("Connection closed")
+91
View File
@@ -0,0 +1,91 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocket
import "io" for Stdout
var host = "ws://127.0.0.1:8080"
var totalMessages = 50000
var warmupMessages = 100
System.print("=== WebSocket Extreme Load Test ===")
System.print("Target: %(host)")
System.print("Messages: %(totalMessages) (warmup: %(warmupMessages))")
System.print("")
Stdout.flush()
var ws = WebSocket.connect(host)
System.print("Connected")
Stdout.flush()
var i = 0
while (i < warmupMessages) {
ws.send("warmup%(i)")
ws.receive()
i = i + 1
}
System.print("Warmup complete")
Stdout.flush()
var errors = 0
var minTime = 999999
var maxTime = 0
var totalTime = 0
var times = []
var startTime = System.clock
i = 0
while (i < totalMessages) {
var msgStart = System.clock
ws.send("msg%(i)")
var response = ws.receive()
var msgEnd = System.clock
var elapsed = msgEnd - msgStart
if (response == null || !response.isText) {
errors = errors + 1
} else {
times.add(elapsed)
totalTime = totalTime + elapsed
if (elapsed < minTime) minTime = elapsed
if (elapsed > maxTime) maxTime = elapsed
}
if (i > 0 && i % 2000 == 0) {
var progress = (i * 100 / totalMessages).floor
var currentRate = i / (System.clock - startTime)
System.print(" Progress: %(progress) percent (%(currentRate.floor) msg/sec)")
Stdout.flush()
}
i = i + 1
}
var endTime = System.clock
var totalElapsed = endTime - startTime
ws.close()
times.sort()
var p50 = times[(times.count * 0.5).floor]
var p90 = times[(times.count * 0.9).floor]
var p95 = times[(times.count * 0.95).floor]
var p99 = times[(times.count * 0.99).floor]
var avgTime = totalTime / times.count
System.print("")
System.print("=== Results ===")
System.print("Total messages: %(totalMessages)")
System.print("Errors: %(errors)")
System.print("Total time: %(totalElapsed)s")
System.print("Throughput: %((totalMessages / totalElapsed).floor) msg/sec")
System.print("")
System.print("=== Latency (per message round-trip) ===")
System.print("Min: %((minTime * 1000000).floor) us")
System.print("Max: %((maxTime * 1000000).floor) us")
System.print("Avg: %((avgTime * 1000000).floor) us")
System.print("P50: %((p50 * 1000000).floor) us")
System.print("P90: %((p90 * 1000000).floor) us")
System.print("P95: %((p95 * 1000000).floor) us")
System.print("P99: %((p99 * 1000000).floor) us")
Stdout.flush()
+44
View File
@@ -0,0 +1,44 @@
// retoor <retoor@molodetz.nl>
import "websocket" for WebSocketServer
System.print("=== WebSocket Server Demo ===")
System.print("Listening on ws://0.0.0.0:8080\n")
var server = WebSocketServer.bind("0.0.0.0", 8080)
while (true) {
System.print("Waiting for connection...")
var ws = server.accept()
if (ws == null) {
System.print("Failed to accept connection")
continue
}
System.print("Client connected")
while (ws.isOpen) {
var msg = ws.receive()
if (msg == null) {
System.print("Connection lost")
break
}
if (msg.isClose) {
System.print("Client sent close frame (code: %(msg.closeCode))")
break
}
if (msg.isText) {
System.print("Received text: %(msg.text)")
ws.send("Echo: %(msg.text)")
} else if (msg.isBinary) {
System.print("Received binary: %(msg.bytes.count) bytes")
ws.sendBinary(msg.bytes)
}
}
System.print("Client disconnected\n")
}