Skip to content

Commit cf94d12

Browse files
flexibeastericonr
authored andcommitted
mdbook-gemini: Add script.
- optional, so if md2gemini isn't in path it fails silently
1 parent b381d47 commit cf94d12

3 files changed

Lines changed: 127 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Void packages:
1818
- `perl`
1919
- `perl-JSON`
2020
- `librsvg-utils`
21+
- `python3-md2gemini`
2122

2223
In order to build and install these files, set the `PREFIX` and `DESTDIR`
2324
environment variables to appropriate values and run `res/build.sh` followed by

book.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ theme = "src/theme"
1414
[output.latex]
1515
optional = true
1616

17+
[output.gemini]
18+
optional = true
19+
1720
[output.linkcheck]
1821
optional = true
1922
follow-web-links = true

res/mdbook-gemini

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/perl
2+
3+
use strict;
4+
use warnings;
5+
6+
use File::Which;
7+
use File::Path qw(make_path);
8+
use JSON;
9+
10+
# Accept input on stdin regardless of whether the 'md2gemini' executable
11+
# is present, to avoid "Broken pipe" errors from mdBook.
12+
13+
my $data;
14+
{
15+
local $/;
16+
undef $/;
17+
$data = <>;
18+
}
19+
20+
if (! defined which 'md2gemini') {
21+
print "'md2gemini' not found in PATH; not building Gemini output\n";
22+
# We can't return non-zero here, as that would cause the entire
23+
# mdBook build process to fail.
24+
exit 0;
25+
}
26+
27+
my $json = JSON->new->decode($data);
28+
my $sections = $json->{book}->{sections};
29+
30+
# Create toc.gmi from SUMMARY.md
31+
32+
my $leader;
33+
34+
open(my $summary, '<', '../../src/SUMMARY.md')
35+
or die "Can't open SUMMARY.md for reading: $!\n";
36+
open(my $toc, '>', 'toc.gmi')
37+
or die "Can't open toc.gmi for writing: $!\n";
38+
39+
print $toc "# Table of Contents\n\n";
40+
while (<$summary>) {
41+
42+
if (/^(\s*)- \[([^\]]+)\]\(([^\)]+)\)/) {
43+
44+
my $depth = $1;
45+
my $heading = $2;
46+
my $path = $3;
47+
48+
if (length($depth) == 0) {
49+
$leader = '-';
50+
} else {
51+
$leader = '-' x (1 + (length($depth) / 3));
52+
}
53+
54+
$path =~ s/\.md$/.gmi/;
55+
56+
print $toc "=> " . $path . " " . $leader . " " . $heading . "\n";
57+
58+
}
59+
60+
}
61+
62+
close($summary)
63+
or die "Can't close SUMMARY.md after reading: $!\n";
64+
close($toc)
65+
or die "Can't close toc.gmi after writing: $!\n";
66+
67+
# Create individual pages.
68+
69+
foreach my $i (@$sections) {
70+
process_json($i);
71+
}
72+
73+
exit 0;
74+
75+
76+
### Functions
77+
78+
sub process_json {
79+
80+
my $i = shift;
81+
my $type = ref($i);
82+
if ($type eq 'HASH') {
83+
if (defined $i->{content}) {
84+
process_content($i->{path},$i->{content});
85+
}
86+
if (defined $i->{Chapter}) {
87+
process_json($i->{Chapter});
88+
}
89+
if (defined $i->{sub_items}) {
90+
foreach my $j ($i->{sub_items}) {
91+
process_json($j);
92+
}
93+
}
94+
}
95+
if ($type eq 'ARRAY') {
96+
foreach my $j (@{$i}) {
97+
process_json($j);
98+
}
99+
}
100+
}
101+
102+
sub process_content {
103+
104+
my $path = shift;
105+
my $directory = $path;
106+
my $filename = $path;
107+
my $content = shift;
108+
my $fh;
109+
110+
$directory =~ s|/[^/]+\.md$||;
111+
$filename =~ s|^.*/([^/]+)\.md$|$1.gmi|;
112+
113+
make_path($directory);
114+
115+
open($fh, "| md2gemini --links copy --md-links --ascii-table > " .
116+
$directory . '/' . $filename)
117+
or die "Can't open pipe to md2gemini: $!\n";
118+
print $fh $content;
119+
print $fh "\n\n" . "=> /toc.gmi Table of Contents" . "\n";
120+
close $fh
121+
or die "Can't close pipe to md2gemini: $!\n";
122+
123+
}

0 commit comments

Comments
 (0)