1#[derive(Debug, Clone)]
5pub struct LuaFunction {
6 pub name: &'static str,
7 pub module: Option<&'static str>,
8 pub description: &'static str,
9 pub params: &'static [LuaParam],
10 pub returns: &'static str,
11}
12
13#[derive(Debug, Clone)]
15pub struct LuaParam {
16 pub name: &'static str,
17 pub typ: &'static str,
18 pub description: &'static str,
19 pub optional: bool,
20}
21
22#[derive(Debug, Clone)]
24pub struct LuaClass {
25 pub name: &'static str,
26 pub description: &'static str,
27 pub fields: &'static [LuaField],
28}
29
30#[derive(Debug, Clone)]
32pub struct LuaField {
33 pub name: &'static str,
34 pub typ: &'static str,
35 pub description: &'static str,
36}
37
38pub static LUA_CLASSES: &[LuaClass] = &[
43 LuaClass {
44 name: "FileInfo",
45 description: "File metadata",
46 fields: &[
47 LuaField {
48 name: "path",
49 typ: "string",
50 description: "Absolute path",
51 },
52 LuaField {
53 name: "name",
54 typ: "string",
55 description: "Full filename with extension",
56 },
57 LuaField {
58 name: "stem",
59 typ: "string",
60 description: "Filename without extension",
61 },
62 LuaField {
63 name: "ext",
64 typ: "string",
65 description: "File extension",
66 },
67 LuaField {
68 name: "is_dir",
69 typ: "boolean",
70 description: "Whether this is a directory",
71 },
72 LuaField {
73 name: "modified",
74 typ: "number|nil",
75 description: "Unix timestamp of last modification",
76 },
77 ],
78 },
79 LuaClass {
80 name: "FrontmatterResult",
81 description: "Result of reading frontmatter from a file. Frontmatter fields are merged to top level.",
82 fields: &[
83 LuaField {
84 name: "raw",
85 typ: "string",
86 description: "Original file content",
87 },
88 LuaField {
89 name: "content",
90 typ: "string",
91 description: "Content after frontmatter",
92 },
93 LuaField {
94 name: "title",
95 typ: "string?",
96 description: "Common frontmatter field",
97 },
98 LuaField {
99 name: "description",
100 typ: "string?",
101 description: "Common frontmatter field",
102 },
103 LuaField {
104 name: "date",
105 typ: "string?",
106 description: "Common frontmatter field",
107 },
108 LuaField {
109 name: "template",
110 typ: "string?",
111 description: "Common frontmatter field",
112 },
113 LuaField {
114 name: "[string]",
115 typ: "string|number|boolean|table|any[]",
116 description: "Additional frontmatter fields (supports nested values)",
117 },
118 ],
119 },
120 LuaClass {
121 name: "GitInfo",
122 description: "Git repository information",
123 fields: &[
124 LuaField {
125 name: "hash",
126 typ: "string",
127 description: "Full commit hash",
128 },
129 LuaField {
130 name: "short_hash",
131 typ: "string",
132 description: "Short hash (7 chars)",
133 },
134 LuaField {
135 name: "branch",
136 typ: "string|nil",
137 description: "Current branch name",
138 },
139 LuaField {
140 name: "author",
141 typ: "string|nil",
142 description: "Commit author",
143 },
144 LuaField {
145 name: "date",
146 typ: "string|nil",
147 description: "Commit date (YYYY-MM-DD)",
148 },
149 LuaField {
150 name: "dirty",
151 typ: "boolean",
152 description: "Has uncommitted changes",
153 },
154 ],
155 },
156 LuaClass {
157 name: "ImageDimensions",
158 description: "Image dimensions",
159 fields: &[
160 LuaField {
161 name: "width",
162 typ: "number",
163 description: "Image width in pixels",
164 },
165 LuaField {
166 name: "height",
167 typ: "number",
168 description: "Image height in pixels",
169 },
170 ],
171 },
172 LuaClass {
173 name: "ImageResizeOptions",
174 description: "Options for image_resize",
175 fields: &[
176 LuaField {
177 name: "width",
178 typ: "number",
179 description: "Target width in pixels",
180 },
181 LuaField {
182 name: "height",
183 typ: "number?",
184 description: "Target height (maintains aspect ratio if omitted)",
185 },
186 LuaField {
187 name: "quality",
188 typ: "number?",
189 description: "Quality 0-100 for lossy formats (default: 85)",
190 },
191 ],
192 },
193 LuaClass {
194 name: "ImageConvertOptions",
195 description: "Options for image_convert",
196 fields: &[
197 LuaField {
198 name: "format",
199 typ: "string?",
200 description: "Target format: 'webp'|'png'|'jpg' (default: from extension)",
201 },
202 LuaField {
203 name: "quality",
204 typ: "number?",
205 description: "Quality 0-100 for lossy formats (default: 85)",
206 },
207 ],
208 },
209 LuaClass {
210 name: "ImageOptimizeOptions",
211 description: "Options for image_optimize",
212 fields: &[LuaField {
213 name: "quality",
214 typ: "number?",
215 description: "Quality 0-100 (default: 85)",
216 }],
217 },
218 LuaClass {
219 name: "BuildCssOptions",
220 description: "Options for build_css",
221 fields: &[LuaField {
222 name: "minify",
223 typ: "boolean?",
224 description: "Minify output CSS (default: false)",
225 }],
226 },
227 LuaClass {
228 name: "BuildJsOptions",
229 description: "Options for build_js",
230 fields: &[LuaField {
231 name: "minify",
232 typ: "boolean?",
233 description: "Minify output JS with dead code elimination (default: false)",
234 }],
235 },
236 LuaClass {
237 name: "GoogleFontOptions",
238 description: "Options for download_google_font",
239 fields: &[
240 LuaField {
241 name: "fonts_dir",
242 typ: "string",
243 description: "Directory to save font files (required)",
244 },
245 LuaField {
246 name: "css_path",
247 typ: "string",
248 description: "Path to save CSS file (required)",
249 },
250 LuaField {
251 name: "css_prefix",
252 typ: "string?",
253 description: "URL prefix for fonts in CSS (default: '/fonts')",
254 },
255 LuaField {
256 name: "weights",
257 typ: "number[]?",
258 description: "Font weights to download (default: {400})",
259 },
260 LuaField {
261 name: "display",
262 typ: "string?",
263 description: "Font display strategy: 'swap'|'block'|'fallback'|'optional' (default: 'swap')",
264 },
265 LuaField {
266 name: "cache",
267 typ: "boolean|string?",
268 description: "Enable caching: true (auto), string (explicit path), false (disabled). Default: true",
269 },
270 LuaField {
271 name: "minify",
272 typ: "boolean?",
273 description: "Minify CSS output (default: true)",
274 },
275 ],
276 },
277 LuaClass {
278 name: "MarkdownEvent",
279 description: "Markdown AST event for transformation",
280 fields: &[
281 LuaField {
282 name: "type",
283 typ: "string",
284 description: "Event type: 'text'|'html'|'code'|'start'|'end'|'softbreak'|'hardbreak'|'rule'",
285 },
286 LuaField {
287 name: "content",
288 typ: "string|nil",
289 description: "Text/HTML/code content",
290 },
291 LuaField {
292 name: "tag",
293 typ: "string|nil",
294 description: "Tag name for start/end events",
295 },
296 LuaField {
297 name: "level",
298 typ: "number|nil",
299 description: "Heading level (1-6)",
300 },
301 LuaField {
302 name: "url",
303 typ: "string|nil",
304 description: "Link/image URL",
305 },
306 LuaField {
307 name: "title",
308 typ: "string|nil",
309 description: "Link/image title",
310 },
311 ],
312 },
313 LuaClass {
314 name: "MarkdownContext",
315 description: "Context information during markdown parsing",
316 fields: &[
317 LuaField {
318 name: "in_paragraph",
319 typ: "boolean",
320 description: "Inside paragraph",
321 },
322 LuaField {
323 name: "in_heading",
324 typ: "boolean",
325 description: "Inside heading",
326 },
327 LuaField {
328 name: "in_list",
329 typ: "boolean",
330 description: "Inside list",
331 },
332 LuaField {
333 name: "in_list_item",
334 typ: "boolean",
335 description: "Inside list item",
336 },
337 LuaField {
338 name: "in_blockquote",
339 typ: "boolean",
340 description: "Inside blockquote",
341 },
342 LuaField {
343 name: "in_link",
344 typ: "boolean",
345 description: "Inside link",
346 },
347 LuaField {
348 name: "in_emphasis",
349 typ: "boolean",
350 description: "Inside emphasis",
351 },
352 LuaField {
353 name: "in_strong",
354 typ: "boolean",
355 description: "Inside strong",
356 },
357 LuaField {
358 name: "in_code_block",
359 typ: "boolean",
360 description: "Inside code block",
361 },
362 LuaField {
363 name: "in_table",
364 typ: "boolean",
365 description: "Inside table",
366 },
367 LuaField {
368 name: "heading_level",
369 typ: "number",
370 description: "Current heading level (0 if not in heading)",
371 },
372 LuaField {
373 name: "list_depth",
374 typ: "number",
375 description: "Nesting depth of lists",
376 },
377 ],
378 },
379 LuaClass {
380 name: "CoroTask",
381 description: "Coroutine task wrapper for cooperative multitasking",
382 fields: &[
383 LuaField {
384 name: "_co",
385 typ: "thread",
386 description: "Internal coroutine",
387 },
388 LuaField {
389 name: "_completed",
390 typ: "boolean",
391 description: "Whether task has completed",
392 },
393 LuaField {
394 name: "_result",
395 typ: "any",
396 description: "Task result",
397 },
398 ],
399 },
400 LuaClass {
401 name: "AsyncTask",
402 description: "Async fetch task handle (await with rs.async.await)",
403 fields: &[LuaField {
404 name: "is_completed",
405 typ: "fun(): boolean",
406 description: "Check if task has completed",
407 }],
408 },
409 LuaClass {
410 name: "AsyncBytesTask",
411 description: "Async bytes fetch task handle (await with rs.async.await)",
412 fields: &[LuaField {
413 name: "is_completed",
414 typ: "fun(): boolean",
415 description: "Check if task has completed",
416 }],
417 },
418 LuaClass {
419 name: "AsyncIOTask",
420 description: "Async I/O task handle (await with rs.async.await)",
421 fields: &[LuaField {
422 name: "is_completed",
423 typ: "fun(): boolean",
424 description: "Check if task has completed",
425 }],
426 },
427 LuaClass {
428 name: "FetchResponse",
429 description: "HTTP response from async.fetch",
430 fields: &[
431 LuaField {
432 name: "status",
433 typ: "number",
434 description: "HTTP status code",
435 },
436 LuaField {
437 name: "ok",
438 typ: "boolean",
439 description: "Whether request was successful (2xx)",
440 },
441 LuaField {
442 name: "body",
443 typ: "string",
444 description: "Response body as string",
445 },
446 LuaField {
447 name: "headers",
448 typ: "table<string, string>",
449 description: "Response headers",
450 },
451 LuaField {
452 name: "json",
453 typ: "fun(): table",
454 description: "Parse body as JSON",
455 },
456 ],
457 },
458 LuaClass {
459 name: "FetchOptions",
460 description: "Options for async.fetch",
461 fields: &[
462 LuaField {
463 name: "method",
464 typ: "string?",
465 description: "HTTP method: GET|POST|PUT|DELETE|PATCH|HEAD (default: GET)",
466 },
467 LuaField {
468 name: "headers",
469 typ: "table<string, string>?",
470 description: "Request headers",
471 },
472 LuaField {
473 name: "body",
474 typ: "string|table?",
475 description: "Request body (table will be JSON encoded)",
476 },
477 LuaField {
478 name: "timeout",
479 typ: "number?",
480 description: "Timeout in seconds",
481 },
482 LuaField {
483 name: "cache",
484 typ: "boolean|string?",
485 description: "Enable caching: true (auto), string (path), false (disabled)",
486 },
487 ],
488 },
489 LuaClass {
490 name: "EncryptedData",
491 description: "Encrypted content data from crypt.encrypt",
492 fields: &[
493 LuaField {
494 name: "ciphertext",
495 typ: "string",
496 description: "Base64-encoded encrypted content",
497 },
498 LuaField {
499 name: "salt",
500 typ: "string",
501 description: "Base64-encoded salt for key derivation",
502 },
503 LuaField {
504 name: "nonce",
505 typ: "string",
506 description: "Base64-encoded nonce for decryption",
507 },
508 ],
509 },
510 LuaClass {
511 name: "EncryptHtmlOptions",
512 description: "Options for crypt.encrypt_html",
513 fields: &[
514 LuaField {
515 name: "password",
516 typ: "string?",
517 description: "Encryption password (uses SITE_PASSWORD env if not provided)",
518 },
519 LuaField {
520 name: "slug",
521 typ: "string?",
522 description: "Page slug for localStorage key (default: 'page')",
523 },
524 LuaField {
525 name: "block_id",
526 typ: "string?",
527 description: "Unique block ID (auto-generated if not provided)",
528 },
529 LuaField {
530 name: "own_password",
531 typ: "boolean?",
532 description: "Whether block has its own password (default: false)",
533 },
534 ],
535 },
536 LuaClass {
537 name: "DirEntry",
538 description: "Directory entry from async.read_dir",
539 fields: &[
540 LuaField {
541 name: "path",
542 typ: "string",
543 description: "Full path to the entry",
544 },
545 LuaField {
546 name: "name",
547 typ: "string",
548 description: "Entry name (filename or directory name)",
549 },
550 LuaField {
551 name: "is_file",
552 typ: "boolean",
553 description: "Whether this is a file",
554 },
555 LuaField {
556 name: "is_dir",
557 typ: "boolean",
558 description: "Whether this is a directory",
559 },
560 LuaField {
561 name: "is_symlink",
562 typ: "boolean",
563 description: "Whether this is a symbolic link",
564 },
565 ],
566 },
567 LuaClass {
568 name: "FileMetadata",
569 description: "File metadata from async.metadata",
570 fields: &[
571 LuaField {
572 name: "is_file",
573 typ: "boolean",
574 description: "Whether this is a file",
575 },
576 LuaField {
577 name: "is_dir",
578 typ: "boolean",
579 description: "Whether this is a directory",
580 },
581 LuaField {
582 name: "len",
583 typ: "number",
584 description: "File size in bytes",
585 },
586 LuaField {
587 name: "readonly",
588 typ: "boolean",
589 description: "Whether file is read-only",
590 },
591 LuaField {
592 name: "modified",
593 typ: "number?",
594 description: "Unix timestamp of last modification",
595 },
596 ],
597 },
598 LuaClass {
599 name: "DateTable",
600 description: "Date as table with year, month, day fields",
601 fields: &[
602 LuaField {
603 name: "year",
604 typ: "number",
605 description: "Year (e.g., 2024)",
606 },
607 LuaField {
608 name: "month",
609 typ: "number",
610 description: "Month (1-12)",
611 },
612 LuaField {
613 name: "day",
614 typ: "number",
615 description: "Day of month (1-31)",
616 },
617 ],
618 },
619];
620
621pub static LUA_FUNCTIONS: &[LuaFunction] = &[
626 LuaFunction {
628 name: "read_file",
629 module: None,
630 description: "Read file contents as string",
631 params: &[LuaParam {
632 name: "path",
633 typ: "string",
634 description: "Path to file",
635 optional: false,
636 }],
637 returns: "string|nil",
638 },
639 LuaFunction {
640 name: "write_file",
641 module: None,
642 description: "Write content to file",
643 params: &[
644 LuaParam {
645 name: "path",
646 typ: "string",
647 description: "Path to write to",
648 optional: false,
649 },
650 LuaParam {
651 name: "content",
652 typ: "string",
653 description: "Content to write",
654 optional: false,
655 },
656 ],
657 returns: "boolean",
658 },
659 LuaFunction {
660 name: "copy_file",
661 module: None,
662 description: "Copy a file (works with binary files)",
663 params: &[
664 LuaParam {
665 name: "src",
666 typ: "string",
667 description: "Source file path",
668 optional: false,
669 },
670 LuaParam {
671 name: "dest",
672 typ: "string",
673 description: "Destination file path",
674 optional: false,
675 },
676 ],
677 returns: "boolean",
678 },
679 LuaFunction {
680 name: "file_exists",
681 module: None,
682 description: "Check if file exists",
683 params: &[LuaParam {
684 name: "path",
685 typ: "string",
686 description: "Path to check",
687 optional: false,
688 }],
689 returns: "boolean",
690 },
691 LuaFunction {
692 name: "list_files",
693 module: None,
694 description: "List files in directory matching pattern",
695 params: &[
696 LuaParam {
697 name: "path",
698 typ: "string",
699 description: "Directory to search",
700 optional: false,
701 },
702 LuaParam {
703 name: "pattern",
704 typ: "string",
705 description: "Glob pattern (default: '*')",
706 optional: true,
707 },
708 ],
709 returns: "FileInfo[]",
710 },
711 LuaFunction {
712 name: "list_dirs",
713 module: None,
714 description: "List subdirectories",
715 params: &[LuaParam {
716 name: "path",
717 typ: "string",
718 description: "Directory to search",
719 optional: false,
720 }],
721 returns: "string[]",
722 },
723 LuaFunction {
724 name: "load_json",
725 module: None,
726 description: "Load and parse JSON file",
727 params: &[LuaParam {
728 name: "path",
729 typ: "string",
730 description: "Path to JSON file",
731 optional: false,
732 }],
733 returns: "table<string, any>|nil",
734 },
735 LuaFunction {
736 name: "load_yaml",
737 module: None,
738 description: "Load and parse YAML file",
739 params: &[LuaParam {
740 name: "path",
741 typ: "string",
742 description: "Path to YAML file",
743 optional: false,
744 }],
745 returns: "table<string, any>|nil",
746 },
747 LuaFunction {
748 name: "load_toml",
749 module: None,
750 description: "Load and parse TOML file",
751 params: &[LuaParam {
752 name: "path",
753 typ: "string",
754 description: "Path to TOML file",
755 optional: false,
756 }],
757 returns: "table<string, any>|nil",
758 },
759 LuaFunction {
760 name: "read_frontmatter",
761 module: None,
762 description: "Read and parse frontmatter from markdown file",
763 params: &[LuaParam {
764 name: "path",
765 typ: "string",
766 description: "Path to markdown file",
767 optional: false,
768 }],
769 returns: "FrontmatterResult|nil",
770 },
771 LuaFunction {
773 name: "glob",
774 module: None,
775 description: "Find files matching glob pattern",
776 params: &[LuaParam {
777 name: "pattern",
778 typ: "string",
779 description: "Glob pattern (e.g., '**/*.md')",
780 optional: false,
781 }],
782 returns: "FileInfo[]",
783 },
784 LuaFunction {
785 name: "scan",
786 module: None,
787 description: "List directories in path",
788 params: &[LuaParam {
789 name: "path",
790 typ: "string",
791 description: "Directory to scan",
792 optional: false,
793 }],
794 returns: "FileInfo[]",
795 },
796 LuaFunction {
798 name: "filter",
799 module: None,
800 description: "Filter items using predicate function",
801 params: &[
802 LuaParam {
803 name: "items",
804 typ: "T[]",
805 description: "Items to filter",
806 optional: false,
807 },
808 LuaParam {
809 name: "fn",
810 typ: "fun(item: T): boolean",
811 description: "Predicate function",
812 optional: false,
813 },
814 ],
815 returns: "T[]",
816 },
817 LuaFunction {
818 name: "sort",
819 module: None,
820 description: "Sort items using comparator function",
821 params: &[
822 LuaParam {
823 name: "items",
824 typ: "T[]",
825 description: "Items to sort",
826 optional: false,
827 },
828 LuaParam {
829 name: "fn",
830 typ: "fun(a: T, b: T): boolean",
831 description: "Comparator (return true if a < b)",
832 optional: false,
833 },
834 ],
835 returns: "T[]",
836 },
837 LuaFunction {
838 name: "map",
839 module: None,
840 description: "Transform items using mapping function",
841 params: &[
842 LuaParam {
843 name: "items",
844 typ: "T[]",
845 description: "Items to transform",
846 optional: false,
847 },
848 LuaParam {
849 name: "fn",
850 typ: "fun(item: T): U",
851 description: "Mapping function",
852 optional: false,
853 },
854 ],
855 returns: "U[]",
856 },
857 LuaFunction {
858 name: "find",
859 module: None,
860 description: "Find first item where predicate returns true",
861 params: &[
862 LuaParam {
863 name: "items",
864 typ: "T[]",
865 description: "Items to search",
866 optional: false,
867 },
868 LuaParam {
869 name: "fn",
870 typ: "fun(item: T): boolean",
871 description: "Predicate function",
872 optional: false,
873 },
874 ],
875 returns: "T|nil",
876 },
877 LuaFunction {
878 name: "group_by",
879 module: None,
880 description: "Group items by key returned by key function",
881 params: &[
882 LuaParam {
883 name: "items",
884 typ: "T[]",
885 description: "Items to group",
886 optional: false,
887 },
888 LuaParam {
889 name: "fn",
890 typ: "fun(item: T): string",
891 description: "Key function",
892 optional: false,
893 },
894 ],
895 returns: "table<string, T[]>",
896 },
897 LuaFunction {
898 name: "unique",
899 module: None,
900 description: "Remove duplicates from array",
901 params: &[LuaParam {
902 name: "items",
903 typ: "T[]",
904 description: "Items to deduplicate",
905 optional: false,
906 }],
907 returns: "T[]",
908 },
909 LuaFunction {
910 name: "reverse",
911 module: None,
912 description: "Reverse array order",
913 params: &[LuaParam {
914 name: "items",
915 typ: "T[]",
916 description: "Items to reverse",
917 optional: false,
918 }],
919 returns: "T[]",
920 },
921 LuaFunction {
922 name: "take",
923 module: None,
924 description: "Take first n items from array",
925 params: &[
926 LuaParam {
927 name: "items",
928 typ: "T[]",
929 description: "Items to take from",
930 optional: false,
931 },
932 LuaParam {
933 name: "n",
934 typ: "number",
935 description: "Number of items to take",
936 optional: false,
937 },
938 ],
939 returns: "T[]",
940 },
941 LuaFunction {
942 name: "skip",
943 module: None,
944 description: "Skip first n items from array",
945 params: &[
946 LuaParam {
947 name: "items",
948 typ: "T[]",
949 description: "Items to skip from",
950 optional: false,
951 },
952 LuaParam {
953 name: "n",
954 typ: "number",
955 description: "Number of items to skip",
956 optional: false,
957 },
958 ],
959 returns: "T[]",
960 },
961 LuaFunction {
962 name: "keys",
963 module: None,
964 description: "Get all keys from a table",
965 params: &[LuaParam {
966 name: "table",
967 typ: "table<K, V>",
968 description: "Table to get keys from",
969 optional: false,
970 }],
971 returns: "K[]",
972 },
973 LuaFunction {
974 name: "values",
975 module: None,
976 description: "Get all values from a table",
977 params: &[LuaParam {
978 name: "table",
979 typ: "table<K, V>",
980 description: "Table to get values from",
981 optional: false,
982 }],
983 returns: "V[]",
984 },
985 LuaFunction {
987 name: "slugify",
988 module: None,
989 description: "Convert text to URL-friendly slug",
990 params: &[LuaParam {
991 name: "text",
992 typ: "string",
993 description: "Text to slugify",
994 optional: false,
995 }],
996 returns: "string",
997 },
998 LuaFunction {
999 name: "word_count",
1000 module: None,
1001 description: "Count words in text",
1002 params: &[LuaParam {
1003 name: "text",
1004 typ: "string",
1005 description: "Text to count",
1006 optional: false,
1007 }],
1008 returns: "number",
1009 },
1010 LuaFunction {
1011 name: "reading_time",
1012 module: None,
1013 description: "Calculate reading time in minutes",
1014 params: &[
1015 LuaParam {
1016 name: "text",
1017 typ: "string",
1018 description: "Text to analyze",
1019 optional: false,
1020 },
1021 LuaParam {
1022 name: "wpm",
1023 typ: "number",
1024 description: "Words per minute (default: 200)",
1025 optional: true,
1026 },
1027 ],
1028 returns: "number",
1029 },
1030 LuaFunction {
1031 name: "truncate",
1032 module: None,
1033 description: "Truncate text with optional suffix",
1034 params: &[
1035 LuaParam {
1036 name: "text",
1037 typ: "string",
1038 description: "Text to truncate",
1039 optional: false,
1040 },
1041 LuaParam {
1042 name: "len",
1043 typ: "number",
1044 description: "Maximum length",
1045 optional: false,
1046 },
1047 LuaParam {
1048 name: "suffix",
1049 typ: "string",
1050 description: "Suffix to append (default: '...')",
1051 optional: true,
1052 },
1053 ],
1054 returns: "string",
1055 },
1056 LuaFunction {
1057 name: "strip_tags",
1058 module: None,
1059 description: "Remove HTML tags from string",
1060 params: &[LuaParam {
1061 name: "html",
1062 typ: "string",
1063 description: "HTML content",
1064 optional: false,
1065 }],
1066 returns: "string",
1067 },
1068 LuaFunction {
1069 name: "format_date",
1070 module: None,
1071 description: "Format a date string",
1072 params: &[
1073 LuaParam {
1074 name: "date",
1075 typ: "string|DateTable",
1076 description: "Date string (YYYY-MM-DD) or table {year, month, day}",
1077 optional: false,
1078 },
1079 LuaParam {
1080 name: "format",
1081 typ: "string",
1082 description: "Output format (chrono strftime)",
1083 optional: false,
1084 },
1085 ],
1086 returns: "string|nil",
1087 },
1088 LuaFunction {
1089 name: "parse_date",
1090 module: None,
1091 description: "Parse date string to table",
1092 params: &[LuaParam {
1093 name: "date_str",
1094 typ: "string",
1095 description: "Date string to parse",
1096 optional: false,
1097 }],
1098 returns: "DateTable|nil",
1099 },
1100 LuaFunction {
1101 name: "hash",
1102 module: None,
1103 description: "Hash content using xxHash64",
1104 params: &[LuaParam {
1105 name: "content",
1106 typ: "string",
1107 description: "Content to hash",
1108 optional: false,
1109 }],
1110 returns: "string",
1111 },
1112 LuaFunction {
1113 name: "hash_file",
1114 module: None,
1115 description: "Hash file contents using xxHash64",
1116 params: &[LuaParam {
1117 name: "path",
1118 typ: "string",
1119 description: "Path to file",
1120 optional: false,
1121 }],
1122 returns: "string|nil",
1123 },
1124 LuaFunction {
1125 name: "url_encode",
1126 module: None,
1127 description: "URL encode a string",
1128 params: &[LuaParam {
1129 name: "text",
1130 typ: "string",
1131 description: "Text to encode",
1132 optional: false,
1133 }],
1134 returns: "string",
1135 },
1136 LuaFunction {
1137 name: "url_decode",
1138 module: None,
1139 description: "URL decode a string",
1140 params: &[LuaParam {
1141 name: "text",
1142 typ: "string",
1143 description: "Text to decode",
1144 optional: false,
1145 }],
1146 returns: "string",
1147 },
1148 LuaFunction {
1150 name: "join_path",
1151 module: None,
1152 description: "Join path segments",
1153 params: &[LuaParam {
1154 name: "...",
1155 typ: "string",
1156 description: "Path segments to join",
1157 optional: false,
1158 }],
1159 returns: "string",
1160 },
1161 LuaFunction {
1162 name: "basename",
1163 module: None,
1164 description: "Get file name from path",
1165 params: &[LuaParam {
1166 name: "path",
1167 typ: "string",
1168 description: "File path",
1169 optional: false,
1170 }],
1171 returns: "string",
1172 },
1173 LuaFunction {
1174 name: "dirname",
1175 module: None,
1176 description: "Get directory from path",
1177 params: &[LuaParam {
1178 name: "path",
1179 typ: "string",
1180 description: "File path",
1181 optional: false,
1182 }],
1183 returns: "string",
1184 },
1185 LuaFunction {
1186 name: "extension",
1187 module: None,
1188 description: "Get file extension from path",
1189 params: &[LuaParam {
1190 name: "path",
1191 typ: "string",
1192 description: "File path",
1193 optional: false,
1194 }],
1195 returns: "string",
1196 },
1197 LuaFunction {
1199 name: "env",
1200 module: None,
1201 description: "Get environment variable",
1202 params: &[LuaParam {
1203 name: "name",
1204 typ: "string",
1205 description: "Variable name",
1206 optional: false,
1207 }],
1208 returns: "string|nil",
1209 },
1210 LuaFunction {
1211 name: "print",
1212 module: None,
1213 description: "Log message to build output",
1214 params: &[LuaParam {
1215 name: "...",
1216 typ: "any",
1217 description: "Values to print",
1218 optional: false,
1219 }],
1220 returns: "nil",
1221 },
1222 LuaFunction {
1223 name: "is_gitignored",
1224 module: None,
1225 description: "Check if path is gitignored",
1226 params: &[LuaParam {
1227 name: "path",
1228 typ: "string",
1229 description: "Path to check",
1230 optional: false,
1231 }],
1232 returns: "boolean",
1233 },
1234 LuaFunction {
1236 name: "git_info",
1237 module: None,
1238 description: "Get git information for repo or file",
1239 params: &[LuaParam {
1240 name: "path",
1241 typ: "string",
1242 description: "File/directory path (default: repo root)",
1243 optional: true,
1244 }],
1245 returns: "GitInfo|nil",
1246 },
1247 LuaFunction {
1249 name: "render_markdown",
1250 module: None,
1251 description: "Render markdown to HTML with optional AST transformation",
1252 params: &[
1253 LuaParam {
1254 name: "content",
1255 typ: "string",
1256 description: "Markdown content",
1257 optional: false,
1258 },
1259 LuaParam {
1260 name: "transform_fn",
1261 typ: "fun(event: MarkdownEvent, ctx: MarkdownContext): MarkdownEvent|nil",
1262 description: "Optional transform function",
1263 optional: true,
1264 },
1265 ],
1266 returns: "string",
1267 },
1268 LuaFunction {
1269 name: "rss_date",
1270 module: None,
1271 description: "Format date for RSS (RFC 2822)",
1272 params: &[LuaParam {
1273 name: "date_string",
1274 typ: "string",
1275 description: "Date string (YYYY-MM-DD)",
1276 optional: false,
1277 }],
1278 returns: "string|nil",
1279 },
1280 LuaFunction {
1281 name: "extract_links_markdown",
1282 module: None,
1283 description: "Extract links from markdown content",
1284 params: &[LuaParam {
1285 name: "content",
1286 typ: "string",
1287 description: "Markdown content",
1288 optional: false,
1289 }],
1290 returns: "string[]",
1291 },
1292 LuaFunction {
1293 name: "extract_links_html",
1294 module: None,
1295 description: "Extract links from HTML content",
1296 params: &[LuaParam {
1297 name: "content",
1298 typ: "string",
1299 description: "HTML content",
1300 optional: false,
1301 }],
1302 returns: "string[]",
1303 },
1304 LuaFunction {
1305 name: "extract_images_markdown",
1306 module: None,
1307 description: "Extract image paths from markdown",
1308 params: &[LuaParam {
1309 name: "content",
1310 typ: "string",
1311 description: "Markdown content",
1312 optional: false,
1313 }],
1314 returns: "string[]",
1315 },
1316 LuaFunction {
1317 name: "extract_images_html",
1318 module: None,
1319 description: "Extract image paths from HTML",
1320 params: &[LuaParam {
1321 name: "content",
1322 typ: "string",
1323 description: "HTML content",
1324 optional: false,
1325 }],
1326 returns: "string[]",
1327 },
1328 LuaFunction {
1329 name: "html_to_text",
1330 module: None,
1331 description: "Convert HTML to formatted plain text",
1332 params: &[LuaParam {
1333 name: "html",
1334 typ: "string",
1335 description: "HTML content",
1336 optional: false,
1337 }],
1338 returns: "string",
1339 },
1340 LuaFunction {
1342 name: "build_css",
1343 module: None,
1344 description: "Build and concatenate CSS files from glob pattern or array of paths (async)",
1345 params: &[
1346 LuaParam {
1347 name: "paths_or_pattern",
1348 typ: "string|string[]",
1349 description: "Glob pattern (e.g., 'styles/*.css') or array of file paths",
1350 optional: false,
1351 },
1352 LuaParam {
1353 name: "output_path",
1354 typ: "string",
1355 description: "Output file path",
1356 optional: false,
1357 },
1358 LuaParam {
1359 name: "options",
1360 typ: "BuildCssOptions",
1361 description: "Build options (minify)",
1362 optional: true,
1363 },
1364 ],
1365 returns: "AsyncIOTask",
1366 },
1367 LuaFunction {
1368 name: "build_js",
1369 module: None,
1370 description: "Build and concatenate JS files with minification and dead code elimination (async)",
1371 params: &[
1372 LuaParam {
1373 name: "paths_or_pattern",
1374 typ: "string|string[]",
1375 description: "Glob pattern (e.g., 'scripts/*.js') or array of file paths",
1376 optional: false,
1377 },
1378 LuaParam {
1379 name: "output_path",
1380 typ: "string",
1381 description: "Output file path",
1382 optional: false,
1383 },
1384 LuaParam {
1385 name: "options",
1386 typ: "BuildJsOptions",
1387 description: "Build options (minify)",
1388 optional: true,
1389 },
1390 ],
1391 returns: "AsyncIOTask",
1392 },
1393 LuaFunction {
1394 name: "check_unused_assets",
1395 module: None,
1396 description: "Find assets in output directory not referenced by any HTML file",
1397 params: &[LuaParam {
1398 name: "output_dir",
1399 typ: "string",
1400 description: "Output directory to check",
1401 optional: false,
1402 }],
1403 returns: "string[]",
1404 },
1405 LuaFunction {
1406 name: "download_google_font",
1407 module: None,
1408 description: "Download Google Font files and generate local CSS (async, returns handle)",
1409 params: &[
1410 LuaParam {
1411 name: "family",
1412 typ: "string",
1413 description: "Font family name (e.g., 'Lexend', 'Open Sans')",
1414 optional: false,
1415 },
1416 LuaParam {
1417 name: "options",
1418 typ: "GoogleFontOptions",
1419 description: "Font options (fonts_dir, css_path required)",
1420 optional: false,
1421 },
1422 ],
1423 returns: "AsyncIOTask",
1424 },
1425 LuaFunction {
1427 name: "image_dimensions",
1428 module: None,
1429 description: "Get image dimensions",
1430 params: &[LuaParam {
1431 name: "path",
1432 typ: "string",
1433 description: "Path to image",
1434 optional: false,
1435 }],
1436 returns: "ImageDimensions|nil",
1437 },
1438 LuaFunction {
1439 name: "image_resize",
1440 module: None,
1441 description: "Resize image",
1442 params: &[
1443 LuaParam {
1444 name: "input",
1445 typ: "string",
1446 description: "Input image path",
1447 optional: false,
1448 },
1449 LuaParam {
1450 name: "output",
1451 typ: "string",
1452 description: "Output image path",
1453 optional: false,
1454 },
1455 LuaParam {
1456 name: "options",
1457 typ: "ImageResizeOptions",
1458 description: "Resize options (width required, height/quality optional)",
1459 optional: false,
1460 },
1461 ],
1462 returns: "boolean",
1463 },
1464 LuaFunction {
1465 name: "image_convert",
1466 module: None,
1467 description: "Convert image format",
1468 params: &[
1469 LuaParam {
1470 name: "input",
1471 typ: "string",
1472 description: "Input image path",
1473 optional: false,
1474 },
1475 LuaParam {
1476 name: "output",
1477 typ: "string",
1478 description: "Output image path",
1479 optional: false,
1480 },
1481 LuaParam {
1482 name: "options",
1483 typ: "ImageConvertOptions",
1484 description: "Convert options (format/quality)",
1485 optional: true,
1486 },
1487 ],
1488 returns: "boolean",
1489 },
1490 LuaFunction {
1491 name: "image_optimize",
1492 module: None,
1493 description: "Optimize/compress image",
1494 params: &[
1495 LuaParam {
1496 name: "input",
1497 typ: "string",
1498 description: "Input image path",
1499 optional: false,
1500 },
1501 LuaParam {
1502 name: "output",
1503 typ: "string",
1504 description: "Output image path",
1505 optional: false,
1506 },
1507 LuaParam {
1508 name: "options",
1509 typ: "ImageOptimizeOptions",
1510 description: "Optimize options (quality)",
1511 optional: true,
1512 },
1513 ],
1514 returns: "boolean",
1515 },
1516 LuaFunction {
1518 name: "task",
1519 module: Some("coro"),
1520 description: "Create coroutine task from function",
1521 params: &[LuaParam {
1522 name: "fn",
1523 typ: "function",
1524 description: "Function to wrap",
1525 optional: false,
1526 }],
1527 returns: "CoroTask",
1528 },
1529 LuaFunction {
1530 name: "await",
1531 module: Some("coro"),
1532 description: "Run task to completion",
1533 params: &[LuaParam {
1534 name: "task",
1535 typ: "CoroTask",
1536 description: "Task to run",
1537 optional: false,
1538 }],
1539 returns: "any",
1540 },
1541 LuaFunction {
1542 name: "yield",
1543 module: Some("coro"),
1544 description: "Yield from current task",
1545 params: &[LuaParam {
1546 name: "value",
1547 typ: "any",
1548 description: "Value to yield",
1549 optional: true,
1550 }],
1551 returns: "any",
1552 },
1553 LuaFunction {
1554 name: "all",
1555 module: Some("coro"),
1556 description: "Run multiple tasks concurrently",
1557 params: &[LuaParam {
1558 name: "tasks",
1559 typ: "CoroTask[]",
1560 description: "Tasks to run",
1561 optional: false,
1562 }],
1563 returns: "any[]",
1564 },
1565 LuaFunction {
1566 name: "race",
1567 module: Some("coro"),
1568 description: "Run tasks and return first completed",
1569 params: &[LuaParam {
1570 name: "tasks",
1571 typ: "CoroTask[]",
1572 description: "Tasks to race",
1573 optional: false,
1574 }],
1575 returns: "any",
1576 },
1577 LuaFunction {
1578 name: "sleep",
1579 module: Some("coro"),
1580 description: "Sleep/delay (yields N times for cooperative scheduling)",
1581 params: &[LuaParam {
1582 name: "n",
1583 typ: "number",
1584 description: "Number of yields",
1585 optional: true,
1586 }],
1587 returns: "nil",
1588 },
1589 LuaFunction {
1591 name: "load_json",
1592 module: Some("parallel"),
1593 description: "Load multiple JSON files in parallel",
1594 params: &[LuaParam {
1595 name: "paths",
1596 typ: "string[]",
1597 description: "Paths to load",
1598 optional: false,
1599 }],
1600 returns: "(table<string, any>|nil)[]",
1601 },
1602 LuaFunction {
1603 name: "read_files",
1604 module: Some("parallel"),
1605 description: "Read multiple files in parallel",
1606 params: &[LuaParam {
1607 name: "paths",
1608 typ: "string[]",
1609 description: "Paths to read",
1610 optional: false,
1611 }],
1612 returns: "(string|nil)[]",
1613 },
1614 LuaFunction {
1615 name: "file_exists",
1616 module: Some("parallel"),
1617 description: "Check multiple files exist in parallel",
1618 params: &[LuaParam {
1619 name: "paths",
1620 typ: "string[]",
1621 description: "Paths to check",
1622 optional: false,
1623 }],
1624 returns: "boolean[]",
1625 },
1626 LuaFunction {
1627 name: "load_yaml",
1628 module: Some("parallel"),
1629 description: "Load multiple YAML files in parallel",
1630 params: &[LuaParam {
1631 name: "paths",
1632 typ: "string[]",
1633 description: "Paths to load",
1634 optional: false,
1635 }],
1636 returns: "(table<string, any>|nil)[]",
1637 },
1638 LuaFunction {
1639 name: "read_frontmatter",
1640 module: Some("parallel"),
1641 description: "Parse frontmatter from multiple files in parallel",
1642 params: &[LuaParam {
1643 name: "paths",
1644 typ: "string[]",
1645 description: "Paths to parse",
1646 optional: false,
1647 }],
1648 returns: "(FrontmatterResult|nil)[]",
1649 },
1650 LuaFunction {
1651 name: "map",
1652 module: Some("parallel"),
1653 description: "Map over items (structure for parallel-ready code)",
1654 params: &[
1655 LuaParam {
1656 name: "items",
1657 typ: "T[]",
1658 description: "Items to map",
1659 optional: false,
1660 },
1661 LuaParam {
1662 name: "fn",
1663 typ: "fun(item: T): U",
1664 description: "Mapping function",
1665 optional: false,
1666 },
1667 ],
1668 returns: "U[]",
1669 },
1670 LuaFunction {
1671 name: "filter",
1672 module: Some("parallel"),
1673 description: "Filter items using predicate",
1674 params: &[
1675 LuaParam {
1676 name: "items",
1677 typ: "T[]",
1678 description: "Items to filter",
1679 optional: false,
1680 },
1681 LuaParam {
1682 name: "fn",
1683 typ: "fun(item: T): boolean",
1684 description: "Predicate function",
1685 optional: false,
1686 },
1687 ],
1688 returns: "T[]",
1689 },
1690 LuaFunction {
1691 name: "reduce",
1692 module: Some("parallel"),
1693 description: "Reduce items to single value",
1694 params: &[
1695 LuaParam {
1696 name: "items",
1697 typ: "T[]",
1698 description: "Items to reduce",
1699 optional: false,
1700 },
1701 LuaParam {
1702 name: "initial",
1703 typ: "U",
1704 description: "Initial accumulator value",
1705 optional: false,
1706 },
1707 LuaParam {
1708 name: "fn",
1709 typ: "fun(acc: U, item: T): U",
1710 description: "Reducer function",
1711 optional: false,
1712 },
1713 ],
1714 returns: "U",
1715 },
1716 LuaFunction {
1717 name: "create_dirs",
1718 module: Some("parallel"),
1719 description: "Create multiple directories in parallel",
1720 params: &[LuaParam {
1721 name: "paths",
1722 typ: "string[]",
1723 description: "Directory paths to create",
1724 optional: false,
1725 }],
1726 returns: "(boolean|string)[]",
1727 },
1728 LuaFunction {
1729 name: "copy_files",
1730 module: Some("parallel"),
1731 description: "Copy multiple files in parallel",
1732 params: &[
1733 LuaParam {
1734 name: "sources",
1735 typ: "string[]",
1736 description: "Source file paths",
1737 optional: false,
1738 },
1739 LuaParam {
1740 name: "destinations",
1741 typ: "string[]",
1742 description: "Destination file paths",
1743 optional: false,
1744 },
1745 ],
1746 returns: "(boolean|string)[]",
1747 },
1748 LuaFunction {
1749 name: "image_convert",
1750 module: Some("parallel"),
1751 description: "Convert multiple images in parallel",
1752 params: &[
1753 LuaParam {
1754 name: "sources",
1755 typ: "string[]",
1756 description: "Source image paths",
1757 optional: false,
1758 },
1759 LuaParam {
1760 name: "destinations",
1761 typ: "string[]",
1762 description: "Destination image paths",
1763 optional: false,
1764 },
1765 LuaParam {
1766 name: "options",
1767 typ: "ImageConvertOptions",
1768 description: "Convert options (quality)",
1769 optional: true,
1770 },
1771 ],
1772 returns: "(boolean|string)[]",
1773 },
1774 LuaFunction {
1776 name: "fetch",
1777 module: Some("async"),
1778 description: "Fetch URL (returns handle, await to get response)",
1779 params: &[
1780 LuaParam {
1781 name: "url",
1782 typ: "string",
1783 description: "URL to fetch",
1784 optional: false,
1785 },
1786 LuaParam {
1787 name: "options",
1788 typ: "FetchOptions",
1789 description: "Request options",
1790 optional: true,
1791 },
1792 ],
1793 returns: "AsyncTask",
1794 },
1795 LuaFunction {
1796 name: "fetch_sync",
1797 module: Some("async"),
1798 description: "Fetch URL (blocking, returns response directly)",
1799 params: &[
1800 LuaParam {
1801 name: "url",
1802 typ: "string",
1803 description: "URL to fetch",
1804 optional: false,
1805 },
1806 LuaParam {
1807 name: "options",
1808 typ: "FetchOptions",
1809 description: "Request options",
1810 optional: true,
1811 },
1812 ],
1813 returns: "FetchResponse",
1814 },
1815 LuaFunction {
1816 name: "fetch_json",
1817 module: Some("async"),
1818 description: "Fetch URL and parse as JSON",
1819 params: &[
1820 LuaParam {
1821 name: "url",
1822 typ: "string",
1823 description: "URL to fetch",
1824 optional: false,
1825 },
1826 LuaParam {
1827 name: "options",
1828 typ: "FetchOptions",
1829 description: "Request options",
1830 optional: true,
1831 },
1832 ],
1833 returns: "table",
1834 },
1835 LuaFunction {
1836 name: "fetch_all",
1837 module: Some("async"),
1838 description: "Fetch multiple URLs concurrently",
1839 params: &[LuaParam {
1840 name: "requests",
1841 typ: "(string|{url: string, options?: FetchOptions})[]",
1842 description: "URLs or request objects",
1843 optional: false,
1844 }],
1845 returns: "FetchResponse[]",
1846 },
1847 LuaFunction {
1848 name: "spawn",
1849 module: Some("async"),
1850 description: "Spawn async fetch task for later await",
1851 params: &[
1852 LuaParam {
1853 name: "url",
1854 typ: "string",
1855 description: "URL to fetch",
1856 optional: false,
1857 },
1858 LuaParam {
1859 name: "options",
1860 typ: "FetchOptions",
1861 description: "Request options",
1862 optional: true,
1863 },
1864 ],
1865 returns: "AsyncTask",
1866 },
1867 LuaFunction {
1868 name: "await",
1869 module: Some("async"),
1870 description: "Await spawned async task",
1871 params: &[LuaParam {
1872 name: "task",
1873 typ: "AsyncTask",
1874 description: "Task to await",
1875 optional: false,
1876 }],
1877 returns: "FetchResponse",
1878 },
1879 LuaFunction {
1880 name: "await_all",
1881 module: Some("async"),
1882 description: "Await multiple async tasks",
1883 params: &[LuaParam {
1884 name: "tasks",
1885 typ: "AsyncTask[]",
1886 description: "Tasks to await",
1887 optional: false,
1888 }],
1889 returns: "FetchResponse[]",
1890 },
1891 LuaFunction {
1892 name: "read_file",
1893 module: Some("async"),
1894 description: "Read file (returns handle)",
1895 params: &[LuaParam {
1896 name: "path",
1897 typ: "string",
1898 description: "File path",
1899 optional: false,
1900 }],
1901 returns: "AsyncIOTask",
1902 },
1903 LuaFunction {
1904 name: "write_file",
1905 module: Some("async"),
1906 description: "Write file (returns handle)",
1907 params: &[
1908 LuaParam {
1909 name: "path",
1910 typ: "string",
1911 description: "File path",
1912 optional: false,
1913 },
1914 LuaParam {
1915 name: "content",
1916 typ: "string",
1917 description: "Content to write",
1918 optional: false,
1919 },
1920 ],
1921 returns: "AsyncIOTask",
1922 },
1923 LuaFunction {
1924 name: "read_files",
1925 module: Some("async"),
1926 description: "Read multiple files concurrently",
1927 params: &[LuaParam {
1928 name: "paths",
1929 typ: "string[]",
1930 description: "File paths",
1931 optional: false,
1932 }],
1933 returns: "(string|nil)[]",
1934 },
1935 LuaFunction {
1936 name: "load_json",
1937 module: Some("async"),
1938 description: "Load and parse JSON file asynchronously",
1939 params: &[LuaParam {
1940 name: "path",
1941 typ: "string",
1942 description: "JSON file path",
1943 optional: false,
1944 }],
1945 returns: "table",
1946 },
1947 LuaFunction {
1948 name: "copy_file",
1949 module: Some("async"),
1950 description: "Copy file (returns handle)",
1951 params: &[
1952 LuaParam {
1953 name: "src",
1954 typ: "string",
1955 description: "Source path",
1956 optional: false,
1957 },
1958 LuaParam {
1959 name: "dst",
1960 typ: "string",
1961 description: "Destination path",
1962 optional: false,
1963 },
1964 ],
1965 returns: "AsyncIOTask",
1966 },
1967 LuaFunction {
1968 name: "rename",
1969 module: Some("async"),
1970 description: "Rename/move file or directory asynchronously",
1971 params: &[
1972 LuaParam {
1973 name: "src",
1974 typ: "string",
1975 description: "Source path",
1976 optional: false,
1977 },
1978 LuaParam {
1979 name: "dst",
1980 typ: "string",
1981 description: "Destination path",
1982 optional: false,
1983 },
1984 ],
1985 returns: "boolean",
1986 },
1987 LuaFunction {
1988 name: "create_dir",
1989 module: Some("async"),
1990 description: "Create directory including parents (returns handle)",
1991 params: &[LuaParam {
1992 name: "path",
1993 typ: "string",
1994 description: "Directory path",
1995 optional: false,
1996 }],
1997 returns: "AsyncIOTask",
1998 },
1999 LuaFunction {
2000 name: "remove_file",
2001 module: Some("async"),
2002 description: "Remove file asynchronously",
2003 params: &[LuaParam {
2004 name: "path",
2005 typ: "string",
2006 description: "File path",
2007 optional: false,
2008 }],
2009 returns: "boolean",
2010 },
2011 LuaFunction {
2012 name: "remove_dir",
2013 module: Some("async"),
2014 description: "Remove directory recursively asynchronously",
2015 params: &[LuaParam {
2016 name: "path",
2017 typ: "string",
2018 description: "Directory path",
2019 optional: false,
2020 }],
2021 returns: "boolean",
2022 },
2023 LuaFunction {
2024 name: "exists",
2025 module: Some("async"),
2026 description: "Check if file/directory exists (returns handle)",
2027 params: &[LuaParam {
2028 name: "path",
2029 typ: "string",
2030 description: "Path to check",
2031 optional: false,
2032 }],
2033 returns: "AsyncIOTask",
2034 },
2035 LuaFunction {
2036 name: "metadata",
2037 module: Some("async"),
2038 description: "Get file metadata asynchronously",
2039 params: &[LuaParam {
2040 name: "path",
2041 typ: "string",
2042 description: "File path",
2043 optional: false,
2044 }],
2045 returns: "FileMetadata",
2046 },
2047 LuaFunction {
2048 name: "read",
2049 module: Some("async"),
2050 description: "Read file as binary data asynchronously",
2051 params: &[LuaParam {
2052 name: "path",
2053 typ: "string",
2054 description: "File path",
2055 optional: false,
2056 }],
2057 returns: "string",
2058 },
2059 LuaFunction {
2060 name: "write",
2061 module: Some("async"),
2062 description: "Write binary data to file (returns handle)",
2063 params: &[
2064 LuaParam {
2065 name: "path",
2066 typ: "string",
2067 description: "File path",
2068 optional: false,
2069 },
2070 LuaParam {
2071 name: "data",
2072 typ: "string",
2073 description: "Binary data to write",
2074 optional: false,
2075 },
2076 ],
2077 returns: "AsyncIOTask",
2078 },
2079 LuaFunction {
2080 name: "fetch_bytes",
2081 module: Some("async"),
2082 description: "Fetch URL binary (returns handle)",
2083 params: &[
2084 LuaParam {
2085 name: "url",
2086 typ: "string",
2087 description: "URL to fetch",
2088 optional: false,
2089 },
2090 LuaParam {
2091 name: "options",
2092 typ: "FetchOptions",
2093 description: "Request options",
2094 optional: true,
2095 },
2096 ],
2097 returns: "AsyncBytesTask",
2098 },
2099 LuaFunction {
2100 name: "read_dir",
2101 module: Some("async"),
2102 description: "List directory contents asynchronously",
2103 params: &[LuaParam {
2104 name: "path",
2105 typ: "string",
2106 description: "Directory path",
2107 optional: false,
2108 }],
2109 returns: "DirEntry[]",
2110 },
2111 LuaFunction {
2112 name: "canonicalize",
2113 module: Some("async"),
2114 description: "Get canonical/absolute path asynchronously",
2115 params: &[LuaParam {
2116 name: "path",
2117 typ: "string",
2118 description: "Path to canonicalize",
2119 optional: false,
2120 }],
2121 returns: "string",
2122 },
2123 LuaFunction {
2125 name: "encrypt",
2126 module: Some("crypt"),
2127 description: "Encrypt content using AES-256-GCM",
2128 params: &[
2129 LuaParam {
2130 name: "content",
2131 typ: "string",
2132 description: "Content to encrypt",
2133 optional: false,
2134 },
2135 LuaParam {
2136 name: "password",
2137 typ: "string",
2138 description: "Encryption password (uses SITE_PASSWORD env if not provided)",
2139 optional: true,
2140 },
2141 ],
2142 returns: "EncryptedData",
2143 },
2144 LuaFunction {
2145 name: "decrypt",
2146 module: Some("crypt"),
2147 description: "Decrypt content using AES-256-GCM",
2148 params: &[
2149 LuaParam {
2150 name: "data",
2151 typ: "EncryptedData",
2152 description: "Encrypted data table with ciphertext, salt, nonce",
2153 optional: false,
2154 },
2155 LuaParam {
2156 name: "password",
2157 typ: "string",
2158 description: "Decryption password (uses SITE_PASSWORD env if not provided)",
2159 optional: true,
2160 },
2161 ],
2162 returns: "string",
2163 },
2164 LuaFunction {
2165 name: "encrypt_html",
2166 module: Some("crypt"),
2167 description: "Encrypt content and wrap in HTML container for browser decryption",
2168 params: &[
2169 LuaParam {
2170 name: "content",
2171 typ: "string",
2172 description: "Content to encrypt (can be HTML)",
2173 optional: false,
2174 },
2175 LuaParam {
2176 name: "options",
2177 typ: "EncryptHtmlOptions",
2178 description: "Encryption options",
2179 optional: true,
2180 },
2181 ],
2182 returns: "string",
2183 },
2184];
2185
2186pub fn generate_emmylua() -> String {
2192 let mut output = String::new();
2193 output.push_str("---@meta rs-web\n\n");
2194 output.push_str("-- Auto-generated EmmyLua type definitions for rs-web\n");
2195 output.push_str("-- Generated with: rs-web types --lua\n");
2196 output.push_str("--\n");
2197 output.push_str("-- Usage:\n");
2198 output.push_str("-- local rs = require(\"rs-web\")\n");
2199 output.push_str("-- local content = rs.read_file(\"path/to/file.md\")\n");
2200 output.push_str("-- local html = rs.render_markdown(content)\n\n");
2201
2202 output.push_str(
2204 "-- =============================================================================\n",
2205 );
2206 output.push_str("-- TYPE DEFINITIONS\n");
2207 output.push_str(
2208 "-- =============================================================================\n\n",
2209 );
2210
2211 for class in LUA_CLASSES {
2212 output.push_str(&format!("---@class {}\n", class.name));
2213 for field in class.fields {
2214 output.push_str(&format!(
2215 "---@field {} {} {}\n",
2216 field.name, field.typ, field.description
2217 ));
2218 }
2219 output.push('\n');
2220 }
2221
2222 let mut global_fns: Vec<&LuaFunction> = Vec::new();
2224 let mut coro_fns: Vec<&LuaFunction> = Vec::new();
2225 let mut parallel_fns: Vec<&LuaFunction> = Vec::new();
2226 let mut async_fns: Vec<&LuaFunction> = Vec::new();
2227 let mut crypt_fns: Vec<&LuaFunction> = Vec::new();
2228
2229 for func in LUA_FUNCTIONS {
2230 match func.module {
2231 None => global_fns.push(func),
2232 Some("coro") => coro_fns.push(func),
2233 Some("parallel") => parallel_fns.push(func),
2234 Some("async") => async_fns.push(func),
2235 Some("crypt") => crypt_fns.push(func),
2236 _ => global_fns.push(func),
2237 }
2238 }
2239
2240 output.push_str(
2242 "-- =============================================================================\n",
2243 );
2244 output.push_str("-- CORO SUBMODULE\n");
2245 output.push_str(
2246 "-- =============================================================================\n\n",
2247 );
2248 output.push_str("---@class RsCoroModule\n");
2249 for func in &coro_fns {
2250 let params = func
2251 .params
2252 .iter()
2253 .map(|p| {
2254 let opt = if p.optional { "?" } else { "" };
2255 format!("{}{}: {}", p.name, opt, p.typ)
2256 })
2257 .collect::<Vec<_>>()
2258 .join(", ");
2259 output.push_str(&format!(
2260 "---@field {} fun({}): {} {}\n",
2261 func.name, params, func.returns, func.description
2262 ));
2263 }
2264 output.push('\n');
2265
2266 output.push_str(
2268 "-- =============================================================================\n",
2269 );
2270 output.push_str("-- PARALLEL SUBMODULE\n");
2271 output.push_str(
2272 "-- =============================================================================\n\n",
2273 );
2274 output.push_str("---@class RsParallelModule\n");
2275 for func in ¶llel_fns {
2276 let params = func
2277 .params
2278 .iter()
2279 .map(|p| {
2280 let opt = if p.optional { "?" } else { "" };
2281 format!("{}{}: {}", p.name, opt, p.typ)
2282 })
2283 .collect::<Vec<_>>()
2284 .join(", ");
2285 output.push_str(&format!(
2286 "---@field {} fun({}): {} {}\n",
2287 func.name, params, func.returns, func.description
2288 ));
2289 }
2290 output.push('\n');
2291
2292 output.push_str(
2294 "-- =============================================================================\n",
2295 );
2296 output.push_str("-- ASYNC SUBMODULE (tokio-backed)\n");
2297 output.push_str(
2298 "-- =============================================================================\n\n",
2299 );
2300 output.push_str("---@class RsAsyncModule\n");
2301 for func in &async_fns {
2302 let params = func
2303 .params
2304 .iter()
2305 .map(|p| {
2306 let opt = if p.optional { "?" } else { "" };
2307 format!("{}{}: {}", p.name, opt, p.typ)
2308 })
2309 .collect::<Vec<_>>()
2310 .join(", ");
2311 output.push_str(&format!(
2312 "---@field {} fun({}): {} {}\n",
2313 func.name, params, func.returns, func.description
2314 ));
2315 }
2316 output.push('\n');
2317
2318 output.push_str(
2320 "-- =============================================================================\n",
2321 );
2322 output.push_str("-- CRYPT SUBMODULE\n");
2323 output.push_str(
2324 "-- =============================================================================\n\n",
2325 );
2326 output.push_str("---@class RsCryptModule\n");
2327 for func in &crypt_fns {
2328 let params = func
2329 .params
2330 .iter()
2331 .map(|p| {
2332 let opt = if p.optional { "?" } else { "" };
2333 format!("{}{}: {}", p.name, opt, p.typ)
2334 })
2335 .collect::<Vec<_>>()
2336 .join(", ");
2337 output.push_str(&format!(
2338 "---@field {} fun({}): {} {}\n",
2339 func.name, params, func.returns, func.description
2340 ));
2341 }
2342 output.push('\n');
2343
2344 output.push_str(
2346 "-- =============================================================================\n",
2347 );
2348 output.push_str("-- RS-WEB MODULE\n");
2349 output.push_str(
2350 "-- =============================================================================\n\n",
2351 );
2352 output.push_str("---@class RsWebModule\n");
2353 output.push_str("---@field _VERSION string Module version\n");
2354 output.push_str("---@field _SANDBOX boolean Whether sandbox mode is enabled\n");
2355 output.push_str("---@field _PROJECT_ROOT string Project root directory\n");
2356 output.push_str("---@field coro RsCoroModule Coroutine helpers\n");
2357 output.push_str("---@field parallel RsParallelModule Parallel processing functions\n");
2358 output.push_str("---@field async RsAsyncModule Async I/O functions (tokio-backed)\n");
2359 output.push_str("---@field crypt RsCryptModule Encryption functions (AES-256-GCM)\n");
2360
2361 for func in &global_fns {
2363 let params = func
2364 .params
2365 .iter()
2366 .map(|p| {
2367 let opt = if p.optional { "?" } else { "" };
2368 format!("{}{}: {}", p.name, opt, p.typ)
2369 })
2370 .collect::<Vec<_>>()
2371 .join(", ");
2372 output.push_str(&format!(
2373 "---@field {} fun({}): {} {}\n",
2374 func.name, params, func.returns, func.description
2375 ));
2376 }
2377 output.push('\n');
2378
2379 output.push_str("---The rs-web module\n");
2381 output.push_str("---@type RsWebModule\n");
2382 output.push_str("local rs = {}\n\n");
2383
2384 output.push_str(
2386 "-- =============================================================================\n",
2387 );
2388 output.push_str("-- FUNCTION STUBS (for IDE completion)\n");
2389 output.push_str(
2390 "-- =============================================================================\n\n",
2391 );
2392
2393 for func in &global_fns {
2394 output.push_str(&format!("---{}\n", func.description));
2395 for param in func.params {
2396 let opt = if param.optional { "?" } else { "" };
2397 output.push_str(&format!(
2398 "---@param {}{} {} {}\n",
2399 param.name, opt, param.typ, param.description
2400 ));
2401 }
2402 output.push_str(&format!("---@return {}\n", func.returns));
2403
2404 let params = func
2405 .params
2406 .iter()
2407 .map(|p| p.name.to_string())
2408 .collect::<Vec<_>>()
2409 .join(", ");
2410 output.push_str(&format!("function rs.{}({}) end\n\n", func.name, params));
2411 }
2412
2413 output.push_str("-- Coro submodule\n");
2415 output.push_str("rs.coro = {}\n\n");
2416
2417 for func in &coro_fns {
2418 output.push_str(&format!("---{}\n", func.description));
2419 for param in func.params {
2420 let opt = if param.optional { "?" } else { "" };
2421 output.push_str(&format!(
2422 "---@param {}{} {} {}\n",
2423 param.name, opt, param.typ, param.description
2424 ));
2425 }
2426 output.push_str(&format!("---@return {}\n", func.returns));
2427
2428 let params = func
2429 .params
2430 .iter()
2431 .map(|p| p.name.to_string())
2432 .collect::<Vec<_>>()
2433 .join(", ");
2434 output.push_str(&format!(
2435 "function rs.coro.{}({}) end\n\n",
2436 func.name, params
2437 ));
2438 }
2439
2440 output.push_str("-- Parallel submodule\n");
2442 output.push_str("rs.parallel = {}\n\n");
2443
2444 for func in ¶llel_fns {
2445 output.push_str(&format!("---{}\n", func.description));
2446 for param in func.params {
2447 let opt = if param.optional { "?" } else { "" };
2448 output.push_str(&format!(
2449 "---@param {}{} {} {}\n",
2450 param.name, opt, param.typ, param.description
2451 ));
2452 }
2453 output.push_str(&format!("---@return {}\n", func.returns));
2454
2455 let params = func
2456 .params
2457 .iter()
2458 .map(|p| p.name.to_string())
2459 .collect::<Vec<_>>()
2460 .join(", ");
2461 output.push_str(&format!(
2462 "function rs.parallel.{}({}) end\n\n",
2463 func.name, params
2464 ));
2465 }
2466
2467 output.push_str("-- Async submodule (tokio-backed)\n");
2469 output.push_str("rs.async = {}\n\n");
2470
2471 for func in &async_fns {
2472 output.push_str(&format!("---{}\n", func.description));
2473 for param in func.params {
2474 let opt = if param.optional { "?" } else { "" };
2475 output.push_str(&format!(
2476 "---@param {}{} {} {}\n",
2477 param.name, opt, param.typ, param.description
2478 ));
2479 }
2480 output.push_str(&format!("---@return {}\n", func.returns));
2481
2482 let params = func
2483 .params
2484 .iter()
2485 .map(|p| p.name.to_string())
2486 .collect::<Vec<_>>()
2487 .join(", ");
2488 output.push_str(&format!(
2489 "function rs.async.{}({}) end\n\n",
2490 func.name, params
2491 ));
2492 }
2493
2494 output.push_str("-- Crypt submodule (AES-256-GCM encryption)\n");
2496 output.push_str("rs.crypt = {}\n\n");
2497
2498 for func in &crypt_fns {
2499 output.push_str(&format!("---{}\n", func.description));
2500 for param in func.params {
2501 let opt = if param.optional { "?" } else { "" };
2502 output.push_str(&format!(
2503 "---@param {}{} {} {}\n",
2504 param.name, opt, param.typ, param.description
2505 ));
2506 }
2507 output.push_str(&format!("---@return {}\n", func.returns));
2508
2509 let params = func
2510 .params
2511 .iter()
2512 .map(|p| p.name.to_string())
2513 .collect::<Vec<_>>()
2514 .join(", ");
2515 output.push_str(&format!(
2516 "function rs.crypt.{}({}) end\n\n",
2517 func.name, params
2518 ));
2519 }
2520
2521 output.push_str("return rs\n");
2522
2523 output
2524}
2525
2526pub fn generate_markdown() -> String {
2528 let mut output = String::new();
2529 output.push_str("# rs-web Lua API Reference\n\n");
2530 output.push_str("Auto-generated documentation for rs-web Lua functions.\n\n");
2531 output.push_str("## Usage\n\n");
2532 output.push_str("```lua\n");
2533 output.push_str("local rs = require(\"rs-web\")\n");
2534 output.push_str("local content = rs.read_file(\"path/to/file.md\")\n");
2535 output.push_str("local html = rs.render_markdown(content)\n");
2536 output.push_str("```\n\n");
2537 output.push_str("## Table of Contents\n\n");
2538 output.push_str("- [Types](#types)\n");
2539 output.push_str("- [File Operations](#file-operations)\n");
2540 output.push_str("- [Search](#search)\n");
2541 output.push_str("- [Collections](#collections)\n");
2542 output.push_str("- [Text Processing](#text-processing)\n");
2543 output.push_str("- [Path Utilities](#path-utilities)\n");
2544 output.push_str("- [Environment](#environment)\n");
2545 output.push_str("- [Git](#git)\n");
2546 output.push_str("- [Content Processing](#content-processing)\n");
2547 output.push_str("- [Image Processing](#image-processing)\n");
2548 output.push_str("- [Coro Module](#coro-module)\n");
2549 output.push_str("- [Parallel Module](#parallel-module)\n");
2550 output.push_str("- [Async Module](#async-module)\n");
2551 output.push_str("- [Crypt Module](#crypt-module)\n\n");
2552
2553 output.push_str("## Types\n\n");
2555 for class in LUA_CLASSES {
2556 output.push_str(&format!("### {}\n\n", class.name));
2557 output.push_str(&format!("{}\n\n", class.description));
2558 output.push_str("| Field | Type | Description |\n");
2559 output.push_str("|-------|------|-------------|\n");
2560 for field in class.fields {
2561 output.push_str(&format!(
2562 "| `{}` | `{}` | {} |\n",
2563 field.name, field.typ, field.description
2564 ));
2565 }
2566 output.push('\n');
2567 }
2568
2569 let categories = [
2571 (
2572 "File Operations",
2573 vec![
2574 "read_file",
2575 "write_file",
2576 "copy_file",
2577 "file_exists",
2578 "list_files",
2579 "list_dirs",
2580 "load_json",
2581 "load_yaml",
2582 "load_toml",
2583 "read_frontmatter",
2584 ],
2585 ),
2586 ("Search", vec!["glob", "scan"]),
2587 (
2588 "Collections",
2589 vec![
2590 "filter", "sort", "map", "find", "group_by", "unique", "reverse", "take", "skip",
2591 "keys", "values",
2592 ],
2593 ),
2594 (
2595 "Text Processing",
2596 vec![
2597 "slugify",
2598 "word_count",
2599 "reading_time",
2600 "truncate",
2601 "strip_tags",
2602 "format_date",
2603 "parse_date",
2604 "hash",
2605 "hash_file",
2606 "url_encode",
2607 "url_decode",
2608 ],
2609 ),
2610 (
2611 "Path Utilities",
2612 vec!["join_path", "basename", "dirname", "extension"],
2613 ),
2614 ("Environment", vec!["env", "print", "is_gitignored"]),
2615 ("Git", vec!["git_info"]),
2616 (
2617 "Content Processing",
2618 vec![
2619 "render_markdown",
2620 "rss_date",
2621 "extract_links_markdown",
2622 "extract_links_html",
2623 "extract_images_markdown",
2624 "extract_images_html",
2625 "html_to_text",
2626 ],
2627 ),
2628 (
2629 "Image Processing",
2630 vec![
2631 "image_dimensions",
2632 "image_resize",
2633 "image_convert",
2634 "image_optimize",
2635 ],
2636 ),
2637 (
2638 "Assets",
2639 vec![
2640 "build_css",
2641 "build_js",
2642 "check_unused_assets",
2643 "download_google_font",
2644 ],
2645 ),
2646 ];
2647
2648 for (cat_name, func_names) in &categories {
2649 output.push_str(&format!("## {}\n\n", cat_name));
2650
2651 for func_name in func_names {
2652 if let Some(func) = LUA_FUNCTIONS
2653 .iter()
2654 .find(|f| f.name == *func_name && f.module.is_none())
2655 {
2656 output.push_str(&format!("### `rs.{}()`\n\n", func.name));
2657 output.push_str(&format!("{}\n\n", func.description));
2658
2659 if !func.params.is_empty() {
2660 output.push_str("**Parameters:**\n\n");
2661 for param in func.params {
2662 let opt = if param.optional { " (optional)" } else { "" };
2663 output.push_str(&format!(
2664 "- `{}`: `{}`{} - {}\n",
2665 param.name, param.typ, opt, param.description
2666 ));
2667 }
2668 output.push('\n');
2669 }
2670
2671 output.push_str(&format!("**Returns:** `{}`\n\n", func.returns));
2672 }
2673 }
2674 }
2675
2676 output.push_str("## Coro Module\n\n");
2678 output.push_str("Coroutine-based cooperative multitasking helpers.\n\n");
2679 for func in LUA_FUNCTIONS.iter().filter(|f| f.module == Some("coro")) {
2680 output.push_str(&format!("### `rs.coro.{}()`\n\n", func.name));
2681 output.push_str(&format!("{}\n\n", func.description));
2682
2683 if !func.params.is_empty() {
2684 output.push_str("**Parameters:**\n\n");
2685 for param in func.params {
2686 let opt = if param.optional { " (optional)" } else { "" };
2687 output.push_str(&format!(
2688 "- `{}`: `{}`{} - {}\n",
2689 param.name, param.typ, opt, param.description
2690 ));
2691 }
2692 output.push('\n');
2693 }
2694
2695 output.push_str(&format!("**Returns:** `{}`\n\n", func.returns));
2696 }
2697
2698 output.push_str("## Parallel Module\n\n");
2700 output.push_str("True parallel processing with Rayon.\n\n");
2701 for func in LUA_FUNCTIONS
2702 .iter()
2703 .filter(|f| f.module == Some("parallel"))
2704 {
2705 output.push_str(&format!("### `rs.parallel.{}()`\n\n", func.name));
2706 output.push_str(&format!("{}\n\n", func.description));
2707
2708 if !func.params.is_empty() {
2709 output.push_str("**Parameters:**\n\n");
2710 for param in func.params {
2711 let opt = if param.optional { " (optional)" } else { "" };
2712 output.push_str(&format!(
2713 "- `{}`: `{}`{} - {}\n",
2714 param.name, param.typ, opt, param.description
2715 ));
2716 }
2717 output.push('\n');
2718 }
2719
2720 output.push_str(&format!("**Returns:** `{}`\n\n", func.returns));
2721 }
2722
2723 output.push_str("## Async Module\n\n");
2725 output.push_str("Async I/O operations backed by Tokio.\n\n");
2726 for func in LUA_FUNCTIONS.iter().filter(|f| f.module == Some("async")) {
2727 output.push_str(&format!("### `rs.async.{}()`\n\n", func.name));
2728 output.push_str(&format!("{}\n\n", func.description));
2729
2730 if !func.params.is_empty() {
2731 output.push_str("**Parameters:**\n\n");
2732 for param in func.params {
2733 let opt = if param.optional { " (optional)" } else { "" };
2734 output.push_str(&format!(
2735 "- `{}`: `{}`{} - {}\n",
2736 param.name, param.typ, opt, param.description
2737 ));
2738 }
2739 output.push('\n');
2740 }
2741
2742 output.push_str(&format!("**Returns:** `{}`\n\n", func.returns));
2743 }
2744
2745 output.push_str("## Crypt Module\n\n");
2747 output.push_str("Encryption functions using AES-256-GCM with Argon2id key derivation.\n\n");
2748 for func in LUA_FUNCTIONS.iter().filter(|f| f.module == Some("crypt")) {
2749 output.push_str(&format!("### `rs.crypt.{}()`\n\n", func.name));
2750 output.push_str(&format!("{}\n\n", func.description));
2751
2752 if !func.params.is_empty() {
2753 output.push_str("**Parameters:**\n\n");
2754 for param in func.params {
2755 let opt = if param.optional { " (optional)" } else { "" };
2756 output.push_str(&format!(
2757 "- `{}`: `{}`{} - {}\n",
2758 param.name, param.typ, opt, param.description
2759 ));
2760 }
2761 output.push('\n');
2762 }
2763
2764 output.push_str(&format!("**Returns:** `{}`\n\n", func.returns));
2765 }
2766
2767 output
2768}