1# vim: set ts=2 sts=2 sw=2 expandtab smarttab:
2#
3# This file is part of Pod-Markdown
4#
5# This software is copyright (c) 2011 by Randy Stauner.
6#
7# This is free software; you can redistribute it and/or modify it under
8# the same terms as the Perl 5 programming language system itself.
9#
10use 5.008;
11use strict;
12use warnings;
13
14package Pod::Markdown;
15# git description: v3.200-4-gd31d626
16
17our $AUTHORITY = 'cpan:RWSTAUNER';
18# ABSTRACT: Convert POD to Markdown
19$Pod::Markdown::VERSION = '3.300';
20use Pod::Simple 3.27 (); # detected_encoding and keep_encoding bug fix
21use parent qw(Pod::Simple::Methody);
22use Encode ();
23use URI::Escape ();
24
25our %URL_PREFIXES = (
26  sco      => 'http://search.cpan.org/perldoc?',
27  metacpan => 'https://metacpan.org/pod/',
28  man      => 'http://man.he.net/man',
29);
30$URL_PREFIXES{perldoc} = $URL_PREFIXES{metacpan};
31
32our $LOCAL_MODULE_RE = qr/^(Local::|\w*?_\w*)/;
33
34## no critic
35#{
36  our $HAS_HTML_ENTITIES;
37
38  # Stolen from Pod::Simple::XHTML 3.28. {{{
39
40  BEGIN {
41    $HAS_HTML_ENTITIES = eval "require HTML::Entities; 1";
42  }
43
44  my %entities = (
45    q{>} => 'gt',
46    q{<} => 'lt',
47    q{'} => '#39',
48    q{"} => 'quot',
49    q{&} => 'amp',
50  );
51
52  sub encode_entities {
53    my $self = shift;
54    my $ents = $self->html_encode_chars;
55    return HTML::Entities::encode_entities( $_[0], $ents ) if $HAS_HTML_ENTITIES;
56    if (defined $ents) {
57        $ents =~ s,(?<!\\)([]/]),\\$1,g;
58        $ents =~ s,(?<!\\)\\\z,\\\\,;
59    } else {
60        $ents = join '', keys %entities;
61    }
62    my $str = $_[0];
63    $str =~ s/([$ents])/'&' . ($entities{$1} || sprintf '#x%X', ord $1) . ';'/ge;
64    return $str;
65  }
66
67  # }}}
68
69  # Add a few very common ones for consistency and readability
70  # (in case HTML::Entities isn't available).
71  %entities = (
72    # Pod::Markdown has always required 5.8 so unicode_to_native will be available.
73    chr(utf8::unicode_to_native(0xA0)) => 'nbsp',
74    chr(utf8::unicode_to_native(0xA9)) => 'copy',
75    %entities
76  );
77
78  sub __entity_encode_ord_he {
79    my $chr = chr $_[0];
80    # Skip the encode_entities() logic and go straight for the substitution
81    # since we already have the char we know we want replaced.
82    # Both the hash and the function are documented as exportable (so should be reliable).
83    return $HTML::Entities::char2entity{ $chr } || HTML::Entities::num_entity( $chr );
84  }
85  sub __entity_encode_ord_basic {
86    return '&' . ($entities{chr $_[0]} || sprintf '#x%X', $_[0]) . ';';
87  }
88
89  # From HTML::Entities 3.69
90  my $DEFAULT_ENTITY_CHARS = '^\n\r\t !\#\$%\(-;=?-~';
91
92#}
93## use critic
94
95# Use hash for simple "exists" check in `new` (much more accurate than `->can`).
96my %attributes = map { ($_ => 1) }
97  qw(
98    html_encode_chars
99    match_encoding
100    output_encoding
101    local_module_re
102    local_module_url_prefix
103    man_url_prefix
104    perldoc_url_prefix
105    perldoc_fragment_format
106    markdown_fragment_format
107    include_meta_tags
108    escape_url
109  );
110
111
112sub new {
113  my $class = shift;
114  my %args = @_;
115
116  my $self = $class->SUPER::new();
117  $self->preserve_whitespace(1);
118  $self->nbsp_for_S(1);
119  $self->accept_targets(qw( markdown html ));
120  $self->escape_url(1);
121
122  # Default to the global, but allow it to be overwritten in args.
123  $self->local_module_re($LOCAL_MODULE_RE);
124
125  for my $type ( qw( perldoc man ) ){
126    my $attr  = $type . '_url_prefix';
127    # Initialize to the alias.
128    $self->$attr($type);
129  }
130
131  while( my ($attr, $val) = each %args ){
132    # NOTE: Checking exists on a private var means we don't allow Pod::Simple
133    # attributes to be set this way.  It's not very consistent, but I think
134    # I'm ok with that for now since there probably aren't many Pod::Simple attributes
135    # being changed besides `output_*` which feel like API rather than attributes.
136    # We'll see.
137    # This is currently backward-compatible as we previously just put the attribute
138    # into the private stash so anything unknown was silently ignored.
139    # We could open this up to `$self->can($attr)` in the future if that seems better
140    # but it tricked me when I was testing a misspelled attribute name
141    # which also happened to be a Pod::Simple method.
142
143    exists $attributes{ $attr } or
144      # Provide a more descriptive message than "Can't locate object method".
145      warn("Unknown argument to ${class}->new(): '$attr'"), next;
146
147    # Call setter.
148    $self->$attr($val);
149  }
150
151  # TODO: call from the setters.
152  $self->_prepare_fragment_formats;
153
154  if(defined $self->local_module_url_prefix && $self->local_module_url_prefix eq '' && !$self->escape_url) {
155    warn("turning escape_url with an empty local_module_url_prefix is not recommended as relative URLs could be confused for IPv6 addresses");
156  }
157
158  return $self;
159}
160
161for my $type ( qw( local_module perldoc man ) ){
162  my $attr  = $type . '_url_prefix';
163  no strict 'refs'; ## no critic
164  *$attr = sub {
165    my $self = shift;
166    if (@_) {
167      $self->{$attr} = $URL_PREFIXES{ $_[0] } || $_[0];
168    }
169    else {
170      return $self->{$attr};
171    }
172  }
173}
174
175## Attribute accessors ##
176
177
178sub html_encode_chars {
179  my $self  = shift;
180  my $stash = $self->_private;
181
182  # Setter.
183  if( @_ ){
184    # If false ('', 0, undef), disable.
185    if( !$_[0] ){
186      delete $stash->{html_encode_chars};
187      $stash->{encode_amp}  = 1;
188      $stash->{encode_lt}   = 1;
189    }
190    else {
191      # Special case boolean '1' to mean "all".
192      # If we have HTML::Entities, undef will use the default.
193      # Without it, we need to specify so that we use the same list (for consistency).
194      $stash->{html_encode_chars} = $_[0] eq '1' ? ($HAS_HTML_ENTITIES ? undef : $DEFAULT_ENTITY_CHARS) : $_[0];
195
196      # If [char] doesn't get encoded, we need to do it ourselves.
197      $stash->{encode_amp}  = ($self->encode_entities('&') eq '&');
198      $stash->{encode_lt}   = ($self->encode_entities('<') eq '<');
199    }
200    return;
201  }
202
203  # Getter.
204  return $stash->{html_encode_chars};
205}
206
207
208# I prefer ro-accessors (immutability!) but it can be confusing
209# to not support the same API as other Pod::Simple classes.
210
211# NOTE: Pod::Simple::_accessorize is not a documented public API.
212# Skip any that have already been defined.
213__PACKAGE__->_accessorize(grep { !__PACKAGE__->can($_) } keys %attributes);
214
215sub _prepare_fragment_formats {
216  my ($self) = @_;
217
218  foreach my $attr ( keys %attributes ){
219    next unless $attr =~ /^(\w+)_fragment_format/;
220    my $type = $1;
221    my $format = $self->$attr;
222
223    # If one was provided.
224    if( $format ){
225      # If the attribute is a coderef just use it.
226      next if ref($format) eq 'CODE';
227    }
228    # Else determine a default.
229    else {
230      if( $type eq 'perldoc' ){
231        # Choose a default that matches the destination url.
232        my $target = $self->perldoc_url_prefix;
233        foreach my $alias ( qw( metacpan sco ) ){
234          if( $target eq $URL_PREFIXES{ $alias } ){
235            $format = $alias;
236          }
237        }
238        # This seems like a reasonable fallback.
239        $format ||= 'pod_simple_xhtml';
240      }
241      else {
242        $format = $type;
243      }
244    }
245
246    # The short name should become a method name with the prefix prepended.
247    my $prefix = 'format_fragment_';
248    $format =~ s/^$prefix//;
249    die "Unknown fragment format '$format'"
250      unless $self->can($prefix . $format);
251
252    # Save it.
253    $self->$attr($format);
254  }
255
256  return;
257}
258
259## Backward compatible API ##
260
261# For backward compatibility (previously based on Pod::Parser):
262# While Pod::Simple provides a parse_from_file() method
263# it's primarily for Pod::Parser compatibility.
264# When called without an output handle it will print to STDOUT
265# but the old Pod::Markdown never printed to a handle
266# so we don't want to start now.
267sub parse_from_file {
268  my ($self, $file) = @_;
269
270  # TODO: Check that all dependent cpan modules use the Pod::Simple API
271  # then add a deprecation warning here to avoid confusion.
272
273  $self->output_string(\($self->{_as_markdown_}));
274  $self->parse_file($file);
275}
276
277# Likewise, though Pod::Simple doesn't define this method at all.
278sub parse_from_filehandle { shift->parse_from_file(@_) }
279
280
281## Document state ##
282
283sub _private {
284  my ($self) = @_;
285  $self->{_Pod_Markdown_} ||= {
286    indent      => 0,
287    stacks      => [],
288    states      => [{}],
289    link        => [],
290    encode_amp  => 1,
291    encode_lt   => 1,
292  };
293}
294
295sub _increase_indent {
296  ++$_[0]->_private->{indent} >= 1
297    or die 'Invalid state: indent < 0';
298}
299sub _decrease_indent {
300  --$_[0]->_private->{indent} >= 0
301    or die 'Invalid state: indent < 0';
302}
303
304sub _new_stack {
305  push @{ $_[0]->_private->{stacks} }, [];
306  push @{ $_[0]->_private->{states} }, {};
307}
308
309sub _last_string {
310  $_[0]->_private->{stacks}->[-1][-1];
311}
312
313sub _pop_stack_text {
314  $_[0]->_private->{last_state} = pop @{ $_[0]->_private->{states} };
315  join '', @{ pop @{ $_[0]->_private->{stacks} } };
316}
317
318sub _stack_state {
319  $_[0]->_private->{states}->[-1];
320}
321
322sub _save {
323  my ($self, $text) = @_;
324  push @{ $self->_private->{stacks}->[-1] }, $text;
325  # return $text; # DEBUG
326}
327
328sub _save_line {
329  my ($self, $text) = @_;
330
331  $text = $self->_process_escapes($text);
332
333  $self->_save($text . $/);
334}
335
336# For paragraphs, etc.
337sub _save_block {
338  my ($self, $text) = @_;
339
340  $self->_stack_state->{blocks}++;
341
342  $self->_save_line($self->_indent($text) . $/);
343}
344
345## Formatting ##
346
347sub _chomp_all {
348  my ($self, $text) = @_;
349  1 while chomp $text;
350  return $text;
351}
352
353sub _indent {
354  my ($self, $text) = @_;
355  my $level = $self->_private->{indent};
356
357  if( $level ){
358    my $indent = ' ' x ($level * 4);
359
360    # Capture text on the line so that we don't indent blank lines (/^\x20{4}$/).
361    $text =~ s/^(.+)/$indent$1/mg;
362  }
363
364  return $text;
365}
366
367# as_markdown() exists solely for backward compatibility
368# and requires having called parse_from_file() to be useful.
369
370
371sub as_markdown {
372    my ($parser, %args) = @_;
373    my @header;
374    # Don't add meta tags again if we've already done it.
375    if( $args{with_meta} && !$parser->include_meta_tags ){
376        @header = $parser->_build_markdown_head;
377    }
378    return join("\n" x 2, @header, $parser->{_as_markdown_});
379}
380
381sub _build_markdown_head {
382    my $parser    = shift;
383    my $data      = $parser->_private;
384    return join "\n",
385        map  { qq![[meta \l$_="$data->{$_}"]]! }
386        grep { defined $data->{$_} }
387        qw( Title Author );
388}
389
390## Escaping ##
391
392# http://daringfireball.net/projects/markdown/syntax#backslash
393# Markdown provides backslash escapes for the following characters:
394#
395# \   backslash
396# `   backtick
397# *   asterisk
398# _   underscore
399# {}  curly braces
400# []  square brackets
401# ()  parentheses
402# #   hash mark
403# +   plus sign
404# -   minus sign (hyphen)
405# .   dot
406# !   exclamation mark
407
408# However some of those only need to be escaped in certain places:
409# * Backslashes *do* need to be escaped or they may be swallowed by markdown.
410# * Word-surrounding characters (/[`*_]/) *do* need to be escaped mid-word
411# because the markdown spec explicitly allows mid-word em*pha*sis.
412# * I don't actually see anything that curly braces are used for.
413# * Escaping square brackets is enough to avoid accidentally
414# creating links and images (so we don't need to escape plain parentheses
415# or exclamation points as that would generate a lot of unnecesary noise).
416# Parentheses will be escaped in urls (&end_L) to avoid premature termination.
417# * We don't need a backslash for every hash mark or every hyphen found mid-word,
418# just the ones that start a line (likewise for plus and dot).
419# (Those will all be handled by _escape_paragraph_markdown).
420
421
422# Backslash escape markdown characters to avoid having them interpreted.
423sub _escape_inline_markdown {
424  local $_ = $_[1];
425
426# s/([\\`*_{}\[\]()#+-.!])/\\$1/g; # See comments above.
427  s/([\\`*_\[\]])/\\$1/g;
428
429  return $_;
430}
431
432# Escape markdown characters that would be interpreted
433# at the start of a line.
434sub _escape_paragraph_markdown {
435    local $_ = $_[1];
436
437    # Escape headings, horizontal rules, (unordered) lists, and blockquotes.
438    s/^([-+#>])/\\$1/mg;
439
440    # Markdown doesn't support backslash escapes for equal signs
441    # even though they can be used to underline a header.
442    # So use html to escape them to avoid having them interpreted.
443    s/^([=])/sprintf '&#x%x;', ord($1)/mge;
444
445    # Escape the dots that would wrongfully create numbered lists.
446    s/^( (?:>\s+)? \d+ ) (\.\x20)/$1\\$2/xgm;
447
448    return $_;
449}
450
451
452# Additionally Markdown allows inline html so we need to escape things that look like it.
453# While _some_ Markdown processors handle backslash-escaped html,
454# [Daring Fireball](http://daringfireball.net/projects/markdown/syntax) states distinctly:
455# > In HTML, there are two characters that demand special treatment: < and &...
456# > If you want to use them as literal characters, you must escape them as entities, e.g. &lt;, and &amp;.
457
458# It goes on to say:
459# > Markdown allows you to use these characters naturally,
460# > taking care of all the necessary escaping for you.
461# > If you use an ampersand as part of an HTML entity,
462# > it remains unchanged; otherwise it will be translated into &amp;.
463# > Similarly, because Markdown supports inline HTML,
464# > if you use angle brackets as delimiters for HTML tags, Markdown will treat them as such.
465
466# In order to only encode the occurrences that require it (something that
467# could be interpreted as an entity) we escape them all so that we can do the
468# suffix test later after the string is complete (since we don't know what
469# strings might come after this one).
470
471my %_escape =
472  map {
473    my ($k, $v) = split /:/;
474    # Put the "code" marker before the char instead of after so that it doesn't
475    # get confused as the $2 (which is what requires us to entity-encode it).
476    # ( "XsX", "XcsX", "X(c?)sX" )
477    my ($s, $code, $re) = map { "\0$_$v\0" } '', map { ($_, '('.$_.'?)') } 'c';
478
479    (
480      $k         => $s,
481      $k.'_code' => $code,
482      $k.'_re'   => qr/$re/,
483    )
484  }
485    qw( amp:& lt:< );
486
487# Make the values of this private var available to the tests.
488sub __escape_sequences { %_escape }
489
490
491# HTML-entity encode any characters configured by the user.
492# If that doesn't include [&<] then we escape those chars so we can decide
493# later if we will entity-encode them or put them back verbatim.
494sub _encode_or_escape_entities {
495  my $self  = $_[0];
496  my $stash = $self->_private;
497  local $_  = $_[1];
498
499  if( $stash->{encode_amp} ){
500    if( exists($stash->{html_encode_chars}) ){
501      # Escape all amps for later processing.
502      # Pass intermediate strings to entity encoder so that it doesn't
503      # process any of the characters of our escape sequences.
504      # Use -1 to get "as many fields as possible" so that we keep leading and
505      # trailing (possibly empty) fields.
506      $_ = join $_escape{amp}, map { $self->encode_entities($_) } split /&/, $_, -1;
507    }
508    else {
509      s/&/$_escape{amp}/g;
510    }
511  }
512  elsif( exists($stash->{html_encode_chars}) ){
513    $_ = $self->encode_entities($_);
514  }
515
516  s/</$_escape{lt}/g
517    if $stash->{encode_lt};
518
519  return $_;
520}
521
522# From Markdown.pl version 1.0.1 line 1172 (_DoAutoLinks).
523my $EMAIL_MARKER = qr{
524#   <                  # Opening token is in parent regexp.
525        (?:mailto:)?
526    (
527      [-.\w]+
528      \@
529      [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
530    )
531    >
532}x;
533
534# Process any escapes we put in the text earlier,
535# now that the text is complete (end of a block).
536sub _process_escapes {
537  my $self  = $_[0];
538  my $stash = $self->_private;
539  local $_  = $_[1];
540
541  # The patterns below are taken from Markdown.pl 1.0.1 _EncodeAmpsAndAngles().
542  # In this case we only want to encode the ones that Markdown won't.
543  # This is overkill but produces nicer looking text (less escaped entities).
544  # If it proves insufficent then we'll just encode them all.
545
546  # $1: If the escape was in a code sequence, simply replace the original.
547  # $2: If the unescaped value would be followed by characters
548  #     that could be interpreted as html, entity-encode it.
549  # else: The character is safe to leave bare.
550
551  # Neither currently allows $2 to contain '0' so bool tests are sufficient.
552
553  if( $stash->{encode_amp} ){
554    # Encode & if succeeded by chars that look like an html entity.
555    s,$_escape{amp_re}((?:#?[xX]?(?:[0-9a-fA-F]+|\w+);)?),
556      $1 ? '&'.$2 : $2 ? '&amp;'.$2 : '&',egos;
557  }
558
559  if( $stash->{encode_lt} ){
560    # Encode < if succeeded by chars that look like an html tag.
561    # Leave email addresses (<foo@bar.com>) for Markdown to process.
562    s,$_escape{lt_re}((?=$EMAIL_MARKER)|(?:[a-z/?\$!])?),
563      $1 ? '<'.$2 : $2 ?  '&lt;'.$2 : '<',egos;
564  }
565
566  return $_;
567}
568
569
570## Parsing ##
571
572sub handle_text {
573  my $self  = $_[0];
574  my $stash = $self->_private;
575  local $_  = $_[1];
576
577  # Unless we're in a code span, verbatim block, or formatted region.
578  unless( $stash->{no_escape} ){
579
580    # We could, in theory, alter what gets escaped according to context
581    # (for example, escape square brackets (but not parens) inside link text).
582    # The markdown produced might look slightly nicer but either way you're
583    # at the whim of the markdown processor to interpret things correctly.
584    # For now just escape everything.
585
586    # Don't let literal characters be interpreted as markdown.
587    $_ = $self->_escape_inline_markdown($_);
588
589    # Entity-encode (or escape for later processing) necessary/desired chars.
590    $_ = $self->_encode_or_escape_entities($_);
591
592  }
593  # If this _is_ a code section, do limited/specific handling.
594  else {
595    # Always escaping these chars ensures that we won't mangle the text
596    # in the unlikely event that a sequence matching our escape occurred in the
597    # input stream (since we're going to escape it and then unescape it).
598    s/&/$_escape{amp_code}/gos if $stash->{encode_amp};
599    s/</$_escape{lt_code}/gos  if $stash->{encode_lt};
600  }
601
602  $self->_save($_);
603}
604
605sub start_Document {
606  my ($self) = @_;
607  $self->_new_stack;
608}
609
610sub   end_Document {
611  my ($self) = @_;
612  $self->_check_search_header;
613  my $end = pop @{ $self->_private->{stacks} };
614
615  @{ $self->_private->{stacks} } == 0
616    or die 'Document ended with stacks remaining';
617
618  my @doc = $self->_chomp_all(join('', @$end)) . $/;
619
620  if( $self->include_meta_tags ){
621    unshift @doc, $self->_build_markdown_head, ($/ x 2);
622  }
623
624  if( my $encoding = $self->_get_output_encoding ){
625    # Do the check outside the loop(s) for efficiency.
626    my $ents = $HAS_HTML_ENTITIES ? \&__entity_encode_ord_he : \&__entity_encode_ord_basic;
627    # Iterate indices to avoid copying large strings.
628    for my $i ( 0 .. $#doc ){
629      print { $self->{output_fh} } Encode::encode($encoding, $doc[$i], $ents);
630    }
631  }
632  else {
633    print { $self->{output_fh} } @doc;
634  }
635}
636
637sub _get_output_encoding {
638  my ($self) = @_;
639
640  # If 'match_encoding' is set we need to return an encoding.
641  # If pod has no =encoding, Pod::Simple will guess if it sees a high-bit char.
642  # If there are no high-bit chars, encoding is undef.
643  # Use detected_encoding() rather than encoding() because if Pod::Simple
644  # can't use whatever encoding was specified, we probably can't either.
645  # Fallback to 'o_e' if no match is found.  This gives the user the choice,
646  # since otherwise there would be no reason to specify 'o_e' *and* 'm_e'.
647  # Fallback to UTF-8 since it is a reasonable default these days.
648
649  return $self->detected_encoding || $self->output_encoding || 'UTF-8'
650    if $self->match_encoding;
651
652  # If output encoding wasn't specified, return false.
653  return $self->output_encoding;
654}
655
656## Blocks ##
657
658sub start_Verbatim {
659  my ($self) = @_;
660  $self->_new_stack;
661  $self->_private->{no_escape} = 1;
662}
663
664sub end_Verbatim {
665  my ($self) = @_;
666
667  my $text = $self->_pop_stack_text;
668
669  $text = $self->_indent_verbatim($text);
670
671  $self->_private->{no_escape} = 0;
672
673  # Verbatim blocks do not generate a separate "Para" event.
674  $self->_save_block($text);
675}
676
677sub _indent_verbatim {
678  my ($self, $paragraph) = @_;
679
680    # NOTE: Pod::Simple expands the tabs for us (as suggested by perlpodspec).
681    # Pod::Simple also has a 'strip_verbatim_indent' attribute
682    # but it doesn't sound like it gains us anything over this method.
683
684    # POD verbatim can start with any number of spaces (or tabs)
685    # markdown should be 4 spaces (or a tab)
686    # so indent any paragraphs so that all lines start with at least 4 spaces
687    my @lines = split /\n/, $paragraph;
688    my $indent = ' ' x 4;
689    foreach my $line ( @lines ){
690        next unless $line =~ m/^( +)/;
691        # find the smallest indentation
692        $indent = $1 if length($1) < length($indent);
693    }
694    if( (my $smallest = length($indent)) < 4 ){
695        # invert to get what needs to be prepended
696        $indent = ' ' x (4 - $smallest);
697
698        # Prepend indent to each line.
699        # We could check /\S/ to only indent non-blank lines,
700        # but it's backward compatible to respect the whitespace.
701        # Additionally, both pod and markdown say they ignore blank lines
702        # so it shouldn't hurt to leave them in.
703        $paragraph = join "\n", map { length($_) ? $indent . $_ : '' } @lines;
704    }
705
706  return $paragraph;
707}
708
709sub start_Para {
710  $_[0]->_new_stack;
711}
712
713sub   end_Para {
714  my ($self) = @_;
715  my $text = $self->_pop_stack_text;
716
717  $text = $self->_escape_paragraph_markdown($text);
718
719  $self->_save_block($text);
720}
721
722
723## Headings ##
724
725sub start_head1 { $_[0]->_start_head(1) }
726sub   end_head1 { $_[0]->_end_head(1) }
727sub start_head2 { $_[0]->_start_head(2) }
728sub   end_head2 { $_[0]->_end_head(2) }
729sub start_head3 { $_[0]->_start_head(3) }
730sub   end_head3 { $_[0]->_end_head(3) }
731sub start_head4 { $_[0]->_start_head(4) }
732sub   end_head4 { $_[0]->_end_head(4) }
733
734sub _check_search_header {
735  my ($self) = @_;
736  # Save the text since the last heading if we want it for metadata.
737  if( my $last = $self->_private->{search_header} ){
738    for( $self->_private->{$last} = $self->_last_string ){
739      s/\A\s+//;
740      s/\s+\z//;
741    }
742  }
743}
744sub _start_head {
745  my ($self) = @_;
746  $self->_check_search_header;
747  $self->_new_stack;
748}
749
750sub   _end_head {
751  my ($self, $num) = @_;
752  my $h = '#' x $num;
753
754  my $text = $self->_pop_stack_text;
755  $self->_private->{search_header} =
756      $text =~ /NAME/   ? 'Title'
757    : $text =~ /AUTHOR/ ? 'Author'
758    : undef;
759
760  # TODO: option for $h suffix
761  # TODO: put a name="" if $self->{embed_anchor_tags}; ?
762  # https://rt.cpan.org/Ticket/Display.html?id=57776
763  $self->_save_block(join(' ', $h, $text));
764}
765
766## Lists ##
767
768# With Pod::Simple->parse_empty_lists(1) there could be an over_empty event,
769# but what would you do with that?
770
771sub _start_list {
772  my ($self) = @_;
773  $self->_new_stack;
774
775  # Nest again b/c start_item will pop this to look for preceding content.
776  $self->_increase_indent;
777  $self->_new_stack;
778}
779
780sub   _end_list {
781  my ($self) = @_;
782  $self->_handle_between_item_content;
783
784  # Finish the list.
785
786  # All the child elements should be blocks,
787  # but don't end with a double newline.
788  my $text = $self->_chomp_all($self->_pop_stack_text);
789
790  $_[0]->_save_line($text . $/);
791}
792
793sub _handle_between_item_content {
794  my ($self) = @_;
795
796  # This might be empty (if the list item had no additional content).
797  if( my $text = $self->_pop_stack_text ){
798    # Else it's a sub-document.
799    # If there are blocks we need to separate with blank lines.
800    if( $self->_private->{last_state}->{blocks} ){
801      $text = $/ . $text;
802    }
803    # If not, we can condense the text.
804    # In this module's history there was a patch contributed to specifically
805    # produce "huddled" lists so we'll try to maintain that functionality.
806    else {
807      $text = $self->_chomp_all($text) . $/;
808    }
809    $self->_save($text)
810  }
811
812  $self->_decrease_indent;
813}
814
815sub _start_item {
816  my ($self) = @_;
817  $self->_handle_between_item_content;
818  $self->_new_stack;
819}
820
821sub   _end_item {
822  my ($self, $marker) = @_;
823  my $text = $self->_pop_stack_text;
824  $self->_save_line($self->_indent($marker .
825    # Add a space only if there is text after the marker.
826    (defined($text) && length($text) ? ' ' . $text : '')
827  ));
828
829  # Store any possible contents in a new stack (like a sub-document).
830  $self->_increase_indent;
831  $self->_new_stack;
832}
833
834sub start_over_bullet { $_[0]->_start_list }
835sub   end_over_bullet { $_[0]->_end_list }
836
837sub start_item_bullet { $_[0]->_start_item }
838sub   end_item_bullet { $_[0]->_end_item('-') }
839
840sub start_over_number { $_[0]->_start_list }
841sub   end_over_number { $_[0]->_end_list }
842
843sub start_item_number {
844  $_[0]->_start_item;
845  # It seems like this should be a stack,
846  # but from testing it appears that the corresponding 'end' event
847  # comes right after the text (it doesn't surround any embedded content).
848  # See t/nested.t which shows start-item, text, end-item, para, start-item....
849  $_[0]->_private->{item_number} = $_[1]->{number};
850}
851
852sub   end_item_number {
853  my ($self) = @_;
854  $self->_end_item($self->_private->{item_number} . '.');
855}
856
857# Markdown doesn't support definition lists
858# so do regular (unordered) lists with indented paragraphs.
859sub start_over_text { $_[0]->_start_list }
860sub   end_over_text { $_[0]->_end_list }
861
862sub start_item_text { $_[0]->_start_item }
863sub   end_item_text { $_[0]->_end_item('-')}
864
865
866# perlpodspec equates an over/back region with no items to a blockquote.
867sub start_over_block {
868  # NOTE: We don't actually need to indent for a blockquote.
869  $_[0]->_new_stack;
870}
871
872sub   end_over_block {
873  my ($self) = @_;
874
875  # Chomp first to avoid prefixing a blank line with a `>`.
876  my $text = $self->_chomp_all($self->_pop_stack_text);
877
878  # NOTE: Paragraphs will already be escaped.
879
880  # I don't really like either of these implementations
881  # but the join/map/split seems a little better and benches a little faster.
882  # You would lose the last newline but we've already chomped.
883  #$text =~ s{^(.)?}{'>' . (defined($1) && length($1) ? (' ' . $1) : '')}mge;
884  $text = join $/, map { length($_) ? '> ' . $_ : '>' } split qr-$/-, $text;
885
886  $self->_save_block($text);
887}
888
889## Custom Formats ##
890
891sub start_for {
892  my ($self, $attr) = @_;
893  $self->_new_stack;
894
895  if( $attr->{target} eq 'html' ){
896    # Use another stack so we can indent
897    # (not syntactily necessary but seems appropriate).
898    $self->_new_stack;
899    $self->_increase_indent;
900    $self->_private->{no_escape} = 1;
901    # Mark this so we know to undo it.
902    $self->_stack_state->{for_html} = 1;
903  }
904}
905
906sub end_for {
907  my ($self) = @_;
908  # Data gets saved as a block (which will handle indents),
909  # but if there was html we'll alter this, so chomp and save a block again.
910  my $text = $self->_chomp_all($self->_pop_stack_text);
911
912  if( $self->_private->{last_state}->{for_html} ){
913    $self->_private->{no_escape} = 0;
914    # Save it to the next stack up so we can pop it again (we made two stacks).
915    $self->_save($text);
916    $self->_decrease_indent;
917    $text = join "\n", '<div>', $self->_chomp_all($self->_pop_stack_text), '</div>';
918  }
919
920  $self->_save_block($text);
921}
922
923# Data events will be emitted for any formatted regions that have been enabled
924# (by default, `markdown` and `html`).
925
926sub start_Data {
927  my ($self) = @_;
928  # TODO: limit this to what's in attr?
929  $self->_private->{no_escape}++;
930  $self->_new_stack;
931}
932
933sub   end_Data {
934  my ($self) = @_;
935  my $text = $self->_pop_stack_text;
936  $self->_private->{no_escape}--;
937  $self->_save_block($text);
938}
939
940## Codes ##
941
942sub start_B { $_[0]->_save('**') }
943sub   end_B { $_[0]->start_B()   }
944
945sub start_I { $_[0]->_save('_') }
946sub   end_I { $_[0]->start_I()  }
947
948sub start_C {
949  my ($self) = @_;
950  $self->_new_stack;
951  $self->_private->{no_escape}++;
952}
953
954sub   end_C {
955  my ($self) = @_;
956  $self->_private->{no_escape}--;
957  $self->_save( $self->_wrap_code_span($self->_pop_stack_text) );
958}
959
960# Use code spans for F<>.
961sub start_F { shift->start_C(@_); }
962sub   end_F { shift  ->end_C(@_); }
963
964sub start_L {
965  my ($self, $flags) = @_;
966  $self->_new_stack;
967  push @{ $self->_private->{link} }, $flags;
968}
969
970sub   end_L {
971  my ($self) = @_;
972  my $flags = pop @{ $self->_private->{link} }
973    or die 'Invalid state: link end with no link start';
974
975  my ($type, $to, $section) = @{$flags}{qw( type to section )};
976
977  my $url = (
978    $type eq 'url' ? $to
979      : $type eq 'man' ? $self->format_man_url($to, $section)
980      : $type eq 'pod' ? $self->format_perldoc_url($to, $section)
981      :                  undef
982  );
983
984  my $text = $self->_pop_stack_text;
985
986  # NOTE: I don't think the perlpodspec says what to do with L<|blah>
987  # but it seems like a blank link text just doesn't make sense
988  if( !length($text) ){
989    $text =
990      $section ?
991        $to ? sprintf('"%s" in %s', $section, $to)
992        : ('"' . $section . '"')
993      : $to;
994  }
995
996  # FIXME: What does Pod::Simple::X?HTML do for this?
997  # if we don't know how to handle the url just print the pod back out
998  if (!$url) {
999    $self->_save(sprintf 'L<%s>', $flags->{raw});
1000    return;
1001  }
1002
1003  # In the url we need to escape quotes and parentheses lest markdown
1004  # break the url (cut it short and/or wrongfully interpret a title).
1005
1006  # Backslash escapes do not work for the space and quotes.
1007  # URL-encoding the space is not sufficient
1008  # (the quotes confuse some parsers and produce invalid html).
1009  # I've arbitratily chosen HTML encoding to hide them from markdown
1010  # while mangling the url as litle as possible.
1011  $url =~ s/([ '"])/sprintf '&#x%x;', ord($1)/ge;
1012
1013  # We also need to double any backslashes that may be present
1014  # (lest they be swallowed up) and stop parens from breaking the url.
1015  $url =~ s/([\\()])/\\$1/g;
1016
1017  # TODO: put section name in title if not the same as $text
1018  $self->_save('[' . $text . '](' . $url . ')');
1019}
1020
1021sub start_X {
1022  $_[0]->_new_stack;
1023}
1024
1025sub   end_X {
1026  my ($self) = @_;
1027  my $text = $self->_pop_stack_text;
1028  # TODO: mangle $text?
1029  # TODO: put <a name="$text"> if configured
1030}
1031
1032# A code span can be delimited by multiple backticks (and a space)
1033# similar to pod codes (C<< code >>), so ensure we use a big enough
1034# delimiter to not have it broken by embedded backticks.
1035sub _wrap_code_span {
1036  my ($self, $arg) = @_;
1037  my $longest = 0;
1038  while( $arg =~ /([`]+)/g ){
1039    my $len = length($1);
1040    $longest = $len if $longest < $len;
1041  }
1042  my $delim = '`' x ($longest + 1);
1043  my $pad = $longest > 0 ? ' ' : '';
1044  return $delim . $pad . $arg . $pad . $delim;
1045}
1046
1047## Link Formatting (TODO: Move this to another module) ##
1048
1049
1050sub format_man_url {
1051    my ($self, $to) = @_;
1052    my ($page, $part) = ($to =~ /^ ([^(]+) (?: \( (\S+) \) )? /x);
1053    return $self->man_url_prefix . ($part || 1) . '/' . ($page || $to);
1054}
1055
1056
1057sub format_perldoc_url {
1058  my ($self, $name, $section) = @_;
1059
1060  my $url_prefix = $self->perldoc_url_prefix;
1061  if (
1062    defined($name)
1063    && $self->is_local_module($name)
1064    && defined($self->local_module_url_prefix)
1065  ) {
1066    $url_prefix = $self->local_module_url_prefix;
1067  }
1068
1069  my $url = '';
1070
1071  # If the link is to another module (external link).
1072  if ($name) {
1073    $url = $url_prefix . ($self->escape_url ? URI::Escape::uri_escape($name) : $name);
1074  }
1075
1076  # See https://rt.cpan.org/Ticket/Display.html?id=57776
1077  # for a discussion on the need to mangle the section.
1078  if ($section){
1079
1080    my $method = $url
1081      # If we already have a prefix on the url it's external.
1082      ? $self->perldoc_fragment_format
1083      # Else an internal link points to this markdown doc.
1084      : $self->markdown_fragment_format;
1085
1086    $method = 'format_fragment_' . $method
1087      unless ref($method);
1088
1089    {
1090      # Set topic to enable code refs to be simple.
1091      local $_ = $section;
1092      $section = $self->$method($section);
1093    }
1094
1095    $url .= '#' . $section;
1096  }
1097
1098  return $url;
1099}
1100
1101
1102# TODO: simple, pandoc, etc?
1103
1104sub format_fragment_markdown {
1105  my ($self, $section) = @_;
1106
1107  # If this is an internal link (to another section in this doc)
1108  # we can't be sure what the heading id's will look like
1109  # (it depends on what is rendering the markdown to html)
1110  # but we can try to follow popular conventions.
1111
1112  # http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html#header-identifiers-in-html-latex-and-context
1113  #$section =~ s/(?![-_.])[[:punct:]]//g;
1114  #$section =~ s/\s+/-/g;
1115  $section =~ s/\W+/-/g;
1116  $section =~ s/-+$//;
1117  $section =~ s/^-+//;
1118  $section = lc $section;
1119  #$section =~ s/^[^a-z]+//;
1120  $section ||= 'section';
1121
1122  return $section;
1123}
1124
1125
1126{
1127  # From Pod::Simple::XHTML 3.28.
1128  # The strings gets passed through encode_entities() before idify().
1129  # If we don't do it here the substitutions below won't operate consistently.
1130
1131  sub format_fragment_pod_simple_xhtml {
1132    my ($self, $t) = @_;
1133
1134    # encode_entities {
1135      # We need to use the defaults in case html_encode_chars has been customized
1136      # (since the purpose is to match what external sources are doing).
1137
1138      local $self->_private->{html_encode_chars};
1139      $t = $self->encode_entities($t);
1140    # }
1141
1142    # idify {
1143      for ($t) {
1144          s/<[^>]+>//g;            # Strip HTML.
1145          s/&[^;]+;//g;            # Strip entities.
1146          s/^\s+//; s/\s+$//;      # Strip white space.
1147          s/^([^a-zA-Z]+)$/pod$1/; # Prepend "pod" if no valid chars.
1148          s/^[^a-zA-Z]+//;         # First char must be a letter.
1149          s/[^-a-zA-Z0-9_:.]+/-/g; # All other chars must be valid.
1150          s/[-:.]+$//;             # Strip trailing punctuation.
1151      }
1152    # }
1153
1154    return $t;
1155  }
1156}
1157
1158
1159sub format_fragment_pod_simple_html {
1160  my ($self, $section) = @_;
1161
1162  # From Pod::Simple::HTML 3.28.
1163
1164  # section_name_tidy {
1165    $section =~ s/^\s+//;
1166    $section =~ s/\s+$//;
1167    $section =~ tr/ /_/;
1168    $section =~ tr/\x00-\x1F\x80-\x9F//d if 'A' eq chr(65); # drop crazy characters
1169
1170    #$section = $self->unicode_escape_url($section);
1171      # unicode_escape_url {
1172      $section =~ s/([^\x00-\xFF])/'('.ord($1).')'/eg;
1173        #  Turn char 1234 into "(1234)"
1174      # }
1175
1176    $section = '_' unless length $section;
1177    return $section;
1178  # }
1179}
1180
1181
1182sub format_fragment_metacpan { shift->format_fragment_pod_simple_xhtml(@_); }
1183sub format_fragment_sco      { shift->format_fragment_pod_simple_html(@_);  }
1184
1185
1186sub is_local_module {
1187  my ($self, $name) = @_;
1188
1189  return ($name =~ $self->local_module_re);
1190}
1191
11921;
1193
1194__END__
1195
1196=pod
1197
1198=encoding UTF-8
1199
1200=for :stopwords Marcel Gruenauer Victor Moral Ryan C. Thompson <rct at thompsonclan d0t
1201org> Aristotle Pagaltzis Randy Stauner ACKNOWLEDGEMENTS html cpan
1202testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto
1203metadata placeholders metacpan
1204
1205=head1 NAME
1206
1207Pod::Markdown - Convert POD to Markdown
1208
1209=head1 VERSION
1210
1211version 3.300
1212
1213=for test_synopsis my ($pod_string);
1214
1215=head1 SYNOPSIS
1216
1217  # Pod::Simple API is supported.
1218
1219  # Command line usage: Parse a pod file and print to STDOUT:
1220  # $ perl -MPod::Markdown -e 'Pod::Markdown->new->filter(@ARGV)' path/to/POD/file > README.md
1221
1222  # Work with strings:
1223  my $markdown;
1224  my $parser = Pod::Markdown->new;
1225  $parser->output_string(\$markdown);
1226  $parser->parse_string_document($pod_string);
1227
1228  # See Pod::Simple docs for more.
1229
1230=head1 DESCRIPTION
1231
1232This module uses L<Pod::Simple> to convert POD to Markdown.
1233
1234Literal characters in Pod that are special in Markdown
1235(like *asterisks*) are backslash-escaped when appropriate.
1236
1237By default C<markdown> and C<html> formatted regions are accepted.
1238Regions of C<markdown> will be passed through unchanged.
1239Regions of C<html> will be placed inside a C<< E<lt>divE<gt> >> tag
1240so that markdown characters won't be processed.
1241Regions of C<:markdown> or C<:html> will be processed as POD and included.
1242To change which regions are accepted use the L<Pod::Simple> API:
1243
1244  my $parser = Pod::Markdown->new;
1245  $parser->unaccept_targets(qw( markdown html ));
1246
1247=head2 A note on encoding and escaping
1248
1249The common L<Pod::Simple> API returns a character string.
1250If you want Pod::Markdown to return encoded octets, there are two attributes
1251to assist: L</match_encoding> and L</output_encoding>.
1252
1253When an output encoding is requested any characters that are not valid
1254for that encoding will be escaped as HTML entities.
1255
1256This is not 100% safe, however.
1257
1258Markdown escapes all ampersands inside of code spans, so escaping a character
1259as an HTML entity inside of a code span will not be correct.
1260However, with pod's C<S> and C<E> sequences it is possible
1261to end up with high-bit characters inside of code spans.
1262
1263So, while C<< output_encoding => 'ascii' >> can work, it is not recommended.
1264For these reasons (and more), C<UTF-8> is the default, fallback encoding (when one is required).
1265
1266If you prefer HTML entities over literal characters you can use
1267L</html_encode_chars> which will only operate outside of code spans (where it is safe).
1268
1269=head1 METHODS
1270
1271=head2 new
1272
1273  Pod::Markdown->new(%options);
1274
1275The constructor accepts the following named arguments:
1276
1277=over 4
1278
1279=item *
1280
1281C<local_module_url_prefix>
1282
1283Alters the perldoc urls that are created from C<< LE<lt>E<gt> >> codes
1284when the module is a "local" module (C<"Local::*"> or C<"Foo_Corp::*"> (see L<perlmodlib>)).
1285
1286The default is to use C<perldoc_url_prefix>.
1287
1288=item *
1289
1290C<local_module_re>
1291
1292Alternate regular expression for determining "local" modules.
1293Default is C<< our $LOCAL_MODULE_RE = qr/^(Local::|\w*?_\w*)/ >>.
1294
1295=item *
1296
1297C<man_url_prefix>
1298
1299Alters the man page urls that are created from C<< LE<lt>E<gt> >> codes.
1300
1301The default is C<http://man.he.net/man>.
1302
1303=item *
1304
1305C<perldoc_url_prefix>
1306
1307Alters the perldoc urls that are created from C<< LE<lt>E<gt> >> codes.
1308Can be:
1309
1310=over 4
1311
1312=item *
1313
1314C<metacpan> (shortcut for C<https://metacpan.org/pod/>)
1315
1316=item *
1317
1318C<sco> (shortcut for C<http://search.cpan.org/perldoc?>)
1319
1320=item *
1321
1322any url
1323
1324=back
1325
1326The default is C<metacpan>.
1327
1328    Pod::Markdown->new(perldoc_url_prefix => 'http://localhost/perl/pod');
1329
1330=item *
1331
1332C<perldoc_fragment_format>
1333
1334Alters the format of the url fragment for any C<< LE<lt>E<gt> >> links
1335that point to a section of an external document (C<< L<name/section> >>).
1336The default will be chosen according to the destination L</perldoc_url_prefix>.
1337Alternatively you can specify one of the following:
1338
1339=over 4
1340
1341=item *
1342
1343C<metacpan>
1344
1345=item *
1346
1347C<sco>
1348
1349=item *
1350
1351C<pod_simple_xhtml>
1352
1353=item *
1354
1355C<pod_simple_html>
1356
1357=item *
1358
1359A code ref
1360
1361=back
1362
1363The code ref can expect to receive two arguments:
1364the parser object (C<$self>) and the section text.
1365For convenience the topic variable (C<$_>) is also set to the section text:
1366
1367  perldoc_fragment_format => sub { s/\W+/-/g; }
1368
1369=item *
1370
1371C<markdown_fragment_format>
1372
1373Alters the format of the url fragment for any C<< LE<lt>E<gt> >> links
1374that point to an internal section of this document (C<< L</section> >>).
1375
1376Unfortunately the format of the id attributes produced
1377by whatever system translates the markdown into html is unknown at the time
1378the markdown is generated so we do some simple clean up.
1379
1380B<Note:> C<markdown_fragment_format> and C<perldoc_fragment_format> accept
1381the same values: a (shortcut to a) method name or a code ref.
1382
1383=item *
1384
1385C<include_meta_tags>
1386
1387Specifies whether or not to print author/title meta tags at the top of the document.
1388Default is false.
1389
1390=item *
1391
1392C<escape_url>
1393
1394Specifies whether or not to escape URLs.  Default is true.  It is not recommended
1395to turn this off with an empty local_module_url_prefix, as the resulting local
1396module URLs can be confused with IPv6 addresses by web browsers.
1397
1398=back
1399
1400=head2 html_encode_chars
1401
1402A string of characters to encode as html entities
1403(using L<HTML::Entities/encode_entities> if available, falling back to numeric entities if not).
1404
1405Possible values:
1406
1407=over 4
1408
1409=item *
1410
1411A value of C<1> will use the default set of characters from L<HTML::Entities> (control chars, high-bit chars, and C<< <&>"' >>).
1412
1413=item *
1414
1415A false value will disable.
1416
1417=item *
1418
1419Any other value is used as a string of characters (like a regular expression character class).
1420
1421=back
1422
1423By default this is disabled and literal characters will be in the output stream.
1424If you specify a desired L</output_encoding> any characters not valid for that encoding will be HTML entity encoded.
1425
1426B<Note> that Markdown requires ampersands (C<< & >>) and left angle brackets (C<< < >>)
1427to be entity-encoded if they could otherwise be interpreted as html entities.
1428If this attribute is configured to encode those characters, they will always be encoded.
1429If not, the module will make an effort to only encode the ones required,
1430so there will be less html noise in the output.
1431
1432=head2 match_encoding
1433
1434Boolean: If true, use the C<< =encoding >> of the input pod
1435as the encoding for the output.
1436
1437If no encoding is specified, L<Pod::Simple> will guess the encoding
1438if it sees a high-bit character.
1439
1440If no encoding is guessed (or the specified encoding is unusable),
1441L</output_encoding> will be used if it was specified.
1442Otherwise C<UTF-8> will be used.
1443
1444This attribute is not recommended
1445but is provided for consistency with other pod converters.
1446
1447Defaults to false.
1448
1449=head2 output_encoding
1450
1451The encoding to use when writing to the output file handle.
1452
1453If neither this nor L</match_encoding> are specified,
1454a character string will be returned in whatever L<Pod::Simple> output method you specified.
1455
1456=head2 local_module_re
1457
1458Returns the regular expression used to determine local modules.
1459
1460=head2 local_module_url_prefix
1461
1462Returns the url prefix in use for local modules.
1463
1464=head2 man_url_prefix
1465
1466Returns the url prefix in use for man pages.
1467
1468=head2 perldoc_url_prefix
1469
1470Returns the url prefix in use (after resolving shortcuts to urls).
1471
1472=head2 perldoc_fragment_format
1473
1474Returns the coderef or format name used to format a url fragment
1475to a section in an external document.
1476
1477=head2 markdown_fragment_format
1478
1479Returns the coderef or format name used to format a url fragment
1480to an internal section in this document.
1481
1482=head2 include_meta_tags
1483
1484Returns the boolean value indicating
1485whether or not meta tags will be printed.
1486
1487=head2 escape_url
1488
1489Returns the boolean value indicating
1490whether or not URLs should be escaped.
1491
1492=head2 format_man_url
1493
1494Used internally to create a url (using L</man_url_prefix>)
1495from a string like C<man(1)>.
1496
1497=head2 format_perldoc_url
1498
1499    # With $name and section being the two parts of L<name/section>.
1500    my $url = $parser->format_perldoc_url($name, $section);
1501
1502Used internally to create a url from
1503the name (of a module or script)
1504and a possible section (heading).
1505
1506The format of the url fragment (when pointing to a section in a document)
1507varies depending on the destination url
1508so L</perldoc_fragment_format> is used (which can be customized).
1509
1510If the module name portion of the link is blank
1511then the section is treated as an internal fragment link
1512(to a section of the generated markdown document)
1513and L</markdown_fragment_format> is used (which can be customized).
1514
1515=head2 format_fragment_markdown
1516
1517Format url fragment for an internal link
1518by replacing non-word characters with dashes.
1519
1520=head2 format_fragment_pod_simple_xhtml
1521
1522Format url fragment like L<Pod::Simple::XHTML/idify>.
1523
1524=head2 format_fragment_pod_simple_html
1525
1526Format url fragment like L<Pod::Simple::HTML/section_name_tidy>.
1527
1528=head2 format_fragment_metacpan
1529
1530Format fragment for L<metacpan.org>
1531(uses L</format_fragment_pod_simple_xhtml>).
1532
1533=head2 format_fragment_sco
1534
1535Format fragment for L<search.cpan.org>
1536(uses L</format_fragment_pod_simple_html>).
1537
1538=head2 is_local_module
1539
1540Uses C<local_module_re> to determine if passed module is a "local" module.
1541
1542=for Pod::Coverage parse_from_file
1543parse_from_filehandle
1544
1545=for Pod::Coverage as_markdown
1546
1547=for Pod::Coverage handle_text
1548end_.+
1549start_.+
1550encode_entities
1551
1552=head1 SEE ALSO
1553
1554=over 4
1555
1556=item *
1557
1558L<pod2markdown> - script included for command line usage
1559
1560=item *
1561
1562L<Pod::Simple> - Super class that handles Pod parsing
1563
1564=item *
1565
1566L<perlpod> - For writing POD
1567
1568=item *
1569
1570L<perlpodspec> - For parsing POD
1571
1572=item *
1573
1574L<http://daringfireball.net/projects/markdown/syntax> - Markdown spec
1575
1576=back
1577
1578=head1 SUPPORT
1579
1580=head2 Perldoc
1581
1582You can find documentation for this module with the perldoc command.
1583
1584  perldoc Pod::Markdown
1585
1586=head2 Websites
1587
1588The following websites have more information about this module, and may be of help to you. As always,
1589in addition to those websites please use your favorite search engine to discover more resources.
1590
1591=over 4
1592
1593=item *
1594
1595MetaCPAN
1596
1597A modern, open-source CPAN search engine, useful to view POD in HTML format.
1598
1599L<https://metacpan.org/release/Pod-Markdown>
1600
1601=back
1602
1603=head2 Bugs / Feature Requests
1604
1605Please report any bugs or feature requests by email to C<bug-pod-markdown at rt.cpan.org>, or through
1606the web interface at L<https://rt.cpan.org/Public/Bug/Report.html?Queue=Pod-Markdown>. You will be automatically notified of any
1607progress on the request by the system.
1608
1609=head2 Source Code
1610
1611
1612L<https://github.com/rwstauner/Pod-Markdown>
1613
1614  git clone https://github.com/rwstauner/Pod-Markdown.git
1615
1616=head1 AUTHORS
1617
1618=over 4
1619
1620=item *
1621
1622Marcel Gruenauer <marcel@cpan.org>
1623
1624=item *
1625
1626Victor Moral <victor@taquiones.net>
1627
1628=item *
1629
1630Ryan C. Thompson <rct at thompsonclan d0t org>
1631
1632=item *
1633
1634Aristotle Pagaltzis <pagaltzis@gmx.de>
1635
1636=item *
1637
1638Randy Stauner <rwstauner@cpan.org>
1639
1640=back
1641
1642=head1 CONTRIBUTORS
1643
1644=for stopwords Aristotle Pagaltzis Cindy Wang (CindyLinz) Graham Ollis Mike Covington motemen moznion Peter Vereshagin Ryan C. Thompson Yasutaka ATARASHI
1645
1646=over 4
1647
1648=item *
1649
1650Aristotle Pagaltzis <aristotle@cpan.org>
1651
1652=item *
1653
1654Cindy Wang (CindyLinz) <cindylinz@gmail.com>
1655
1656=item *
1657
1658Graham Ollis <plicease@cpan.org>
1659
1660=item *
1661
1662Mike Covington <mfcovington@gmail.com>
1663
1664=item *
1665
1666motemen <motemen@cpan.org>
1667
1668=item *
1669
1670moznion <moznion@cpan.org>
1671
1672=item *
1673
1674Peter Vereshagin <veresc@cpan.org>
1675
1676=item *
1677
1678Ryan C. Thompson <rthompson@cpan.org>
1679
1680=item *
1681
1682Yasutaka ATARASHI <yakex@cpan.org>
1683
1684=back
1685
1686=head1 COPYRIGHT AND LICENSE
1687
1688This software is copyright (c) 2011 by Randy Stauner.
1689
1690This is free software; you can redistribute it and/or modify it under
1691the same terms as the Perl 5 programming language system itself.
1692
1693=cut
1694