1/*
2    This file is part of HelpViewer (http://www.roard.com/helpviewer)
3    Copyright (C) 2003 Nicolas Roard (nicolas@roard.com)
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include "HandlerStructureXLP.h"
21
22#define HAVING(str) ([[elementName lowercaseString] isEqualToString: str])
23
24@implementation HandlerStructureXLP
25
26- (id) init {
27	self = [super init];
28	_firstSection = [[Section alloc] initWithHeader: @"document"];
29	_currentSection = _firstSection;
30	_document = NO;
31	content = nil;
32	return self;
33}
34
35- (id) initWithSection: (Section*) section {
36	self = [super init];
37	ASSIGN (_firstSection, section);
38	_currentSection = _firstSection;
39	_currentContent = [section text];
40	_document = YES;
41	content = nil;
42	return self;
43}
44
45- (void) dealloc {
46	RELEASE (_firstSection);
47}
48
49- (void) startElement: (NSString*) elementName attributes: (NSMutableDictionary*) elementAttributes {
50    //NSLog (@"startElement : <%@>", elementName);
51    NSString* name = nil;
52    NSString* src = nil;
53
54    if ([elementAttributes objectForKey: @"name"] != nil)
55    {
56	name = [NSString stringWithString: [elementAttributes objectForKey: @"name"]];
57    }
58
59    if ([elementAttributes objectForKey: @"src"] != nil)
60    {
61	src = [NSString stringWithString: [elementAttributes objectForKey: @"src"]];
62    }
63
64    if HAVING (@"document")
65    {
66    	_document = YES;
67    }
68
69    if (_document)
70    {
71	if (
72		HAVING (@"section")
73		|| HAVING (@"chapter")
74		|| HAVING (@"part")
75		|| HAVING (@"plain")
76	   )
77	{
78		//NSLog (@"<section>name=%@", name);
79		Section* newSection = [[Section alloc] initWithHeader: name];
80		if (src != nil)
81		{
82			[newSection setPath: src];
83		}
84
85		if HAVING (@"chapter") [newSection setType: SECTION_TYPE_CHAPTER];
86		if HAVING (@"part") [newSection setType: SECTION_TYPE_PART];
87		if HAVING (@"plain") [newSection setType: SECTION_TYPE_PLAIN];
88
89		[_currentSection setLoaded: YES];
90		[_currentSection addSub: newSection];
91		_currentSection = newSection;
92		_currentContent = [newSection text];
93		[_currentSection retain];
94		[_currentContent retain];
95	}
96	else
97	{
98		id tag = [[NSString alloc] initWithFormat: @"<%@", elementName];
99		id str = [[NSMutableAttributedString alloc] initWithString: tag];
100
101		[tag release];
102		int i;
103
104		NSEnumerator *enumerator = [elementAttributes keyEnumerator];
105		id key;
106
107		while ((key = [enumerator nextObject]))
108		{
109			id strelem = [[NSString alloc] initWithFormat: @" %@=%@",
110				key, [elementAttributes objectForKey: key]];
111			id astrelem = [[NSMutableAttributedString alloc] initWithString: strelem];
112			[str appendAttributedString: astrelem];
113			[astrelem release];
114			[strelem release];
115	    	}
116		id strend = [[NSMutableAttributedString alloc] initWithString: @">"];
117
118		[_currentContent appendAttributedString: str];
119		[_currentContent appendAttributedString: strend];
120		//[self addCurrentProgression: ([str length] + 1)];
121
122		[str release];
123		[strend release];
124	}
125    }
126}
127
128- (void) endElement: (NSString*) elementName {
129    //NSLog (@"endElement : <%@>", elementName);
130
131    if HAVING (@"document")
132    {
133    	_document = NO;
134    }
135
136    if (_document)
137    {
138	if (
139		HAVING (@"section")
140		|| HAVING (@"chapter")
141		|| HAVING (@"part")
142		|| HAVING (@"plain")
143	   )
144	{
145		//NSLog (@"characters (attr) : %@", _currentContent);
146		//NSLog (@"</section>");
147
148		if ([[_currentSection text] length] > 0)
149		{
150			[_currentSection setLoaded: YES];
151		}
152
153		Section* parent = [_currentSection parent];
154		if (parent != nil)
155		{
156			ASSIGN (_currentSection, parent);
157			ASSIGN (_currentContent, [parent text]);
158		}
159	}
160	else
161	{
162		id tag = [[NSString alloc] initWithFormat: @"</%@>", elementName];
163		id str = [[NSMutableAttributedString alloc] initWithString: tag];
164		[_currentContent appendAttributedString: str];
165		//[self addCurrentProgression: [str length]];
166		[str release];
167		[tag release];
168		//NSLog (@"</%@>",elementName);
169	}
170    }
171
172}
173
174- (void) characters: (NSString*) name {
175    if (_document)
176    {
177    	//NSLog (@"characters : %@", name);
178	NSString* str;
179
180	if ([name isEqualToString: @"<"]) str = [NSString stringWithString: @"&lt;"];
181	else if ([name isEqualToString: @">"]) str = [NSString stringWithString: @"&gt;"];
182	else str = [NSString trimString: name];
183
184    	NSMutableAttributedString* astr = [[NSMutableAttributedString alloc] initWithString: str];
185	[_currentContent appendAttributedString: astr];
186	//[self addCurrentProgression: [astr length]];
187	[astr release];
188    }
189}
190
191- (void) addCurrentProgression: (int) add
192{
193	current += add;
194	NSLog (@"Lu (%d) : %.2f / %.2f (%.2f%)", add, current, max, current*100/max);
195}
196
197- (Section*) sections {
198	return _firstSection;
199}
200- (void) setPath: (NSString*) p {
201	if (p != nil)
202	{
203		ASSIGN (path, p);
204		//NSLog (@"Handler setPath: %@", p);
205		content = [[NSData alloc] initWithContentsOfFile: path];
206	}
207}
208- (void) parse {
209	NSLog (@"HandlerStructureXLP parse");
210	//[Parser parserWithHandler: self withData: content];
211	max = (float) [content length];
212	[[GSHTMLParser parserWithSAXHandler: self withData: content] parse];
213	current = max;
214}
215
216- (void) setTextView: (NSTextView*) textview {
217//    textView = textview;
218}
219
220@end
221