Skip to content

Commit

Permalink
make semantic blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
finanalyst committed Jul 29, 2023
1 parent 9333519 commit 466dad5
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 61 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
>Change log

# 2023-07-28 v4.9.0
* fix nested (and custom blocks) which were incorrectly rendering trailing lists.

* fixed semantic blocks

* moved VERSION DESCRIPTION AUTHOR SUMMARY into Semantic blocks, but treat them as if `:hidden` is set

* add `semantic:` to `P<>`

# 2023-07-27 v4.8.4
* fix table to pass on caption and target.

Expand Down Expand Up @@ -477,4 +486,4 @@ change testing


----
Rendered from CHANGELOG at 2023-07-27T15:39:38Z
Rendered from CHANGELOG at 2023-07-29T22:31:39Z
8 changes: 8 additions & 0 deletions doc/CHANGELOG.rakudoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
=TITLE Raku::Pod::Render
=SUBTITLE Change log

=head1 2023-07-28 v4.9.0
=item fix nested (and custom blocks) which were incorrectly rendering trailing lists.
=item fixed semantic blocks
=item moved VERSION DESCRIPTION AUTHOR SUMMARY into Semantic blocks, but treat them
as if C<:hidden> is set

=item add C<semantic:> to C<P<>>

=head1 2023-07-27 v4.8.4
=item fix table to pass on caption and target.

Expand Down
155 changes: 109 additions & 46 deletions lib/ProcessedPod.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ class PodFile {

#| language of pod file
has Str $.lang is rw is default('en') = 'en';
#| store data of semantic blocks
#| information to be included in eg html header
has @.raw-metadata;
#| toc structure , collected and rendered separately to body
#| toc structure, collected and rendered separately to body
has @.raw-toc;
#| glossary structure
has %.raw-glossary;
Expand Down Expand Up @@ -387,10 +388,9 @@ class ProcessedPod does SetupTemplates {
#| renders on the meta data
method render-meta(--> Str) {
return '' if (!?$!pod-file.raw-metadata or $!no-meta or $.pod-file.pod-config-data<no-meta>);
# this should be more generic, but is restricted to maintain some backward compatibility
self.rendition('meta',
%( :meta(
$!pod-file.raw-metadata.grep({ .<name>.uc ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>) })
$!pod-file.raw-metadata
))
)
}
Expand Down Expand Up @@ -498,7 +498,7 @@ class ProcessedPod does SetupTemplates {
my $fnNumber = +$!pod-file.raw-footnotes + 1;
my $fnTarget = self.rewrite-target("fn$fnNumber", :unique);
my $retTarget = self.rewrite-target("fnret$fnNumber", :unique);
$!pod-file.raw-footnotes.push: %( :$text, :$retTarget, :$fnNumber, :$fnTarget);
$!pod-file.raw-footnotes.push: %( :$text, :$retTarget, :$fnNumber, :$fnTarget, :$context );
(:$fnTarget, :$fnNumber, :$retTarget, :$context ).hash
}

Expand Down Expand Up @@ -607,6 +607,40 @@ class ProcessedPod does SetupTemplates {
), :$defn
)
}
multi method handle(Pod::Block::Input $node, Int $in-level, Context $context = Preformatted, Bool :$defn = False, --> Str) {
# first completion is to flush a retained list before the contents of the block are processed
my $retained-list = $.completion($in-level, 'zero', %(), :$defn );
my $contents = [~] gather for $node.contents { take self.handle($_, $in-level, Preformatted, :$defn ) };
my $template = $node.config<template> // 'input';
my $name-space = $node.config<name-space> // $template;
my $data = $_ with %!plugin-data{ $name-space };

$retained-list
~ $.completion($in-level, $template,
%( :$contents,
$node.config,
"$name-space" => $data,
:config(self.config),
), :$defn
)
}
multi method handle(Pod::Block::Output $node, Int $in-level, Context $context = Preformatted, Bool :$defn = False, --> Str) {
# first completion is to flush a retained list before the contents of the block are processed
my $retained-list = $.completion($in-level, 'zero', %(), :$defn );
my $contents = [~] gather for $node.contents { take self.handle($_, $in-level, Preformatted, :$defn ) };
my $template = $node.config<template> // 'output';
my $name-space = $node.config<name-space> // $template;
my $data = $_ with %!plugin-data{ $name-space };

$retained-list
~ $.completion($in-level, $template,
%( :$contents,
$node.config,
"$name-space" => $data,
:config(self.config),
), :$defn
)
}

