Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ zig-out/
*.o
extension_api.json
docs/plans/
.worktrees/
8 changes: 8 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ pub fn build(b: *std.Build) void {
.optimize = optimize,
}).module("zigdown");

const zig_xml = b.dependency("xml", .{
.target = target,
.optimize = optimize,
}).module("xml");

const mod = b.addModule("gdoc", .{
.root_source_file = b.path("src/root.zig"),
.target = target,
.imports = &.{
.{ .name = "bbcodez", .module = bbcodez },
.{ .name = "known-folders", .module = known_folders },
.{ .name = "zigdown", .module = zigdown },
.{ .name = "xml", .module = zig_xml },
},
});
mod.addOptions("build_options", build_options);
Expand Down Expand Up @@ -67,12 +73,14 @@ pub fn build(b: *std.Build) void {
});

const run_mod_tests = b.addRunArtifact(mod_tests);
run_mod_tests.setEnvironmentVariable("GDOC_NO_XML", "1");

const exe_tests = b.addTest(.{
.root_module = exe.root_module,
});

const run_exe_tests = b.addRunArtifact(exe_tests);
run_exe_tests.setEnvironmentVariable("GDOC_NO_XML", "1");

const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_mod_tests.step);
Expand Down
4 changes: 4 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
.url = "https://github.com/JacobCrabill/zigdown/archive/refs/tags/v1.2.0.tar.gz",
.hash = "zigdown-1.2.0-M06JT7-lFQCrQRNGBipFjSt-qAvFSLgy8-f-D4VFAeOi",
},
.xml = .{
.url = "git+https://github.com/ianprime0509/zig-xml#8874de5b846f4e3e806a062cd11a01b2bb90fc7a",
.hash = "xml-0.2.0-ZTbP3wE6AgCsnyZut_plzxi6WB2tzzh3kFRBOp3AL7n9",
},
},
.paths = .{
"build.zig",
Expand Down
12 changes: 12 additions & 0 deletions snapshots/class_with_tutorials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Sprite2D

General-purpose sprite node.

## Description

A node that displays a 2D texture.

## Tutorials

- [Custom drawing in 2D](https://docs.godotengine.org/en/stable/tutorials/2d/custom_drawing_in_2d.html)
- [All 2D Demos](https://github.com/godotengine/godot-demo-projects/tree/master/2d)
50 changes: 50 additions & 0 deletions src/DocDatabase.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ pub const EntryKind = enum {
signal,
};

pub const Tutorial = struct {
title: []const u8,
url: []const u8,
};

pub const Entry = struct {
key: []const u8,
name: []const u8,
Expand All @@ -30,6 +35,7 @@ pub const Entry = struct {
brief_description: ?[]const u8 = null,
signature: ?[]const u8 = null,
members: ?[]usize = null,
tutorials: ?[]const Tutorial = null,
};

const RootState = enum {
Expand Down Expand Up @@ -421,6 +427,15 @@ fn generateMarkdownForEntry(self: DocDatabase, allocator: Allocator, entry: Entr
try writer.print("\n## Description\n\n{s}\n", .{desc});
}

if (entry.tutorials) |tutorials| {
if (tutorials.len > 0) {
try writer.writeAll("\n## Tutorials\n\n");
for (tutorials) |tutorial| {
try writer.print("- [{s}]({s})\n", .{ tutorial.title, tutorial.url });
}
}
}

if (entry.members) |member_indices| {
try self.generateMemberListings(allocator, member_indices, writer);
}
Expand Down Expand Up @@ -1263,6 +1278,41 @@ test "generateMarkdownForSymbol for class with members" {
try writer.flush();
}

test "generateMarkdownForSymbol for class with tutorials" {
const allocator = std.testing.allocator;

var db = DocDatabase{
.symbols = StringArrayHashMap(Entry).empty,
};
defer db.symbols.deinit(allocator);

const tutorials = [_]Tutorial{
.{ .title = "Custom drawing in 2D", .url = "https://docs.godotengine.org/en/stable/tutorials/2d/custom_drawing_in_2d.html" },
.{ .title = "All 2D Demos", .url = "https://github.com/godotengine/godot-demo-projects/tree/master/2d" },
};

const entry = Entry{
.key = "Sprite2D",
.name = "Sprite2D",
.kind = .class,
.brief_description = "General-purpose sprite node.",
.description = "A node that displays a 2D texture.",
.tutorials = &tutorials,
};
try db.symbols.put(allocator, "Sprite2D", entry);

// Write snapshot
var file = try std.fs.cwd().createFile("snapshots/class_with_tutorials.md", .{});
defer file.close();

var buf: [4096]u8 = undefined;
var file_writer = file.writer(&buf);
const writer = &file_writer.interface;

try db.generateMarkdownForSymbol(allocator, "Sprite2D", writer);
try writer.flush();
}

const std = @import("std");
const ArenaAllocator = std.heap.ArenaAllocator;
const Allocator = std.mem.Allocator;
Expand Down
42 changes: 42 additions & 0 deletions src/Spinner.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const std = @import("std");

const Spinner = @This();

const frames = [_][]const u8{ "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" };
const delay_ns = 80 * std.time.ns_per_ms;

message: []const u8,
thread: ?std.Thread = null,
stop: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),

pub fn start(self: *Spinner) void {
self.stop.store(false, .release);
self.thread = std.Thread.spawn(.{}, run, .{self}) catch return;
}

pub fn finish(self: *Spinner) void {
if (self.thread == null) return;

self.stop.store(true, .release);
self.thread.?.join();
self.thread = null;

const stderr = std.fs.File.stderr();
var buf: [256]u8 = undefined;
var w = stderr.writer(&buf);
w.interface.writeAll("\r\x1b[2K") catch {};
w.interface.flush() catch {};
}

fn run(self: *Spinner) void {
const stderr = std.fs.File.stderr();
var buf: [256]u8 = undefined;
var w = stderr.writer(&buf);
var i: usize = 0;
while (!self.stop.load(.acquire)) {
w.interface.print("\r{s} {s}", .{ frames[i], self.message }) catch return;
w.interface.flush() catch return;
i = (i + 1) % frames.len;
std.Thread.sleep(delay_ns);
}
}
Loading
Loading