Text-WikiCreole-0.07/0000755000175000017500000000000011072156463012550 5ustar jnjjnjText-WikiCreole-0.07/MANIFEST0000644000175000017500000000053111072153225013671 0ustar jnjjnjChanges MANIFEST META.yml # Will be created by "make dist" Makefile.PL README lib/Text/WikiCreole.pm t/block.html t/block.markup t/block.t t/escape.html t/escape.markup t/escape.t t/inline.html t/inline.markup t/inline.t t/link.t t/opentag.t t/plugin.t t/specialchars.html t/specialchars.markup t/specialchars.t t/amp.html t/amp.markup t/amp.t Text-WikiCreole-0.07/README0000644000175000017500000000366011072156426013434 0ustar jnjjnjText-WikiCreole Text::WikiCreole implements the Wiki Creole markup language, version 1.0, as described at http://www.wikicreole.org. It reads Creole 1.0 markup and returns XHTML. In addition to the official Creole 1.0 markup elements, it also supports several extensions, such as plugins, superscript, subscript, underline, definition lists, indented paragraphs, plugins, etc. CHANGES: Version 0.07: Bug fix: Italics around links rendered incorrectly. Version 0.06: Bug fix: & not converted to & where appropriate Feature addition: creole_barelink() and creole_custombarelinks() functions for customized handling of http://google.com style links courtesy of Bernd Zeimetz Version 0.05: Added creole_customlinks() and creole_customimgs() Version 0.04: Fixed a bug with creole_parse and undefined input Version 0.03: Added <<< alternate plugin >>> syntax Version 0.02: Fixed bug parsing plugin blocks Fixed bug with nowiki blocks at end of file Added creole_img for custom image URLs Version 0.01: Initial release. INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. perldoc Text::WikiCreole You can also look for information at: Search CPAN http://search.cpan.org/dist/Text-WikiCreole CPAN Request Tracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text-WikiCreole AnnoCPAN, annotated CPAN documentation: http://annocpan.org/dist/Text-WikiCreole CPAN Ratings: http://cpanratings.perl.org/d/Text-WikiCreole COPYRIGHT AND LICENCE Copyright (C) 2007 Jason Burnett This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Text-WikiCreole-0.07/Changes0000644000175000017500000000146011072156371014042 0ustar jnjjnjRevision history for Text-WikiCreole 0.07 10/5/2008 Bug fix: Italics around links rendered incorrectly 0.06 10/5/2008 Bug fix: & not converted to & where appropriate Feature addition: creole_barelink() and creole_custombarelinks() functions for customized handling of http://google.com style links courtesy of Bernd Zeimetz 0.05 10/11/2007 Added creole_customlinks() and creole_customimgs() 0.04 10/10/2007 Fixed a bug with creole_parse and undefined input 0.03 9/21/2007 Added <<< alternate plugin >>> syntax, since Perl can be hard to embed in << 2-bracket >> plugins 0.02 9/12/2007 Fixed bug parsing plugin blocks Fixed bug with nowiki blocks at end of file Added creole_img for custom image URLs 0.01 9/11/2007 Initial Release Text-WikiCreole-0.07/lib/0000755000175000017500000000000011072156463013316 5ustar jnjjnjText-WikiCreole-0.07/lib/Text/0000755000175000017500000000000011072156463014242 5ustar jnjjnjText-WikiCreole-0.07/lib/Text/WikiCreole.pm0000755000175000017500000006302211072156445016643 0ustar jnjjnjpackage Text::WikiCreole; require Exporter; @ISA = (Exporter); @EXPORT = qw(creole_parse creole_plugin creole_tag creole_img creole_customimgs creole_link creole_barelink creole_customlinks creole_custombarelinks); use vars qw($VERSION); use strict; use warnings; our $VERSION = "0.07"; sub strip_head_eq { # strip lead/trail white/= from headings $_[0] =~ s/^\s*=*\s*//o; $_[0] =~ s/\s*=*\s*$//o; return $_[0]; } sub strip_list { # strip list markup trickery $_[0] =~ s/(?:`*| *)[\*\#]/`/o; $_[0] =~ s/\n(?:`*| *)[\*\#]/\n`/gso; return $_[0]; } # characters that may indicate inline wiki markup my @specialchars = ('^', '\\', '*', '/', '_', ',', '{', '[', '<', '~', '|', "\n", '#', ':', ';', '(', '-', '.'); # plain characters - auto-generated below (ascii printable minus @specialchars) my @plainchars; # non-plain text inline widgets my @inline = ('strong', 'em', 'br', 'esc', 'img', 'link', 'ilink', 'inowiki', 'sub', 'sup', 'mono', 'u', 'plug', 'plug2', 'tm', 'reg', 'copy', 'ndash', 'ellipsis', 'amp'); my @all_inline = (@inline, 'plain', 'any'); # including plain text # blocks my @blocks = ('h1', 'h2', 'h3', 'hr', 'nowiki', 'h4', 'h5', 'h6', 'ul', 'ol', 'table', 'p', 'ip', 'dl', 'plug', 'plug2', 'blank'); # handy - used several times in %chunks my $eol = '(?:\n|$)'; # end of line (or string) my $bol = '(?:^|\n)'; # beginning of line (or string) # user-supplied plugin parser function my $plugin_function; # user-supplied link URL parser function my $link_function; # user-supplied bare link parser function my $barelink_function; # user-supplied image URL parser function my $img_function; # initialize once my $initialized = 0; my %chunks = ( top => { contains => \@blocks, }, blank => { curpat => "(?= *$eol)", fwpat => "(?=(?:^|\n) *$eol)", stops => '(?=\S)', hint => ["\n"], filter => sub { return ""; }, # whitespace into the bit bucket open => "", close => "", }, p => { curpat => '(?=.)', stops => ['blank', 'ip', 'h', 'hr', 'nowiki', 'ul', 'ol', 'dl', 'table'], hint => \@plainchars, contains => \@all_inline, filter => sub { chomp $_[0]; return $_[0]; }, open => "

