File Coverage

blib/lib/Org/To/Base.pm
Criterion Covered Total %
statement 41 89 46.0
branch 31 70 44.2
condition 2 4 50.0
subroutine 8 12 66.6
pod 2 2 100.0
total 84 177 47.4


line stmt bran cond sub pod time code
1             package Org::To::Base;
2              
3             our $DATE = '2020-09-11'; # DATE
4             our $VERSION = '0.233'; # VERSION
5              
6 2     2   1183 use 5.010001;
  2         8  
7 2     2   11 use Log::ger;
  2         3  
  2         9  
8              
9 2     2   406 use List::Util qw(first);
  2         4  
  2         157  
10 2     2   12 use Moo;
  2         3  
  2         10  
11 2     2   708 use experimental 'smartmatch';
  2         5  
  2         25  
12              
13             has include_tags => (is => 'rw');
14             has exclude_tags => (is => 'rw');
15              
16             sub _included_children {
17 5     5   12 my ($self, $elem) = @_;
18              
19 5         18 my @htags = $elem->get_tags;
20 5   100     295 my @children = @{$elem->children // []};
  5         40  
21 5 50       24 if ($self->include_tags) {
22 0 0   0   0 if (!defined(first {$_ ~~ @htags} @{$self->include_tags})) {
  0         0  
  0         0  
23             # headline doesn't contain include_tags, select only
24             # suheadlines that contain them
25 0         0 @children = ();
26 0   0     0 for my $c (@{ $elem->children // []}) {
  0         0  
27 0 0       0 next unless $c->isa('Org::Element::Headline');
28             my @hl_included = $elem->find(
29             sub {
30 0     0   0 my $el = shift;
31             return unless
32 0 0       0 $elem->isa('Org::Element::Headline');
33 0         0 my @t = $elem->get_tags;
34 0         0 return defined(first {$_ ~~ @t}
35 0         0 @{$self->include_tags});
  0         0  
36 0         0 });
37 0 0       0 next unless @hl_included;
38 0         0 push @children, $c;
39             }
40 0 0       0 return () unless @children;
41             }
42             }
43 5 50       32 if ($self->exclude_tags) {
44 0     0   0 return () if defined(first {$_ ~~ @htags}
45 0 0       0 @{$self->exclude_tags});
  0         0  
46             }
47 5         17 @children;
48             }
49              
50             sub export {
51 4     4 1 53306 my ($self, $doc) = @_;
52              
53 4         22 my $inct = $self->include_tags;
54 4 50       15 if ($inct) {
55 0         0 my $doc_has_include_tags;
56 0         0 for my $h ($doc->find('Org::Element::Headline')) {
57 0         0 my @htags = $h->get_tags;
58 0 0   0   0 if (defined(first {$_ ~~ @htags} @$inct)) {
  0         0  
59 0         0 $doc_has_include_tags++;
60 0         0 last;
61             }
62             }
63 0 0       0 $self->include_tags(undef) unless $doc_has_include_tags;
64             }
65              
66 4         17 $self->export_elements($doc);
67             }
68              
69             sub export_elements {
70 18     18 1 42 my ($self, @elems) = @_;
71              
72 18         30 my $res = [];
73             ELEM:
74 18         37 for my $elem (@elems) {
75 21 50       84 if ($self->can("before_export_element")) {
76 21         57 $self->before_export_element(
77             hook => 'before_export_element',
78             elem => $elem,
79             );
80             }
81 21 50       129 if (log_is_trace) {
82 0         0 require String::Escape;
83 0         0 log_trace("exporting element %s (%s) ...", ref($elem),
84             String::Escape::elide(
85             String::Escape::printable($elem->as_string), 30));
86             }
87 21         80 my $elc = ref($elem);
88              
89 21 100       187 if ($elc eq 'Org::Element::Block') {
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
90 1         4 push @$res, $self->export_block($elem);
91             } elsif ($elc eq 'Org::Element::FixedWidthSection') {
92 1         4 push @$res, $self->export_fixed_width_section($elem);
93             } elsif ($elc eq 'Org::Element::Comment') {
94 0         0 push @$res, $self->export_comment($elem);
95             } elsif ($elc eq 'Org::Element::Drawer') {
96 0         0 push @$res, $self->export_drawer($elem);
97             } elsif ($elc eq 'Org::Element::Footnote') {
98 0         0 push @$res, $self->export_footnote($elem);
99             } elsif ($elc eq 'Org::Element::Headline') {
100 5         27 push @$res, $self->export_headline($elem);
101             } elsif ($elc eq 'Org::Element::List') {
102 0         0 push @$res, $self->export_list($elem);
103             } elsif ($elc eq 'Org::Element::ListItem') {
104 0         0 push @$res, $self->export_list_item($elem);
105             } elsif ($elc eq 'Org::Element::RadioTarget') {
106 0         0 push @$res, $self->export_radio_target($elem);
107             } elsif ($elc eq 'Org::Element::Setting') {
108 2         12 push @$res, $self->export_setting($elem);
109             } elsif ($elc eq 'Org::Element::Table') {
110 0         0 push @$res, $self->export_table($elem);
111             } elsif ($elc eq 'Org::Element::TableCell') {
112 0         0 push @$res, $self->export_table_cell($elem);
113             } elsif ($elc eq 'Org::Element::TableRow') {
114 0         0 push @$res, $self->export_table_row($elem);
115             } elsif ($elc eq 'Org::Element::TableVLine') {
116 0         0 push @$res, $self->export_table_vline($elem);
117             } elsif ($elc eq 'Org::Element::Target') {
118 0         0 push @$res, $self->export_target($elem);
119             } elsif ($elc eq 'Org::Element::Text') {
120 8         26 push @$res, $self->export_text($elem);
121             } elsif ($elc eq 'Org::Element::Link') {
122 0         0 push @$res, $self->export_link($elem);
123             } elsif ($elc eq 'Org::Element::TimeRange') {
124 0         0 push @$res, $self->export_time_range($elem);
125             } elsif ($elc eq 'Org::Element::Timestamp') {
126 0         0 push @$res, $self->export_timestamp($elem);
127             } elsif ($elc eq 'Org::Document') {
128 4         19 push @$res, $self->export_document($elem);
129             } else {
130 0         0 log_warn("Don't know how to export $elc element, skipped");
131 0 0       0 push @$res, $self->export_elements(@{$elem->children})
  0         0  
132             if $elem->children;
133             }
134              
135 21 50       154 if ($self->can("after_export_element")) {
136 0         0 $self->after_export_element(
137             hook => 'after_export_element',
138             elem => $elem,
139             );
140             }
141             }
142              
143 18         86 join "", @$res;
144             }
145              
146             1;
147             # ABSTRACT: Base class for Org exporters
148              
149             __END__
150              
151             =pod
152              
153             =encoding UTF-8
154              
155             =head1 NAME
156              
157             Org::To::Base - Base class for Org exporters
158              
159             =head1 VERSION
160              
161             This document describes version 0.233 of Org::To::Base (from Perl distribution Org-To-HTML), released on 2020-09-11.
162              
163             =head1 SYNOPSIS
164              
165             # Not to be used directly. Use one of its subclasses, like Org::To::HTML.
166              
167             =head1 DESCRIPTION
168              
169             This module is a base class for Org exporters. To create an exporter, subclass
170             from this class (as well as add L<Org::To::Role> role) and provide an
171             implementation for the export_*() methods. Add extra attributes for export
172             options as necessary (for example, Org::To::HTML adds C<html_title>, C<css_url>,
173             and so on).
174              
175             =for Pod::Coverage BUILD
176              
177             =head1 ATTRIBUTES
178              
179             =head2 include_tags => ARRAYREF
180              
181             Works like Org's 'org-export-select-tags' variable. If the whole document
182             doesn't have any of these tags, then the whole document will be exported.
183             Otherwise, trees that do not carry one of these tags will be excluded. If a
184             selected tree is a subtree, the heading hierarchy above it will also be selected
185             for export, but not the text below those headings.
186              
187             =head2 exclude_tags => ARRAYREF
188              
189             If the whole document doesn't have any of these tags, then the whole document
190             will be exported. Otherwise, trees that do not carry one of these tags will be
191             excluded. If a selected tree is a subtree, the heading hierarchy above it will
192             also be selected for export, but not the text below those headings.
193              
194             exclude_tags is evaluated after include_tags.
195              
196             =head1 METHODS
197              
198             =head2 $exp->export($doc) => STR
199              
200             Export Org.
201              
202             =head2 $exp->export_elements(@elems) => STR
203              
204             Export Org element objects and with the children, recursively. Will call various
205             C<export_*()> methods according to element class. Should return a string which
206             is the exported document.
207              
208             Several hooks are recognized and will be invoked if defined:
209              
210             =over
211              
212             =item * before_export_element
213              
214             Will be called before calling each C<export_*()>. Will be passed hash argument
215             C<%hash> containing these keys: C<hook> (hook name, in this case
216             C<before_export_element>), C<elem> (the element object).
217              
218             =item * after_export_element
219              
220             Will be called after calling each C<export_*()>. Will be passed hash argument
221             C<%hash> containing these keys: C<hook> (hook name, in this case
222             C<after_export_element>), C<elem> (the element object).
223              
224             =back
225              
226             =head1 HOMEPAGE
227              
228             Please visit the project's homepage at L<https://metacpan.org/release/Org-To-HTML>.
229              
230             =head1 SOURCE
231              
232             Source repository is at L<https://github.com/perlancar/perl-Org-To-HTML>.
233              
234             =head1 BUGS
235              
236             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Org-To-HTML>
237              
238             When submitting a bug or request, please include a test-file or a
239             patch to an existing test-file that illustrates the bug or desired
240             feature.
241              
242             =head1 AUTHOR
243              
244             perlancar <perlancar@cpan.org>
245              
246             =head1 COPYRIGHT AND LICENSE
247              
248             This software is copyright (c) 2020, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2011 by perlancar@cpan.org.
249              
250             This is free software; you can redistribute it and/or modify it under
251             the same terms as the Perl 5 programming language system itself.
252              
253             =cut