<<
path:
root/public/blog.git/html/src/gen/replace.jai
blob: b2be13428623841a4379b7b680af2989613a5193
[raw]
[clear marker]
4 buffer: *String_Builder,
13 if is_heading(current, i_ptr.*, post, .OPEN) {
14 return replace_heading(buffer, current, i_ptr, post, uri);
16 else if is_image(current, i_ptr.*, post) {
17 return replace_image(buffer, i_ptr, post, uri, dont_show_images);
24 buffer: *String_Builder,
28 dont_show_images: bool,
32 /** Reminder: pop() advanced already */
33 initial_idx := i_ptr.* - 1;
35 tag_img := parser_consume_including(initial_idx, post, "/>");
38 tag_open := parser_consume_including(0, tag_img, "\"");
39 src_path := parser_consume_till(tag_open.count, tag_img, "\"");
40 tag_closed := parser_consume_including(tag_open.count + src_path.count, tag_img, "/>");
42 offset := tag_open.count + src_path.count + tag_closed.count - 1;
43 advance_by(i_ptr, offset);
45 src_path_new, src_path_resized := img_update_path(uri, src_path);
47 src_path_new_absolute := tprint("%/%", DIR_WWW_IMAGES, src_path_new);
48 src_path_resized_absolute := tprint("%/%", DIR_WWW_IMAGES, src_path_resized);
50 src_path_new_relative := tprint("%/%", SUBDIR_IMAGES, src_path_new);
51 src_path_resized_relative := tprint("%/%", SUBDIR_IMAGES, src_path_resized);
53 img_copy_to(src_path, src_path_new_absolute);
54 img_resize_and_copy_to(src_path, src_path_resized_absolute);
56 img_src := ifx dont_show_images then "" else src_path_resized_relative;
58 img_new := tprint("%%%",
64 new := create_link(src_path_new_relative, img_new, target="blank", prefix="");
69 buffer: *String_Builder,
77 /** Reminder: pop() advanced already */
78 initial_idx := i_ptr.* - 1;
80 tag_open := parser_consume_including(i_ptr.* - 1, post, #char ">");
82 advance_by(i_ptr, tag_open);
84 title := parser_consume_till(i_ptr.* - 1, post, #char "<");
86 advance_by(i_ptr, title);
88 maybe_tag_closed := is_heading(current, i_ptr.*, post, .CLOSED);
89 if !maybe_tag_closed return "";
91 tag_closed := parser_consume_including(i_ptr.* - 1, post, #char ">");
92 bail(tag_closed, ">");
93 advance_by(i_ptr, tag_closed);
95 id := create_id(url, title);
96 tag_with_id := inject_id(tag_open, title, id);
97 link := create_link(id, title);
108replace_reference :: (
109 buffer: *String_Builder,
116 maybe_ref := is_md_link(post, i_ptr.* - 1);
117 if !maybe_ref return "";
119 advance_by(i_ptr, REFERENCE_MARKER);
121 reference := parser_consume_till(i_ptr.* - 1, post, #char "]");
122 bail(reference, "]");
123 advance_by(i_ptr, reference);
125 id := create_id(url, reference);
126 link := create_link(id, reference);
138peek :: () -> u8 #expand {
139 return parser_peek(`i, `post);
142peek_forward :: (offset := 1) -> u8 #expand {
143 return parser_peek_forward(`i, `post, offset);
146advance_by :: parser_advance_by;
148advance_by :: (s: string) #expand {
149 parser_advance_by(*`i, s);
152/** Note(adam): h1 is ignored */
154 current: u8, i: int, post: string, kind: enum { OPEN; CLOSED; }
158 // Assuming the first char is already checked
165 if next != "h" return false;
167 if next != "/" && peek_forward() != "h" return false;
171 maybe_heading := peek_forward(offset);
174 if maybe_heading <= 50 && maybe_heading >= 54 return false;
176 maybe_closed_tag := peek_forward(1 + offset);
177 if maybe_closed_tag == ">" return true;
182is_image :: (current: u8, i: int, post: string) -> bool {
183 return parser_match(post, "img src=", i);
186is_md_link :: (post: string, index: int) -> bool {
187 return parser_match(post, REFERENCE_MARKER, index);
190inject_id :: (tag_open: string, title: string, url_new: string) -> string {
191 closed := find_index_from_left(tag_open, ">");
192 assert(closed != -1); // Cannot happen!
194 first_part := slice(tag_open, 0, closed);
195 id := tprint("% id=\"%\">", first_part, url_new);
200create_id :: (url: string, s: string) -> string {
201 normalized_kinda := normalize_string(s);
202 low := to_lower_copy(normalized_kinda);
203 id := tprint("%-%", url, low);
207create_link :: (url: string, label: string, target := "self", prefix := "#") -> string {
208 return tprint("<a href=\"%1%2\" target=\"_%3\">%4</a>",
216img_update_path :: (uri: string, image_name: string) -> (full: string, resized: string) {
217 without_extension := path_strip_extension(image_name);
218 file_extension := path_extension(image_name);
220 full := tprint("%-%", uri, image_name);
222 "%-%-scaled.%", uri, without_extension, file_extension
224 return full, resized;
227img_copy_to :: (name: string, path_new: string) {
228 if is_file(path_new) return;
229 path_old := tprint("%/%", DIR_POSTS_IMAGES, name);
231 ok := copy_file(path_old, path_new);
234 "Error: Could not copy file. From: '%' to '%'",
240img_resize_and_copy_to :: (name: string, path_new: string, quality: s32 = 80) {
241 if is_file(path_new) return;
243 image_fp := tprint("%/%", DIR_POSTS_IMAGES, name);
245 width, height, channels: s32;
246 input: *u8 = stbi_load(to_c_string(image_fp), *width, *height, *channels, 0);
249 report_and_exit("Error: Could not load image from: %", image_fp);
252 if width < PAGE_IMAGE_MAX_WIDTH {
253 img_copy_to(name, path_new);
257 target_width: s32 = PAGE_IMAGE_MAX_WIDTH;
259 heightf := cast(float, height);
260 widthf := cast(float, width);
261 max_widthf := cast(float, PAGE_IMAGE_MAX_WIDTH);
262 target_height: s32 = xx (heightf * (max_widthf / widthf));
264 output := alloc(target_width * target_height * channels);
267 if width > PAGE_IMAGE_MAX_WIDTH {
268 ok := stbir_resize_uint8(
269 input, width, height, 0,
270 output, target_width, target_height, 0,
274 if ok != OK then report_and_exit("Error: Could not resize image: %", image_fp);
277 ok := stbi_write_jpg(
278 to_c_string(path_new), target_width, target_height, channels, output, quality
281 if ok != OK then report_and_exit("Error: Could not save image to: %", path_new);
284bail :: (returned_str: string, s: string, loc := #caller_location) #expand {
285 if returned_str return;
286 report_and_exit(PARSER_ERROR_MSG, `post, s, loc=loc);