", close => "

\n\n", }, ip => { curpat => '(?=:)', fwpat => '\n(?=:)', stops => ['blank', 'h', 'hr', 'nowiki', 'ul', 'ol', 'dl', 'table'], hint => [':'], contains => ['p', 'ip'], filter => sub { $_[0] =~ s/://o; $_[0] =~ s/\n:/\n/so; return $_[0]; }, open => "
", close => "
\n", }, dl => { curpat => '(?=;)', fwpat => '\n(?=;)', stops => ['blank', 'h', 'hr', 'nowiki', 'ul', 'ol', 'table'], hint => [';'], contains => ['dt', 'dd'], open => "
\n", close => "
\n", }, dt => { curpat => '(?=;)', fwpat => '\n(?=;)', stops => '(?=:|\n)', hint => [';'], contains => \@all_inline, filter => sub { $_[0] =~ s/^;\s*//o; return $_[0]; }, open => "
", close => "
\n", }, dd => { curpat => '(?=\n|:)', fwpat => '(?:\n|:)', stops => '(?=:)|\n(?=;)', hint => [':', "\n"], contains => \@all_inline, filter => sub { $_[0] =~ s/(?:\n|:)\s*//so; $_[0] =~ s/\s*$//so; return $_[0]; }, open => "
", close => "
\n", }, table => { curpat => '(?= *\|.)', fwpat => '\n(?= *\|.)', stops => '\n(?= *[^\|])', contains => ['tr'], hint => ['|', ' '], open => "\n", close => "
\n\n", }, tr => { curpat => '(?= *\|)', stops => '\n', contains => ['td', 'th'], hint => ['|', ' '], filter => sub { $_[0] =~ s/^ *//o; $_[0] =~ s/\| *$//o; return $_[0]; }, open => " \n", close => " \n", }, td => { curpat => '(?=\|[^=])', # this gnarly regex fixes ambiguous '|' for links/imgs/nowiki in tables stops => '[^~](?=\|(?!(?:[^\[]*\]\])|(?:[^\{]*\}\})))', contains => \@all_inline, hint => ['|'], filter => sub {$_[0] =~ s/^ *\| *//o; $_[0] =~ s/\s*$//so; return $_[0]; }, open => " ", close => "\n", }, th => { curpat => '(?=\|=)', # this gnarly regex fixes ambiguous '|' for links/imgs/nowiki in tables stops => '[^~](?=\|(?!(?:[^\[]*\]\])|(?:[^\{]*\}\})))', contains => \@all_inline, hint => ['|'], filter => sub {$_[0] =~ s/^ *\|= *//o; $_[0] =~ s/\s*$//so; return $_[0]; }, open => " ", close => "\n", }, ul => { curpat => '(?=(?:`| *)\*[^\*])', fwpat => '(?=\n(?:`| *)\*[^\*])', stops => ['blank', 'ip', 'h', 'nowiki', 'li', 'table', 'hr', 'dl'], contains => ['ul', 'ol', 'li'], hint => ['*', ' '], filter => \&strip_list, open => "\n", }, ol => { curpat => '(?=(?:`| *)\#[^\#])', fwpat => '(?=\n(?:`| *)\#[^\#])', stops => ['blank', 'ip', 'h', 'nowiki', 'li', 'table', 'hr', 'dl'], contains => ['ul', 'ol', 'li'], hint => ['#', ' '], filter => \&strip_list, open => "
    \n", close => "
