blib/lib/Netscape/Bookmarks/Category.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 138 | 185 | 74.5 |
branch | 44 | 62 | 70.9 |
condition | 23 | 33 | 69.7 |
subroutine | 26 | 35 | 74.2 |
pod | 21 | 22 | 95.4 |
total | 252 | 337 | 74.7 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Netscape::Bookmarks::Category; | ||||||
2 | |||||||
3 | =encoding utf8 | ||||||
4 | |||||||
5 | =head1 NAME | ||||||
6 | |||||||
7 | Netscape::Bookmarks::Category - manipulate, or create Netscape Bookmarks files | ||||||
8 | |||||||
9 | =head1 SYNOPSIS | ||||||
10 | |||||||
11 | use Netscape::Bookmarks; | ||||||
12 | |||||||
13 | #parse an existing file | ||||||
14 | my $bookmarks = new Netscape::Bookmarks $bookmarks_file; | ||||||
15 | |||||||
16 | #print a Netscape compatible file | ||||||
17 | print $bookmarks->as_string; | ||||||
18 | |||||||
19 | =head1 DESCRIPTION | ||||||
20 | |||||||
21 | The Netscape bookmarks file has several basic components: | ||||||
22 | |||||||
23 | title | ||||||
24 | folders (henceforth called categories) | ||||||
25 | links | ||||||
26 | aliases | ||||||
27 | separators | ||||||
28 | |||||||
29 | On disk, Netscape browsers store this information in HTML. In the browser, | ||||||
30 | it is displayed under the "Bookmarks" menu. The data can be manipulated | ||||||
31 | through the browser interface. | ||||||
32 | |||||||
33 | This module allows one to manipulate the bookmarks file programmatically. One | ||||||
34 | can parse an existing bookmarks file, manipulate the information, and write it | ||||||
35 | as a bookmarks file again. Furthermore, one can skip the parsing step to create | ||||||
36 | a new bookmarks file and write it in the proper format to be used by a Netscape | ||||||
37 | browser. | ||||||
38 | |||||||
39 | The Bookmarks.pm module simply parses the bookmarks file passed to it as the | ||||||
40 | only argument to the constructor: | ||||||
41 | |||||||
42 | my $bookmarks = new Netscape::Bookmarks $bookmarks_file; | ||||||
43 | |||||||
44 | The returned object is a Netscape::Bookmarks::Category object, since the bookmark file is | ||||||
45 | simply a collection of categories that contain any of the components listed | ||||||
46 | above. The top level (i.e. root) category is treated specially and defines the | ||||||
47 | title of the bookmarks file. | ||||||
48 | |||||||
49 | =head1 METHODS | ||||||
50 | |||||||
51 | =over 4 | ||||||
52 | |||||||
53 | =cut | ||||||
54 | |||||||
55 | 6 | 6 | 73519 | use strict; | |||
6 | 27 | ||||||
6 | 226 | ||||||
56 | |||||||
57 | 6 | 6 | 82 | use base qw( Netscape::Bookmarks::AcceptVisitor Netscape::Bookmarks::Isa ); | |||
6 | 13 | ||||||
6 | 1285 | ||||||
58 | 6 | 6 | 46 | use subs qw(); | |||
6 | 13 | ||||||
6 | 168 | ||||||
59 | 6 | 6 | 34 | use vars qw( $VERSION $ERROR $LAST_ID %IDS ); | |||
6 | 17 | ||||||
6 | 443 | ||||||
60 | |||||||
61 | 6 | 6 | 41 | use constant START_LIST => ' '; |
|||
6 | 17 | ||||||
6 | 555 | ||||||
62 | 6 | 6 | 44 | use constant END_LIST => ' '; |
|||
6 | 28 | ||||||
6 | 353 | ||||||
63 | 6 | 6 | 40 | use constant START_LIST_ITEM => ' |
|||
6 | 14 | ||||||
6 | 334 | ||||||
64 | 6 | 6 | 48 | use constant TAB => ' '; | |||
6 | 14 | ||||||
6 | 358 | ||||||
65 | 6 | 6 | 38 | use constant FOLDED_TRUE => 1; | |||
6 | 12 | ||||||
6 | 306 | ||||||
66 | 6 | 6 | 37 | use constant FOLDED_FALSE => 0; | |||
6 | 20 | ||||||
6 | 295 | ||||||
67 | 6 | 6 | 35 | use constant TRUE => 'true'; | |||
6 | 11 | ||||||
6 | 13219 | ||||||
68 | |||||||
69 | $VERSION = "2.303"; | ||||||
70 | |||||||
71 | %IDS = (); | ||||||
72 | $LAST_ID = -1; | ||||||
73 | |||||||
74 | =item Netscape::Bookmarks::Category-E |
||||||
75 | |||||||
76 | The new method creates a Category. It takes a hash reference | ||||||
77 | that specifies the properties of the category. The valid keys | ||||||
78 | in that hash are | ||||||
79 | |||||||
80 | folded collapsed state of the category ( 1 or 0 ) | ||||||
81 | title | ||||||
82 | add_date | ||||||
83 | description | ||||||
84 | |||||||
85 | =cut | ||||||
86 | |||||||
87 | sub new | ||||||
88 | { | ||||||
89 | 78 | 78 | 1 | 162 | my $class = shift; | ||
90 | 78 | 126 | my $param = shift; | ||||
91 | |||||||
92 | 78 | 125 | my $self = {}; | ||||
93 | 78 | 165 | bless $self, $class; | ||||
94 | |||||||
95 | 78 | 100 | 203 | $self->{'folded'} = FOLDED_TRUE unless $param->{'folded'} == FOLDED_FALSE; | |||
96 | 78 | 100 | 182 | $self->{'personal_toolbar_folder'} = TRUE if $param->{'personal_toolbar_folder'}; | |||
97 | |||||||
98 | 78 | 100 | 66 | 526 | unless( exists $IDS{$param->{'id'}} or $param->{'id'} =~ /\D/) | ||
99 | { | ||||||
100 | 12 | 33 | $param->{'id'} = ++$LAST_ID; | ||||
101 | 12 | 37 | $IDS{$LAST_ID}++; | ||||
102 | } | ||||||
103 | |||||||
104 | 78 | 50 | 66 | 251 | if( defined $param->{'add_date'} and $param->{'add_date'} =~ /\D/ ) | ||
105 | { | ||||||
106 | 0 | 0 | $param->{'add_date'} = 0; | ||||
107 | } | ||||||
108 | |||||||
109 | 78 | 216 | $self->{'mozilla'} = $param->{'mozilla'}; | ||||
110 | 78 | 163 | $self->{'title'} = $param->{'title'}; | ||||
111 | 78 | 133 | $self->{'add_date'} = $param->{'add_date'}; | ||||
112 | 78 | 159 | $self->{'last_modified'} = $param->{'last_modified'}; | ||||
113 | 78 | 131 | $self->{'id'} = $param->{'id'}; | ||||
114 | 78 | 151 | $self->{'description'} = $param->{'description'}; | ||||
115 | 78 | 185 | $self->{'thingys'} = []; | ||||
116 | |||||||
117 | 78 | 210 | $self; | ||||
118 | } | ||||||
119 | |||||||
120 | sub mozilla | ||||||
121 | { | ||||||
122 | 41 | 41 | 0 | 100 | my $self = shift; | ||
123 | 41 | 78 | my $value = shift; | ||||
124 | |||||||
125 | 41 | 50 | 157 | $self->{'mozilla'} = $value if defined $value; | |||
126 | |||||||
127 | 41 | 165 | $self->{'mozilla'}; | ||||
128 | } | ||||||
129 | |||||||
130 | =item $category-E |
||||||
131 | |||||||
132 | The add() function adds an element to a category. The element must be a Alias, | ||||||
133 | Link, Category, or Separator object. Returns TRUE or FALSE. | ||||||
134 | |||||||
135 | =cut | ||||||
136 | |||||||
137 | sub add | ||||||
138 | { | ||||||
139 | 536 | 536 | 1 | 888 | my $self = shift; | ||
140 | 536 | 789 | my $thingy = shift; | ||||
141 | |||||||
142 | return unless | ||||||
143 | 536 | 50 | 100 | 1564 | ref $thingy eq 'Netscape::Bookmarks::Link' or | ||
100 | |||||||
66 | |||||||
144 | ref $thingy eq 'Netscape::Bookmarks::Category' or | ||||||
145 | ref $thingy eq 'Netscape::Bookmarks::Separator' or | ||||||
146 | ref $thingy eq 'Netscape::Bookmarks::Alias'; | ||||||
147 | |||||||
148 | 536 | 858 | push @{ $self->{'thingys'} }, $thingy; | ||||
536 | 1621 | ||||||
149 | } | ||||||
150 | |||||||
151 | =item $category-E |
||||||
152 | |||||||
153 | Removes the given object from the Category by calling the object's | ||||||
154 | remove() method. | ||||||
155 | |||||||
156 | Returns the number of objects removed from the Category. | ||||||
157 | |||||||
158 | =cut | ||||||
159 | |||||||
160 | sub remove_element | ||||||
161 | { | ||||||
162 | 0 | 0 | 1 | 0 | my $self = shift; | ||
163 | 0 | 0 | my $thingy = shift; | ||||
164 | |||||||
165 | 0 | 0 | my $old_count = $self->count; | ||||
166 | |||||||
167 | $self->{'thingys'} = | ||||||
168 | 0 | 0 | 0 | [ grep { $_ ne $thingy and $_->remove } $self->elements ]; | |||
0 | 0 | ||||||
169 | |||||||
170 | 0 | 0 | return $old_count - $self->count; | ||||
171 | } | ||||||
172 | |||||||
173 | =item $category-E |
||||||
174 | |||||||
175 | Performs any clean up necessary to remove this object from the | ||||||
176 | Bookmarks tree. Although this method does not recursively remove | ||||||
177 | objects which it contains, it probably should. | ||||||
178 | |||||||
179 | =cut | ||||||
180 | |||||||
181 | 0 | 0 | 1 | 0 | sub remove { 1; } | ||
182 | |||||||
183 | =item $category-E |
||||||
184 | |||||||
185 | Returns title to the category. With a | ||||||
186 | defined argument TITLE, it replaces the current | ||||||
187 | title. | ||||||
188 | |||||||
189 | =cut | ||||||
190 | |||||||
191 | sub title | ||||||
192 | { | ||||||
193 | 39 | 39 | 1 | 89 | my $self = shift; | ||
194 | |||||||
195 | 39 | 50 | 140 | if( defined $_[0] ) | |||
196 | { | ||||||
197 | 0 | 0 | $self->{'title'} = shift; | ||||
198 | } | ||||||
199 | |||||||
200 | 39 | 127 | $self->{'title'}; | ||||
201 | } | ||||||
202 | |||||||
203 | =item $category-E |
||||||
204 | |||||||
205 | Returns the ID of the category. This is an arbitrary, unique number. | ||||||
206 | |||||||
207 | =cut | ||||||
208 | |||||||
209 | sub id | ||||||
210 | { | ||||||
211 | 37 | 37 | 1 | 71 | my $self = shift; | ||
212 | |||||||
213 | 37 | 104 | $self->{'id'}; | ||||
214 | } | ||||||
215 | |||||||
216 | =item $category-E |
||||||
217 | |||||||
218 | Returns the description of the category. With a | ||||||
219 | defined argument DESCRIPTION, it replaces the current | ||||||
220 | description. | ||||||
221 | |||||||
222 | =cut | ||||||
223 | |||||||
224 | sub description | ||||||
225 | { | ||||||
226 | 49 | 49 | 1 | 113 | my $self = shift; | ||
227 | |||||||
228 | 49 | 100 | 140 | if( defined $_[0] ) | |||
229 | { | ||||||
230 | 10 | 23 | $self->{'description'} = shift; | ||||
231 | } | ||||||
232 | |||||||
233 | 49 | 144 | $self->{'description'}; | ||||
234 | } | ||||||
235 | |||||||
236 | =item $category-E |
||||||
237 | |||||||
238 | Returns the folded state of the category (TRUE or FALSE). If the category is | ||||||
239 | "folded", Netscape shows a collapsed folder for this category. | ||||||
240 | |||||||
241 | =cut | ||||||
242 | |||||||
243 | sub folded | ||||||
244 | { | ||||||
245 | 37 | 37 | 1 | 75 | my $self = shift; | ||
246 | |||||||
247 | 37 | 100 | 153 | return $self->{'folded'} ? 1 : 0; | |||
248 | } | ||||||
249 | |||||||
250 | =item $category-E |
||||||
251 | |||||||
252 | Returns the ADD_DATE attribute of the category. | ||||||
253 | |||||||
254 | =cut | ||||||
255 | |||||||
256 | sub add_date | ||||||
257 | { | ||||||
258 | 37 | 37 | 1 | 81 | my $self = shift; | ||
259 | |||||||
260 | 37 | 91 | return $self->{'add_date'}; | ||||
261 | } | ||||||
262 | |||||||
263 | =item $category-E |
||||||
264 | |||||||
265 | Returns the LAST_MODIFIED attribute of the category. | ||||||
266 | |||||||
267 | =cut | ||||||
268 | |||||||
269 | sub last_modified | ||||||
270 | { | ||||||
271 | 37 | 37 | 1 | 73 | my $self = shift; | ||
272 | |||||||
273 | 37 | 92 | return $self->{'last_modified'}; | ||||
274 | } | ||||||
275 | |||||||
276 | =item $category-E |
||||||
277 | |||||||
278 | Returns the PERSONAL_TOOLBAR_FOLDER attribute of the category. | ||||||
279 | |||||||
280 | =cut | ||||||
281 | |||||||
282 | sub personal_toolbar_folder | ||||||
283 | { | ||||||
284 | 37 | 37 | 1 | 72 | my $self = shift; | ||
285 | |||||||
286 | 37 | 91 | return $self->{'personal_toolbar_folder'}; | ||||
287 | } | ||||||
288 | |||||||
289 | =item $category-E |
||||||
290 | |||||||
291 | In scalar context returns an array reference to the elements in | ||||||
292 | the category. In list context returns a list of the elements in | ||||||
293 | the category. | ||||||
294 | |||||||
295 | =cut | ||||||
296 | |||||||
297 | sub elements | ||||||
298 | { | ||||||
299 | 44 | 44 | 1 | 96 | my $self = shift; | ||
300 | |||||||
301 | 44 | 50 | 129 | if( wantarray ) { @{ $self->{'thingys'} } } | |||
44 | 74 | ||||||
44 | 214 | ||||||
302 | 0 | 0 | else { $self->{'thingys'} } | ||||
303 | } | ||||||
304 | |||||||
305 | =item $category-E |
||||||
306 | |||||||
307 | Returns a count of the number of objects in the Category. | ||||||
308 | |||||||
309 | =cut | ||||||
310 | |||||||
311 | 0 | 0 | 1 | 0 | sub count { scalar @{ $_[0]->{'thingys'} } } | ||
0 | 0 | ||||||
312 | |||||||
313 | =item $category-E |
||||||
314 | |||||||
315 | Returns a list of the Category objects in the category. | ||||||
316 | |||||||
317 | =cut | ||||||
318 | |||||||
319 | sub categories | ||||||
320 | { | ||||||
321 | 0 | 0 | 1 | 0 | my $self = shift; | ||
322 | |||||||
323 | 0 | 0 | my @list = grep ref $_ eq 'Netscape::Bookmarks::Category', | ||||
324 | $self->elements; | ||||||
325 | |||||||
326 | 0 | 0 | return @list; | ||||
327 | } | ||||||
328 | |||||||
329 | =item $category-E |
||||||
330 | |||||||
331 | Returns a list of the Link objects in the category. | ||||||
332 | |||||||
333 | =cut | ||||||
334 | |||||||
335 | sub links | ||||||
336 | { | ||||||
337 | 0 | 0 | 1 | 0 | my $self = shift; | ||
338 | |||||||
339 | 0 | 0 | my @list = grep ref $_ eq 'Netscape::Bookmarks::Link', | ||||
340 | $self->elements; | ||||||
341 | |||||||
342 | 0 | 0 | return @list; | ||||
343 | } | ||||||
344 | |||||||
345 | =item $category-E |
||||||
346 | |||||||
347 | Returns an HTML string representation of the category, but not | ||||||
348 | the elements of the category. | ||||||
349 | |||||||
350 | =cut | ||||||
351 | |||||||
352 | sub as_headline | ||||||
353 | { | ||||||
354 | 37 | 37 | 1 | 83 | my $self = shift; | ||
355 | |||||||
356 | 37 | 100 | 106 | my $folded = $self->folded ? "FOLDED" : ""; | |||
357 | 37 | 108 | my $title = $self->title; | ||||
358 | 37 | 106 | my $desc = $self->description; | ||||
359 | 37 | 108 | my $add_date = $self->add_date; | ||||
360 | 37 | 95 | my $last_modified = $self->last_modified; | ||||
361 | 37 | 100 | my $id = $self->id; | ||||
362 | 37 | 109 | my $personal_toolbar_folder = $self->personal_toolbar_folder; | ||||
363 | |||||||
364 | 37 | 100 | 66 | 173 | $desc = defined $desc && $desc ne '' ? "\n |
||
365 | |||||||
366 | 37 | 100 | 109 | $folded = $folded ? qq|FOLDED| : ''; | |||
367 | 37 | 100 | 103 | $add_date = $add_date ? qq|ADD_DATE="$add_date"| : ''; | |||
368 | 37 | 100 | 108 | $last_modified = $last_modified ? qq|LAST_MODIFIED="$last_modified"| : ''; | |||
369 | 37 | 100 | 92 | $personal_toolbar_folder = $personal_toolbar_folder | |||
370 | ? qq|PERSONAL_TOOLBAR_FOLDER="true"| : ''; | ||||||
371 | 37 | 100 | 218 | $id = $id =~ m/\D/ ? qq|ID="$id"| : ''; | |||
372 | |||||||
373 | 37 | 177 | my $attr = join " ", grep $_, ($folded, $add_date, $last_modified, | ||||
374 | $personal_toolbar_folder, $id ); | ||||||
375 | |||||||
376 | 37 | 50 | 189 | $attr = " " . $attr if $attr; | |||
377 | 37 | 218 | $attr =~ s/\s+$//; # XXX: ugh | ||||
378 | |||||||
379 | 37 | 201 | return qq|$title$desc| |
||||
380 | } | ||||||
381 | |||||||
382 | =item $category-E |
||||||
383 | |||||||
384 | This method performs a depth-first traversal of the Bookmarks | ||||||
385 | tree and executes the CODE reference at each node. | ||||||
386 | |||||||
387 | The CODE reference receives two arguments - the object on which | ||||||
388 | it should operate and its level in the tree. | ||||||
389 | |||||||
390 | =cut | ||||||
391 | |||||||
392 | sub recurse | ||||||
393 | { | ||||||
394 | 0 | 0 | 1 | 0 | my $self = shift; | ||
395 | 0 | 0 | my $sub = shift; | ||||
396 | 0 | 0 | 0 | my $level = shift || 0; | |||
397 | |||||||
398 | 0 | 0 | 0 | unless( ref $sub eq 'CODE' ) | |||
399 | { | ||||||
400 | 0 | 0 | warn "Argument to recurse is not a code reference"; | ||||
401 | 0 | 0 | return; | ||||
402 | } | ||||||
403 | |||||||
404 | 0 | 0 | $sub->( $self, $level ); | ||||
405 | |||||||
406 | 0 | 0 | ++$level; | ||||
407 | 0 | 0 | foreach my $element ( $self->elements ) | ||||
408 | { | ||||||
409 | 0 | 0 | 0 | if( $element->isa( __PACKAGE__ ) ) | |||
410 | { | ||||||
411 | 0 | 0 | $element->recurse( $sub, $level ); | ||||
412 | } | ||||||
413 | else | ||||||
414 | { | ||||||
415 | 0 | 0 | $sub->( $element, $level ); | ||||
416 | } | ||||||
417 | } | ||||||
418 | 0 | 0 | --$level; | ||||
419 | |||||||
420 | } | ||||||
421 | |||||||
422 | =item $category-E |
||||||
423 | |||||||
424 | This method performs a depth-first traversal of the Bookmarks | ||||||
425 | tree and introduces the visitor object to each object. | ||||||
426 | |||||||
427 | This is different from recurse() which only calls its | ||||||
428 | CODEREF on nodes. The VISITOR operates on nodes and | ||||||
429 | vertices. The VISITOR must have a visit() method | ||||||
430 | recognizable by can(). This method does not trap | ||||||
431 | errors in the VISITOR. | ||||||
432 | |||||||
433 | See L |
||||||
434 | Visitors. | ||||||
435 | |||||||
436 | =cut | ||||||
437 | |||||||
438 | sub introduce | ||||||
439 | { | ||||||
440 | 5 | 5 | 1 | 428 | my $self = shift; | ||
441 | 5 | 13 | my $visitor = shift; | ||||
442 | 5 | 100 | 19 | my $level = shift || 0; | |||
443 | |||||||
444 | 5 | 50 | 33 | unless( $visitor->can('visit') ) | |||
445 | { | ||||||
446 | 0 | 0 | warn "Argument to introduce cannot visit()!"; | ||||
447 | 0 | 0 | return; | ||||
448 | } | ||||||
449 | |||||||
450 | 5 | 35 | $self->visitor( $visitor ); | ||||
451 | |||||||
452 | 5 | 18 | ++$level; | ||||
453 | 5 | 25 | foreach my $element ( $self->elements ) | ||||
454 | { | ||||||
455 | |||||||
456 | 16 | 100 | 222 | if( $element->isa( __PACKAGE__ ) ) | |||
457 | { | ||||||
458 | 4 | 26 | $element->introduce( $visitor, $level ); | ||||
459 | } | ||||||
460 | else | ||||||
461 | { | ||||||
462 | 12 | 86 | $element->visitor( $visitor ); | ||||
463 | } | ||||||
464 | |||||||
465 | } | ||||||
466 | 5 | 176 | --$level; | ||||
467 | |||||||
468 | } | ||||||
469 | |||||||
470 | =item $category-E |
||||||
471 | |||||||
472 | Sorts the elements in the category using the provided CODE | ||||||
473 | reference. If you do not specify a CODE reference, the | ||||||
474 | elements are sorted by title (with the side effect of | ||||||
475 | removing Separators from the Category). | ||||||
476 | |||||||
477 | This function does not recurse, although you can use | ||||||
478 | the recurse() method to do that. | ||||||
479 | |||||||
480 | Since the built-in sort() uses the package variables | ||||||
481 | C<$a> and C<$b>, your sort subroutine has to make sure | ||||||
482 | that it is accessing the right C<$a> and C<$b>, which | ||||||
483 | are the ones in the package C |
||||||
484 | You can start your CODE reference with a package | ||||||
485 | declaration to ensure the right thing happens: | ||||||
486 | |||||||
487 | my $sub = sub { | ||||||
488 | package Netscape::Bookmarks::Category; | ||||||
489 | |||||||
490 | $b->title cmp $a->title; | ||||||
491 | }; | ||||||
492 | |||||||
493 | $category->sort_elements( $sub ); | ||||||
494 | |||||||
495 | If you know a better way to do this, please let me know. :) | ||||||
496 | |||||||
497 | =cut | ||||||
498 | |||||||
499 | sub sort_elements | ||||||
500 | { | ||||||
501 | 0 | 0 | 1 | 0 | my $self = shift; | ||
502 | 0 | 0 | my $sub = shift; | ||||
503 | |||||||
504 | 0 | 0 | 0 | 0 | if( defined $sub and not ref $sub eq 'CODE' ) | ||
0 | |||||||
505 | { | ||||||
506 | 0 | 0 | warn "Second argument to sort_elements is not a CODE reference."; | ||||
507 | 0 | 0 | return; | ||||
508 | } | ||||||
509 | elsif( not defined $sub ) | ||||||
510 | { | ||||||
511 | 0 | 0 | 0 | $sub = sub { $a->title cmp $b->title }; | |||
0 | 0 | ||||||
512 | } | ||||||
513 | |||||||
514 | 0 | 0 | local *my_sorter = $sub; | ||||
515 | |||||||
516 | $self->{'thingys'} = [ sort my_sorter | ||||||
517 | 0 | 0 | grep { not $_->isa( 'Netscape::Bookmarks::Separator' ) } | ||||
518 | 0 | 0 | @{ $self->{'thingys'} } ]; | ||||
0 | 0 | ||||||
519 | } | ||||||
520 | |||||||
521 | =item $category-E |
||||||
522 | |||||||
523 | Returns an HTML string representation of the category as the | ||||||
524 | top level category, along with all of the elements of the | ||||||
525 | category and the Categories that it contains, recursively. | ||||||
526 | |||||||
527 | =cut | ||||||
528 | |||||||
529 | sub as_string | ||||||
530 | { | ||||||
531 | 2 | 2 | 1 | 1568 | my $self = shift; | ||
532 | |||||||
533 | 2 | 13 | my $title = $self->title; | ||||
534 | 2 | 100 | 9 | my $desc = $self->description || "\n"; | |||
535 | |||||||
536 | 2 | 100 | 11 | my $meta = $self->mozilla ? | |||
537 | qq|\n| : | ||||||
538 | ''; | ||||||
539 | |||||||
540 | 2 | 18 | my $str = <<"HTML"; | ||||
541 | |||||||
542 | $meta | ||||||
545 | |
||||||
546 | $title |
||||||
547 | |||||||
548 | HTML | ||||||
549 | |||||||
550 | 2 | 100 | 66 | 12 | $str .= " |
||
551 | |||||||
552 | 2 | 9 | $str .= START_LIST . "\n"; | ||||
553 | |||||||
554 | 2 | 15 | foreach my $element ( $self->elements ) | ||||
555 | { | ||||||
556 | 34 | 117 | $str .= $self->_as_string( $element, 1 ); | ||||
557 | } | ||||||
558 | |||||||
559 | 2 | 10 | $str .= END_LIST . "\n"; | ||||
560 | |||||||
561 | 2 | 166 | return $str; | ||||
562 | } | ||||||
563 | |||||||
564 | # _as_string does most of the work that as_string would normally | ||||||
565 | # do. | ||||||
566 | sub _as_string | ||||||
567 | { | ||||||
568 | 268 | 268 | 633 | my $self = shift; | |||
569 | 268 | 526 | my $obj = shift; | ||||
570 | 268 | 523 | my $level = shift; | ||||
571 | |||||||
572 | 268 | 483 | my $str; | ||||
573 | 268 | 100 | 100 | 1161 | if( ref $obj eq 'Netscape::Bookmarks::Category' ) | ||
100 | |||||||
50 | |||||||
574 | { | ||||||
575 | 37 | 153 | $str .= TAB x ($level) . START_LIST_ITEM . $obj->as_headline; | ||||
576 | |||||||
577 | 37 | 100 | 124 | unless( $self->mozilla ) | |||
578 | { | ||||||
579 | 4 | 11 | $str .= TAB x ($level-1) . START_LIST . "\n"; | ||||
580 | } | ||||||
581 | else | ||||||
582 | { | ||||||
583 | 33 | 113 | $str .= TAB x ($level) . START_LIST . "\n"; | ||||
584 | } | ||||||
585 | |||||||
586 | 37 | 84 | ++$level; | ||||
587 | 37 | 109 | foreach my $ref ( $obj->elements ) | ||||
588 | { | ||||||
589 | 234 | 789 | $str .= $self->_as_string( $ref, $level ); | ||||
590 | } | ||||||
591 | 37 | 95 | --$level; | ||||
592 | |||||||
593 | 37 | 123 | $str .= TAB x ($level) . END_LIST . "\n"; | ||||
594 | } | ||||||
595 | elsif( ref $obj eq 'Netscape::Bookmarks::Link' or | ||||||
596 | ref $obj eq 'Netscape::Bookmarks::Alias' ) | ||||||
597 | { | ||||||
598 | 229 | 1056 | $str .= TAB x ($level) . START_LIST_ITEM | ||||
599 | . $obj->as_string . "\n" | ||||||
600 | } | ||||||
601 | elsif( ref $obj eq 'Netscape::Bookmarks::Separator' ) | ||||||
602 | { | ||||||
603 | 2 | 11 | $str .= TAB x ($level) . $obj->as_string . "\n" | ||||
604 | } | ||||||
605 | |||||||
606 | 268 | 1396 | return $str; | ||||
607 | |||||||
608 | } | ||||||
609 | |||||||
610 | =item $obj->write_file( FILENAME ) | ||||||
611 | |||||||
612 | UNIMPLEMENTED! | ||||||
613 | |||||||
614 | =cut | ||||||
615 | |||||||
616 | sub write_file | ||||||
617 | { | ||||||
618 | 0 | 0 | 1 | my $self = shift; | |||
619 | 0 | my $filename = shift; | |||||
620 | |||||||
621 | 0 | return; | |||||
622 | } | ||||||
623 | |||||||
624 | "if you want to beleive everything you read, so be it."; | ||||||
625 | |||||||
626 | __END__ |