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