File Coverage

blib/lib/Perinci/To/Doc/Role/Section.pm
Criterion Covered Total %
statement 42 63 66.6
branch 13 22 59.0
condition 4 12 33.3
subroutine 6 9 66.6
pod 6 6 100.0
total 71 112 63.3


line stmt bran cond sub pod time code
1             package Perinci::To::Doc::Role::Section;
2              
3             our $DATE = '2021-02-21'; # DATE
4             our $VERSION = '0.875'; # VERSION
5              
6 1     1   10977 use 5.010;
  1         6  
7 1     1   7 use Log::ger;
  1         2  
  1         12  
8 1     1   242 use Moo::Role;
  1         3  
  1         8  
9              
10             has doc_sections => (is=>'rw');
11             has doc_lines => (is => 'rw'); # store final result, array
12             has doc_indent_level => (is => 'rw');
13             has doc_indent_str => (is => 'rw', default => sub{" "}); # indent characters
14              
15             sub add_doc_section_before {
16 3     3 1 1659 my ($self, $name, $before) = @_;
17 3         12 my $ss = $self->doc_sections;
18 3 50       9 return unless $ss;
19 3         5 my $i = 0;
20 3         6 my $added;
21 3   66     20 while ($i < @$ss && defined($before)) {
22 8 100       18 if ($ss->[$i] eq $before) {
23 2         3 my $pos = $i;
24 2         8 splice @$ss, $pos, 0, $name;
25 2         5 $added++;
26 2         7 last;
27             }
28 6         18 $i++;
29             }
30 3 100       14 unshift @$ss, $name unless $added;
31             }
32              
33             sub add_doc_section_after {
34 3     3 1 1890 my ($self, $name, $after) = @_;
35 3         11 my $ss = $self->doc_sections;
36 3 50       11 return unless $ss;
37 3         4 my $i = 0;
38 3         6 my $added;
39 3   66     16 while ($i < @$ss && defined($after)) {
40 11 100       27 if ($ss->[$i] eq $after) {
41 2         6 my $pos = $i+1;
42 2         18 splice @$ss, $pos, 0, $name;
43 2         4 $added++;
44 2         4 last;
45             }
46 9         22 $i++;
47             }
48 3 100       14 push @$ss, $name unless $added;
49             }
50              
51             sub delete_doc_section {
52 3     3 1 1736 my ($self, $name) = @_;
53 3         11 my $ss = $self->doc_sections;
54 3 50       11 return unless $ss;
55 3         4 my $i = 0;
56 3         10 while ($i < @$ss) {
57 6 100       15 if ($ss->[$i] eq $name) {
58 2         8 splice @$ss, $i, 1;
59             } else {
60 4         12 $i++;
61             }
62             }
63             }
64              
65             sub inc_doc_indent {
66 0     0 1   my ($self, $n) = @_;
67 0   0       $n //= 1;
68 0           $self->{doc_indent_level} += $n;
69             }
70              
71             sub dec_doc_indent {
72 0     0 1   my ($self, $n) = @_;
73 0   0       $n //= 1;
74 0           $self->{doc_indent_level} -= $n;
75 0 0         die "BUG: Negative doc indent level" unless $self->{doc_indent_level} >=0;
76             }
77              
78             sub gen_doc {
79 0     0 1   my ($self, %opts) = @_;
80 0           log_trace("-> gen_doc(opts=%s)", \%opts);
81              
82 0           $self->doc_lines([]);
83 0           $self->doc_indent_level(0);
84              
85 0 0         $self->before_gen_doc(%opts) if $self->can("before_gen_doc");
86              
87 0   0       for my $s (@{ $self->doc_sections // [] }) {
  0            
88 0           my $meth = "gen_doc_section_$s";
89 0           log_trace("=> $meth(%s)", \%opts);
90 0           $self->$meth(%opts);
91             }
92              
93 0 0         $self->after_gen_doc(%opts) if $self->can("after_gen_doc");
94              
95 0           log_trace("<- gen_doc()");
96 0           join("", @{ $self->doc_lines });
  0            
97             }
98              
99             1;
100             # ABSTRACT: Role for class that generates documentation with sections
101              
102             __END__
103              
104             =pod
105              
106             =encoding UTF-8
107              
108             =head1 NAME
109              
110             Perinci::To::Doc::Role::Section - Role for class that generates documentation with sections
111              
112             =head1 VERSION
113              
114             This document describes version 0.875 of Perinci::To::Doc::Role::Section (from Perl distribution Perinci-To-Doc), released on 2021-02-21.
115              
116             =head1 DESCRIPTION
117              
118             This is a role for classes that produce documentation with sections. This role
119             provides a workflow for parsing and generating sections, regulating indentation,
120             and a C<gen_doc()> method.
121              
122             To generate documentation, first you provide a list of section names in
123             C<doc_sections>. Then you run C<gen_doc()>, which will call
124             C<gen_doc_section_SECTION()> method for each section consecutively, which is
125             supposed to append lines of text to C<doc_lines>. Finally all the added lines is
126             concatenated together and returned by C<gen_doc()>.
127              
128             =head1 ATTRIBUTES
129              
130             =head2 doc_sections => ARRAY
131              
132             Should be set to the names of available sections.
133              
134             =head2 doc_lines => ARRAY
135              
136             =head2 doc_indent_level => INT
137              
138             =head2 doc_indent_str => STR (default ' ' (two spaces))
139              
140             Character(s) used for indent.
141              
142             =head1 METHODS
143              
144             =head2 add_doc_section_before($name, $anchor)
145              
146             =head2 add_doc_section_after($name, $anchor)
147              
148             =head2 delete_doc_section($name)
149              
150             =head2 inc_doc_indent([N])
151              
152             =head2 dec_doc_indent([N])
153              
154             =head2 gen_doc() => STR
155              
156             Generate documentation.
157              
158             The method will first initialize C<doc_lines> to an empty array C<[]> and
159             C<doc_indent_level> to 0.
160              
161             It will then call C<before_gen_doc> if the hook method exists, to allow class to
162             do stuffs prior to document generation. L<Perinci::To::Text> uses this, for
163             example, to retrieve metadata from Riap server.
164              
165             Then, as described in L</"DESCRIPTION">, for each section listed in
166             C<doc_sections> it will call C<gen_doc_section_SECTION>.
167              
168             After that, it will call C<after_gen_doc> if the hook method exists, to allow
169             class to do stuffs after document generation.
170              
171             Lastly, it returns concatenated C<doc_lines>.
172              
173             =head1 HOMEPAGE
174              
175             Please visit the project's homepage at L<https://metacpan.org/release/Perinci-To-Doc>.
176              
177             =head1 SOURCE
178              
179             Source repository is at L<https://github.com/perlancar/perl-Perinci-To-Doc>.
180              
181             =head1 BUGS
182              
183             Please report any bugs or feature requests on the bugtracker website L<https://github.com/perlancar/perl-Perinci-To-Doc/issues>
184              
185             When submitting a bug or request, please include a test-file or a
186             patch to an existing test-file that illustrates the bug or desired
187             feature.
188              
189             =head1 SEE ALSO
190              
191             This role is used, among others, by: C<Perinci::To::*> modules.
192              
193             L<Perinci::To::Doc::Role::Section::AddTextLines> which provides C<add_doc_lines>
194             to add text with optional text wrapping.
195              
196             =head1 AUTHOR
197              
198             perlancar <perlancar@cpan.org>
199              
200             =head1 COPYRIGHT AND LICENSE
201              
202             This software is copyright (c) 2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013 by perlancar@cpan.org.
203              
204             This is free software; you can redistribute it and/or modify it under
205             the same terms as the Perl 5 programming language system itself.
206              
207             =cut