//#+vet explicit-allocators package main import "core:fmt" import vmem "core:mem/virtual" import "core:mem" import "core:os" import "core:strings" import "core:time" import fleg "flag" /* Order of operations: * 1. Generate blog/index.md * 2. Parse ALL .md files into .html files * 3. Write HTML prefixes into .hmtl files * 4. (write fancy timings and footer for main page) */ create_html_file :: proc(md_f: string, dir: string, output_dir: string, allocater := context.allocator) -> (file: ^os.File, err: os.Error){ sb := strings.builder_make(allocater) //sb for writing to files defer strings.builder_destroy(&sb) md_filename := strings.split(md_f, dir, allocater) trimmed_filename := strings.trim_right(md_filename[1], ".md") // sck: Change to output directory. Not sure if this also is needed //But messing around with it means I create a lot of //files to clean up. Works for now! os.change_directory(output_dir) strings.write_string(&sb, fmt.aprintf("%v", trimmed_filename, allocator = allocater)) strings.write_string(&sb, ".html") //get "full" name for creation + writing to html file full_filename := strings.to_string(sb) file = os.create(full_filename) or_return return file, nil } write_footer_and_timings :: proc(trimmed_filename: string, file: ^os.File, start: time.Tick, allocator := context.allocator){ switch trimmed_filename { case "index": buf: [1024]u8 date := time.now() end := time.tick_since(start) os.write_string(file, "

") } } main :: proc() { // Arena used for ALL allocations, easier to drop everything at end of execution. arena: vmem.Arena arena_err := vmem.arena_init_growing(&arena) ensure(arena_err == nil) arena_alloc := vmem.arena_allocator(&arena) context.allocator = arena_alloc defer vmem.arena_destroy(&arena) //clean up everything! when ODIN_DEBUG { total_size: int track: mem.Tracking_Allocator mem.tracking_allocator_init(&track, context.allocator) context.allocator = mem.tracking_allocator(&track) defer { if len(track.allocation_map) > 0 { fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map)) for _, entry in track.allocation_map { fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location) total_size += entry.size } } if len(track.bad_free_array) > 0 { fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array)) for entry in track.bad_free_array { fmt.eprintf("- %p @ %v\n", entry.memory, entry.location) } } fmt.printfln("[INFO] TOTAL: %v bytes at end of generation!", total_size) mem.tracking_allocator_destroy(&track) } } fleg.init_custom_allocator(context.allocator) //defer fleg.destroy() //not needede when we free the alloc' anyway directory: string output_dir: string fleg.StringVar(&directory, "dir", "", "input directory of .MD files", required = true) fleg.StringVar(&output_dir, "out", "", "output directory (html files)", required = true) fleg.parse_flags() start := time.tick_now() //start timer for footer // First generate the blog index MARKDOWN file generate_blog_index_md_file(directory, context.allocator) // Walk directory and collect .md files md_files := walk_tree_and_get_md_names(directory, context.allocator) // ************* MAIN LOOP ************ for file, _ in md_files { if file == ".DS_Store" { continue } //Ignore annoying MacOS (TODO: clean up proc?) md_filename := strings.split(file, directory, context.allocator) trimmed_filename := strings.trim_right(md_filename[1], ".md") // sck: I am not sure if changing dir's is needed but I am now relying on it lol os.change_directory(directory) // turn all .md files into parsed .html files! html_content, parse_err := parse_file_md_to_html(file, context.allocator) if parse_err != nil { fmt.eprintfln("ERROR: Could not parse file %s: %s", file, os.error_string(parse_err)) } final_html_file, html_file_err := create_html_file(file, directory, output_dir, context.allocator) if html_file_err != nil { fmt.eprintfln("ERROR: Could not create file %s: %s", file, os.error_string(html_file_err)) } write_prefixs_to_html_file(final_html_file) os.write_string(final_html_file, html_content) //WRITE PAGE defer write_footer_and_timings(trimmed_filename, final_html_file, start, context.allocator) } defer free_all(context.allocator) }