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