9
9
use lib ' lib' ;
10
10
use Perl6::TypeGraph;
11
11
use Perl6::TypeGraph::Viz;
12
+ use Perl6::Documentable::Registry;
12
13
13
14
sub url-munge ($ _ ) {
14
15
return $ _ if m {^ <[ a..z ] >+ '://' };
15
16
return " /type/$ _" if m /^ <[ A..Z ] > /;
16
17
return " /routine/$ _" if m /^ <[ a..z ] > /;
18
+ # poor man's <identifier>
19
+ if m / ^ '&' ( \w <[ [\w'- ] >* ) $ / {
20
+ return " /routine/$0" ;
21
+ }
17
22
return $ _ ;
18
23
}
19
24
20
25
my $ * DEBUG = False ;
21
26
22
27
my $ tg ;
23
- my % names ;
24
- my % types ;
25
- my % routines ;
26
28
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
+ }
28
34
29
35
sub pod-gist (Pod ::Block $ pod , $ level = 0 ) {
30
36
my $ leading = ' ' x $ level ;
63
69
}
64
70
}
65
71
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
+
66
79
sub MAIN (Bool : $ debug , Bool : $ typegraph = False ) {
67
80
$ * 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> {
69
83
mkdir " html/$ _" unless " html/$ _" . IO ~~ : e;
70
84
}
71
85
@@ -82,38 +96,53 @@ (Bool :$debug, Bool :$typegraph = False)
82
96
}
83
97
say " ... done" ;
84
98
85
- $ footer = footer-html;
86
-
87
-
99
+ my $ dr = Perl6::Documentable::Registry. new ;
88
100
89
101
for (@ source ) {
90
102
my $ podname = . key ;
91
103
my $ file = . value ;
92
104
my $ what = $ podname ~~ /^ <[ A..Z ] > | '::' / ?? ' type' !! ' language' ;
93
105
say " $ file. path () => $ what /$ podname" ;
94
- % names {$ podname }{$ what }. push : " /$ what /$ podname" ;
95
- % types {$ what }{$ podname } = " /$ what /$ podname" ;
96
106
my $ pod = eval slurp ($ file . path ) ~ " \n \$=pod" ;
107
+ $ pod .= [0 ];
97
108
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
+
99
136
next ;
100
137
}
101
138
$ pod = $ pod [0 ];
102
139
103
140
say pod-gist($ pod ) if $ * DEBUG ;
104
141
my @ chunks = chunks-grep($ pod . content,
105
142
: 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}),
107
144
);
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
+
117
146
if $ tg . types{$ podname } -> $ t {
118
147
$ pod . content. push : Pod ::Block::Named. new (
119
148
name => ' Image' ,
@@ -164,19 +193,60 @@ (Bool :$debug, Bool :$typegraph = False)
164
193
}
165
194
}
166
195
}
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 );
168
233
}
169
234
235
+ $ dr . compose;
236
+
237
+ write-disambiguation-files($ dr );
238
+ write-operator-files($ dr );
170
239
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 ' .'
177
248
}
178
- say " done writing per-routine files" ;
179
- # TODO: write top-level disambiguation files
249
+ say " \n done writing per-routine files" ;
180
250
}
181
251
182
252
sub chunks-grep (: $ from ! , : & to ! , * @ elems ) {
@@ -244,8 +314,6 @@ (Bool :$debug, Bool :$typegraph = False)
244
314
sub write-type-graph-images (: $ force ) {
245
315
unless $ force {
246
316
my $ dest = ' html/images/type-graph-Any.svg' . path ;
247
- say " cwd: " , cwd;
248
- say ' type-graph.txt' . path . e ;
249
317
if $ dest . e && $ dest . modified >= ' type-graph.txt' . path . modified {
250
318
say " Not writing type graph images, it seems to be up-to-date" ;
251
319
say " To force writing of type graph images, supply the --typegraph" ;
@@ -316,71 +384,143 @@ (Bool :$debug, Bool :$typegraph = False)
316
384
' ;
317
385
}
318
386
319
- sub write-search-file () {
387
+ sub write-search-file ($ dr ) {
320
388
say " Writing html/search.html" ;
321
389
my $ template = slurp (" search_template.html" );
322
390
my @ items ;
323
391
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) } \" \} "
326
397
});
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) } \" \} "
329
401
});
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 } "\} ]
332
407
});
333
408
334
409
my $ items = @ items . join (" ,\n " );
335
410
spurt (" html/search.html" , $ template . subst (" ITEMS" , $ items ));
336
411
}
337
412
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 ) {
339
474
say " Writing html/index.html" ;
475
+ my % routine-seen ;
340
476
my $ pod = pod-with-title(' Perl 6 Documentation' ,
341
477
Pod ::Block::Para. new (
342
478
content => [' Official Perl 6 documentation' ],
343
479
),
344
480
# TODO: add more
345
481
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 ) )
348
484
}),
349
485
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 ))
352
488
}),
353
489
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))
356
493
}),
357
494
);
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 );
361
496
}
362
497
363
- sub write-routine-file (: $ name ! , : @ chunks ! ) {
498
+ sub write-routine-file ($ dr , $ name ) {
364
499
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
367
508
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,
372
513
})
373
514
);
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 );
377
516
}
378
517
379
518
sub footer-html () {
519
+ state $ dt = ~ DateTime . now;
380
520
qq [
381
521
<div id="footer">
382
522
<p>
383
- Generated on { DateTime . now } from the sources at
523
+ Generated on $ dt from the sources at
384
524
<a href="https://github.com/perl6/doc">perl6/doc on github</a>.
385
525
</p>
386
526
<p>
0 commit comments