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