multi method handle(Pod::Block::Comment $node, Int $in-level, Context $context = None, Bool :$defn = False, --> Str) {
$.completion($in-level, 'zero', %(), :$defn )
Expand Down Expand Up @@ -703,13 +737,6 @@ class ProcessedPod does SetupTemplates {
# we can't guarantee SUBTITLE will be after TITLE
}

multi method handle(Pod::Block::Named $node where .name ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>),
Int $in-level, Context $context, Bool :$defn = False, --> Str) {
$.register-meta(:name($node.name.tclc), :value(recurse-until-str($node)));
$.completion($in-level, 'zero', %(), :$defn )
# make sure any list is correctly ended.
}

# Semantic blocks other than above treat as head1
multi method handle(Pod::Block::Named $node where .name ~~ / ^ <upper>+ $ /,
Int $in-level, Context $context, Bool :$defn = False, --> Str) {
Expand All @@ -731,34 +758,41 @@ class ProcessedPod does SetupTemplates {
$level = 1;
}
}
my $toc-caption = $node.config<toc-caption> // $node.name;
with $node.config<hidden> or $node.name ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>) {
$toc = False;
}
my $caption = $node.config<caption> // $node.name;
# possibilities: :template or :name-space given in metadata
# or SEMANTIC (viz. node.name) template in template hash
my $semantic = $node.name if $.tmpl{ $node.name }:exists;
my $semantic = $node.name if $.tmpl{ $node.name }:exists; # if doesn't exist then Any
my $template = $node.config<template> // $semantic;
my $name-space = $node.config<name-space> // $template // $node.name;
my $data = $_ with %!plugin-data{ $name-space };
my $target = $.register-toc(:$level, :text($toc-caption), :is-title);
my $target = $.register-toc( :$level, :text($caption), :!is-title, :$toc );
my $contents = trim( [~] gather for $node.contents { take self.handle($_, $in-level, $context, :$defn) } );
$.register-meta(:name($node.name), :value($contents));
with $template {
$retained-list ~ $.completion($in-level, $template, {
$contents ~= $.completion($in-level, 'zero', %(), :$defn );
my $raw-contents = trim( [~] gather for $node.contents { take self.handle($_, $in-level, Context::Raw, :$defn) } );
$raw-contents ~= $.completion($in-level, 'zero', %(), :$defn );
my $rendered;
with $template { # only defined if there is block name template, or template given
$rendered = $.completion($in-level, $template, {
:$level,
:text($toc-caption),
:text($caption),
:$target,
:top($.pod-file.top),
$name-space => $data,
$node.config,
:config(self.config),
:$context,
:$contents,
:$raw-contents,
}, :$defn
)
}
else {
$retained-list ~ $.completion($in-level, 'heading', {
$rendered = $.completion($in-level, 'heading', {
:$level,
:text($toc-caption),
:text($caption),
:$target,
:top($.pod-file.top),
$name-space => $data,
Expand All @@ -768,15 +802,11 @@ class ProcessedPod does SetupTemplates {
}, :$defn
) ~ $contents
}
}

multi method handle(Pod::Block::Named $node where .name.lc ~~ any(< output input >), Int $in-level,
Context $context = None, Bool :$defn = False, --> Str) {
$.completion($in-level, 'zero', %(), :$defn )
~ $.completion($in-level, .name.lc,
%( :contents([~] gather for $node.contents { take self.handle($_, $in-level, Preformatted, :$defn) }),$node.config
), :$defn
)
$.register-meta(:name($node.name), :value($rendered));
if $node.config<hidden> or $node.name ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>) {
$rendered = ''
}
$retained-list ~ $rendered
}

multi method handle(Pod::Block::Named $node where .name.lc eq 'raw', Int $in-level,
Expand Down Expand Up @@ -809,19 +839,23 @@ class ProcessedPod does SetupTemplates {
}
}
my $target = '';
my $toc-caption = $node.config<toc-caption> // recurse-until-str($node).tclc;
$target = $.register-toc(:$level, :text($toc-caption), :$toc);
my $caption = $node.config<caption> // recurse-until-str($node).tclc;
$target = $.register-toc(:$level, :text($caption), :$toc);
my $template = $node.config<template> // $node.name.lc;
my $name-space = $node.config<name-space> // $template // $node.name.lc;
my $data = $_ with %!plugin-data{ $name-space };
$.completion($in-level, 'zero', %(), :$defn )
~ $.completion($in-level, $template,
%( :contents([~] gather for $node.contents { take self.handle($_, $in-level, $context, :$defn) }),
$node.config,
:$target,
:raw-contents( [~] gather for $node.contents { take self.handle($_, $in-level, Raw, :$defn ) } ),
$name-space => $data,
:config(self.config),
my $unrendered-list = $.completion($in-level, 'zero', %(), :$defn );
my $contents = [~] gather for $node.contents { take self.handle($_, $in-level, $context, :$defn) }
$contents ~= $.completion($in-level, 'zero', %(), :$defn );
my $raw-contents = [~] gather for $node.contents { take self.handle($_, $in-level, Raw, :$defn ) }
$raw-contents ~= $.completion($in-level, 'zero', %(), :$defn );
$unrendered-list ~ $.completion($in-level, $template, %(
:$contents,
$node.config,
:$target,
:$raw-contents,
$name-space => $data,
:config(self.config),
), :$defn
)
}
Expand Down Expand Up @@ -1153,10 +1187,17 @@ class ProcessedPod does SetupTemplates {
)
}
}

# footnotes depends on raw-contents being rendered after rendered contents
multi method handle(Pod::FormattingCode $node where .type eq 'N', Int $in-level, Context $context = None, Bool :$defn = False, --> Str) {
my $text = [~] gather for $node.contents { take $.handle($_, $in-level, $context, :$defn) };
$.completion($in-level, 'format-n', $.register-footnote(:$text, :$context), :$defn)
my %params;
if $context ~~ Context::Raw {
%params = $!pod-file.raw-footnotes[*-1]
}
else {
%params = $.register-footnote(:$text, :$context )
}
$.completion($in-level, 'format-n', %params, :$defn)
}

multi method handle(Pod::FormattingCode $node where .type eq 'E', Int $in-level,
Expand Down Expand Up @@ -1215,13 +1256,33 @@ class ProcessedPod does SetupTemplates {
multi method handle(Pod::FormattingCode $node where .type eq 'P', Int $in-level,
Context $context = None, Bool :$defn = False, --> Str) {
my Str $link-contents = recurse-until-str($node);
my $link = ($node.meta eqv [] | [""] ?? $link-contents !! $node.meta).Str;
my URI $uri .= new($link);
my $link = ($node.meta eqv [] | [""] ?? $link-contents !! $node.meta).Str.trim;
my $schema = '';
my $uri = '';
if $link ~~ / ^ $<sch> = (\w+) ':' \s* $<uri> = (.*) $ / {
$schema = $<sch>.Str;
$uri = $<uri>.Str
}
my Str $contents;
my LibCurl::Easy $curl;
my Bool $no-render = False;
my Bool $html = False;
given $uri.scheme {
given $schema {
when 'toc' {
$contents = "See: $link-contents"
}
when 'index' {
$contents = "See: $link-contents"
}
when 'semantic' {
$no-render = True;
$.pod-file.raw-metadata.grep({ .<name> ~~ $uri }).map({ $contents ~= .<value> });
without $contents {
$contents = "See: $link-contents";
$no-render = False;
}
}
when 'http' | 'https' {
my LibCurl::Easy $curl;
$curl .= new(:URL($link), :followlocation, :failonerror );
try {
$curl.perform;
Expand All @@ -1237,7 +1298,8 @@ class ProcessedPod does SetupTemplates {
}
}
when 'file' | '' {
if $uri.path.Str.IO.f {
my URI $uri .= new($link);
if $uri.path.Str.IO ~~ :e & :f {
$contents = $uri.path.Str.IO.slurp;
}
else {
Expand All @@ -1258,6 +1320,7 @@ class ProcessedPod does SetupTemplates {
:config(self.config),
:meta( $node.meta ),
:$context,
:$no-render,
), :$defn)
}
}
12 changes: 9 additions & 3 deletions resources/html-templates-rakuclosure.raku
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,20 @@ use v6;
},
'meta' => sub ( %prm, %tml ) {
with %prm<meta> {
[~] %prm<meta>.map({
'<meta name="' ~ %tml<escaped>( .<name> )
~ '" value="' ~ %tml<escaped>( .<value> )
[~] %prm<meta>
.grep({ $_<name> ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>) } )
.map({
'<meta name="' ~ .<name>.tclc
~ '" value="' ~ .<value>
~ "\" />\n"
})
}
else { '' }
},
'VERSION' => sub (%prm, %tml) { %prm<raw-contents> },
'DESCRIPTION' => sub (%prm, %tml) { %prm<raw-contents> },
'AUTHOR' => sub (%prm, %tml) { %prm<raw-contents> },
'SUMMARY' => sub (%prm, %tml) { %prm<raw-contents> },
'toc' => sub ( %prm, %tml ) {
"<div id=\"_TOC\"><table>\n<caption>Table of Contents</caption>\n"
~ [~] %prm<toc>.map({
Expand Down
12 changes: 9 additions & 3 deletions resources/test_things/html-rakuclosure.raku
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,20 @@ use v6;
},
'meta' => sub ( %prm, %tml ) {
with %prm<meta> {
[~] %prm<meta>.map({
'<meta name="' ~ %tml<escaped>( .<name> )
~ '" value="' ~ %tml<escaped>( .<value> )
[~] %prm<meta>
.grep({ $_<name> ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>) } )
.map({
'<meta name="' ~ .<name>.tclc
~ '" value="' ~ .<value>
~ "\" />\n"
})
}
else { '' }
},
'VERSION' => sub (%prm, %tml) { %prm<raw-contents> },
'DESCRIPTION' => sub (%prm, %tml) { %prm<raw-contents> },
'AUTHOR' => sub (%prm, %tml) { %prm<raw-contents> },
'SUMMARY' => sub (%prm, %tml) { %prm<raw-contents> },
'toc' => sub ( %prm, %tml ) {
"<div id=\"_TOC\"><table>\n<caption>Table of Contents</caption>\n"
~ [~] %prm<toc>.map({
Expand Down
2 changes: 1 addition & 1 deletion xt/20-page-components-rakudoc.rakutest
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ for $rakudoc-structure.^methods.grep({
}) { ok $_($rakudoc-structure).elems, $_.name ~' has elements' };

is-deeply-relaxed $rakudoc-structure.templates-used.BagHash,
("pod"=>1,"heading"=>5,"para"=>7,"format-x"=>4,"format-n"=>1,"raw"=>5,"escaped"=>22,
("pod"=>1,"heading"=>7,"para"=>9,"format-x"=>4,"format-n"=>1,"raw"=>9,"escaped"=>24,
:1footnotes, :1glossary, :1source-wrap, :1meta, :1toc).BagHash,
'used the expected templates';

Expand Down
11 changes: 9 additions & 2 deletions xt/30-pod-meta-data.rakutest
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ my $rv;
use RenderPod::Templating;
my @templates = SetupTemplates.new.required;


my %templates = @templates Z=> @templates.map( { gen-closure-template( $_ ) });
%templates<escaped> = sub ($s) { $s };
%templates<meta> = sub ( %prm, %tmp ) {
"<meta>\n"
~ %prm<meta>.map( { $_<name> ~ '=' ~ $_<value> ~ "\n"} )
~ %prm<meta>
.grep({ $_<name> ~~ any(<VERSION DESCRIPTION AUTHOR SUMMARY>) } )
.map( { $_<name>.tclc ~ '=' ~ $_<value> ~ "\n"} )
~ '</meta>'
};
%templates<source-wrap> = sub (%prm, %tml ) {
Expand All @@ -33,6 +34,12 @@ my %templates = @templates Z=> @templates.map( { gen-closure-template( $_ ) });
%templates<heading> = sub (%prm, %tml) {
"<config>" ~ %prm<text> ~ %prm<config>.sort.fmt("%s=>%s") ~ '</config>'
};
%templates<AUTHOR> = sub (%prm, %tml) {
%prm<raw-contents>
};
%templates<SUMMARY> = sub (%prm, %tml) {
%prm<raw-contents>
};
$processor.templates(%templates);

=begin pod :kind("Language") :subkind("Language") :category("fundamental") :content-columns
Expand Down
Loading

0 comments on commit 466dad5

Please sign in to comment.