summaryrefslogtreecommitdiff
path: root/scripts/kmd/old_main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kmd/old_main.zig')
-rw-r--r--scripts/kmd/old_main.zig297
1 files changed, 297 insertions, 0 deletions
diff --git a/scripts/kmd/old_main.zig b/scripts/kmd/old_main.zig
new file mode 100644
index 0000000..16feb59
--- /dev/null
+++ b/scripts/kmd/old_main.zig
@@ -0,0 +1,297 @@
+const std = @import("std");
+const kmd = @import("kmd.zig");
+const Allocator = std.mem.Allocator;
+
+// Globals
+const stdout_file = std.io.getStdOut().writer();
+var bw = std.io.bufferedWriter(stdout_file);
+const stdout = bw.writer();
+
+var output: []const u8 = undefined;
+var input: []const u8 = undefined;
+var template: []const u8 = undefined;
+var debug = false;
+
+fn print(comptime fmt: []const u8, args: anytype) !void {
+ try stdout.print(fmt, args);
+ try bw.flush();
+}
+
+fn usage() noreturn {
+ print("TODO: add usage\n", .{}) catch {
+ std.process.exit(1);
+ };
+ std.process.exit(0);
+}
+
+const Jezup = struct {
+ const Mode = enum {
+ none,
+ p,
+ ul,
+ ol,
+ };
+ title: []const u8,
+ date: []const u8,
+ contents: []const u8,
+
+ pub fn init(self: *Jezup, text: []const u8) void {
+ var it = std.mem.splitAny(u8, text, "\n");
+ self.title = it.first();
+ self.date = it.next().?;
+ self.contents = it.rest();
+ }
+
+ pub fn calculateSizeOfContentsAsHtml(self: *Jezup) usize {
+ var mode: Mode = .none;
+ var it = std.mem.splitAny(u8, self.contents, "\n");
+ var line: []const u8 = it.first();
+ var additional: usize = 0;
+ var handled = false; // if !handled and not empty, default is to handle as <p>
+ while (true) {
+ // handle <h1>, <h2>, etc.
+ if (std.mem.startsWith(u8, line, "# ")) {
+ handled = true;
+ additional += 8; // <h1></h2> = 9 minus 2 from "# "
+ }
+
+ if (std.mem.startsWith(u8, line, "## ")) {
+ handled = true;
+ additional += 7;
+ }
+
+ if (std.mem.startsWith(u8, line, "### ")) {
+ handled = true;
+ additional += 6;
+ }
+ if (std.mem.startsWith(u8, line, "- ")) {
+ handled = true;
+ additional += if (mode == .ul) 8 else 7;
+ if (mode != .ul) mode = .ul;
+ }
+
+ if (std.mem.startsWith(u8, line, "~ ")) {
+ handled = true;
+ additional += if (mode == .ol) 8 else 7;
+ if (mode != .ol) mode = .ol;
+ }
+
+ if (mode == .none and !handled and !std.mem.eql(u8, line, "")) {
+ mode = .p;
+ additional += 4; // <p>\n
+ }
+
+ // handle <a href="https://link.com"></a>
+ // @@[][] becomes <a href=""></a> -> 6 bytes becomes 15 -> 9 add bytes
+ additional += std.mem.count(u8, line, "@@[") * 9;
+
+ // handle > and < - they become &gt; and &lt; so +3 bytes each
+ additional += std.mem.count(u8, line, "<") * 3;
+ additional += std.mem.count(u8, line, ">") * 3;
+
+ // peek next and if empty, that means \n\n chain - cancel out cond.
+ if (it.peek() == null or std.mem.eql(u8, it.peek().?, "")) {
+ switch (mode) {
+ .p => {
+ additional += 6; // \n</p>\n
+ }, // add </p>\n
+ .ul => {
+ additional += 11;
+ }, // add </li>\n</ul> (11 bytes)
+ .ol => {
+ additional += 11;
+ }, // add </li></ul>
+ .none => {}, // do nothing
+ }
+ mode = .none;
+ break;
+ } else {
+ line = it.next().?;
+ }
+ }
+ // handle <br>
+ additional += std.mem.count(u8, self.contents, ";;") * 2; // <br> (4) - ;; (2) -> 2 add chars
+ return additional + self.contents.len;
+ }
+
+ fn append(buf: *[256]u8, pos: *usize, data: []const u8) void {
+ std.mem.copyForwards(u8, buf[pos.*..], data);
+ pos.* += data.len;
+ }
+
+ pub fn contentsAsHtml(self: *Jezup, allocator: Allocator, required_capacity_param: ?usize) ![]const u8 {
+ var mode: Mode = .none;
+ var it = std.mem.splitAny(u8, self.contents, "\n");
+ var line: []const u8 = it.first();
+ const required_capacity = if (required_capacity_param) |req| req else calculateSizeOfContentsAsHtml(self);
+ var handled = false; // if !handled and not empty, default is to handle as <p>
+
+ // allocate the new buffer - text + additional_bytes_req
+ // this will hold the full output
+ var buf: []u8 = try allocator.alloc(u8, required_capacity - 1);
+ var pos: usize = 0; // offset to memcpy to
+
+ // hold the buffer for the entire line
+ var linebuf: [256]u8 = undefined;
+ var linepos: usize = 0;
+
+ std.debug.print("allocated_capacity: {}\n", .{required_capacity - 1});
+ std.debug.print("The length of buf is: {}\n", .{buf.len});
+ std.debug.print("buf = {s};\nbuf[pos..] = {s};\n", .{ buf, buf[pos..] });
+
+ // Part two - actually run the changes
+ {
+ // TODO: handle em, b, br, ul, ol, p, <, >
+ // NOTE: handling hN a
+ while (true) {
+ // reset
+ @memset(&linebuf, 0);
+ linepos = 0;
+
+ std.debug.print("While iteration with line: {s}\n", .{line});
+ // handle <h1>, <h2>, etc.
+ // these are "interrupting handlers" which disrupt the normal flow of <p>
+ // included are: hN, ul, ol.
+ if (std.mem.startsWith(u8, line, "# ")) {
+ handled = true;
+ append(&linebuf, &linepos, "<h1>");
+ append(&linebuf, &linepos, line[2..]);
+ append(&linebuf, &linepos, "</h1>\n");
+ }
+
+ if (std.mem.startsWith(u8, line, "## ")) {
+ handled = true;
+ append(&linebuf, &linepos, "<h2>");
+ append(&linebuf, &linepos, line[3..]);
+ append(&linebuf, &linepos, "</h2>\n");
+ }
+
+ if (std.mem.startsWith(u8, line, "### ")) {
+ handled = true;
+ append(&linebuf, &linepos, "<h3>");
+ append(&linebuf, &linepos, line[4..]);
+ append(&linebuf, &linepos, "</h3>\n");
+ }
+
+ if (std.mem.startsWith(u8, line, "- ") or std.mem.startsWith(u8, line, "~ ")) {
+ handled = true;
+ if (mode != .ul and mode != .ol) {
+ mode = if (line[0] == '-') .ul else .ol;
+ append(&linebuf, &linepos, if (line[0] == '-') "<ul>\n<li>" else "<ol>\n<li>");
+ } else {
+ append(&linebuf, &linepos, "</li>\n<li>");
+ }
+ append(&linebuf, &linepos, line[2..]);
+ }
+
+ if (mode == .none and !handled and !std.mem.eql(u8, line, "")) {
+ std.debug.print("executed p\n", .{});
+ mode = .p;
+ append(&linebuf, &linepos, "<p>\n");
+ }
+
+ // handle <a> (@@[][])
+ var i: usize = 0; // index into the line (not linebuf)
+ var found_href = false;
+ while (std.mem.indexOfPos(u8, line, i, "@@[")) |index_start| {
+ found_href = true;
+ std.debug.print("@@[ while clause: i = {}; linebuf = {s}\n", .{ i, linebuf });
+ // copy until the link
+ append(&linebuf, &linepos, line[i..index_start]);
+
+ const desc_start = index_start + 3;
+ const desc_end = std.mem.indexOfPos(u8, line, desc_start, "]").?; // safe as @@[ must contain desc and href components in form @@[desc][href]
+ const href_begin = desc_end + 2;
+ const href_end = std.mem.indexOfPos(u8, line, href_begin, "]").?;
+ const desc = line[desc_start..desc_end];
+ const href = line[href_begin..href_end];
+ i = href_end + 1;
+
+ // copy the link
+ append(&linebuf, &linepos, "<a href=\"");
+ append(&linebuf, &linepos, href);
+ append(&linebuf, &linepos, "\">");
+ append(&linebuf, &linepos, desc);
+ append(&linebuf, &linepos, "</a>");
+ std.debug.print("@@[ while post: i = {}; linebuf = {s}\n----\n", .{ i, linebuf });
+ }
+ if (found_href) {
+ std.debug.print("@@[ else clause: i = {}; line.len = {}\n", .{ i, line.len });
+ append(&linebuf, &linepos, line[i..]); // FIXME panic here!
+ }
+ std.debug.print("After @@[: {s}\n", .{linebuf});
+
+ // handle > and < - they become &gt; and &lt; so +3 bytes each
+ // TODO
+ // additional += std.mem.count(u8, line, "<") * 3;
+ // additional += std.mem.count(u8, line, ">") * 3;
+
+ // TODO: write it all out, get rid of the break above
+ if (it.peek() == null or std.mem.eql(u8, it.peek().?, "")) {
+ switch (mode) {
+ .p => append(&linebuf, &linepos, "\n</p>\n"),
+ .ul => append(&linebuf, &linepos, "</li>\n</ul>"),
+ .ol => append(&linebuf, &linepos, "</li>\n</ol>"),
+ .none => {}, // do nothing
+ }
+ mode = .none;
+ } else {}
+
+ // copy linebuf into buf
+ std.debug.print("copied linebuf = {s}; buf.len = {}; pos = {}; linebuf.len = {}; linepos = {}\n", .{ linebuf, buf.len, pos, linebuf.len, linepos });
+ std.mem.copyForwards(u8, buf[pos..], linebuf[0..linepos]);
+ pos += linepos; // linebuf.len is always 256
+ line = it.next().?;
+ handled = false;
+ std.debug.print("---- CLOSE LINE ----\n", .{});
+ if (it.peek() == null) {
+ std.debug.print("---- QUITTING ----\n", .{});
+ break;
+ }
+ }
+ }
+ return buf;
+ }
+};
+
+test "jezup.contentsToHtml" {
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ const allocator = gpa.allocator();
+ var jz1: Jezup = undefined;
+ const str = "Title\n2024-10-01\n# My header\nThis line has @@[a link][https://gabbott.dev] in it\n\nThis line has @@[two][https://kagi.com] and @@[three][https://boodle.mon] awesome links.";
+ const out = "<h1>My header</h1>\nThis line has <a href=\"https://gabbott.dev\">a link</a> in it\n\nThis line has <a href=\"https://kagi.com\">two</a> and <a href=\"https://boodle.mon\">three</a> awesome links.";
+ jz1.init(str);
+
+ const html = try jz1.contentsAsHtml(allocator, null);
+ defer allocator.free(html);
+
+ std.debug.print("HTML\n----\n{s}\n| len = {}\n", .{ html, html.len });
+ try std.testing.expect(std.mem.eql(u8, html, out));
+}
+
+pub fn main() !void {
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ const allocator = gpa.allocator();
+
+ const args = try std.process.argsAlloc(allocator);
+
+ var i: usize = 1;
+ while (i < args.len) : (i += 1) {
+ if (std.mem.eql(u8, args[i], "-o")) {
+ i += 1;
+ output = args[i];
+ } else if (std.mem.eql(u8, args[i], "-i")) {
+ i += 1;
+ input = args[i];
+ } else if (std.mem.eql(u8, args[i], "-t")) {
+ i += 1;
+ template = args[i];
+ } else if (std.mem.eql(u8, args[i], "-d")) {
+ debug = true;
+ } else if (std.mem.eql(u8, args[i], "-h")) {
+ usage();
+ } else {
+ try print("not a valid arg\n", .{});
+ }
+ }
+}