dual-faced cards now print much more sanely

also eliminated some duplicated/unnecessary logic
This commit is contained in:
Lumen Keyes 2024-07-17 22:56:42 -06:00
parent 78bad5b043
commit 5ad5b2edf3
3 changed files with 507 additions and 516 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,3 @@
//TODO: print mana cost beside each name for dual-faced cards
//TODO: consider eliminating the TextCard struct
//TODO: add some kind of "update" command to support pulling new oracle data
//TODO: implement oracleFileName as a cli arg
@ -37,6 +36,7 @@ const Card = struct {
toughness: ?[]const u8 = null, //coerced to string
card_faces: ?[]Card = null, //array of cards
loyalty: ?[]const u8 = null, //coerced to string
isFace: bool = undefined, //cheeky little property that I added
};
const TextCard = struct {
@ -105,23 +105,21 @@ pub fn main() !void {
var jsonReader = json.reader(allocator, oracleFile.reader());
const parsedJson = try json.parseFromTokenSource([]Card, allocator, &jsonReader, .{ .ignore_unknown_fields = true });
var cardNames = std.ArrayList([]const u8).init(allocator);
var cardNames = std.BufSet.init(allocator);
const listText = try cwd.readFileAlloc(allocator, listFileName, 1024 * 100);
var listLines = std.mem.splitAny(u8, listText, "\n");
while (listLines.next()) |line| {
if (line.len < 5) break;
const cardName = line[indexOf(u8, line, " ").? + 1 .. indexOf(u8, line, "(").? - 1];
try cardNames.append(try allocator.dupe(u8, cardName));
try cardNames.insert(cardName);
}
var cards = std.StringArrayHashMap(TextCard).init(allocator);
for (parsedJson.value) |cardObj| {
for (cardNames.items, 0..) |cardName, i| {
if (std.mem.eql(u8, cardName, cardObj.name)) {
const printableCard = try card(cardObj, allocator, false);
for (parsedJson.value) |*cardObj| {
if (cardNames.contains(cardObj.name)) {
cardObj.isFace = false;
const printableCard = try card(cardObj.*, allocator);
try cards.put(cardObj.name, printableCard);
_ = cardNames.orderedRemove(i);
}
}
}
@ -148,12 +146,10 @@ pub fn main() !void {
for (allPrinted.items, 1..) |text, rowNum| {
const pageRelative = rowNum % pageHeight;
const pageOffset: f32 = 12 * @as(f32, @floatFromInt(pageRelative));
if (pageRelative != 0) {
_ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, pdfHeight - pageOffset, c.PDF_BLACK);
} else {
if (pageRelative == 0) {
page = c.pdf_append_page(pdf_doc);
_ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, pdfHeight - pageOffset, c.PDF_BLACK);
}
_ = c.pdf_add_text(pdf_doc, page, try std.mem.Allocator.dupeZ(allocator, u8, text), 8, 10, pdfHeight - pageOffset, c.PDF_BLACK);
}
_ = c.pdf_save(pdf_doc, "output.pdf");
@ -163,12 +159,12 @@ pub fn main() !void {
fn card(
cardObj: Card,
allocator: std.mem.Allocator,
isFace: bool,
) !TextCard {
var cardText = std.ArrayList([]const u8).init(allocator);
var fullUnformattedText = std.ArrayList(u8).init(allocator);
if (!isFace) {
if (cardObj.card_faces == null or cardObj.isFace) {
try fullUnformattedText.appendSlice(try std.mem.concat(allocator, u8, &[_][]const u8{
cardObj.name,
if (cardObj.mana_cost.len > 0) " " else "",
@ -176,23 +172,23 @@ fn card(
" (",
cardObj.type_line,
") >> ",
}));
}
try fullUnformattedText.appendSlice(try std.mem.concat(allocator, u8, &[_][]const u8{
cardObj.oracle_text,
if (cardObj.power) |_| " (" else "",
cardObj.power orelse "",
if (cardObj.power) |_| "/" else "",
cardObj.toughness orelse "",
if (cardObj.power) |_| ") " else "",
if(cardObj.loyalty) |_| "[" else "",
cardObj.loyalty orelse "",
if(cardObj.loyalty) |_| "]" else "",
}));
}
if (cardObj.card_faces) |faces| {
for (faces, 0..) |face, idx| {
const faceText = (try card(face, allocator, true)).lines;
for (faces, 0..) |*face, idx| {
face.isFace = true;
const faceText = (try card(face.*, allocator)).lines;
try fullUnformattedText.appendSlice(std.mem.trim(u8, try std.mem.join(allocator, " ", faceText), "\n"));
if (idx == 0) try fullUnformattedText.appendSlice("// ");
}
@ -201,25 +197,20 @@ fn card(
var line = std.ArrayList(u8).init(allocator);
var wordIterator = std.mem.splitAny(u8, fullUnformattedText.items, "\n ");
while (wordIterator.next()) |word| {
if (line.items.len + word.len + 1 < cardWidth) {
if (line.items.len + word.len + 1 >= cardWidth) {
try cardText.append(try line.toOwnedSlice());
line.clearAndFree();
}
try line.appendSlice(word);
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 {
try cardText.append(try line.toOwnedSlice());
}
if(!isFace and constantHeight) {
const actualHeight: usize = cardText.items.len;
assert(actualHeight <= cardHeight);
const diff = cardHeight - actualHeight;
try cardText.appendNTimes(" " ** (cardWidth - 2), diff);
} else if(!isFace) {
if(!cardObj.isFace and constantHeight) {
assert(cardText.items.len <= cardHeight);
try cardText.appendNTimes(" " ** (cardWidth - 2), cardHeight - cardText.items.len);
} else if(!cardObj.isFace) {
try cardText.append(" " ** (cardWidth - 2));
}
assert(cardText.items.len <= cardHeight);

Binary file not shown.