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