Makko, the people-oriented static site generator made for blogging. forge.starlightnet.work/Team/Makko
ssg static-site-generator makko starlight-network
at main 3.8 kB view raw
1const std = @import("std"); 2 3//////////////////////////////////////////////////////// 4// The following data structure has a bunch of aliased 5// data types specifically so it's easier to understand 6// for people with no experience in Zig, and perhaps 7// little to no experience programming. 8// 9// Please avoid complicated terminology unless it is 10// fully necessary. 11//////////////////////////////////////////////////////// 12 13pub const Tag = struct { 14 name: []const u8, 15 posts: []Post, 16}; 17 18pub const Time = struct { 19 raw: Integer, 20 21 year: Integer, 22 month: TwoDigits, 23 day: TwoDigits, 24 25 hour: TwoDigits, 26 minute: TwoDigits, 27 second: TwoDigits, 28}; 29 30pub const Post = struct { 31 id: Id = 0, 32 is_secret: bool, 33 34 title: String, 35 description: String, 36 author: String, 37 38 // kebab-case list of tags 39 tags: []const String, 40 41 source: Path, 42 url: Path, 43 44 created: Time, 45 updated: Time, 46 47 body: ?String, 48}; 49 50website: struct { 51 title: String, 52 description: String, 53 url: String, 54 55 feeds: struct { 56 html: ?Path = null, 57 rss: ?Path = null, 58 atom: ?Path = null, 59 }, 60}, 61 62pass: struct { 63 feed_template: Hash, 64 post_template: Hash, 65}, 66 67// JSON Map of custom values 68custom: Value, 69 70// Only valid when processing individual posts 71post: ?Post = null, 72 73// Only valid when processing feeds. 74posts: ?[]Post = null, 75 76tags: []Tag, 77 78// Map of tag name to list of posts 79by_tag: Value, 80 81//////////////////////////////////////////////////////// 82//////////////////////////////////////////////////////// 83//////////////////////////////////////////////////////// 84///////////// IMPLEMENTATION DETAILS /////////////////// 85 86const String = []const u8; 87const Path = String; 88const Integer = i64; 89const Float = f64; 90const ArbitraryData = std.json.Value; 91const Value = std.json.Value; 92const TwoDigits = [2]u8; 93 94pub const empty_time = std.mem.zeroes(Time); 95pub const Hash = Integer; 96pub const Id = Integer; 97 98const helper = @import("helper.zig"); 99 100// TODO: Zig MUST have a function for this!!!! 101fn formatTwoDigits(n: u8) [2]u8 { 102 return if (n < 10) 103 [_]u8{ '0', '0' + n } 104 else 105 [_]u8{ 106 '0' + @as(u8, @intCast(n / 10)), 107 '0' + @as(u8, @intCast(n % 10)), 108 }; 109} 110 111pub fn timeFromTimestamp(now: i64) Time { 112 const Datetime = @import("datetime").datetime.Datetime; 113 114 var time: Time = undefined; 115 116 const e = Datetime.fromTimestamp(now); 117 118 time.raw = now; 119 time.year = @intCast(e.date.year); 120 121 time.month = formatTwoDigits(e.date.month); 122 time.day = formatTwoDigits(e.date.day); 123 124 time.hour = formatTwoDigits(e.time.hour); 125 time.minute = formatTwoDigits(e.time.minute); 126 time.second = formatTwoDigits(e.time.second); 127 128 return time; 129} 130 131pub fn copyPost(post: Post, allocator: std.mem.Allocator) !Post { 132 return Post{ 133 .id = post.id, 134 .is_secret = post.is_secret, 135 136 .title = try allocator.dupe(u8, post.title), 137 .description = try allocator.dupe(u8, post.description), 138 .author = try allocator.dupe(u8, post.author), 139 140 .tags = try helper.copyStringList(allocator, post.tags), 141 142 .source = try allocator.dupe(u8, post.source), // Relative to source path 143 .url = try allocator.dupe(u8, post.url), // Relative to output path 144 145 .created = post.created, 146 .updated = post.updated, 147 148 .body = if (post.body) |body| 149 try allocator.dupe(u8, body) 150 else 151 null, 152 }; 153} 154 155pub fn freePost(post: Post, allocator: std.mem.Allocator) void { 156 allocator.free(post.title); 157 allocator.free(post.description); 158 allocator.free(post.author); 159 helper.freeStringList(allocator, post.tags); 160 allocator.free(post.source); 161 allocator.free(post.url); 162 if (post.body) |body| 163 allocator.free(body); 164}