Skip to content

Commit 15eeda8

Browse files
committed
Merge branch 'master' of github.com:perl6/doc
2 parents e7a4202 + db7f995 commit 15eeda8

27 files changed

+1543
-85
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ index.data
44
html/*.html
55
html/routine/
66
html/type/
7+
html/op/
78
html/language/
89
html/images/

META.info

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name" : "p6doc",
3+
"version" : "*",
4+
"description" : "Perl 6 documentation (tools and docs)",
5+
"depends" : [ "URI" ],
6+
"source-url" : "git://github.com/perl6/doc.git"
7+
}

htmlify.pl

Lines changed: 200 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,28 @@
99
use lib 'lib';
1010
use Perl6::TypeGraph;
1111
use Perl6::TypeGraph::Viz;
12+
use Perl6::Documentable::Registry;
1213

1314
sub url-munge($_) {
1415
return $_ if m{^ <[a..z]>+ '://'};
1516
return "/type/$_" if m/^<[A..Z]>/;
1617
return "/routine/$_" if m/^<[a..z]>/;
18+
# poor man's <identifier>
19+
if m/ ^ '&'( \w <[[\w'-]>* ) $/ {
20+
return "/routine/$0";
21+
}
1722
return $_;
1823
}
1924

2025
my $*DEBUG = False;
2126

2227
my $tg;
23-
my %names;
24-
my %types;
25-
my %routines;
2628
my %methods-by-type;
27-
my $footer;
29+
my $footer = footer-html;
30+
31+
sub p2h($pod) {
32+
pod2html($pod, :url(&url-munge), :$footer);
33+
}
2834

2935
sub pod-gist(Pod::Block $pod, $level = 0) {
3036
my $leading = ' ' x $level;
@@ -63,9 +69,17 @@
6369
}
6470
}
6571

72+
sub first-code-block(@pod) {
73+
if @pod[1] ~~ Pod::Block::Code {
74+
return @pod[1].content.grep(Str).join;
75+
}
76+
'';
77+
}
78+
6679
sub MAIN(Bool :$debug, Bool :$typegraph = False) {
6780
$*DEBUG = $debug;
68-
for ('', <type language routine images>) {
81+
for '', <type language routine images op op/prefix op/postfix op/infix
82+
op/circumfix op/postcircumfix op/listop> {
6983
mkdir "html/$_" unless "html/$_".IO ~~ :e;
7084
}
7185

@@ -82,38 +96,53 @@ (Bool :$debug, Bool :$typegraph = False)
8296
}
8397
say "... done";
8498

85-
$footer = footer-html;
86-
87-
99+
my $dr = Perl6::Documentable::Registry.new;
88100

89101
for (@source) {
90102
my $podname = .key;
91103
my $file = .value;
92104
my $what = $podname ~~ /^<[A..Z]> | '::'/ ?? 'type' !! 'language';
93105
say "$file.path() => $what/$podname";
94-
%names{$podname}{$what}.push: "/$what/$podname";
95-
%types{$what}{$podname} = "/$what/$podname";
96106
my $pod = eval slurp($file.path) ~ "\n\$=pod";
107+
$pod.=[0];
97108
if $what eq 'language' {
98-
spurt "html/$what/$podname.html", pod2html($pod, :url(&url-munge), :$footer);
109+
spurt "html/$what/$podname.html", p2h($pod);
110+
if $podname eq 'operators' {
111+
my @chunks = chunks-grep($pod.content,
112+
:from({ $_ ~~ Pod::Heading and .level == 2}),
113+
:to({ $^b ~~ Pod::Heading and $^b.level <= $^a.level}),
114+
);
115+
for @chunks -> $chunk {
116+
my $heading = $chunk[0].content[0].content[0];
117+
next unless $heading ~~ / ^ [in | pre | post | circum | postcircum ] fix | listop /;
118+
my $what = ~$/;
119+
my $operator = $heading.split(' ', 2)[1];
120+
$dr.add-new(
121+
:kind<operator>,
122+
:subkind($what),
123+
:pod($chunk),
124+
:!pod-is-complete,
125+
:name($operator),
126+
);
127+
}
128+
}
129+
$dr.add-new(
130+
:kind<language>,
131+
:name($podname),
132+
:$pod,
133+
:pod-is-complete,
134+
);
135+
99136
next;
100137
}
101138
$pod = $pod[0];
102139

103140
say pod-gist($pod) if $*DEBUG;
104141
my @chunks = chunks-grep($pod.content,
105142
:from({ $_ ~~ Pod::Heading and .level == 2}),
106-
:to({ $^b ~~ Pod::Heading and $^b.level <= $^a.level}),
143+
:to({ $^b ~~ Pod::Heading and $^b.level <= $^a.level}),
107144
);
108-
for @chunks -> $chunk {
109-
my $name = $chunk[0].content[0].content[0];
110-
say "$podname.$name" if $*DEBUG;
111-
next if $name ~~ /\s/;
112-
%methods-by-type{$podname}.push: $chunk;
113-
%names{$name}<routine>.push: "/type/$podname.html#" ~ uri_escape($name);
114-
%routines{$name}.push: $podname => $chunk;
115-
%types<routine>{$name} = "/routine/" ~ uri_escape( $name );
116-
}
145+
117146
if $tg.types{$podname} -> $t {
118147
$pod.content.push: Pod::Block::Named.new(
119148
name => 'Image',
@@ -164,19 +193,60 @@ (Bool :$debug, Bool :$typegraph = False)
164193
}
165194
}
166195
}
167-
spurt "html/$what/$podname.html", pod2html($pod, :url(&url-munge), :$footer);
196+
my $d = $dr.add-new(
197+
:kind<type>,
198+
# TODO: subkind
199+
:$pod,
200+
:pod-is-complete,
201+
:name($podname),
202+
);
203+
204+
for @chunks -> $chunk {
205+
my $name = $chunk[0].content[0].content[0];
206+
say "$podname.$name" if $*DEBUG;
207+
next if $name ~~ /\s/;
208+
%methods-by-type{$podname}.push: $chunk;
209+
# deterimine whether it's a sub or method
210+
my Str $subkind;
211+
{
212+
my %counter;
213+
for first-code-block($chunk).lines {
214+
if ms/^ 'multi'? (sub|method)»/ {
215+
%counter{$0}++;
216+
}
217+
}
218+
if %counter == 1 {
219+
($subkind,) = %counter.keys;
220+
}
221+
}
222+
223+
$dr.add-new(
224+
:kind<routine>,
225+
:$subkind,
226+
:$name,
227+
:pod($chunk),
228+
:!pod-is-complete,
229+
:origin($d),
230+
);
231+
}
232+
spurt "html/$what/$podname.html", p2h($pod);
168233
}
169234

235+
$dr.compose;
236+
237+
write-disambiguation-files($dr);
238+
write-operator-files($dr);
170239
write-type-graph-images(:force($typegraph));
171-
write-search-file();
172-
write-index-file();
173-
say "Writing per-routine files...";
174-
for %routines.kv -> $name, @chunks {
175-
write-routine-file(:$name, :@chunks);
176-
%routines.delete($name);
240+
write-search-file($dr);
241+
write-index-file($dr);
242+
say "Writing per-routine files";
243+
my %routine-seen;
244+
for $dr.lookup('routine', :by<kind>).list -> $d {
245+
next if %routine-seen{$d.name}++;
246+
write-routine-file($dr, $d.name);
247+
print '.'
177248
}
178-
say "done writing per-routine files";
179-
# TODO: write top-level disambiguation files
249+
say "\ndone writing per-routine files";
180250
}
181251

182252
sub chunks-grep(:$from!, :&to!, *@elems) {
@@ -244,8 +314,6 @@ (Bool :$debug, Bool :$typegraph = False)
244314
sub write-type-graph-images(:$force) {
245315
unless $force {
246316
my $dest = 'html/images/type-graph-Any.svg'.path;
247-
say "cwd: ", cwd;
248-
say 'type-graph.txt'.path.e;
249317
if $dest.e && $dest.modified >= 'type-graph.txt'.path.modified {
250318
say "Not writing type graph images, it seems to be up-to-date";
251319
say "To force writing of type graph images, supply the --typegraph";
@@ -316,71 +384,143 @@ (Bool :$debug, Bool :$typegraph = False)
316384
';
317385
}
318386

319-
sub write-search-file() {
387+
sub write-search-file($dr) {
320388
say "Writing html/search.html";
321389
my $template = slurp("search_template.html");
322390
my @items;
323391
my sub fix-url ($raw) { $raw.substr(1) ~ '.html' };
324-
@items.push: %types<language>.pairs.sort.map({
325-
"\{ label: \"Language: {.key}\", value: \"{.key}\", url: \"{ fix-url(.value) }\" \}"
392+
@items.push: $dr.lookup('language', :by<kind>).sort(*.name).map({
393+
"\{ label: \"Language: {.name}\", value: \"{.name}\", url: \"{ fix-url(.url) }\" \}"
394+
});
395+
@items.push: $dr.lookup('type', :by<kind>).sort(*.name).map({
396+
"\{ label: \"Type: {.name}\", value: \"{.name}\", url: \"{ fix-url(.url) }\" \}"
326397
});
327-
@items.push: %types<type>.sort.map({
328-
"\{ label: \"Type: {.key}\", value: \"{.key}\", url: \"{ fix-url(.value) }\" \}"
398+
my %seen;
399+
@items.push: $dr.lookup('routine', :by<kind>).grep({!%seen{.name}++}).sort(*.name).map({
400+
"\{ label: \"{ (.subkind // 'Routine').tclc }: {.name}\", value: \"{.name}\", url: \"{ fix-url(.url) }\" \}"
329401
});
330-
@items.push: %types<routine>.sort.map({
331-
"\{ label: \"Routine: {.key}\", value: \"{.key}\", url: \"{ fix-url(.value) }\" \}"
402+
sub escape(Str $s) {
403+
$s.trans([</ \\ ">] => [<\\/ \\\\ \\">]);
404+
}
405+
@items.push: $dr.lookup('operator', :by<kind>).map({
406+
qq[\{ label: "$_.human-kind() {escape .name}", value: "{escape .name}", url: "{ fix-url .url }"\}]
332407
});
333408

334409
my $items = @items.join(",\n");
335410
spurt("html/search.html", $template.subst("ITEMS", $items));
336411
}
337412

338-
sub write-index-file() {
413+
sub write-disambiguation-files($dr) {
414+
say "Writing disambiguation files";
415+
for $dr.grouped-by('name').kv -> $name, $p is copy {
416+
print '.';
417+
my $pod = pod-with-title("Disambiguation for '$name'");
418+
if $p.elems == 1 {
419+
$p.=[0] if $p ~~ Array;
420+
if $p.origin -> $o {
421+
$pod.content.push:
422+
pod-block(
423+
pod-link("'$name' is a $p.human-kind()", $p.url),
424+
' from ',
425+
pod-link($o.human-kind() ~ ' ' ~ $o.name, $o.url),
426+
);
427+
}
428+
else {
429+
$pod.content.push:
430+
pod-block(
431+
pod-link("'$name' is a $p.human-kind()", $p.url)
432+
);
433+
}
434+
}
435+
else {
436+
$pod.content.push:
437+
pod-block("'$name' can be anything of the following"),
438+
$p.map({
439+
if .origin -> $o {
440+
pod-item(
441+
pod-link(.human-kind, .url),
442+
' from ',
443+
pod-link($o.human-kind() ~ ' ' ~ $o.name, $o.url),
444+
)
445+
}
446+
else {
447+
pod-item( pod-link(.human-kind, .url) )
448+
}
449+
});
450+
}
451+
spurt "html/$name.html", p2h($pod);
452+
}
453+
say "... done writing disambiguation files";
454+
}
455+
456+
sub write-operator-files($dr) {
457+
say "Writing operator files";
458+
for $dr.lookup('operator', :by<kind>).list -> $doc {
459+
my $what = $doc.subkind;
460+
my $op = $doc.name;
461+
my $pod = pod-with-title(
462+
"$what.tclc() $op operator",
463+
pod-block(
464+
"Documentation for $what $op, extracted from ",
465+
pod-link("the operators language documentation", "/language/operators")
466+
),
467+
@($doc.pod),
468+
);
469+
spurt "html/op/$what/$op.html", p2h($pod);
470+
}
471+
}
472+
473+
sub write-index-file($dr) {
339474
say "Writing html/index.html";
475+
my %routine-seen;
340476
my $pod = pod-with-title('Perl 6 Documentation',
341477
Pod::Block::Para.new(
342478
content => ['Official Perl 6 documentation'],
343479
),
344480
# TODO: add more
345481
pod-heading("Language Documentation"),
346-
%types<language>.pairs.sort.map({
347-
pod-item( pod-link(.key, .value) )
482+
$dr.lookup('language', :by<kind>).sort(*.name).map({
483+
pod-item( pod-link(.name, .url) )
348484
}),
349485
pod-heading('Types'),
350-
%types<type>.sort.map({
351-
pod-item(pod-link(.key, .value))
486+
$dr.lookup('type', :by<kind>).sort(*.name).map({
487+
pod-item(pod-link(.name, .url))
352488
}),
353489
pod-heading('Routines'),
354-
%types<routine>.sort.map({
355-
pod-item(pod-link(.key, .value))
490+
$dr.lookup('routine', :by<kind>).sort(*.name).map({
491+
next if %routine-seen{.name}++;
492+
pod-item(pod-link(.name, .url))
356493
}),
357494
);
358-
my $file = open :w, "html/index.html";
359-
$file.print: pod2html($pod, :url(&url-munge), :$footer);
360-
$file.close;
495+
spurt 'html/index.html', p2h($pod);
361496
}
362497

363-
sub write-routine-file(:$name!, :@chunks!) {
498+
sub write-routine-file($dr, $name) {
364499
say "Writing html/routine/$name.html" if $*DEBUG;
365-
my $pod = pod-with-title("Documentation for routine $name",
366-
pod-block("Documentation for routine $name, assembled from the
500+
my @docs = $dr.lookup($name, :by<name>).grep(*.kind eq 'routine');
501+
my $subkind = 'routine';
502+
{
503+
my @subkinds = @docs>>.subkind;
504+
$subkind = @subkinds[0] if all(@subkinds>>.defined) && [eq] @subkinds;
505+
}
506+
my $pod = pod-with-title("Documentation for $subkind $name",
507+
pod-block("Documentation for $subkind $name, assembled from the
367508
following types:"),
368-
@chunks.map(-> Pair (:key($type), :value($chunk)) {
369-
pod-heading($type),
370-
pod-block("From ", pod-link($type, "/type/{$type}#$name")),
371-
@$chunk
509+
@docs.map({
510+
pod-heading(.origin.name ~ '.' ~ .name),
511+
pod-block("From ", pod-link(.origin.name, .origin.url ~ '#' ~ .name)),
512+
.pod.list,
372513
})
373514
);
374-
my $file = open :w, "html/routine/$name.html";
375-
$file.print: pod2html($pod, :url(&url-munge), :$footer);
376-
$file.close;
515+
spurt "html/routine/$name.html", p2h($pod);
377516
}
378517

379518
sub footer-html() {
519+
state $dt = ~DateTime.now;
380520
qq[
381521
<div id="footer">
382522
<p>
383-
Generated on {DateTime.now} from the sources at
523+
Generated on $dt from the sources at
384524
<a href="https://github.com/perl6/doc">perl6/doc on github</a>.
385525
</p>
386526
<p>

0 commit comments

Comments
 (0)