/[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.6 - (show annotations) (download)
Sat Nov 6 05:50:26 2004 UTC (20 years ago) by wakaba
Branch: MAIN
CVS Tags: manakai-release-0-3-2, manakai-release-0-3-1, manakai-release-0-4-0, manakai-200612, HEAD
Changes since 1.5: +3 -3 lines
Minor syntaxical clarifications

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.5 $=~/\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 = Message::Markup::SuikaWikiConfig20::Node->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 defined $name and
49 substr ($name, 0, 1) eq '\\';
50 substr ($val, 0, 1) = '' if defined $val and
51 substr ($val, 0, 1) eq '\\';
52 if (substr ($name, -6) eq '[list]') {
53 substr ($name, -6) = '';
54 $val = length ($val) ? [$val] : [];
55 $is_list_element = 1;
56 } else {
57 $is_list_element = 0;
58 }
59 $current_element = $root->append_new_node (type => '#element',
60 local_name => $name,
61 value => $val);
62 if (defined $2) { ## Foo: bar
63 $current = $root;
64 $current_element = $root;
65 } else { ## Foo:\n bar\n baz
66 $current = $current_element;
67 $is_new_element = 1;
68 }
69 } elsif ($line =~ /^\s+(\@+)(.*):\s*([^\s:][^:]*)?$/) {
70 my ($nest, $name, $val) = (length $1, $2, $3);
71 substr ($name, 0, 1) = '' if defined $name and
72 substr ($name, 0, 1) eq '\\';
73 substr ($val, 0, 1) = '' if defined $val and
74 substr ($val, 0, 1) eq '\\';
75 if (substr ($name, -6) eq '[list]') {
76 substr ($name, -6) = '';
77 $val = (defined ($val) and length ($val)) ? [$val] : [];
78 $is_list_element = 1;
79 } else {
80 $is_list_element = 0;
81 }
82 my $ce;
83 if (length ($name)) {
84 while ($current_element->flag ('p__nest_level', undef,
85 default => 0) >= $nest) {
86 $current_element = $current_element->parent_node;
87 }
88 $ce = $current_element->append_new_node
89 (type => '#element',
90 local_name => $name,
91 value => $val);
92 $ce->flag ('p__nest_level'
93 => $current_element->flag ('p__nest_level', undef,
94 default => 0) + 1);
95 unless (defined $3) { ## @foo: \nbar
96 $current_element = $ce;
97 $current = $ce;
98 $is_new_element = 1;
99 }
100 } else {
101 while ($current_element->flag ('p__nest_level', undef,
102 default => 0) >= $nest - 1) {
103 $current_element = $current_element->parent_node;
104 }
105 $current_element->append_text ($val) if defined $val;
106 $current = $current_element;
107 unless (defined $3) { ## @@: \nbar
108 $is_new_element = 1;
109 }
110 }
111 } elsif ($line =~ /^\s+([^\s#].*)$/) {
112 my $val = $1;
113 substr ($val, 0, 1) = '' if substr ($val, 0, 1) eq '\\';
114 if ($is_new_element || $is_list_element) {
115 $current_element->append_text ($val);
116 $is_new_element = 0;
117 } else {
118 $current_element->append_text ("\x0A" . $val);
119 }
120 } elsif ($line =~ /^\s+$/) {
121 # skip
122 } elsif ($line =~ /^\s*\#(.*)$/) {
123 if ($current->node_type eq '#comment') {
124 $current->append_text ("\x0A" . $1);
125 } else {
126 $current = $root->append_new_node (type => '#comment', value => $1);
127 }
128 } else {
129 $current = $root;
130 #print STDERR qq(**$line**\n);
131 }
132 }
133 $root;
134 }
135
136 sub flag ($$;$) {
137 my ($self, $name, $value) = @_;
138 if (defined $value) {
139 $self->{flag}->{$name} = $value;
140 }
141 $self->{flag}->{$name};
142 }
143
144 sub option ($$;$) {
145 my ($self, $name, $value) = @_;
146 if (defined $value) {
147 $self->{option}->{$name} = $value;
148 }
149 $self->{option}->{$name};
150 }
151
152 =back
153
154 =head1 EXAMPLE
155
156 use Message::Markup::SuikaWikiConfig20::Parser;
157 my $parser = new Message::Markup::SuikaWikiConfig20::Parser;
158
159 my $conf = $parser->parse_text ($config);
160 print $conf->get_attribute ('Some Configuration Item');
161
162 =head1 SEE ALSO
163
164 Message::Markup::SuikaWikiConfig20::Node,
165 SuikaWiki <http://suika.fam.cx/~wakaba/-temp/wiki/wiki?SuikaWiki>,
166 <http://suika.fam.cx/~wakaba/-temp/wiki/wiki?SuikaWikiConfig/2.0>
167
168 =head1 HISTORY
169
170 This module was part of SuikaWiki 2, with the name of
171 C<SuikaWiki::Markup::SuikaWikiConfig20::Parser>.
172
173 =head1 LICENSE
174
175 Copyright 2003 Wakaba <w@suika.fam.cx>
176
177 This program is free software; you can redistribute it and/or
178 modify it under the same terms as Perl itself.
179
180 =cut
181
182 1; # $Date: 2004/09/18 11:51:37 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24