11const std = @import ("std" );
22const Epub = @import ("../epub/Epub.zig" );
3+ const xhtml = @import ("xhtml.zig" );
34
45const output_folder = "epub-files" ;
5- const meta_inf_folder = output_folder ++ "/META-INF" ;
6- const oebps_folder = output_folder ++ "/OEBPS" ;
6+ const meta_inf_folder = output_folder ++ "/META-INF/ " ;
7+ const oebps_folder = output_folder ++ "/OEBPS/ " ;
78const mimetype = output_folder ++ "/mimetype" ;
89const mimetype_content = "application/epub+zip" ;
9- const images_folder = oebps_folder ++ "/images" ;
10- const stylesheet = oebps_folder ++ "/stylesheet.css" ;
11- const container = meta_inf_folder ++ "/container.xml" ;
10+ const images_folder = oebps_folder ++ "images/" ;
11+ const stylesheet = oebps_folder ++ "stylesheet.css" ;
12+ const container = meta_inf_folder ++ "container.xml" ;
13+ const content_opf = oebps_folder ++ "content.opf" ;
14+
1215const container_content =
1316 \\<?xml version="1.0"?>
1417 \\<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
1518 \\ <rootfiles>
16- \\ <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml" />
19+ \\ <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
1720 \\ </rootfiles>
1821 \\</container>
1922;
2023
2124pub fn createEpubFiles (epub : * Epub ) ! void {
25+ const cwd = std .fs .cwd ();
26+
2227 try createOrOverrideDir (output_folder );
23- try std . fs . cwd () .makeDir (meta_inf_folder );
24- try std . fs . cwd () .makeDir (oebps_folder );
25- try std . fs . cwd () .makeDir (images_folder );
28+ try cwd .makeDir (meta_inf_folder );
29+ try cwd .makeDir (oebps_folder );
30+ try cwd .makeDir (images_folder );
2631 try createFileAndWrite (mimetype , mimetype_content );
2732 try createFileAndWrite (container , container_content );
2833
34+ try createContentOpf (epub );
35+
2936 std .log .debug ("Generating stylesheet if set: {s}\n " , .{stylesheet });
3037 if (epub .stylesheet ) | ss | try ss .generate (stylesheet );
38+
39+ std .log .debug ("Copying cover image if set: {any}\n " , .{epub .cover_image });
40+ if (epub .cover_image ) | path | {
41+ try saveToImageFolder (epub .allocator , path );
42+ }
43+
44+ std .log .debug ("Copying images if set: {any}\n " , .{epub .cover_image });
45+ if (epub .images ) | images | {
46+ for (images ) | img | try saveToImageFolder (epub .allocator , img );
47+ }
48+ }
49+
50+ fn saveToImageFolder (allocator : std.mem.Allocator , from : []const u8 ) ! void {
51+ const cwd = std .fs .cwd ();
52+ const epub_image_path = try std .mem .concat (allocator , u8 , &.{ images_folder , std .fs .path .basename (from ) });
53+ defer allocator .free (epub_image_path );
54+ try cwd .copyFile (from , cwd , epub_image_path , .{});
3155}
3256
3357fn createFileAndWrite (filename : []const u8 , content : []const u8 ) ! void {
@@ -38,13 +62,80 @@ fn createFileAndWrite(filename: []const u8, content: []const u8) !void {
3862}
3963
4064fn createOrOverrideDir (dirname : []const u8 ) ! void {
41- std .fs .cwd ().makeDir (dirname ) catch | err | {
65+ const cwd = std .fs .cwd ();
66+
67+ cwd .makeDir (dirname ) catch | err | {
4268 if (err == error .PathAlreadyExists ) {
4369 std .log .debug ("Deleting and creating existent dir: {s}\n " , .{dirname });
44- try std . fs . cwd () .deleteTree (dirname );
45- try std . fs . cwd () .makeDir (dirname );
70+ try cwd .deleteTree (dirname );
71+ try cwd .makeDir (dirname );
4672 } else {
4773 return err ;
4874 }
4975 };
5076}
77+
78+ fn createContentOpf (epub : * Epub ) ! void {
79+ var file = try std .fs .cwd ().createFile (content_opf , .{});
80+ defer file .close ();
81+ try file .writeAll (xhtml .content_opf_package_metadata );
82+
83+ // METADATA
84+ const metadata = epub .metadata ;
85+
86+ const title = try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_title , .{metadata .title });
87+ defer epub .allocator .free (title );
88+ try file .writeAll (title );
89+
90+ const creator = try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_creator , .{metadata .creator });
91+ defer epub .allocator .free (creator );
92+ try file .writeAll (creator );
93+
94+ const identifier = switch (metadata .identifier .identifier_type ) {
95+ .ISBN = > try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_identifier_isbn , .{metadata .identifier .value }),
96+ .UUID = > try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_identifier_uuid , .{metadata .identifier .value }),
97+ };
98+ defer epub .allocator .free (identifier );
99+ try file .writeAll (identifier );
100+
101+ const language = try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_language , .{metadata .language .toString ()});
102+ defer epub .allocator .free (language );
103+ try file .writeAll (language );
104+
105+ if (metadata .date ) | d | {
106+ const date = try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_date , .{d });
107+ defer epub .allocator .free (date );
108+ try file .writeAll (date );
109+ }
110+
111+ if (metadata .publisher ) | p | {
112+ const publisher = try std .fmt .allocPrint (epub .allocator , xhtml .content_opt_metadata_publisher , .{p });
113+ defer epub .allocator .free (publisher );
114+ try file .writeAll (publisher );
115+ }
116+
117+ if (epub .cover_image ) | _ | try file .writeAll (xhtml .content_opt_metadata_cover_image );
118+
119+ try file .writeAll (xhtml .content_opf_metadata_manifest );
120+
121+ // MANIFEST
122+ if (epub .stylesheet ) | _ | try file .writeAll (xhtml .content_opf_manifest_css );
123+
124+ if (epub .sections ) | sections | {
125+ for (sections .items ) | section | {
126+ const id = try std .mem .replaceOwned (u8 , epub .allocator , section .title , " " , "" );
127+ defer epub .allocator .free (id );
128+ const html = try std .fmt .allocPrint (epub .allocator , xhtml .content_opf_manifest_xhtml , .{ id , id });
129+ defer epub .allocator .free (html );
130+ try file .writeAll (html );
131+ }
132+ }
133+
134+ if (epub .cover ) | _ | {
135+ const html = try std .fmt .allocPrint (epub .allocator , xhtml .content_opf_manifest_xhtml , .{ "cover" , "cover" });
136+ defer epub .allocator .free (html );
137+ try file .writeAll (html );
138+ }
139+
140+ // cover_img
141+ }
0 commit comments