@shd101wyy/yo 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/cjs/index.cjs +1 -1
- package/out/cjs/yo-cli.cjs +685 -588
- package/out/esm/index.mjs +1 -1
- package/out/types/src/doc/render-html.d.ts +5 -1
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/build-site.ts +37 -0
- package/std/build.yo +8 -4
- package/std/encoding/base64.yo +7 -4
- package/std/encoding/hex.yo +7 -4
- package/std/encoding/html.yo +7 -4
- package/std/encoding/json.yo +9 -6
- package/std/encoding/punycode.yo +9 -6
- package/std/encoding/toml.yo +7 -4
- package/std/encoding/utf16.yo +7 -4
- package/std/fs/dir.yo +16 -13
- package/std/fs/file.yo +19 -16
- package/std/http/client.yo +12 -6
package/package.json
CHANGED
package/scripts/build-site.ts
CHANGED
|
@@ -75,6 +75,42 @@ function escapeHtml(s: string): string {
|
|
|
75
75
|
* - `https://shd101wyy.github.io/Yo/` → `std/index.html` (relative, same site)
|
|
76
76
|
* - `#anchor` links → kept as-is
|
|
77
77
|
*/
|
|
78
|
+
/**
|
|
79
|
+
* Generate a GitHub-compatible slug from heading text.
|
|
80
|
+
* - Strip HTML tags
|
|
81
|
+
* - Lowercase
|
|
82
|
+
* - Replace spaces with hyphens
|
|
83
|
+
* - Remove non-alphanumeric characters (except hyphens)
|
|
84
|
+
*/
|
|
85
|
+
function slugify(text: string): string {
|
|
86
|
+
return text
|
|
87
|
+
.replace(/<[^>]+>/g, "") // strip HTML tags
|
|
88
|
+
.trim()
|
|
89
|
+
.toLowerCase()
|
|
90
|
+
.replace(/\s+/g, "-")
|
|
91
|
+
.replace(/[^a-z0-9-]/g, "")
|
|
92
|
+
.replace(/-+/g, "-")
|
|
93
|
+
.replace(/^-|-$/g, "");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Add `id` attributes to heading elements so that #anchor links work.
|
|
98
|
+
* Handles duplicate slugs by appending `-1`, `-2`, etc.
|
|
99
|
+
*/
|
|
100
|
+
function injectHeadingIds(html: string): string {
|
|
101
|
+
const slugCounts = new Map<string, number>();
|
|
102
|
+
return html.replace(
|
|
103
|
+
/<(h[1-6])>([\s\S]*?)<\/\1>/gi,
|
|
104
|
+
(_match: string, tag: string, content: string) => {
|
|
105
|
+
let slug = slugify(content);
|
|
106
|
+
const count = slugCounts.get(slug) ?? 0;
|
|
107
|
+
slugCounts.set(slug, count + 1);
|
|
108
|
+
if (count > 0) slug = `${slug}-${count}`;
|
|
109
|
+
return `<${tag} id="${slug}">${content}</${tag}>`;
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
78
114
|
function rewriteReadmeLinks(html: string): string {
|
|
79
115
|
// Rewrite the generated docs link to relative std/ path (same site)
|
|
80
116
|
html = html.replace(
|
|
@@ -383,6 +419,7 @@ async function main(): Promise<void> {
|
|
|
383
419
|
});
|
|
384
420
|
|
|
385
421
|
let readmeHtml = md.render(readmeSrc);
|
|
422
|
+
readmeHtml = injectHeadingIds(readmeHtml);
|
|
386
423
|
readmeHtml = rewriteReadmeLinks(readmeHtml);
|
|
387
424
|
|
|
388
425
|
const css = generateHomepageCSS();
|
package/std/build.yo
CHANGED
|
@@ -18,13 +18,17 @@
|
|
|
18
18
|
|
|
19
19
|
/// Optimization level for compiled artifacts.
|
|
20
20
|
Optimize :: enum(
|
|
21
|
-
/// No optimizations, full debug info.
|
|
21
|
+
/// No optimizations, full debug info.
|
|
22
|
+
/// Compiler Flags: `-O0 -g`
|
|
22
23
|
Debug,
|
|
23
|
-
/// Optimized with safety checks.
|
|
24
|
+
/// Optimized with safety checks.
|
|
25
|
+
/// Compiler Flags: `-O2 -g`
|
|
24
26
|
ReleaseSafe,
|
|
25
|
-
/// Maximum speed optimizations.
|
|
27
|
+
/// Maximum speed optimizations.
|
|
28
|
+
/// Compiler Flags: `-O3`
|
|
26
29
|
ReleaseFast,
|
|
27
|
-
/// Optimize for binary size.
|
|
30
|
+
/// Optimize for binary size.
|
|
31
|
+
/// Compiler Flags `-O2`
|
|
28
32
|
ReleaseSmall
|
|
29
33
|
);
|
|
30
34
|
export Optimize;
|
package/std/encoding/base64.yo
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
//! Base64 encoding and decoding (RFC 4648) with standard and URL-safe variants.
|
|
2
2
|
//!
|
|
3
|
-
//! Example
|
|
4
|
-
//! { base64_encode, base64_decode } :: import "std/encoding/base64";
|
|
3
|
+
//! # Example
|
|
5
4
|
//!
|
|
6
|
-
//!
|
|
7
|
-
//!
|
|
5
|
+
//! ```rust
|
|
6
|
+
//! { base64_encode, base64_decode } :: import "std/encoding/base64";
|
|
7
|
+
//!
|
|
8
|
+
//! s := base64_encode(data);
|
|
9
|
+
//! b := base64_decode(s.to_str()).unwrap();
|
|
10
|
+
//! ```
|
|
8
11
|
|
|
9
12
|
open import "../string";
|
|
10
13
|
{ ArrayList } :: import "../collections/array_list";
|
package/std/encoding/hex.yo
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Converts between raw bytes (`ArrayList(u8)`) and hex strings.
|
|
4
4
|
//!
|
|
5
|
-
//! Example
|
|
6
|
-
//! { hex_encode, hex_decode } :: import "std/encoding/hex";
|
|
5
|
+
//! # Example
|
|
7
6
|
//!
|
|
8
|
-
//!
|
|
9
|
-
//!
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { hex_encode, hex_decode } :: import "std/encoding/hex";
|
|
9
|
+
//!
|
|
10
|
+
//! s := hex_encode(data); // "deadbeef"
|
|
11
|
+
//! b := hex_decode("deadbeef");
|
|
12
|
+
//! ```
|
|
10
13
|
|
|
11
14
|
open import "../string";
|
|
12
15
|
{ ArrayList } :: import "../collections/array_list";
|
package/std/encoding/html.yo
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
//! Decodes named (&), decimal (&), and hex (&) HTML character references.
|
|
4
4
|
//! Uses Legacy mode — entities without trailing semicolon are also decoded.
|
|
5
5
|
//!
|
|
6
|
-
//! Example
|
|
7
|
-
//! { decode_html } :: import "std/encoding/html";
|
|
6
|
+
//! # Example
|
|
8
7
|
//!
|
|
9
|
-
//!
|
|
10
|
-
//!
|
|
8
|
+
//! ```rust
|
|
9
|
+
//! { decode_html } :: import "std/encoding/html";
|
|
10
|
+
//!
|
|
11
|
+
//! result := decode_html(`& < & &`);
|
|
12
|
+
//! assert((result == `& < & &`), "decoded entities");
|
|
13
|
+
//! ```
|
|
11
14
|
|
|
12
15
|
open import "../string";
|
|
13
16
|
{ HashMap } :: import "../collections/hash_map";
|
package/std/encoding/json.yo
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Provides a dynamically-typed JSON value tree.
|
|
4
4
|
//!
|
|
5
|
-
//! Example
|
|
6
|
-
//! { json_parse, json_stringify, JsonValue } :: import "std/encoding/json";
|
|
7
|
-
//! { Exception } :: import "std/error";
|
|
5
|
+
//! # Example
|
|
8
6
|
//!
|
|
9
|
-
//!
|
|
10
|
-
//!
|
|
11
|
-
//!
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { json_parse, json_stringify, JsonValue } :: import "std/encoding/json";
|
|
9
|
+
//! { Exception } :: import "std/error";
|
|
10
|
+
//!
|
|
11
|
+
//! given(exn) := Exception(throw : ((err) -> { escape (); }));
|
|
12
|
+
//! v := json_parse(`{"x": 1}`);
|
|
13
|
+
//! println(json_stringify(v));
|
|
14
|
+
//! ```
|
|
12
15
|
|
|
13
16
|
open import "../string";
|
|
14
17
|
{ ArrayList } :: import "../collections/array_list";
|
package/std/encoding/punycode.yo
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Provides punycode encoding/decoding and IDN hostname conversion.
|
|
4
4
|
//!
|
|
5
|
-
//! Example
|
|
6
|
-
//! { punycode_decode, punycode_encode, to_unicode, to_ascii } :: import "std/encoding/punycode";
|
|
5
|
+
//! # Example
|
|
7
6
|
//!
|
|
8
|
-
//!
|
|
9
|
-
//!
|
|
10
|
-
//!
|
|
11
|
-
//!
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { punycode_decode, punycode_encode, to_unicode, to_ascii } :: import "std/encoding/punycode";
|
|
9
|
+
//!
|
|
10
|
+
//! encoded := punycode_encode(`München`);
|
|
11
|
+
//! decoded := punycode_decode(encoded);
|
|
12
|
+
//! ascii_domain := to_ascii(`münchen.de`); // "xn--mnchen-3ya.de"
|
|
13
|
+
//! unicode_domain := to_unicode(ascii_domain); // "münchen.de"
|
|
14
|
+
//! ```
|
|
12
15
|
|
|
13
16
|
open import "../string";
|
|
14
17
|
{ ArrayList } :: import "../collections/array_list";
|
package/std/encoding/toml.yo
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
//! Parses a subset of TOML into a `TomlValue` tree.
|
|
4
4
|
//! Supports: strings, integers, booleans, table sections, comments.
|
|
5
5
|
//!
|
|
6
|
-
//! Example
|
|
7
|
-
//!
|
|
8
|
-
//!
|
|
9
|
-
//!
|
|
6
|
+
//! # Example
|
|
7
|
+
//!
|
|
8
|
+
//! ```rust
|
|
9
|
+
//! { toml_parse, TomlValue } :: import "std/encoding/toml";
|
|
10
|
+
//! // Or via the encoding index:
|
|
11
|
+
//! { toml_parse, TomlValue } :: import "std/encoding";
|
|
12
|
+
//! ```
|
|
10
13
|
|
|
11
14
|
open import "../string";
|
|
12
15
|
{ ArrayList } :: import "../collections/array_list";
|
package/std/encoding/utf16.yo
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Converts between Yo's UTF-8 `str` and UTF-16 code units (`ArrayList(u16)`).
|
|
4
4
|
//!
|
|
5
|
-
//! Example
|
|
6
|
-
//! { utf8_to_utf16, utf16_to_utf8 } :: import "std/encoding/utf16";
|
|
5
|
+
//! # Example
|
|
7
6
|
//!
|
|
8
|
-
//!
|
|
9
|
-
//!
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { utf8_to_utf16, utf16_to_utf8 } :: import "std/encoding/utf16";
|
|
9
|
+
//!
|
|
10
|
+
//! words := utf8_to_utf16("hello");
|
|
11
|
+
//! s := utf16_to_utf8(words);
|
|
12
|
+
//! ```
|
|
10
13
|
|
|
11
14
|
open import "../string";
|
|
12
15
|
{ ArrayList } :: import "../collections/array_list";
|
package/std/fs/dir.yo
CHANGED
|
@@ -2,21 +2,24 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Wraps low-level `std/sys/dir` with typed APIs using the `Exception` effect.
|
|
4
4
|
//!
|
|
5
|
-
//! Example
|
|
6
|
-
//! { create_dir, remove_dir, read_dir } :: import "std/fs/dir";
|
|
7
|
-
//! { Path } :: import "std/path";
|
|
5
|
+
//! # Example
|
|
8
6
|
//!
|
|
9
|
-
//!
|
|
10
|
-
//!
|
|
11
|
-
//!
|
|
12
|
-
//! { println(error.to_string()); exit(i32(1)); }
|
|
13
|
-
//! )
|
|
14
|
-
//! };
|
|
7
|
+
//! ```rust
|
|
8
|
+
//! { create_dir, remove_dir, read_dir } :: import "std/fs/dir";
|
|
9
|
+
//! { Path } :: import "std/path";
|
|
15
10
|
//!
|
|
16
|
-
//!
|
|
17
|
-
//!
|
|
18
|
-
//!
|
|
19
|
-
//!
|
|
11
|
+
//! main :: (fn(using(io : IO)) -> unit)({
|
|
12
|
+
//! given(exn) : Exception = {
|
|
13
|
+
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
14
|
+
//! { println(error.to_string()); exit(i32(1)); }
|
|
15
|
+
//! )
|
|
16
|
+
//! };
|
|
17
|
+
//!
|
|
18
|
+
//! io.await(create_dir(Path.new(`/tmp/yo_test`)));
|
|
19
|
+
//! entries := io.await(read_dir(Path.new(`/tmp/yo_test`)));
|
|
20
|
+
//! io.await(remove_dir(Path.new(`/tmp/yo_test`)));
|
|
21
|
+
//! });
|
|
22
|
+
//! ```
|
|
20
23
|
|
|
21
24
|
{ GlobalAllocator } :: import "../allocator";
|
|
22
25
|
{ malloc, free } :: GlobalAllocator;
|
package/std/fs/file.yo
CHANGED
|
@@ -3,26 +3,29 @@
|
|
|
3
3
|
//! Wraps a file descriptor with typed async I/O operations.
|
|
4
4
|
//! Uses the `Exception` effect for error handling.
|
|
5
5
|
//!
|
|
6
|
-
//! Example
|
|
7
|
-
//! { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
6
|
+
//! # Example
|
|
8
7
|
//!
|
|
9
|
-
//!
|
|
10
|
-
//!
|
|
11
|
-
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
12
|
-
//! { println(error); panic("Exception found."); }
|
|
13
|
-
//! )
|
|
14
|
-
//! );
|
|
8
|
+
//! ```rust
|
|
9
|
+
//! { File, read_string, write_file, OpenMode } :: import "std/fs/file";
|
|
15
10
|
//!
|
|
16
|
-
//!
|
|
17
|
-
//!
|
|
11
|
+
//! main :: (fn(using(io : IO)) -> unit)({
|
|
12
|
+
//! given(exn) := Exception(
|
|
13
|
+
//! throw : (fn(forall(T : Type), error: AnyError) -> T)(
|
|
14
|
+
//! { println(error); panic("Exception found."); }
|
|
15
|
+
//! )
|
|
16
|
+
//! );
|
|
18
17
|
//!
|
|
19
|
-
//!
|
|
20
|
-
//!
|
|
21
|
-
//! println(content);
|
|
18
|
+
//! // Write a file
|
|
19
|
+
//! io.await(write_file(Path.new(`test.txt`), `hello world`));
|
|
22
20
|
//!
|
|
23
|
-
//!
|
|
24
|
-
//!
|
|
25
|
-
//!
|
|
21
|
+
//! // Read it back
|
|
22
|
+
//! content := io.await(read_string(Path.new(`test.txt`)));
|
|
23
|
+
//! println(content);
|
|
24
|
+
//!
|
|
25
|
+
//! // Open with OpenMode
|
|
26
|
+
//! f := io.await(File.open(Path.new(`test.txt`), .Read));
|
|
27
|
+
//! });
|
|
28
|
+
//! ```
|
|
26
29
|
|
|
27
30
|
{ GlobalAllocator } :: import "../allocator";
|
|
28
31
|
{ malloc, free } :: GlobalAllocator;
|
package/std/http/client.yo
CHANGED
|
@@ -245,9 +245,12 @@ _read_http_response :: (fn(stream: TcpStream, using(io : IO, exn : Exception)) -
|
|
|
245
245
|
|
|
246
246
|
/// Perform an HTTP request with custom options.
|
|
247
247
|
///
|
|
248
|
-
/// Example
|
|
249
|
-
///
|
|
250
|
-
///
|
|
248
|
+
/// # Example
|
|
249
|
+
///
|
|
250
|
+
/// ```rust
|
|
251
|
+
/// opts := FetchOptions.new().with_method(.POST).with_body(`{"key": "value"}`);
|
|
252
|
+
/// resp := io.await(fetch_with(`http://example.com/api`, opts, using(io)));
|
|
253
|
+
/// ```
|
|
251
254
|
fetch_with :: (fn(url_str: String, opts: FetchOptions, using(io : IO)) ->
|
|
252
255
|
Impl(Future(HttpResponse, IO, Exception))
|
|
253
256
|
)(
|
|
@@ -359,9 +362,12 @@ export fetch_with;
|
|
|
359
362
|
/// Perform an HTTP GET request to the given URL string.
|
|
360
363
|
/// Returns the `HttpResponse` on success.
|
|
361
364
|
///
|
|
362
|
-
/// Example
|
|
363
|
-
///
|
|
364
|
-
///
|
|
365
|
+
/// # Example
|
|
366
|
+
///
|
|
367
|
+
/// ```rust
|
|
368
|
+
/// resp := io.await(fetch(`http://example.com`, using(io)));
|
|
369
|
+
/// cond(resp.is_ok() => println(resp.body), true => println(`Error`));
|
|
370
|
+
/// ```
|
|
365
371
|
fetch :: (fn(url_str: String, using(io : IO)) ->
|
|
366
372
|
Impl(Future(HttpResponse, IO, Exception))
|
|
367
373
|
)(
|