1
/* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
* $Id: htmllib.pmod,v 1.1.1.1 2006/03/27 12:40:10 exodusd Exp $
20
constant cvs_version="$Id: htmllib.pmod,v 1.1.1.1 2006/03/27 12:40:10 exodusd Exp $";
25
#include <attributes.h>
27
//#define KEEP_UTF // keep the UTF8 converted encoding for output
31
string ahref_link_navigate(object obj, void|string prefix)
33
if ( !stringp(prefix) ) prefix = "";
34
return "<a "+href_link_navigate(obj)+">"+prefix+obj->get_identifier()+
38
string href_link_navigate_postfix(object obj, string prefix, string postfix)
44
if (!stringp(prefix)) prefix="";
45
if (!stringp(postfix))postfix="";
47
if ( obj->get_object_class() & CLASS_EXIT ) {
48
dest = obj->get_exit();
49
path = get_module("filepath:tree")->object_to_filename(dest);
50
href = "href=\""+path+postfix+"\"";
53
href = "href=\""+prefix+replace_uml(obj->get_identifier())+postfix+"\"";
57
string href_link_navigate(object obj, void|string prefix)
63
if ( !stringp(prefix) ) prefix = "";
65
if ( obj->get_object_class() & CLASS_EXIT ) {
66
dest = obj->get_exit();
67
path = get_module("filepath:tree")->object_to_filename(dest);
68
href = "href=\""+path+"\"";
71
href = "href=\""+prefix+replace_uml(obj->get_identifier())+"\"";
75
string create_tag(string name, mapping attrs)
77
string attr_string = "";
78
foreach(indices(attrs), string a) {
79
attr_string += " " + a + "=\""+attrs[a]+"\"";
81
return sprintf("<%s%s>", name, attr_string);
86
inherit "AbstractCallbacks";
88
static string output = ""; // the output
89
static mapping rxml_handlers = ([ ]);
90
static mapping rxml_attributes = ([ ]);
91
static mapping variables = ([ ]);
92
static string encoding = "utf-8";
93
static int scriptmode = 0;
95
static ADT.Queue NodeDataQueue = ADT.Queue();
97
void create(mapping vars) {
101
int store_data(string data) {
102
string node_data = NodeDataQueue->read();
103
if ( stringp(node_data) ) {
105
NodeDataQueue->write(node_data);
111
void startDocumentSAX(object parser, void|mixed userData) {
112
output = "<!-- sTeam link consistency and HTML extension parser - modified document view !-->\n";
115
void startElementSAX(object parser, string name,
116
mapping(string:string) attrs, void|mixed userData)
118
if ( name == "script" )
121
if ( !rxml_handlers[name] ) {
122
string attr_string = "";
123
if ( mappingp(attrs) ) {
124
foreach(indices(attrs), string a) {
126
attr_string += " " + a + "=\""+attrs[a]+"\"";
129
string tagstr = "<"+name+ attr_string + ">";
131
if ( !store_data(tagstr) )
135
rxml_attributes[name] = attrs;
136
NodeDataQueue->write(""); // if is empty string then fill
139
static string call_handler(function f, mapping attributes, string data)
141
mapping params = variables;
142
if ( !mappingp(attributes) )
145
params->args = attributes;
146
params->args->body = data;
148
mixed err = catch(result=f(params));
150
FATAL("SAX: error calling handler %s\n%O", err[0], err[1]);
151
result = "<!-- error calling handler -->";
156
void endElementSAX(object parser, string name, void|mixed userData)
160
if ( name == "script" )
162
function hfunc = rxml_handlers[name];
163
mapping attr = rxml_attributes[name];
165
if ( functionp(hfunc) ) {
166
tagstr = call_handler(hfunc, attr, NodeDataQueue->read());
167
if ( !store_data(tagstr) )
170
else if ( lower_case(name) != "br" )
172
tagstr = "</"+name+">";
173
if ( !store_data(tagstr) )
178
void errorSAX(object parser, string msg, void|mixed userData) {
179
output += "<!-- SAX: " + msg + "-->\n";
181
void cdataBlockSAX(object parser, string value, void|mixed userData)
184
value = replace(value, ({ "<", ">", }), ({ "<", ">" }));
185
if ( !store_data(value) )
188
void charactersSAX(object parser, string chars, void|mixed userData)
191
chars = replace(chars, ({ "<", ">", }), ({ "<", ">" }));
193
if ( !store_data(chars) )
196
void commentSAX(object parser, string value, void|mixed userData)
198
output += "<!--"+value+"-->\n";
200
void referenceSAX(object parser, string name, void|mixed userData)
202
werror("referenceSAX(%s)\n", name);
205
void entityDeclSAX(object parser, string name, int type, string publicId,
206
string systemId, string content, void|mixed userData)
208
werror("entityDecl(%s)\n", name);
211
void notationDeclSAX(object parser, string name, string publicId,
212
string systemId, void|mixed userData)
214
werror("notationDecl(%s)\n", name);
216
void unparsedEntityDeclSAX(object parser, string name, string publicId,
217
string systemId, string notationName,
220
werror("unparsedEntityDecl(%s)\n", name);
222
string getEntitySAX(object parser, string name, void|mixed userData)
224
werror("getEntitySax(%s)\n", name);
226
void attributeDeclSAX(object parser, string elem, string fullname,
227
int type, int def, void|mixed userData)
229
werror("attributeDeclSAX(%s, %s)\n", elem, fullname);
231
void internalSubsetSAX(object parser, string name, string externalID,
232
string systemID, void|mixed uData)
235
void ignorableWhitespaceSAX(object parser, string chars, void|mixed uData)
239
void set_handlers(mapping h)
249
string get_tag_name(object tag)
251
string name = tag->get_identifier();
252
sscanf(name, "%s.pike", name);
256
function get_tag_function(object tag)
261
instance = tag->get_instance();
262
if ( !objectp(instance) )
265
return instance->execute;
270
string parse_rxml(string|object html, mapping variables, mapping tags, string|void encoding)
272
object cb = rxmlHandler(variables);
275
cb->set_handlers(tags);
276
if ( objectp(html) ) {
277
encoding = html->query_attribute(DOC_ENCODING);
279
else if ( !stringp(encoding) )
280
encoding = detect_encoding(html);
282
encoding = lower_case(encoding);
285
if ( stringp(inp) && strlen(inp) == 0 )
288
object sax = xml.HTML(inp, cb, ([ ]), 0, stringp(html));
289
sax->parse(encoding);
290
string res = cb->get_result();
292
// now it IS utf8 - change back to former encoding
293
if ( stringp(encoding) && encoding != "utf-8" ) {
294
if ( catch(res = xml.utf8_to_html(res)) ) {
295
werror("HTML Conversion failed !\n");
296
if ( encoding == "iso-8859-1" ) {
297
if ( catch(res = xml.utf8_to_isolat1(res)) ) {
298
werror("Failed conversion - skipping rxml !\n");
303
werror("Failed conversion - skipping !\n");
304
return html; // do nothing
314
string execute(mapping vars) {
315
return "Hello World to " + vars->args->name;
320
string execute(mapping vars) {
321
return "<BODY>"+vars->args->body+"</BODY>";
329
"<html><body>Welcome! <h2><test name='test'/></h2></body></html>";
331
result = parse_rxml(result, ([ ]), ([ "test": testTag()->execute, ]));
333
"<html><body>Welcome! <h2>Hello World to test</h2></body></html>" )
334
error("rxml test failed - wrong result " + result);
336
result = "<a><b><c><c apply='1'>"+
338
"<d name='y'/></b></a>";
340
result = parse_rxml(result, ([ ]), ([ "d": testTag()->execute,
341
"c":tagTag()->execute,]));
343
"<a><b><c><BODY>Hello World to x</BODY>Hello World to y</b></a>" )
344
error("nested rxml test failed !");
347
function find_tag(string name)
349
object tags = OBJ("/tags");
350
if ( !objectp(tags) )
352
object tag = tags->get_object_byname(name+".pike");
355
return get_tag_function(tag);
359
mapping find_tags(object obj)
363
if ( obj->get_object_class() & CLASS_CONTAINER ) {
364
mapping result = ([ ]);
365
foreach(obj->get_inventory_by_class(CLASS_DOCLPC), object tag) {
366
function f = get_tag_function(tag);
367
string tagname = get_tag_name(tag);
369
MESSAGE("Warning - no tag function for tag: %s", tagname);
375
else if ( obj->get_object_class() & CLASS_DOCXSL) {
376
object env = obj->get_environment();
378
return find_tags(env->get_object_byname("tags"));
383
string describe() { return "htmllib"; }