ghostty/src/build/GhosttyDocs.zig
2025-07-05 07:22:42 -07:00

125 lines
3.8 KiB
Zig

//! GhosttyDocs generates all the on-disk documentation that Ghostty is
//! installed with (man pages, html, markdown, etc.)
const GhosttyDocs = @This();
const std = @import("std");
const Config = @import("Config.zig");
const SharedDeps = @import("SharedDeps.zig");
steps: []*std.Build.Step,
pub fn init(
b: *std.Build,
deps: *const SharedDeps,
) !GhosttyDocs {
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
errdefer steps.deinit();
const manpages = [_]struct {
name: []const u8,
section: []const u8,
}{
.{ .name = "ghostty", .section = "1" },
.{ .name = "ghostty", .section = "5" },
};
inline for (manpages) |manpage| {
const generate_markdown = b.addExecutable(.{
.name = "mdgen_" ++ manpage.name ++ "_" ++ manpage.section,
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = b.graph.host,
.strip = false,
.omit_frame_pointer = false,
.unwind_tables = .sync,
}),
});
deps.help_strings.addImport(generate_markdown);
const gen_config = config: {
var copy = deps.config.*;
copy.exe_entrypoint = @field(
Config.ExeEntrypoint,
"mdgen_" ++ manpage.name ++ "_" ++ manpage.section,
);
break :config copy;
};
const generate_markdown_options = b.addOptions();
try gen_config.addOptions(generate_markdown_options);
generate_markdown.root_module.addOptions("build_options", generate_markdown_options);
const generate_markdown_step = b.addRunArtifact(generate_markdown);
const markdown_output = generate_markdown_step.captureStdOut();
try steps.append(&b.addInstallFile(
markdown_output,
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".md",
).step);
const generate_html = b.addSystemCommand(&.{"pandoc"});
generate_html.addArgs(&.{
"--standalone",
"--from",
"markdown",
"--to",
"html",
});
generate_html.addFileArg(markdown_output);
try steps.append(&b.addInstallFile(
generate_html.captureStdOut(),
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".html",
).step);
const generate_manpage = b.addSystemCommand(&.{"pandoc"});
generate_manpage.addArgs(&.{
"--standalone",
"--from",
"markdown",
"--to",
"man",
});
generate_manpage.addFileArg(markdown_output);
try steps.append(&b.addInstallFile(
generate_manpage.captureStdOut(),
"share/man/man" ++ manpage.section ++ "/" ++ manpage.name ++ "." ++ manpage.section,
).step);
}
return .{ .steps = steps.items };
}
pub fn install(self: *const GhosttyDocs) void {
const b = self.steps[0].owner;
self.addStepDependencies(b.getInstallStep());
}
pub fn addStepDependencies(
self: *const GhosttyDocs,
other_step: *std.Build.Step,
) void {
for (self.steps) |step| other_step.dependOn(step);
}
/// Installs some dummy files to satisfy the folder structure of docs
/// without actually generating any documentation. This is useful
/// when the `emit-docs` option is not set to true, but we still
/// need the rough directory structure to exist, such as for the macOS
/// app.
pub fn installDummy(self: *const GhosttyDocs, step: *std.Build.Step) void {
_ = self;
const b = step.owner;
var wf = b.addWriteFiles();
const path = "share/man/.placeholder";
step.dependOn(&b.addInstallFile(
wf.add(
path,
"emit-docs not true so no man pages",
),
path,
).step);
}