2001-06-11
2001-06-11 19:12:19 by Martin Stjernholm <mast@lysator.liu.se>
-
d2aca098e56d5482d1d437c7c3aecc1b07b13a31
(198 lines)
(+95/-103)
[
Show
| Annotate
]
Branch: 5.2
Cleaned up the reparsing of the tag from raw_tag_text a bit. Fixed the
bug with splice arguments in combination with propagate_tag.
Rev: server/etc/modules/RXML.pmod/module.pmod:1.164
1:
- // $Id: module.pmod,v 1.163 2001/06/09 02:39:44 nilsson Exp $
+ // $Id: module.pmod,v 1.164 2001/06/11 19:12:19 mast Exp $
// Kludge: Must use "RXML.refs" somewhere for the whole module to be
// loaded correctly.
2276:
if (flags & FLAG_PROC_INSTR) {
if (!content) {
CHECK_RAW_TEXT;
- if (mixed err = catch {
- Parser_HTML()->add_quote_tag (
- "?",
- lambda (object p, string c) {
- sscanf (c, "%*[^ \t\n\r]%s", content);
- throw (0);
- },
- "?")->finish (this->raw_tag_text);
- }) throw (err);
+ content = t_xml->parse_tag (this->raw_tag_text)[2];
#ifdef DEBUG
if (!stringp (content))
fatal_error ("Failed to parse PI tag content for <?%s?> from %O.\n",
2292:
#endif
}
}
-
+
else if (!args || !content && !(flags & FLAG_EMPTY_ELEMENT)) {
CHECK_RAW_TEXT;
- if (mixed err = catch {
- Parser_HTML()->_set_tag_callback (
- lambda (object p, string s) {
- if (!args) args = p->tag_args();
- if (content || flags & FLAG_EMPTY_ELEMENT) throw (0);
- else {
- p->_set_tag_callback (0);
- p->add_container (p->tag_name(),
- lambda (object p, mapping a, string c) {
- content = c;
- throw (0);
- });
- return 1;
- }
- })->finish (this->raw_tag_text);
- }) throw (err);
+ string ignored;
+ [ignored, args, content] = t_xml->parse_tag (this->raw_tag_text);
#ifdef DEBUG
if (!mappingp (args))
fatal_error ("Failed to parse tag args for <%s> from %O.\n",
2320:
tag->name, this->raw_tag_text);
#endif
}
-
+
frame = overridden (args, content || "");
frame->flags |= FLAG_UNPARSED;
return frame;
}
else {
- // Format a new tag, as like the original as possible. FIXME:
- // When it's reformatted, the prefix (if any) won't stick, but
- // it will when it isn't.
+ CHECK_RAW_TEXT;
+ // Format a new tag, as like the original as possible.
if (flags & FLAG_PROC_INSTR) {
- if (content)
- return result_type->format_tag (tag, 0, content);
- else {
- CHECK_RAW_TEXT;
+ if (content) {
+ string name;
+ [name, args, content] = t_xml->parse_tag (this->raw_tag_text);
+ return result_type->format_tag (name, 0, content, tag->flags);
+ }
+ else
return this->raw_tag_text;
}
- }
+
else {
- if (args && (content || flags & FLAG_EMPTY_ELEMENT))
- return result_type->format_tag (tag, args, content);
- else {
- CHECK_RAW_TEXT;
-
+
string s;
#ifdef MODULE_DEBUG
if (mixed err = catch {
#endif
- s = t_xml (PEnt)->eval (this->raw_tag_text,
+ s = t_xml (PXml)->eval (this->raw_tag_text,
get_context(), empty_tag_set);
#ifdef MODULE_DEBUG
}) {
2361:
#endif
if (!args && !content) return s;
- if (mixed err = catch {
- Parser_HTML()->_set_tag_callback (
- lambda (object p, string s) {
- if (!args) args = p->tag_args();
- if (content || flags & FLAG_EMPTY_ELEMENT) throw (0);
- else {
- p->_set_tag_callback (0);
- p->add_container (p->tag_name(),
- lambda (object p, mapping a, string c) {
- content = c;
- throw (0);
- });
- return 1;
- }
- })->finish (this->raw_tag_text);
- }) throw (err);
+ [string name, mapping(string:string) parsed_args,
+ string parsed_content] = t_xml->parse_tag (this->raw_tag_text);
#ifdef DEBUG
- if (!mappingp (args))
+ if (!mappingp (parsed_args))
fatal_error ("Failed to parse tag args for <%s> from %O.\n",
tag->name, this->raw_tag_text);
- if (!stringp (content))
+ if (!stringp (parsed_content))
fatal_error ("Failed to parse tag content for <%s> from %O.\n",
tag->name, this->raw_tag_text);
#endif
-
+ if (!args) args = parsed_args;
+ if (!content) content = parsed_content;
return result_type->format_tag (tag, args, content);
}
- }
- }
+
#undef CHECK_RAW_TEXT
}
-
+ }
//(!) Internals:
2733:
// Note: Approximate code duplication in _eval_args and Tag.eval_args().
string splice_arg = raw_args["::"];
- if (splice_arg && type->entity_syntax)
- // Note: Not really accurate to look at entity_syntax here.
- m_delete (raw_args, "::");
+ if (splice_arg) m_delete (raw_args, "::");
else splice_arg = 0;
mapping(string:Type) splice_req_types;
2756:
String.Buffer fn_text = String.Buffer();
if (splice_arg) {
+ // Note: This assumes an XML-like parser.
Parser p = splice_arg_type->get_pcode_parser (ctx, 0, 0);
THIS_TAG_DEBUG ("Evaluating splice argument %s\n",
utils->format_short (splice_arg));
2772: Inside #if defined(MODULE_DEBUG)
throw_fatal (err);
}
#endif
- string expr =
- sprintf ("%s (context, %s->parse_tag_args ((%s) || \"\"), %s)",
+ fn_text->add (
+ sprintf ("return %s (context, "
+ "RXML.xml_tag_parser->parse_tag_args ((%s) || \"\"), %s) + ([\n",
comp->bind (_eval_args),
- comp->bind (xml_splice_arg_parser),
+
p->p_code->_compile_text (comp),
- comp->bind (splice_req_types));
+ comp->bind (splice_req_types)));
p->p_code = 0;
splice_arg_type->give_back (p);
- args = _eval_args (
- ctx, xml_splice_arg_parser->parse_tag_args (splice_arg || ""),
+ args = _eval_args (ctx, xml_tag_parser->parse_tag_args (splice_arg || ""),
splice_req_types);
-
- if (!zero_type (this->raw_tag_text)) {
- // expr = sprintf (
- // "mapping(string:string) args = %s;\n"
- // "%s->raw_tag_text = %s->format_tag ("
- // "%s, args, %s, %d | RXML.FLAG_RAW_ARGS);\n"
- // "return args;",
- // expr, comp->bind (this), comp->bind (type),
- // comp->bind (tag->name), comp->bind (content), flags);
- // frame->raw_tag_text =
- // t_xml->format_tag (tagname, args, content, flags | FLAG_RAW_ARGS);
+
}
- fn_text->add ("return ");
- fn_text->add (expr);
- fn_text->add (" + ([\n");
- }
+
else {
args = raw_args;
fn_text->add ("return ([\n");
5093:
string capitalize (string val)
{return capitalizer->clone()->finish (val)->read();}
+ array(string|mapping(string:string)) parse_tag (string tag_text)
+ //! Parses the first tag in @[tag_text] and returns an array where
+ //! the first element is the name of the tag, the second its
+ //! argument mapping, and the third the content. The second argument
+ //! is zero iff it's a processing instruction. The third argument is
+ //! zero iff the tag is on the empty element form (i.e. ending with
+ //! '/>').
+ {
+ array(string|mapping(string:string)) res = 0;
+ if (mixed err = catch {
+ if (sizeof (tag_text) >= 2 && tag_text[1] == '?') // A processing instruction.
+ xml_tag_parser->clone()->add_quote_tag (
+ "?",
+ lambda (object p, string content) {
+ string name;
+ sscanf (content, "%[^ \t\n\r]%s", name, content);
+ res = name && content && ({name, 0, content});
+ throw (0);
+ },
+ "?")->finish (tag_text);
+ else
+ xml_tag_parser->clone()->_set_tag_callback (
+ lambda (object p, string s) {
+ if (s == tag_text) {
+ res = p->tag();
+ res[2] = "";
+ throw (0);
+ }
+ else {
+ p->_set_tag_callback (0);
+ p->add_tag (p->tag_name(),
+ lambda (object p, mapping a) {
+ res = p->tag();
+ res[2] = 0;
+ throw (0);
+ });
+ p->add_container (p->tag_name(),
+ lambda (object p, mapping a, string c) {
+ res = ({p->tag_name(), a, c});
+ throw (0);
+ });
+ return 1;
+ }
+ })->finish (tag_text);
+ }) throw (err);
+ return res;
+ }
+
string format_tag (string|Tag tag, void|mapping(string:string) args,
void|string content, void|int flags)
//! Returns a formatted XML tag. The flags argument contains a flag
5633:
static Type splice_arg_type;
+ object/*(Parser.HTML)*/ xml_tag_parser;
static object/*(Parser.HTML)*/
- xml_splice_arg_parser, charref_decode_parser, lowercaser, uppercaser, capitalizer;
+ charref_decode_parser, lowercaser, uppercaser, capitalizer;
static void init_parsers()
{
object/*(Parser.HTML)*/ p = Parser_HTML();
-
+ p->xml_tag_syntax (3);
p->match_tag (0);
- xml_splice_arg_parser = p;
+ xml_tag_parser = p;
// Pretty similar to PEnt..
p = Parser_HTML();