File Coverage

blib/lib/Text/Xatena.pm
Criterion Covered Total %
statement 78 79 98.7
branch 19 22 86.3
condition 6 8 75.0
subroutine 15 15 100.0
pod 1 3 33.3
total 119 127 93.7


line stmt bran cond sub pod time code
1             package Text::Xatena;
2              
3 20     20   808703 use strict;
  20         50  
  20         717  
4 20     20   102 use warnings;
  20         38  
  20         529  
5 20     20   3495 use UNIVERSAL::require;
  20         6744  
  20         191  
6              
7 20     20   8630 use Text::Xatena::LineScanner;
  20         59  
  20         223  
8 20     20   8086 use Text::Xatena::Node;
  20         67  
  20         265  
9 20     20   10640 use Text::Xatena::Node::Root;
  20         53  
  20         161  
10 20     20   7915 use Text::Xatena::Inline;
  20         61  
  20         157  
11 20     20   150 use Text::Xatena::Util;
  20         41  
  20         172  
12              
13             our $VERSION = '0.18';
14              
15             our $SYNTAXES = [
16             'Text::Xatena::Node::SeeMore',
17             'Text::Xatena::Node::SuperPre',
18             'Text::Xatena::Node::StopP',
19             'Text::Xatena::Node::Blockquote',
20             'Text::Xatena::Node::Pre',
21             'Text::Xatena::Node::List',
22             'Text::Xatena::Node::DefinitionList',
23             'Text::Xatena::Node::Table',
24             'Text::Xatena::Node::Section',
25             'Text::Xatena::Node::Comment',
26             ];
27              
28             sub new {
29 103     103 0 1655 my ($class, %opts) = @_;
30              
31 103         410 my $self = bless { %opts }, $class;
32              
33 103   100     658 $self->{templates} ||= {};
34 2 50       9 $self->{templates} = {
35             map {
36 103         360 my $pkg = $_ =~ /::/ ? $_ : "Text::Xatena::Node::$_";
37 2         9 $pkg => $self->{templates}->{$_};
38             }
39 103         161 keys %{ $self->{templates} }
40             };
41              
42 1011 100       3080 $self->{syntaxes} = [
43             map {
44 103 100       504 my $pkg = $_ =~ /::/ ? $_ : "Text::Xatena::Node::$_";
45 1011 50       6119 $pkg->use or die $@;
46 1011         7604 $pkg;
47             }
48 103         227 @{ $opts{syntaxes} || $SYNTAXES }
49             ];
50              
51 103   66     1298 $self->{inline} ||= Text::Xatena::Inline->new;
52              
53 103         376 $self;
54             }
55              
56             sub format {
57 107     107 0 601 my ($self, $string, %opts) = @_;
58 107         1003 $string =~ s{\r\n?|\n}{\n}g;
59              
60 107 100       337 $self->inline($opts{inline}) if $opts{inline};
61              
62 107 100       309 if ($self->{hatena_compatible}) {
63 9         28 $self->{templates}->{'Text::Xatena::Node::Section'} = q[
64             {{= $title }}
65             {{= $content }}
66             ];
67              
68 20     20   9128 no warnings "once", "redefine";
  20         47  
  20         11140  
69             local *Text::Xatena::Node::as_html_paragraph = sub {
70 14     14   33 my ($self, $context, $text, %opts) = @_;
71 14         33 $text = $context->inline->format($text, %opts);
72              
73 14         38 $text =~ s{\n$}{}g;
74 14 50       101 if ($opts{stopp}) {
75 0         0 $text;
76             } else {
77             "

" . join("",

78             map {
79 14 100       47 if (/^(\n+)$/) {
  26         61  
80 6         29 "

" . ("
\n" x (length($1) - 2)) . "

";

81             } else {
82 20         94 $_;
83             }
84             }
85             split(/(\n+)/, $text)
86             ) . "

\n";
87             }
88 9         71 };
89              
90 9         31 $self->_parse($string)->as_html($self);
91             } else {
92 98         306 $self->_parse($string)->as_html($self);
93             }
94             }
95              
96             sub inline {
97 250     250 1 343 my ($self, $new) = @_;
98 250 100       567 if (@_ > 1) {
99 1         4 $self->{inline} = $new;
100             } else {
101 249         2189 $self->{inline};
102             }
103             }
104              
105             sub _parse {
106 120     120   367 my ($self, $string) = @_;
107              
108 120         177 my @syntaxes = @{ $self->{syntaxes} };
  120         599  
109 120         817 my $s = Text::Xatena::LineScanner->new($string);
110 120         800 my $root = Text::Xatena::Node::Root->new ;
111 120         284 my $stack = [ $root ];
112 120         450 loop: until ($s->eos) {
113 388         662 my $parent = $stack->[-1];
114              
115 388         634 for my $pkg (@syntaxes) {
116 3286 100       14806 $pkg->parse($s, $parent, $stack) and next loop;
117             }
118              
119             # plain lines
120 250         7957 push @$parent, $s->next;
121             }
122              
123 120         1424 $root;
124             }
125              
126             sub _tmpl {
127 100     100   223 my ($self, $pkg, $default, $stash) = @_;
128 100         207 my $tmpl = $self->{templates}->{$pkg};
129 100 100 66     749 my $sub = ref($tmpl) eq 'CODE' ? $tmpl : template($tmpl || $default, [ keys %$stash ]);
130 100         342 $self->{templates}->{$pkg} = $sub;
131 100         1811 $sub->($stash);
132             }
133              
134             1;
135             __END__