8
$Pod::Markdown::VERSION = '1.110730';
10
# ABSTRACT: Convert POD to Markdown
11
use parent qw(Pod::Parser);
15
$self->SUPER::initialize(@_);
22
$self->{_MyParser} ||= {
23
Text => [], # final text
24
Indent => 0, # list indent levels counter
25
ListType => '-', # character on every item
26
searching => '' , # what are we searching for? (title, author etc.)
27
Title => undef, # page title
28
Author => undef, # page author
33
my ($parser, %args) = @_;
34
my $data = $parser->_private;
35
my $lines = $data->{Text};
37
if ($args{with_meta}) {
38
@header = $parser->_build_markdown_head;
40
join("\n" x 2, @header, @{$lines});
43
sub _build_markdown_head {
45
my $data = $parser->_private;
47
if (defined $data->{Title}) {
48
$paragraph .= sprintf '[[meta title="%s"]]', $data->{Title};
50
if (defined $data->{Author}) {
51
$paragraph .= "\n" . sprintf '[[meta author="%s"]]', $data->{Author};
57
my ($parser, $text) = @_;
58
my $data = $parser->_private;
59
$text = $parser->_indent_text($text);
60
push @{ $data->{Text} }, $text;
66
my $data = $parser->_private;
67
return pop @{ $data->{Text} };
71
my ($parser, $text) = @_;
72
my $data = $parser->_private;
73
my $level = $data->{Indent};
78
$indent = ' ' x ($level * 4);
79
my @lines = map { $indent . $_; } split(/\n/, $text);
80
return wantarray ? @lines : join("\n", @lines);
85
my @trimmed = grep { $_; } split(/\n/, $text);
86
return wantarray ? @trimmed : join("\n", @trimmed);
90
my ($parser, $command, $paragraph, $line_num) = @_;
91
my $data = $parser->_private;
94
$paragraph = $parser->_clean_text($paragraph);
97
if ($command =~ m{head(\d)}xms) {
100
$paragraph = $parser->interpolate($paragraph, $line_num);
102
# the headers never are indented
103
$parser->_save($parser->format_header($level, $paragraph));
105
if ($paragraph =~ m{NAME}xmsi) {
106
$data->{searching} = 'title';
107
} elsif ($paragraph =~ m{AUTHOR}xmsi) {
108
$data->{searching} = 'author';
110
$data->{searching} = '';
116
elsif ($command =~ m{over}xms) {
118
# update indent level
122
} elsif ($command =~ m{back}xms) {
124
# decrement indent level
126
$data->{searching} = '';
127
} elsif ($command =~ m{item}xms) {
128
$paragraph = $parser->interpolate($paragraph, $line_num);
129
$paragraph =~ s{^\h* \* \h*}{}xms;
131
if ($data->{searching} eq 'listpara') {
132
$data->{searching} = 'listheadhuddled';
135
$data->{searching} = 'listhead';
138
if (length $paragraph) {
139
$parser->textblock($paragraph, $line_num);
143
# ignore other commands
148
my ($parser, $paragraph) = @_;
149
$parser->_save($paragraph);
153
my ($parser, $paragraph, $line_num) = @_;
154
my $data = $parser->_private;
156
# interpolate the paragraph for embebed sequences
157
$paragraph = $parser->interpolate($paragraph, $line_num);
159
# clean the empty lines
160
$paragraph = $parser->_clean_text($paragraph);
163
if ($data->{searching} =~ m{title|author}xms) {
164
$data->{ ucfirst $data->{searching} } = $paragraph;
165
$data->{searching} = '';
166
} elsif ($data->{searching} =~ m{listhead(huddled)?$}xms) {
168
$paragraph = sprintf '%s %s', $data->{ListType}, $paragraph;
170
$paragraph = $parser->_unsave() . "\n" . $paragraph;
172
$data->{searching} = 'listpara';
173
} elsif ($data->{searching} eq 'listpara') {
174
$data->{searching} = '';
178
$parser->_save($paragraph);
181
sub interior_sequence {
182
my ($seq_command, $seq_argument, $pod_seq) = @_[1..3];
184
'I' => sub { return '_' . $_[1] . '_' }, # italic
185
'B' => sub { return '__' . $_[1] . '__' }, # bold
186
'C' => sub { return '`' . $_[1] . '`' }, # monospace
187
'F' => sub { return '`' . $_[1] . '`' }, # system path
188
'S' => sub { return '`' . $_[1] . '`' }, # code
190
my $charname = $_[1];
191
return '<' if $charname eq 'lt';
192
return '>' if $charname eq 'gt';
193
return '|' if $charname eq 'verbar';
194
return '/' if $charname eq 'sol';
195
return "&$charname;";
197
'L' => \&_resolv_link,
199
if (exists $interiors{$seq_command}) {
200
my $code = $interiors{$seq_command};
201
return $code->($seq_command, $seq_argument, $pod_seq);
203
return sprintf '%s<%s>', $seq_command, $seq_argument;
208
my ($cmd, $arg) = @_;
209
my $text = $arg =~ s"^(.+?)\|"" ? $1 : '';
211
if ($arg =~ m{^http|ftp}xms) { # direct link to a URL
213
return sprintf '[%s](%s)', $text, $arg;
214
} elsif ($arg =~ m{^/(.*)$}) {
217
return "[$text](\#pod_$1)";
218
} elsif ($arg =~ m{^(\w+(?:::\w+)*)$}) {
220
return "[$text](http://search.cpan.org/perldoc?$1)";
222
return sprintf '%s<%s>', $cmd, $arg;
227
my ($level, $paragraph) = @_[1,2];
228
sprintf '%s %s', '#' x $level, $paragraph;