Email-MIME-Kit-Assembler-Markdown
view release on metacpan or search on metacpan
lib/Email/MIME/Kit/Assembler/Markdown.pm view on Meta::CPAN
init_arg => undef,
);
has marker => (is => 'ro', isa => 'Str', default => 'CONTENT');
has skip_marker => (is => 'ro', isa => 'Str', default => 'SKIP-LINE');
has path => (
is => 'ro',
isa => 'Str',
lazy => 1,
default => sub { $_[0]->manifest->{path} },
);
sub BUILD {
my ($self) = @_;
my $class = ref $self;
confess "$class does not support alternatives"
if @{ $self->manifest->{alternatives} || [] };
confess "$class does not support attachments"
if @{ $self->manifest->{attachments} || [] };
confess "$class does not support MIME content attributes"
if %{ $self->manifest->{attributes} || {} };
}
sub _prep_header {
my ($self, $header, $stash) = @_;
my @done_header;
for my $entry (@$header) {
confess "no field name candidates"
unless my (@hval) = grep { /^[^:]/ } keys %$entry;
confess "multiple field name candidates: @hval" if @hval > 1;
my $value = $entry->{ $hval[ 0 ] };
if (ref $value) {
my ($v, $p) = @$value;
$value = join q{; }, $v, map { "$_=$p->{$_}" } keys %$p;
} else {
my $renderer = $self->renderer;
if (exists $entry->{':renderer'}) {
undef $renderer if ! defined $entry->{':renderer'};
confess 'alternate renderers not supported';
}
$value = ${ $renderer->render(\$value, $stash) } if defined $renderer;
}
push @done_header, $hval[0] => $value;
}
return \@done_header;
}
sub assemble {
my ($self, $stash) = @_;
my $markdown = ${ $self->kit->get_decoded_kit_entry( $self->path ) };
my $plaintext = $markdown;
if ($self->renderer) {
{
local $stash->{part_type} = 'text';
my $output = $self->renderer->render(\$markdown, $stash);
$plaintext = ${ $self->renderer->render(\$markdown, $stash) };
}
{
local $stash->{part_type} = 'html';
$markdown = ${ $self->renderer->render(\$markdown, $stash) };
}
}
# We'll remove any line containing <!-- SKIP-LINE --> from the plain text
# part. Meanwhile, the comment is removed from the Markdown, but the rest of
# the line is left intact. -- rjbs, 2021-11-23
my $skip_marker = $self->skip_marker;
$plaintext =~ s{^.*<!--\s+\Q$skip_marker\E\s+-->.*$}{}mg;
$markdown =~ s{<!--\s+\Q$skip_marker\E\s+-->}{}mg;
if ($self->encode_entities) {
$markdown = HTML::Entities::encode_entities($markdown);
}
if ($self->munge_signature) {
my ($body, $sig) = split /^-- $/m, $markdown, 2;
if (defined $sig) {
$sig =~ s{^}{<br />}mg;
$markdown = "$body\n\n$sig";
}
}
my %content = (
html => Text::Markdown->new(tab_width => 2)->markdown($markdown),
text => $plaintext,
);
for my $type (keys %content) {
my $type_wrapper = "$type\_wrapper";
if (my $wrapper_path = $self->$type_wrapper) {
my $wrapper = ${ $self->kit->get_decoded_kit_entry($wrapper_path) };
if ($self->render_wrapper) {
local $stash->{wrapped_content} = $content{$type};
local $stash->{part_type} = $type;
my $output_ref = $self->renderer->render(\$wrapper, $stash);
$content{$type} = $$output_ref;
} else {
my $marker = $self->marker;
my $marker_re = qr{<!--\s+\Q$marker\E\s+-->};
confess "$type_wrapper does not contain comment containing marker"
unless $wrapper =~ $marker_re;
$wrapper =~ s/$marker_re/$content{$type}/;
$content{$type} = $wrapper;
}
}
}
my $header = $self->_prep_header(
$self->manifest->{header},
$stash,
);
my $html_part = Email::MIME->create(
body_str => $content{html},
attributes => {
content_type => "text/html",
charset => 'utf-8',
encoding => 'quoted-printable',
},
);
my $text_part = Email::MIME->create(
body_str => $content{text},
attributes => {
content_type => "text/plain",
charset => 'utf-8',
encoding => 'quoted-printable',
},
);
my $container = Email::MIME->create(
header_str => $header,
parts => [ $text_part, $html_part ],
attributes => { content_type => 'multipart/alternative' },
);
return $container;
}
no Moose;
no Moose::Util::TypeConstraints;
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
( run in 0.476 second using v1.01-cache-2.11-cpan-d7f47b0818f )