File Coverage

blib/lib/Rubric/Entry/Formatter.pm
Criterion Covered Total %
statement 28 31 90.3
branch 9 16 56.2
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 45 55 81.8


line stmt bran cond sub pod time code
1 12     12   63 use strict;
  12         20  
  12         304  
2 12     12   57 use warnings;
  12         41  
  12         544  
3             package Rubric::Entry::Formatter;
4             # ABSTRACT: a base class for entry body formatters
5             $Rubric::Entry::Formatter::VERSION = '0.156';
6             #pod =head1 DESCRIPTION
7             #pod
8             #pod This class serves as a single point of dispatch for attempts to format entry
9             #pod bodies from their native format into rendered output.
10             #pod
11             #pod =cut
12              
13 12     12   78 use Carp ();
  12         47  
  12         215  
14 12     12   80 use Rubric::Config;
  12         98  
  12         93  
15              
16             #pod =head1 METHODS
17             #pod
18             #pod =head2 C< format >
19             #pod
20             #pod my $formatted = Rubric::Entry::Formatter->format(\%arg);
21             #pod
22             #pod This method accepts a set of named arguments and returns formatted output in
23             #pod the requested format. If it is unable to do so, it throws an exception.
24             #pod
25             #pod Valid arguments are:
26             #pod
27             #pod markup - the markup format used to mark up the text (default: _default)
28             #pod text - the text that has been marked up and should be formatted (required)
29             #pod format - the requested output format (required)
30             #pod
31             #pod Formatting requests are dispatched according to the configuration in
32             #pod C.
33             #pod
34             #pod =cut
35              
36             sub _load_formatter {
37 18     18   37 my ($class, $formatter) = @_;
38              
39 18 100       34 return 1 if eval { $formatter->can('as_text'); };
  18         289  
40              
41             ## no critic (StringyEval)
42 3 50       263 return 1 if eval qq{require $formatter};
43             ## use critic
44              
45 0         0 return 0;
46             }
47              
48             sub _formatter_for {
49 18     18   39 my ($class, $markup) = @_;
50              
51 18         93 my $markup_formatter = Rubric::Config->markup_formatter;
52             $markup_formatter->{_default} = 'Rubric::Entry::Formatter::Nil'
53 18 100       91 unless $markup_formatter->{_default};
54              
55             Carp::croak "no formatter is registered for $markup markup"
56 18 50       68 unless my $formatter = $markup_formatter->{ $markup };
57              
58 18         89 return $formatter;
59             }
60              
61             sub format {
62 18     18 1 1376 my ($class, $arg) = @_;
63 18         103 my $config = {}; # extra configuration for formatter code
64              
65 18         75 my $formatter = $class->_formatter_for($arg->{markup});
66              
67 18 50       72 if (ref $formatter) {
68 0         0 $config = { %$formatter };
69             Carp::croak "formatter config for $arg->{markup} includes no class"
70 0 0       0 unless $formatter = delete $config->{class};
71             }
72              
73 18 50       80 $class->_load_formatter($formatter)
74             or Carp::croak "couldn't load formatter '$formatter': $@";
75              
76 18 50       187 my $formatter_code = $formatter->can("as_$arg->{format}")
77             or Carp::croak "$formatter does not implement formatting to $arg->{format}";
78              
79 18         77 $formatter_code->($formatter, $arg, $config);
80             }
81              
82             #pod =head1 WRITING FORMATTERS
83             #pod
84             #pod Writing a formatter should be very simple; the interface is very simple,
85             #pod although it's also very young and so it may change when I figure out the
86             #pod problems in the current implementation.
87             #pod
88             #pod A formatter must implement an C method for each format to which it
89             #pod claims to be able to output formatted text. When Rubric::Entry::Formatter
90             #pod wants to dispatch text for formatting, it will call that method as follows:
91             #pod
92             #pod my $formatted = Formatter->as_whatever(\%arg);
93             #pod
94             #pod The arguments in C<%arg> will be the same as those passed to
95             #pod Rubric::Entry::Formatter.
96             #pod
97             #pod Actually, the method is found and called via C, so a suitably programmed
98             #pod module can respond to C to allow it to render into all the format it likes
99             #pod -- or at least to claim to.
100             #pod
101             #pod =cut
102              
103             1;
104              
105             __END__