api_doc_builder.odin 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package karl2d_api_doc_builder
  2. import os "core:os/os2"
  3. import os1 "core:os"
  4. import vmem "core:mem/virtual"
  5. import "core:log"
  6. import "core:fmt"
  7. import "core:odin/parser"
  8. import "core:odin/ast"
  9. import "core:strings"
  10. import "core:slice"
  11. import "core:hash"
  12. main :: proc() {
  13. arena: vmem.Arena
  14. context.allocator = vmem.arena_allocator(&arena)
  15. context.temp_allocator = context.allocator
  16. context.logger = log.create_console_logger()
  17. plug_ast, plug_ast_ok := parser.parse_package_from_path(".")
  18. log.ensuref(plug_ast_ok, "Could not generate AST for package")
  19. b := strings.builder_make()
  20. strings.write_string(&b, "// This file is purely documentational and never built.\n")
  21. strings.write_string(&b, "#+build ignore\n")
  22. strings.write_string(&b, "package karl2d\n")
  23. prev_line: int
  24. for n, &f in plug_ast.files {
  25. if !strings.ends_with(n, "karl2d.odin") {
  26. continue
  27. }
  28. decl_loop: for &d in f.decls {
  29. #partial switch &dd in d.derived {
  30. case ^ast.Value_Decl:
  31. val: string
  32. for v, vi in dd.values {
  33. #partial switch vd in v.derived {
  34. case ^ast.Proc_Lit:
  35. name := f.src[dd.names[vi].pos.offset:dd.names[vi].end.offset]
  36. type := f.src[vd.type.pos.offset:vd.type.end.offset]
  37. docs := dd.docs == nil ? "" : f.src[dd.docs.pos.offset:dd.docs.end.offset]
  38. val = fmt.tprintf("%v :: %v", name, type)
  39. }
  40. }
  41. if val == "" {
  42. val = f.src[dd.pos.offset:dd.end.offset]
  43. }
  44. if val == "API_END :: true" {
  45. break decl_loop
  46. }
  47. if dd.docs != nil {
  48. strings.write_rune(&b, '\n')
  49. strings.write_string(&b, f.src[dd.docs.pos.offset:dd.docs.end.offset])
  50. strings.write_rune(&b, '\n')
  51. } else {
  52. if prev_line != dd.pos.line - 1 {
  53. strings.write_rune(&b, '\n')
  54. }
  55. }
  56. strings.write_string(&b, val)
  57. strings.write_rune(&b, '\n')
  58. prev_line = dd.pos.line
  59. }
  60. }
  61. }
  62. _ = os.write_entire_file("karl2d.doc.odin", transmute([]u8)(strings.to_string(b)))
  63. }