/[suikacvs]/messaging/manakai/lib/Message/Markup/SuikaWikiConfig20/Parser.pm
Suika

Contents of /messaging/manakai/lib/Message/Markup/SuikaWikiConfig20/Parser.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sat Nov 15 07:42:34 2003 UTC (20 years, 11 months ago) by wakaba
Branch: MAIN
Transmitted from SuikaWiki

1 wakaba 1.1
2     =head1 NAME
3    
4     Message::Markup::SuikaWikiConfig20::Parser: manakai --- SuikaWikiConfig/2.0 parser
5    
6     =head1 DESCRIPTION
7    
8     SuikaWikiConfig/2.0 is a general configuration description format.
9     This module can be used to parse such configuration and to
10     generate node tree for it.
11    
12     This module is part of manakai.
13    
14     =cut
15    
16     package Message::Markup::SuikaWikiConfig20::Parser;
17     use strict;
18     our $VERSION = do{my @r=(q$Revision: 1.3 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
19     require Message::Markup::SuikaWikiConfig20::Node;
20    
21     =head1 METHODS
22    
23     =over 4
24    
25     =item $x = Message::Markup::SuikaWikiConfig20::Parser->new (%options)
26    
27     Returns new instance of parser
28    
29     =cut
30    
31     sub new ($;%) {
32     my $class = shift;
33     my $self = bless {@_}, $class;
34     $self;
35     }
36    
37     sub parse_text ($$) {
38     my ($self, $s) = @_;
39     my $root = SuikaWiki::Markup::SuikaWikiConfig20->new
40     (type => '#document');
41     my $current = $root;
42     my $current_element = $root;
43     my $is_new_element = 0;
44     my $is_list_element = 0;
45     for my $line (split /\x0D?\x0A/, $s) {
46     if ($line =~ /^([^#\s].*):\s*([^\s:][^:]*)?$/) {
47     my ($name, $val) = ($1, $2);
48     substr ($name, 0, 1) = '' if substr ($name, 0, 1) eq '\\';
49     substr ($val, 0, 1) = '' if substr ($val, 0, 1) eq '\\';
50     if (substr ($name, -6) eq '[list]') {
51     substr ($name, -6) = '';
52     $val = length ($val) ? [$val] : [];
53     $is_list_element = 1;
54     } else {
55     $is_list_element = 0;
56     }
57     $current_element = $root->append_new_node (type => '#element',
58     local_name => $name,
59     value => $val);
60     if (defined $2) { ## Foo: bar
61     $current = $root;
62     $current_element = $root;
63     } else { ## Foo:\n bar\n baz
64     $current = $current_element;
65     $is_new_element = 1;
66     }
67     } elsif ($line =~ /^\s+(\@+)(.*):\s*([^\s:][^:]*)?$/) {
68     my ($nest, $name, $val) = (length $1, $2, $3);
69     substr ($name, 0, 1) = '' if substr ($name, 0, 1) eq '\\';
70     substr ($val, 0, 1) = '' if substr ($val, 0, 1) eq '\\';
71     if (substr ($name, -6) eq '[list]') {
72     substr ($name, -6) = '';
73     $val = length ($val) ? [$val] : [];
74     $is_list_element = 1;
75     } else {
76     $is_list_element = 0;
77     }
78     my $ce;
79     if (length ($name)) {
80     while ($current_element->flag ('p__nest_level') >= $nest) {
81     $current_element = $current_element->parent_node;
82     }
83     $ce = $current_element->append_new_node (type => '#element',
84     local_name => $name,
85     value => $val);
86     $ce->flag (p__nest_level
87     => $current_element->flag ('p__nest_level') + 1);
88     unless (defined $3) { ## @foo: \nbar
89     $current_element = $ce;
90     $current = $ce;
91     $is_new_element = 1;
92     }
93     } else {
94     while ($current_element->flag ('p__nest_level') > $nest - 1) {
95     $current_element = $current_element->parent_node;
96     }
97     $current_element->append_text ($val);
98     $current = $current_element;
99     unless (defined $3) { ## @@: \nbar
100     $is_new_element = 1;
101     }
102     }
103     } elsif ($line =~ /^\s+([^\s#].*)$/) {
104     my $val = $1;
105     substr ($val, 0, 1) = '' if substr ($val, 0, 1) eq '\\';
106     if ($is_new_element || $is_list_element) {
107     $current_element->append_text ($val);
108     $is_new_element = 0;
109     } else {
110     $current_element->append_text ("\x0A" . $val);
111     }
112     } elsif ($line =~ /^\s+$/) {
113     # skip
114     } elsif ($line =~ /^\s*\#(.*)$/) {
115     if ($current->node_type eq '#comment') {
116     $current->append_text ("\x0A" . $1);
117     } else {
118     $current = $root->append_new_node (type => '#comment', value => $1);
119     }
120     } else {
121     $current = $root;
122     #print STDERR qq(**$line**\n);
123     }
124     }
125     $root;
126     }
127    
128     sub flag ($$;$) {
129     my ($self, $name, $value) = @_;
130     if (defined $value) {
131     $self->{flag}->{$name} = $value;
132     }
133     $self->{flag}->{$name};
134     }
135    
136     sub option ($$;$) {
137     my ($self, $name, $value) = @_;
138     if (defined $value) {
139     $self->{option}->{$name} = $value;
140     }
141     $self->{option}->{$name};
142     }
143    
144     =back
145    
146     =head1 EXAMPLE
147    
148     use Message::Markup::SuikaWikiConfig20::Parser;
149     my $parser = new Message::Markup::SuikaWikiConfig20::Parser;
150    
151     my $conf = $parser->parse_text ($config);
152     print $conf->get_attribute ('Some Configuration Item');
153    
154     =head1 SEE ALSO
155    
156     Message::Markup::SuikaWikiConfig20::Node,
157     SuikaWiki <http://suika.fam.cx/~wakaba/-temp/wiki/wiki?SuikaWiki>,
158     <http://suika.fam.cx/~wakaba/-temp/wiki/wiki?SuikaWikiConfig/2.0>
159    
160     =head1 HISTORY
161    
162     This module was part of SuikaWiki 2, with the name of
163     C<SuikaWiki::Markup::SuikaWikiConfig20::Parser>.
164    
165     =head1 LICENSE
166    
167     Copyright 2003 Wakaba <w@suika.fam.cx>
168    
169     This program is free software; you can redistribute it and/or
170     modify it under the same terms as Perl itself.
171    
172     =cut
173    
174     1; # $Date: 2003/11/15 07:14:35 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24