Alex 'AdUser' Z
10 years ago
commit
3edb670600
1 changed files with 123 additions and 0 deletions
@ -0,0 +1,123 @@ |
|||||||
|
package Text::Dokuwiki; |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use feature qw/ switch /; |
||||||
|
use utf8; |
||||||
|
|
||||||
|
use Data::Dumper; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my ($class) = @_; |
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
return bless($self, $class); |
||||||
|
} |
||||||
|
|
||||||
|
sub parse { |
||||||
|
my ($self, $text) = @_; |
||||||
|
my ($tree, $mode, $attrs, $buf) = ([], 'text', '', ''); |
||||||
|
|
||||||
|
my @lines = split /\r?\n/o, $text; |
||||||
|
my $linenum = 0; |
||||||
|
|
||||||
|
foreach my $line (@lines) { |
||||||
|
$linenum++; |
||||||
|
|
||||||
|
given ($mode) { |
||||||
|
when ("codeblk") { |
||||||
|
if ($line =~ m{^\s*</code>}o) { |
||||||
|
push @{ $tree }, [code => $attrs, 0 => $buf]; |
||||||
|
($buf, $attrs, $mode) = ('', {}, undef); next; |
||||||
|
} |
||||||
|
$buf .= $line . "\n"; |
||||||
|
} |
||||||
|
when ("code") { |
||||||
|
if ($line =~ m/^\s{2}(.+)/o) { |
||||||
|
$buf .= $line . "\n"; next; |
||||||
|
} else { |
||||||
|
push @{ $tree }, [pre => {}, 0 => $buf]; |
||||||
|
($buf, $attrs, $mode) = ('', {}, undef); continue; |
||||||
|
} |
||||||
|
} |
||||||
|
when ("list") { |
||||||
|
if ($line =~ m/^\s{2}([\*-])\s+(.+)/o) { |
||||||
|
push @{ $buf }, [li => {}, 0 => $2]; |
||||||
|
next; |
||||||
|
} else { |
||||||
|
push @{ $tree }, [ul => {}, @$buf]; # TODO: lost list type |
||||||
|
($buf, $attrs, $mode) = ('', {}, undef); continue; |
||||||
|
} |
||||||
|
} |
||||||
|
when ("table") { |
||||||
|
... |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
given ($line) { |
||||||
|
# header |
||||||
|
when (m/^\s?(={1,6}) (.+) \g{1}\s*/o) { |
||||||
|
my $level = $1 =~ tr/=/=/; |
||||||
|
$level = 7 - $level; # invert |
||||||
|
push @{ $tree }, ["h$level" => {}, 0 => $2]; |
||||||
|
next; |
||||||
|
} |
||||||
|
# code block |
||||||
|
when (m/^\s?<code\s*(\S+)?>\s*$/o) { |
||||||
|
$attrs = ($2) ? {class => $2} : {}; |
||||||
|
$mode = "codeblk"; |
||||||
|
next; |
||||||
|
} |
||||||
|
# lists |
||||||
|
when (m/^\s{2}([\*-])\s+(.+)/o) { |
||||||
|
$mode = 'list'; |
||||||
|
$buf = []; |
||||||
|
push @{ $buf }, [li => {}, 0 => $2]; |
||||||
|
next; |
||||||
|
} |
||||||
|
# table |
||||||
|
when (m/^\s?[\|\^]/o) { |
||||||
|
$mode = 'table'; |
||||||
|
$buf = $line . "\n"; # render later |
||||||
|
next; |
||||||
|
} |
||||||
|
# code idented with two spaces |
||||||
|
when (m/^\s{2}(\S.+)/o) { |
||||||
|
$mode = 'code'; |
||||||
|
$buf = $line . "\n"; |
||||||
|
next; |
||||||
|
} |
||||||
|
# nonempty line |
||||||
|
when (m/^\s?(\S.+)/o) { |
||||||
|
push @{ $tree }, [p => {}, 0 => $1]; |
||||||
|
next; |
||||||
|
} |
||||||
|
# empty lines; |
||||||
|
when (m/^\s*$/) { |
||||||
|
push @{ $tree }, [br => {}]; |
||||||
|
$mode = undef; |
||||||
|
next; |
||||||
|
} |
||||||
|
# catchall |
||||||
|
default { |
||||||
|
printf "Unmatched % 3d: %s\n", $linenum, $line; |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $tree; |
||||||
|
} |
||||||
|
|
||||||
|
1; |
||||||
|
|
||||||
|
__END__ |
||||||
|
|
||||||
|
[div => {class => 'block'}, # <div class='block'> |
||||||
|
0 => 'text1', # Hello! |
||||||
|
[strong => {}, 0 => 'bold text'], # <strong>user</strong> |
||||||
|
0 => ', this is converted text.', # , this is converted text. |
||||||
|
[br => {}], # <br/> |
||||||
|
[p => {}, 0 => 'Second paragraph'] # <p>Second paragraph</p> |
||||||
|
] # </div> |
Loading…
Reference in new issue