\n", }, li => { curpat => '(?=`[^\*\#])', fwpat => '\n(?=`[^\*\#])', stops => '\n(?=`)', hint => ['`'], filter => sub { $_[0] =~ s/` *//o; chomp $_[0]; return $_[0]; }, contains => \@all_inline, open => "
  • ", close => "
  • \n", }, nowiki => { curpat => '(?=\{\{\{ *\n)', fwpat => '\n(?=\{\{\{ *\n)', stops => "\n\}\}\} *$eol", hint => ['{'], filter => sub { substr($_[0], 0, 3, ''); $_[0] =~ s/\}\}\}\s*$//o; $_[0] =~ s/&/&/go; $_[0] =~ s//>/go; return $_[0]; }, open => "
    ", close => "
    \n\n", }, hr => { curpat => "(?= *-{4,} *$eol)", fwpat => "\n(?= *-{4,} *$eol)", hint => ['-', ' '], stops => $eol, open => "
    \n\n", close => "", filter => sub { return ""; } # ----- into the bit bucket }, h => { curpat => '(?=(?:^|\n) *=)' }, # matches any heading h1 => { curpat => '(?= *=[^=])', hint => ['=', ' '], stops => '\n', contains => \@all_inline, open => "

    ", close => "

    \n\n", filter => \&strip_head_eq, }, h2 => { curpat => '(?= *={2}[^=])', hint => ['=', ' '], stops => '\n', contains => \@all_inline, open => "

    ", close => "

    \n\n", filter => \&strip_head_eq, }, h3 => { curpat => '(?= *={3}[^=])', hint => ['=', ' '], stops => '\n', contains => \@all_inline, open => "

    ", close => "

    \n\n", filter => \&strip_head_eq, }, h4 => { curpat => '(?= *={4}[^=])', hint => ['=', ' '], stops => '\n', contains => \@all_inline, open => "

    ", close => "

    \n\n", filter => \&strip_head_eq, }, h5 => { curpat => '(?= *={5}[^=])', hint => ['=', ' '], stops => '\n', contains => \@all_inline, open => "
    ", close => "
    \n\n", filter => \&strip_head_eq, }, h6 => { curpat => '(?= *={6,})', hint => ['=', ' '], stops => '\n', contains => \@all_inline, open => "
    ", close => "
    \n\n", filter => \&strip_head_eq, }, plain => { curpat => '(?=[^\*\/_\,\^\\\\{\[\<\|])', stops => \@inline, hint => \@plainchars, open => '', close => '' }, any => { # catch-all curpat => '(?=.)', stops => \@inline, open => '', close => '' }, br => { curpat => '(?=\\\\\\\\)', stops => '\\\\\\\\', hint => ['\\'], filter => sub { return ''; }, open => '
    ', close => '', }, esc => { curpat => '(?=~[\S])', stops => '~.', hint => ['~'], filter => sub { substr($_[0], 0, 1, ''); return $_[0]; }, open => '', close => '', }, inowiki => { curpat => '(?=\{{3}.*?\}*\}{3})', stops => '.*?\}*\}{3}', hint => ['{'], filter => sub { substr($_[0], 0, 3, ''); $_[0] =~ s/\}{3}$//o; $_[0] =~ s/&/&/go; $_[0] =~ s//>/go; return $_[0]; }, open => "", close => "", }, plug => { curpat => '(?=\<{3}.*?\>*\>{3})', stops => '.*?\>*\>{3}', hint => ['<'], filter => sub { substr($_[0], 0, 3, ''); $_[0] =~ s/\>{3}$//o; if($plugin_function) { return &$plugin_function($_[0]); } return "<<<$_[0]>>>"; }, open => "", close => "", }, plug2 => { curpat => '(?=\<{2}.*?\>*\>{2})', stops => '.*?\>*\>{2}', hint => ['<'], filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\>{2}$//o; if($plugin_function) { return &$plugin_function($_[0]); } return "<<$_[0]>>"; }, open => "", close => "", }, ilink => { curpat => '(?=(?:https?|ftp):\/\/)', stops => '(?=[[:punct:]]?(?:\s|$))', hint => ['h', 'f'], filter => sub { $_[0] =~ s/^\s*//o; $_[0] =~ s/\s*$//o; if($barelink_function) { $_[0] = &$barelink_function($_[0]); } return "href=\"$_[0]\">$_[0]"; }, open => " "", }, link => { curpat => '(?=\[\[[^\n]+?\]\])', stops => '\]\]', hint => ['['], contains => ['href', 'atext'], filter => sub { substr($_[0], 0, 2, ''); substr($_[0], -2, 2, ''); $_[0] .= "|$_[0]" unless $_[0] =~ tr/|/|/; # text = url unless given return $_[0]; }, open => " "", }, href => { curpat => '(?=[^\|])', stops => '(?=\|)', filter => sub { $_[0] =~ s/^\s*//o; $_[0] =~ s/\s*$//o; if($link_function) { $_[0] = &$link_function($_[0]); } return $_[0]; }, open => 'href="', close => '">', }, atext => { curpat => '(?=\|)', stops => '\n', hint => ['|'], contains => \@all_inline, filter => sub { $_[0] =~ s/^\|\s*//o; $_[0] =~ s/\s*$//o; return $_[0]; }, open => '', close => '', }, img => { curpat => '(?=\{\{[^\{][^\n]*?\}\})', stops => '\}\}', hint => ['{'], contains => ['imgsrc', 'imgalt'], filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\}\}$//o; return $_[0]; }, open => " " />", }, imgalt => { curpat => '(?=\|)', stops => '\n', hint => ['|'], filter => sub { $_[0] =~ s/^\|\s*//o; $_[0] =~ s/\s*$//o; return $_[0]; }, open => ' alt="', close => '"', }, imgsrc => { curpat => '(?=[^\|])', stops => '(?=\|)', filter => sub { $_[0] =~ s/^\s*//o; $_[0] =~ s/\s*$//o; if($img_function) { $_[0] = &$img_function($_[0]); } return $_[0]; }, open => 'src="', close => '"', }, strong => { curpat => '(?=\*\*)', stops => '\*\*.*?\*\*', hint => ['*'], contains => \@all_inline, filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\*\*$//o; return $_[0]; }, open => "", close => "", }, em => { curpat => '(?=\/\/)', stops => '\/\/.*?(? ['/'], contains => \@all_inline, filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\/\/$//o; return $_[0]; }, open => "", close => "", }, mono => { curpat => '(?=\#\#)', stops => '\#\#.*?\#\#', hint => ['#'], contains => \@all_inline, filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\#\#$//o; return $_[0]; }, open => "", close => "", }, sub => { curpat => '(?=,,)', stops => ',,.*?,,', hint => [','], contains => \@all_inline, filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\,\,$//o; return $_[0]; }, open => "", close => "", }, sup => { curpat => '(?=\^\^)', stops => '\^\^.*?\^\^', hint => ['^'], contains => \@all_inline, filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/\^\^$//o; return $_[0]; }, open => "", close => "", }, u => { curpat => '(?=__)', stops => '__.*?__', hint => ['_'], contains => \@all_inline, filter => sub { substr($_[0], 0, 2, ''); $_[0] =~ s/__$//o; return $_[0]; }, open => "", close => "", }, amp => { curpat => '(?=\&(?!\w+\;))', stops => '.', hint => ['&'], filter => sub { return "&"; }, open => "", close => "", }, tm => { curpat => '(?=\(TM\))', stops => '\(TM\)', hint => ['('], filter => sub { return "™"; }, open => "", close => "", }, reg => { curpat => '(?=\(R\))', stops => '\(R\)', hint => ['('], filter => sub { return "®"; }, open => "", close => "", }, copy => { curpat => '(?=\(C\))', stops => '\(C\)', hint => ['('], filter => sub { return "©"; }, open => "", close => "", }, ndash => { curpat => '(?=--)', stops => '--', hint => ['-'], filter => sub { return "–"; }, open => "", close => "", }, ellipsis => { curpat => '(?=\.\.\.)', stops => '\.\.\.', hint => ['.'], filter => sub { return "…"; }, open => "", close => "", }, ); sub parse; # predeclared because it's recursive sub parse { my ($tref, $chunk) = @_; my ($html, $ch); my $pos = 0; my $lpos = 0; while(1) { if($ch) { # if we already know what kind of chunk this is if ($$tref =~ /$chunks{$ch}{delim}/g) { # find where it stops... $pos = pos($$tref); # another chunk } else { $pos = length $$tref; # end of string } $html .= $chunks{$ch}{open}; # print the open tag my $t = substr($$tref, $lpos, $pos - $lpos); # grab the chunk if($chunks{$ch}{filter}) { # filter it, if applicable $t = &{$chunks{$ch}{filter}}($t); } $lpos = $pos; # remember where this chunk ends (where next begins) if($t && $chunks{$ch}{contains}) { # if it contains other chunks... $html .= parse(\$t, $ch); # recurse. } else { $html .= $t; # otherwise, print it } $html .= $chunks{$ch}{close}; # print the close tag } if($pos && $pos == length($$tref)) { # we've eaten the whole string last; } else { # more string to come $ch = undef; my $fc = substr($$tref, $pos, 1); # get a hint about the next chunk foreach (@{$chunks{$chunk}{hints}{$fc}}) { # print "trying $_ for -$fc- on -" . substr($$tref, $pos, 2) . "-\n"; if($$tref =~ $chunks{$_}{curpatcmp}) { # hint helped id the chunk $ch = $_; last; } } unless($ch) { # hint didn't help foreach (@{$chunks{$chunk}{contains}}) { # check all possible chunks # print "trying $_ on -" . substr($$tref, $pos, 2) . "-\n"; if ($$tref =~ $chunks{$_}{curpatcmp}) { # found one $ch = $_; last; } } last unless $ch; # no idea what this is. ditch the rest and give up. } } } return $html; # voila! } # compile a regex that matches any of the patterns that interrupt the # current chunk. sub delim { if(ref $chunks{$_[0]}{stops}) { my $regex; foreach(@{$chunks{$_[0]}{stops}}) { if($chunks{$_}{fwpat}) { $regex .= "$chunks{$_}{fwpat}|"; } else { $regex .= "$chunks{$_}{curpat}|"; } } chop $regex; return qr/$regex/s; } else { return qr/$chunks{$_[0]}{stops}/s; } } # one-time optimization of the grammar - speeds the parser up a ton sub init { return if $initialized; $initialized = 1; # build an array of "plain content" characters by subtracting @specialchars # from ascii printable (ascii 32 to 126) my %is_special = map({$_ => 1} @specialchars); for (32 .. 126) { push(@plainchars, chr($_)) unless $is_special{chr($_)}; } # precompile a bunch of regexes foreach my $c (keys %chunks) { if($chunks{$c}{curpat}) { $chunks{$c}{curpatcmp} = qr/\G$chunks{$c}{curpat}/s; } if($chunks{$c}{stops}) { $chunks{$c}{delim} = delim $c; } if($chunks{$c}{contains}) { # store hints about each chunk to speed id foreach my $ct (@{$chunks{$c}{contains}}) { foreach (@{$chunks{$ct}{hint}}) { push @{$chunks{$c}{hints}{$_}}, $ct; } } } } } sub creole_parse { return unless defined $_[0] && length $_[0] > 0; my $text = $_[0]; init; my $html = parse(\$text, "top"); return $html; } sub creole_plugin { return unless defined $_[0]; $plugin_function = $_[0]; } sub creole_link { return unless defined $_[0]; $link_function = $_[0]; } sub creole_customlinks { $chunks{href}{open} = ""; $chunks{href}{close} = ""; $chunks{link}{open} = ""; $chunks{link}{close} = ""; delete $chunks{link}{contains}; $chunks{link}{filter} = sub { if($link_function) { $_[0] = &$link_function($_[0]); } return $_[0]; } } sub creole_barelink { return unless defined $_[0]; $barelink_function = $_[0]; } sub creole_custombarelinks { $chunks{ilink}{open} = ""; $chunks{ilink}{close} = ""; $chunks{ilink}{filter} = sub { if($barelink_function) { $_[0] = &$barelink_function($_[0]); } return $_[0]; } } sub creole_customimgs { $chunks{img}{open} = ""; $chunks{img}{close} = ""; delete $chunks{img}{contains}; $chunks{img}{filter} = sub { if($img_function) { $_[0] = &$img_function($_[0]); } return $_[0]; } } sub creole_img { return unless defined $_[0]; $img_function = $_[0]; } sub creole_tag { my ($tag, $type, $text) = @_; if(! $tag) { foreach (sort keys %chunks) { my $o = $chunks{$_}{open}; my $c = $chunks{$_}{close}; next unless $o && $o =~ /> and <<< plugin content >>> Write a function that receives the text between the <<>> delimiters as $_[0] (and not including the delimiters) and returns the text to be displayed. For example, here is a simple plugin that converts plugin text to uppercase: sub uppercase_plugin { $_[0] =~ s/([a-z])/\u$1/gs; return $_[0]; } creole_plugin \&uppercase_plugin; If you do not register a plugin function, plugin markup will be left as is, including the surrounding << >>. =head2 creole_link You may wish to customize [[ links ]], such as to prefix a hostname, port, etc. Write a function, similar to the plugin function, which receives the URL part of the link (with leading and trailing whitespace stripped) as $_[0] and returns the customized link. For example, to prepend "http://my.domain/" to pagename: sub mylink { return "http://my.domain/$_[0]"; } creole_link \&mylink; =head2 creole_customlinks If you want complete control over links, rather than just modifying the URL, register your link markup function with creole_link() as above and then call creole_customlinks(). Now your function will receive the entire link markup chunk, such as [[ some_wiki_page | page description ]] and must return HTML. This has no effect on "bare" link markup, such as http://cpan.org. =head2 creole_barelink Same purpose as creole_link, but for "bare" link markup. sub mybarelink { return "$_[0].html"; } creole_barelink \&mybarelink; =head2 creole_custombarelinks Same purpose as creole_customlinks, but for "bare" link markup. =head2 creole_img Same purpose as creole_link, but for image URLs. sub myimg { return "http://my.comain/$_[0]"; } creole_img \&myimg; =head2 creole_customimgs Similar to creole_customlinks, but for images. =head2 creole_tag You may wish to customize the opening and/or closing tags for the various bits of Creole markup. For example, to assign a CSS class to list items: creole_tag("li", "open", "
  • "); Or to see all current tags: print creole_tag(); The tags that may be of interest are: br dd dl dt em h1 h2 h3 h4 h5 h6 hr ilink img inowiki ip li link mono nowiki ol p strong sub sup table td th tr u ul Those should be self-explanatory, except for inowiki (inline nowiki), ilink (bare links, e.g. http://www.cpan.org), and ip (indented paragraph). =head1 OFFICIAL MARKUP Here is a summary of the official Creole 1.0 markup elements. See http://www.wikicreole.org for the full details. Headings: = heading 1 ->

    heading 1

    == heading 2 ->

    heading 2

    ... ====== heading 6 ->
    heading 6
    Various inline markup: ** bold ** -> bold // italics // -> italics **// both //** -> both [[ link ]] -> link [[ link | text ]] -> text http://cpan.org -> http://cpan.org line \\ break -> line
    break {{img.jpg|alt}} -> alt Lists: * unordered list Tables: |= h1 |= h2 -> | c1 | c2
    h1h2
    c1c2
    Nowiki (Preformatted): {{{
          ** not bold **          ** not bold **
          escaped HTML:   ->      escaped HTML:
           test            <i> test </i>
        }}}                     
    
        {{{ inline\\also }}} -> inline\\also
    
        Escape Character:
        ~** not bold **    ->    ** not bold **
        tilde: ~~          ->    tilde: ~
    
        Paragraphs are separated by other blocks and blank lines.  
        Inline markup can usually be combined, overlapped, etc.  List
        items and plugin text can span lines.
    
    =head1 EXTENDED MARKUP
    
        In addition to OFFICIAL MARKUP, Text::WikiCreole also supports
        the following markup:
    
        Plugins:
        << plugin >>        ->    whatever you want (see creole_plugin above)
        <<< plugin >>>      ->    whatever you want (see creole_plugin above)
            Triple-bracket syntax has priority, in order to allow you to embed
            double-brackets in plugins, such as to embed Perl code.
    
        Inline:
        ## monospace ##     ->     monospace 
        ^^ superscript ^^   ->     superscript 
        ,, subscript ,,     ->     subscript 
        __ underline __     ->     underline 
        (TM)                ->    ™
        (R)                 ->    ®
        (C)                 ->    ©
        ...                 ->    …
        --                  ->    –
    
        Indented Paragraphs:
        :this               ->    

    this is indented is indented

    :: more indented

    more indented

    Definition Lists: ; Title ->
    Title
    : item 1 : item 2
    item 1
    item 2
    ; Title 2 : item2a
    Title 2
    item 2a
    =head1 AUTHOR Jason Burnett, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc Text::WikiCreole You can also look for information at: =over 4 =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * RT: CPAN's request tracker L =item * Search CPAN L =back =head1 ACKNOWLEDGEMENTS The parsing algorithm is basically the same as (and inspired by) the one in Document::Parser. Document::Parser is OO and is, as such, incompatible with my brain. =head1 COPYRIGHT & LICENSE Copyright 2007 Jason Burnett, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Text-WikiCreole-0.07/Makefile.PL0000644000175000017500000000076410667332062014531 0ustar jnjjnjuse strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Text::WikiCreole', AUTHOR => 'Jason Burnett ', VERSION_FROM => 'lib/Text/WikiCreole.pm', ABSTRACT_FROM => 'lib/Text/WikiCreole.pm', PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Text-WikiCreole-*' }, ); Text-WikiCreole-0.07/META.yml0000644000175000017500000000054211072156463014022 0ustar jnjjnj# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Text-WikiCreole version: 0.07 version_from: lib/Text/WikiCreole.pm installdirs: site requires: Test::More: 0 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.30_01 Text-WikiCreole-0.07/t/0000755000175000017500000000000011072156463013013 5ustar jnjjnjText-WikiCreole-0.07/t/specialchars.markup0000644000175000017500000000054310671561030016671 0ustar jnjjnjthere are several special chars you can use, such as \\ line breaks,\\ trademark symbols (TM),\\ registered trademark symbols (R),\\ copyright symbols (C),\\ elipsis ...,\\ dashes, --, or string them together: ------ * use them \\ in lists ## trademark (TM) | in tables | column\\2 | dash -- | elipsis... {{{ anywhere but nowiki: (TM), (R), \\ }}} Text-WikiCreole-0.07/t/inline.html0000644000175000017500000000373310671560532015165 0ustar jnjjnj

    bold at at start of file

    bold, italics, underline, superscript, subscript, and monospace all work the same way.

    italics at start of paragraph

    a paragraph with monospace in the middle with more after

    underline with no closing markup

    • subscript as first list item, continued on second line
    • first list item
    • superscript as second item, no closing tag
    • with more to come
    • first item
      1. monospace with bold as first subitem in numbered list
        • another sublist after with italics

    heading with bold , which is redundant but possible

    heading with italics is not redundant

    here's a table with italics in it
    second row squared etcetera

    here's a link with bold italics in it. here's some bold inside italics and underlined . here's what happens when you don't mix bold and italics properly. don't try it in __ inline nowiki __ , but feel free to put it inside monospace .

    no point in trying to put ^^ superscript ^^ inside nowiki blocks either
    
    how 'bout Underlined bold in a definition list?
    not to mention, the actual italicized definition

    should also be able to put bold and superscript in an indented paragraph

    Text-WikiCreole-0.07/t/amp.t0000644000175000017500000000060111072152123013737 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; $name = "amp"; # load the markup open M, "; } close M; # load the html to compare open H, "; } close H; $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/opentag.t0000644000175000017500000000045310671561467014647 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; # test user-customized open tag creole_tag("p", "open", "

    "); $markup = qq|This is a paragraph.|; $goodhtml = qq|

    This is a paragraph.

    |; $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/escape.html0000644000175000017500000000106310671560520015136 0ustar jnjjnj

    use the escape character to stop {{{ nowiki blocks from being nowiki blocks }}}

    * escape lists

    • you can also * escape the second list item

    = escape a heading

    : escape an indented paragraph

    escape a horizontal line -––

    | escape a | table | r2c1 | rc2c |

    {{{ escape nowiki with bold in it }}}

    ; escape definition lists : like so

    you can also escape inline markup like ** bold **, // italics//, \\ newlines, [[ links ]], {{images}}, etc

    Text-WikiCreole-0.07/t/specialchars.t0000644000175000017500000000061210671557117015645 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; $name = "specialchars"; # load the markup open M, "; } close M; # load the html to compare open H, "; } close H; $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/amp.html0000644000175000017500000000022611072153036014447 0ustar jnjjnj

    Ampersand is a special case. By itself (like here: & &and here), it should be converted to & (which should itself be left alone)

    Text-WikiCreole-0.07/t/block.markup0000644000175000017500000000167310671555443015342 0ustar jnjjnj* list at start of file ** second level ### third level numbered list ### second one ** back to second level Just a regular paragraph * interrupted by a list another paragraph | interrupted by | a table | r2c1 | r2c2 another paragraph = interrupted by a heading * how about a list ====== interrupted by a small heading * this is a new list | tables | can be interrupted | by paragraphs | tables | can be interrupted | # by lists | tables | can be interrupted | ; by anything: that's not a table * a list * can be interrupted : by an indented paragraph * a list * can be interrupted {{{ by a nowiki block }}} a paragraph can be interrupted {{{ by a nowiki block }}} ; any block can be : interrupted {{{ by a nowiki block }}} horizontal lines ----- also interrupt other blocks {{{ ----- but not nowiki }}} * see, lists ----- * are interrupted by lines also ; crazy stuff happens ----- : when a line splits a definition list Text-WikiCreole-0.07/t/plugin.t0000644000175000017500000000065310671560340014477 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; # test user-supplied plugin function $markup = qq|This is a paragraph with an uppercasing << plugin >>. Check it out.|; $goodhtml = qq|

    This is a paragraph with an uppercasing PLUGIN . Check it out.

    |; sub uppercase { $_[0] =~ s/([a-z])/\u$1/gso; return $_[0]; } creole_plugin(\&uppercase); $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/link.t0000644000175000017500000000067410671560440014142 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; # test user-supplied link modifying function $markup = qq|This is a paragraph with an uppercased [[ link ]]. Check it out.|; $goodhtml = qq|

    This is a paragraph with an uppercased link. Check it out.

    |; sub uppercase { $_[0] =~ s/([a-z])/\u$1/gso; return $_[0]; } creole_link(\&uppercase); $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/specialchars.html0000644000175000017500000000113210671561042016334 0ustar jnjjnj

    there are several special chars you can use, such as
    line breaks,
    trademark symbols ™,
    registered trademark symbols ®,
    copyright symbols ©,
    elipsis …,
    dashes, –, or string them together: –––

    • use them
      in lists
      1. trademark ™
    in tables column
    2
    dash – elipsis…
      anywhere but nowiki: (TM), (R), \\
    
    Text-WikiCreole-0.07/t/escape.t0000644000175000017500000000060410671555467014453 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; $name = "escape"; # load the markup open M, "; } close M; # load the html to compare open H, "; } close H; $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/inline.t0000644000175000017500000000060410671553250014455 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; $name = "inline"; # load the markup open M, "; } close M; # load the html to compare open H, "; } close H; $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/escape.markup0000644000175000017500000000073510671557000015475 0ustar jnjjnjuse the escape character to stop ~{{{ nowiki blocks from being nowiki blocks }}} ~* escape lists * you can also ~* escape the second list item ~= escape a heading ~: escape an indented paragraph escape a horizontal line ~----- ~| escape a | table ~| r2c1 | rc2c | ~{{{ escape nowiki ** with bold in it ** }}} ~; escape definition lists ~: like so you can also escape inline markup like ~** bold ~**, ~// italics~//, ~\\ newlines, ~[[ links ]], ~{{images}}, etc Text-WikiCreole-0.07/t/amp.markup0000644000175000017500000000020611072153010014770 0ustar jnjjnjAmpersand is a special case. By itself (like here: & &and here), it should be converted to & (which should itself be left alone) Text-WikiCreole-0.07/t/block.t0000644000175000017500000000060310671553306014272 0ustar jnjjnj#!perl -T use Test::Simple tests => 1; use Text::WikiCreole; $name = "block"; # load the markup open M, "; } close M; # load the html to compare open H, "; } close H; $html = creole_parse $markup; ok( $html eq $goodhtml ); Text-WikiCreole-0.07/t/block.html0000644000175000017500000000343010671560503014771 0ustar jnjjnj
    • list at start of file
      • second level
        1. third level numbered list
        2. second one
      • back to second level

    Just a regular paragraph

    • interrupted by a list

    another paragraph

    interrupted by a table
    r2c1 r2c2

    another paragraph

    interrupted by a heading

    • how about a list
    interrupted by a small heading
    • this is a new list
    tables can be interrupted

    by paragraphs

    tables can be interrupted
    1. by lists
    tables can be interrupted
    by anything
    that's not a table
    • a list
    • can be interrupted

    by an indented paragraph

    • a list
    • can be interrupted
      by a nowiki block
    

    a paragraph can be interrupted

      by a nowiki block
    
    any block can be
    interrupted
      by a nowiki block
    

    horizontal lines


    also interrupt other blocks

    -----
    but not nowiki
    
    • see, lists

    • are interrupted by lines also
    crazy stuff happens

    when a line splits a definition list

    Text-WikiCreole-0.07/t/inline.markup0000644000175000017500000000251110671553062015511 0ustar jnjjnj** bold at at start of file ** **bold**, //italics//, __underline__, ^^superscript^^, __subscript__, and ##monospace## all work the same way. // italics at start of paragraph // a paragraph with ## monospace in the middle ## with more after __ underline with no closing markup * ,, subscript as first list item, continued on second line ,, * first list item * ^^ superscript as second item, no closing tag * with more to come * first item ## ## monospace ** with bold ** as first subitem in numbered list ## *** another sublist after // with italics // = heading ** with bold **, which is redundant but possible == heading // with italics // is not redundant | here's a table | with // italics in it | second row ^^ squared ^^ | etcetera here's a [[ link | link //** with bold italics **// in it ]]. here's some __// ** bold ** inside italics // and underlined __. here's what happens when you don't mix ** bold and // italics ** // properly. don't try it in {{{ __ inline nowiki __ }}}, but feel free to put it ## // inside monospace // ##. {{{ no point in trying to put ^^ superscript ^^ inside nowiki blocks either }}} ; how 'bout **__ Underlined bold __** in a definition list? : not to mention, the actual // italicized definition // : should also be able to put ** bold ^^ and superscript ^^ ** in an indented paragraph