cleaning up codebase, adding unicode support
This commit is contained in:
		
							parent
							
								
									bc3ff140b1
								
							
						
					
					
						commit
						44869a7926
					
				|  | @ -1,12 +1,11 @@ | ||||||
| const std = @import("std"); | const std = @import("std"); | ||||||
| 
 | 
 | ||||||
| pub fn build(b: *std.Build) void { | pub fn build(b: *std.Build) void { | ||||||
|  |     const zg = b.dependency("zg", .{}); | ||||||
|     const target = b.standardTargetOptions(.{}); |     const target = b.standardTargetOptions(.{}); | ||||||
| 
 | 
 | ||||||
|     const optimize = b.standardOptimizeOption(.{}); |     const optimize = b.standardOptimizeOption(.{}); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     const exe = b.addExecutable(.{ |     const exe = b.addExecutable(.{ | ||||||
|         .name = "proxy-print", |         .name = "proxy-print", | ||||||
|         .root_source_file = b.path("src/print.zig"), |         .root_source_file = b.path("src/print.zig"), | ||||||
|  | @ -20,12 +19,13 @@ pub fn build(b: *std.Build) void { | ||||||
|     }); |     }); | ||||||
|     exe.addIncludePath(b.path("include")); |     exe.addIncludePath(b.path("include")); | ||||||
|     exe.linkLibC(); |     exe.linkLibC(); | ||||||
|  |     exe.root_module.addImport("grapheme", zg.module("grapheme")); | ||||||
|  |     exe.root_module.addImport("DisplayWidth", zg.module("DisplayWidth")); | ||||||
| 
 | 
 | ||||||
|     b.installArtifact(exe); |     b.installArtifact(exe); | ||||||
| 
 | 
 | ||||||
|     const run_cmd = b.addRunArtifact(exe); |     const run_cmd = b.addRunArtifact(exe); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     run_cmd.step.dependOn(b.getInstallStep()); |     run_cmd.step.dependOn(b.getInstallStep()); | ||||||
| 
 | 
 | ||||||
|     if (b.args) |args| { |     if (b.args) |args| { | ||||||
|  |  | ||||||
|  | @ -15,14 +15,10 @@ | ||||||
|     // Once all dependencies are fetched, `zig build` no longer requires |     // Once all dependencies are fetched, `zig build` no longer requires | ||||||
|     // internet connectivity. |     // internet connectivity. | ||||||
|     .dependencies = .{ |     .dependencies = .{ | ||||||
|         //.@"zig-msgpack" = .{ |         .zg = .{ | ||||||
|         //    .url = "https://github.com/zigcc/zig-msgpack/archive/main.tar.gz", |             .url = "https://codeberg.org/dude_the_builder/zg/archive/v0.13.2.tar.gz", | ||||||
|         //    .hash = "1220e4669d29190ac809cd3a7726c20b6b49ea7425b7b89cab16d4dc3172016982bc", |             .hash = "122055beff332830a391e9895c044d33b15ea21063779557024b46169fb1984c6e40", | ||||||
|         //}, |         }, | ||||||
|         //.clap = .{ |  | ||||||
|         //    .url = "https://github.com/Hejsil/zig-clap/archive/refs/tags/0.8.0.tar.gz", |  | ||||||
|         //    .hash = "1220949d4e88864579067b6d4cdad6476c6176f27e782782c2c39b7f2c4817a10efb", |  | ||||||
|         //}, |  | ||||||
|     }, |     }, | ||||||
|     .paths = .{ |     .paths = .{ | ||||||
|         // This makes *all* files, recursively, included in this package. It is generally |         // This makes *all* files, recursively, included in this package. It is generally | ||||||
|  |  | ||||||
							
								
								
									
										2588
									
								
								output.pdf
								
								
								
								
							
							
						
						
									
										2588
									
								
								output.pdf
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -1438,6 +1438,9 @@ static int utf8_to_pdfencoding(struct pdf_doc *pdf, const char *utf8, int len, | ||||||
|         case 0x2dc: // Small Tilde
 |         case 0x2dc: // Small Tilde
 | ||||||
|             *res = 0230; |             *res = 0230; | ||||||
|             break; |             break; | ||||||
|  |         case 0x2212: | ||||||
|  |             *res = 0226; | ||||||
|  |             break; | ||||||
|         case 0x2013: // Endash
 |         case 0x2013: // Endash
 | ||||||
|             *res = 0226; |             *res = 0226; | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
							
								
								
									
										115
									
								
								src/print.zig
								
								
								
								
							
							
						
						
									
										115
									
								
								src/print.zig
								
								
								
								
							|  | @ -3,6 +3,7 @@ | ||||||
| // | // | ||||||
| const std = @import("std"); | const std = @import("std"); | ||||||
| const clap = @import("clap"); | const clap = @import("clap"); | ||||||
|  | const DisplayWidth = @import("DisplayWidth"); | ||||||
| const c = @cImport({ | const c = @cImport({ | ||||||
|     @cInclude("pdfgen.h"); |     @cInclude("pdfgen.h"); | ||||||
| }); | }); | ||||||
|  | @ -69,15 +70,12 @@ pub fn main() !void { | ||||||
|     const parsedJson = try json.parseFromTokenSource([]Card, allocator, &jsonReader, .{ .ignore_unknown_fields = true }); |     const parsedJson = try json.parseFromTokenSource([]Card, allocator, &jsonReader, .{ .ignore_unknown_fields = true }); | ||||||
| 
 | 
 | ||||||
|     var cardNames = std.ArrayList([]const u8).init(allocator); |     var cardNames = std.ArrayList([]const u8).init(allocator); | ||||||
|     const listReader = (try cwd.openFile(listFileName, .{})).reader(); |     const listText = try cwd.readFileAlloc(allocator, listFileName, 1024 * 100); | ||||||
|     var line = std.ArrayList(u8).init(allocator); |     var listLines = std.mem.splitAny(u8, listText, "\n"); | ||||||
|     while (listReader.streamUntilDelimiter(line.writer(), '\n', null)) { |     while (listLines.next()) |line| { | ||||||
|         defer line.clearRetainingCapacity(); |         if (line.len < 5) break; | ||||||
|         const cardName = line.items[indexOf(u8, line.items, " ").? + 1 .. indexOf(u8, line.items, "(").? - 1]; |         const cardName = line[indexOf(u8, line, " ").? + 1 .. indexOf(u8, line, "(").? - 1]; | ||||||
|         try cardNames.append(try allocator.dupe(u8, cardName)); |         try cardNames.append(try allocator.dupe(u8, cardName)); | ||||||
|     } else |err| switch (err) { |  | ||||||
|         error.EndOfStream => {}, |  | ||||||
|         else => return err, |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var cards = std.StringArrayHashMap(TextCard).init(allocator); |     var cards = std.StringArrayHashMap(TextCard).init(allocator); | ||||||
|  | @ -91,13 +89,12 @@ pub fn main() !void { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var allPrinted = std.ArrayList(u8).init(allocator); |     var allPrinted = std.ArrayList([]const u8).init(allocator); | ||||||
| 
 | 
 | ||||||
|     const pdf_doc: *c.pdf_doc = @ptrCast(c.pdf_create(c.PDF_A4_WIDTH, c.PDF_A4_HEIGHT, &c.pdf_info{ .creator = ("My Software" ++ " " ** 53).* }).?); |     const pdf_doc: *c.pdf_doc = @ptrCast(c.pdf_create(c.PDF_A4_WIDTH, c.PDF_A4_HEIGHT, &c.pdf_info{ .creator = ("My Software" ++ " " ** 53).* }).?); | ||||||
|     _ = c.pdf_set_font(pdf_doc, "Times-Roman"); |     _ = c.pdf_set_font(pdf_doc, "Times-Roman"); | ||||||
| 
 | 
 | ||||||
|     var rowToPrint = std.ArrayList(TextCard).init(allocator); |     var rowToPrint = std.ArrayList(TextCard).init(allocator); | ||||||
|     // var cardIterator = cards.valueIterator(); |  | ||||||
|     for (cards.values()) |cardText| { |     for (cards.values()) |cardText| { | ||||||
|         try rowToPrint.append(cardText); |         try rowToPrint.append(cardText); | ||||||
|         if (rowToPrint.items.len >= 3) { |         if (rowToPrint.items.len >= 3) { | ||||||
|  | @ -106,26 +103,22 @@ pub fn main() !void { | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|         try cardRow.print(allocator, rowToPrint.items, &allPrinted); |         try cardRow.print(allocator, rowToPrint.items, &allPrinted); | ||||||
|         std.debug.print("{s}", .{allPrinted.items}); |         for (allPrinted.items) |printLine| { | ||||||
|         //TODO (fixme): |             print("{s}", .{printLine}); | ||||||
|         // wrong type error when not using ptrCast, nothing printed when using it |         } | ||||||
|         // _ = c.pdf_add_text(pdf_doc, page, allPrinted.items[0..50], 12, 10, c.PDF_A4_HEIGHT - 12, c.PDF_BLACK); |         // std.debug.print("{s}", .{allPrinted.items}); | ||||||
|         // _ = c.pdf_add_text(pdf_doc, page, allPrinted.items[0..50], 12, 10, c.PDF_A4_HEIGHT - 12, c.PDF_BLACK); |  | ||||||
|         // _ = c.pdf_add_text(pdf_doc, page, "HELLO WEST VIRGINIA", 12, 10, c.PDF_A4_HEIGHT - 12, c.PDF_BLACK); |  | ||||||
|         rowToPrint.clearAndFree(); |         rowToPrint.clearAndFree(); | ||||||
|     } |     } | ||||||
|     var rowsPrinted: f32 = 0; |  | ||||||
|     var page = c.pdf_append_page(pdf_doc); |     var page = c.pdf_append_page(pdf_doc); | ||||||
|     var textIterator = std.mem.splitAny(u8, allPrinted.items, "\n"); |  | ||||||
|     _ = c.pdf_set_font(pdf_doc, "Courier"); |     _ = c.pdf_set_font(pdf_doc, "Courier"); | ||||||
|     while (textIterator.next()) |text| { |     for (allPrinted.items, 1..) |text, rowNum| { | ||||||
|         if (rowsPrinted < pageHeight) { |         const pageRelative = rowNum % pageHeight; | ||||||
|             rowsPrinted += 1; |         const pageOffset: f32 = 12 * @as(f32, @floatFromInt(pageRelative)); | ||||||
|             _ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, c.PDF_A4_HEIGHT - (12 * rowsPrinted), c.PDF_BLACK); |         if (pageRelative != 0) { | ||||||
|  |             _ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, c.PDF_A4_HEIGHT - pageOffset, c.PDF_BLACK); | ||||||
|         } else { |         } else { | ||||||
|             rowsPrinted = 1; |  | ||||||
|             page = c.pdf_append_page(pdf_doc); |             page = c.pdf_append_page(pdf_doc); | ||||||
|             _ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, c.PDF_A4_HEIGHT - (12 * rowsPrinted), c.PDF_BLACK); |             _ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, c.PDF_A4_HEIGHT - pageOffset, c.PDF_BLACK); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -168,27 +161,28 @@ fn card( | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var line = std.ArrayList(u8).init(allocator); |     var line = std.ArrayList(u8).init(allocator); | ||||||
|     var word = std.ArrayList(u8).init(allocator); |     // var word = std.ArrayList(u8).init(allocator); | ||||||
| 
 | 
 | ||||||
|     for (fullUnformattedText.items) |char| { |     var wordIterator = std.mem.splitAny(u8, fullUnformattedText.items, "\n "); | ||||||
|         try switch (char) { |     while (wordIterator.next()) |word| { | ||||||
|             '\n', ' ' => addWord(&word, &line, &cardText), |         if (line.items.len + word.len + 1 < cardWidth) { | ||||||
|             else => if (std.ascii.isASCII(char)) { |             try line.appendSlice(word); | ||||||
|                 try word.append(char); |             try line.append(' '); | ||||||
|             }, |             assert(line.items.len < 30); | ||||||
|         }; |         } else { | ||||||
|  |             try cardText.append(try line.toOwnedSlice()); | ||||||
|  |             line.clearAndFree(); | ||||||
|  |             try line.appendSlice(word); | ||||||
|  |             try line.append(' '); | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         try addWord(&word, &line, &cardText); |         try cardText.append(try line.toOwnedSlice()); | ||||||
|         const lineToBeAdded = std.mem.trimRight(u8, try line.toOwnedSlice(), " "); |  | ||||||
|         // const lineToBeAdded = try line.toOwnedSlice(); |  | ||||||
|         try cardText.append(lineToBeAdded); |  | ||||||
|         line.clearAndFree(); |  | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     while (wrongCardHeight(cardText.items.len)) { |     while (wrongCardHeight(cardText.items.len)) { | ||||||
|         try cardText.append(" " ** (cardWidth - 2)); |         try cardText.append(" " ** (cardWidth - 2)); | ||||||
|     } |     } | ||||||
|     try cardText.append(" " ** (cardWidth - 2)); |     try cardText.append(" " ** (cardWidth - 2)); | ||||||
|     // return cardText.items; |  | ||||||
|     return TextCard{ .lines = try cardText.toOwnedSlice() }; |     return TextCard{ .lines = try cardText.toOwnedSlice() }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -196,29 +190,20 @@ fn wrongCardHeight(length: usize) bool { | ||||||
|     return (!heightMayVary and length < cardHeight) or length < minCardHeight; |     return (!heightMayVary and length < cardHeight) or length < minCardHeight; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn addWord(word: *std.ArrayList(u8), line: *std.ArrayList(u8), cardText: *std.ArrayList([]const u8)) !void { |  | ||||||
|     if (line.items.len + word.items.len >= (cardWidth)) { |  | ||||||
|         const lineToBeAdded = std.mem.trimRight(u8, try line.toOwnedSlice(), " "); |  | ||||||
|         assert(lineToBeAdded.len < 30); |  | ||||||
|         try cardText.append(lineToBeAdded); |  | ||||||
|         line.clearAndFree(); |  | ||||||
|     } |  | ||||||
|     try line.appendSlice(word.items); |  | ||||||
|     try line.append(' '); |  | ||||||
|     word.clearAndFree(); |  | ||||||
| } |  | ||||||
| const linesList = std.MultiArrayList(cardRow); | const linesList = std.MultiArrayList(cardRow); | ||||||
| const cardRow = struct { | const cardRow = struct { | ||||||
|     first: []const u8 = spacer, |     first: []const u8 = spacer, | ||||||
|     second: []const u8 = spacer, |     second: []const u8 = spacer, | ||||||
|     third: []const u8 = spacer, |     third: []const u8 = spacer, | ||||||
|     last: []const u8 = "\n", |     last: []const u8 = "\n", | ||||||
|     fn print(allocator: std.mem.Allocator, cards: []TextCard, allPrinted: *std.ArrayList(u8)) !void { |     fn print(allocator: std.mem.Allocator, cards: []TextCard, allPrinted: *std.ArrayList([]const u8)) !void { | ||||||
|         _ = allocator; |         // _ = allocator; | ||||||
|         var gpa = std.heap.GeneralPurposeAllocator(.{}){}; |         var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||||||
| 
 | 
 | ||||||
|         var lines = linesList{}; |         var lines = linesList{}; | ||||||
|         defer lines.deinit(gpa.allocator()); |         defer lines.deinit(gpa.allocator()); | ||||||
|  |         const dwd = try DisplayWidth.DisplayWidthData.init(allocator); | ||||||
|  |         const dw = DisplayWidth{ .data = &dwd }; | ||||||
| 
 | 
 | ||||||
|         for (cards, 0..) |cardObj, cardNo| { |         for (cards, 0..) |cardObj, cardNo| { | ||||||
|             //const cardText = try card(cardObj); |             //const cardText = try card(cardObj); | ||||||
|  | @ -227,9 +212,12 @@ const cardRow = struct { | ||||||
|                 //this step is probably unnecessary |                 //this step is probably unnecessary | ||||||
|                 const strippedLine = std.mem.trimRight(u8, line, " "); |                 const strippedLine = std.mem.trimRight(u8, line, " "); | ||||||
|                 const paddedLine = try std.fmt.allocPrint(gpa.allocator(), lineFormatter, .{strippedLine}); |                 const paddedLine = try std.fmt.allocPrint(gpa.allocator(), lineFormatter, .{strippedLine}); | ||||||
|                 const theoreticalLength = (paddedLine.len * 3) + 1; |                 // const theoreticalLength = (paddedLine.len * 3) + 1; | ||||||
|                 assert(paddedLine.len == spacer.len); |                 std.debug.print("{s}\n", .{paddedLine}); | ||||||
|                 assert(theoreticalLength == pageWidth); |                 std.debug.print("expected {d}, got: ", .{dw.strWidth(spacer)}); | ||||||
|  |                 std.debug.print("{d}\n", .{dw.strWidth(paddedLine)}); | ||||||
|  |                 assert(dw.strWidth(paddedLine) == dw.strWidth(spacer)); | ||||||
|  |                 // assert(theoreticalLength == pageWidth); | ||||||
|                 const placeholder = if (idx < lines.items(.first).len) lines.get(idx) else cardRow{}; |                 const placeholder = if (idx < lines.items(.first).len) lines.get(idx) else cardRow{}; | ||||||
|                 const new: cardRow = switch (cardNo) { |                 const new: cardRow = switch (cardNo) { | ||||||
|                     0 => .{ .first = paddedLine }, |                     0 => .{ .first = paddedLine }, | ||||||
|  | @ -245,28 +233,19 @@ const cardRow = struct { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         const rowHeight = lines.items(.first).len; |         const rowHeight = lines.items(.first).len; | ||||||
|         while (remainingPage(allPrinted.items.len) <= rowHeight) { |         while (pageHeight - (allPrinted.items.len % pageHeight) <= rowHeight) { | ||||||
|             try allPrinted.appendSlice(fullWidthSpacer); |             try allPrinted.append(fullWidthSpacer); | ||||||
|         } |         } | ||||||
|         for (lines.items(.first), 0..) |_, idx| { |         for (lines.items(.first), 0..) |_, idx| { | ||||||
|             const line = lines.get(idx); |             const line = lines.get(idx); | ||||||
|             const printedWidth = line.first.len + line.second.len + line.third.len + line.last.len; |             // const printedWidth = line + line.second.len + line.third.len + line.last.len; | ||||||
|             assert(printedWidth == pageWidth); |             // assert(printedWidth == pageWidth); | ||||||
|             const fullLine = try std.mem.concat(gpa.allocator(), u8, &[_][]const u8{ line.first, line.second, line.third, line.last }); |             const fullLine = try std.mem.concat(gpa.allocator(), u8, &[_][]const u8{ line.first, line.second, line.third, line.last }); | ||||||
|             try allPrinted.appendSlice(fullLine); |             try allPrinted.append(fullLine); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| test "Remaining page length" { |  | ||||||
|     try expect(remainingPage(67) == 0); |  | ||||||
|     try expect(remainingPage(1) == 0); |  | ||||||
| } |  | ||||||
| fn remainingPage(length: usize) usize { |  | ||||||
|     assert(length % pageWidth == 0); |  | ||||||
|     return pageHeight - ((length / pageWidth) % pageHeight); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn stringToBool(str: ?[]const u8) bool { | fn stringToBool(str: ?[]const u8) bool { | ||||||
|     return std.mem.eql(u8, (str orelse "false"), "true"); |     return std.mem.eql(u8, (str orelse "false"), "true"); | ||||||
| } | } | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue