ebdb652000-01-14Martin Nilsson // This is a roxen module. Copyright © 1996 - 2000, Idonex AB.
4817401999-08-13Martin Nilsson // #define _stat id->misc->defines[" _stat"] #define _error id->misc->defines[" _error"] #define _extra_heads id->misc->defines[" _extra_heads"] #define _rettext id->misc->defines[" _rettext"] #define _ok id->misc->defines[" _ok"]
8c96aa2000-02-24Martin Nilsson constant cvs_version="$Id: rxmltags.pike,v 1.79 2000/02/24 04:41:27 nilsson Exp $";
4817401999-08-13Martin Nilsson constant thread_safe=1;
bfd5fb1999-10-08Martin Nilsson constant language = roxen->language;
4817401999-08-13Martin Nilsson  #include <module.h> inherit "module"; inherit "roxenlib"; // ---------------- Module registration stuff ----------------
0be6412000-01-18Martin Nilsson constant module_type = MODULE_PARSER | MODULE_PROVIDER;
32b5dc2000-02-18Martin Nilsson constant module_name = "RXML 2.0 tags";
0be6412000-01-18Martin Nilsson constant module_doc = "This module adds a lot of RXML tags.";
16509b1999-12-14Martin Nilsson void create()
4817401999-08-13Martin Nilsson { defvar("insert_href",1,"Allow &lt;insert href&gt;.", TYPE_FLAG|VAR_MORE, "Should the usage of &lt;insert href&gt; be allowed?"); }
16509b1999-12-14Martin Nilsson void start()
659d4b1999-10-18Martin Nilsson {
ecab8b2000-01-23Martin Nilsson  add_api_function("query_modified", api_query_modified, ({ "string" }));
0be6412000-01-18Martin Nilsson  query_tag_set()->prepare_context=set_entities;
4817401999-08-13Martin Nilsson }
b7e95b1999-12-14Martin Nilsson string query_provides() { return "modified"; }
592ed72000-02-06Martin Nilsson constant permitted = "123456789.xabcdefint\"XABCDEFlo<>=0-*+/%%|()"/"";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string sexpr_eval(string what) { array q = what/""; what = "mixed foo(){ return "+(q-(q-permitted))*""+";}"; return (string)compile_string( what )()->foo(); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // ----------------- Entities ----------------------
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageRealfile {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return c->id->realfile||""; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageVirtroot {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return c->id->virtfile||""; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageVirtfile {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return c->id->not_query; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageQuery {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return c->id->query; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageURL {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return c->id->raw_url; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageLastTrue {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value;
592ed72000-02-06Martin Nilsson  int rxml_var_eval(RXML.Context c) { return c->id->misc->defines[" _ok"]; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageLanguage {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return c->id->misc->defines->language || ""; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageScope {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value;
592ed72000-02-06Martin Nilsson  string rxml_var_eval(RXML.Context c) { return c->current_scope(); } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageFileSize {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; int rxml_const_eval(RXML.Context c) { return c->id->misc->defines[" _stat"]?c->id->misc->defines[" _stat"][1]:-4; }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityPageSelf {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) { return (c->id->not_query/"/")[-1]; }
592ed72000-02-06Martin Nilsson }
f1c9f02000-01-26Kenneth Johansson 
6d7a702000-02-07Martin Nilsson mapping page_scope=(["realfile":EntityPageRealfile(), "virtroot":EntityPageVirtroot(), "virtfile":EntityPageVirtfile(), "query":EntityPageQuery(), "url":EntityPageURL(), "last-true":EntityPageLastTrue(), "language":EntityPageLanguage(), "scope":EntityPageScope(), "filesize":EntityPageFileSize(), "self":EntityPageSelf()]);
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityClientReferrer {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; array referrer=c->id->referer; return referrer && sizeof(referrer)?referrer[0]:""; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityClientName {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; array client=c->id->client; return client && sizeof(client)?client[0]:""; } }
e272382000-01-23Kenneth Johansson 
fe1a7d2000-02-11Per Hedbor class EntityClientFullName { inherit RXML.Value; string rxml_const_eval(RXML.Context c) { c->id->misc->cacheable=0; array client=c->id->client; return client && client*" "; } }
6d7a702000-02-07Martin Nilsson class EntityClientIP {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; return c->id->remoteaddr; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityClientAcceptLanguage {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; if(!c->id->misc["accept-language"]) return ""; return c->id->misc["accept-language"][0]; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityClientAcceptLanguages {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; if(!c->id->misc["accept-language"]) return ""; return c->id->misc["accept-language"]*", "; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityClientLanguage {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; if(!c->id->misc->pref_languages) return ""; return c->id->misc->pref_languages->get_language() || ""; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class EntityClientLanguages {
c8164c2000-02-08Martin Nilsson  inherit RXML.Value; string rxml_const_eval(RXML.Context c) {
592ed72000-02-06Martin Nilsson  c->id->misc->cacheable=0; if(!c->id->misc->pref_languages) return ""; return c->id->misc->pref_languages->get_languages()*", "; } }
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson mapping client_scope=([ "ip":EntityClientIP(), "name":EntityClientName(),
fe1a7d2000-02-11Per Hedbor  "full-name":EntityClientFullName(),
6d7a702000-02-07Martin Nilsson  "referrer":EntityClientReferrer(), "accept-language":EntityClientAcceptLanguage(), "accept-languages":EntityClientAcceptLanguages(), "language":EntityClientLanguage(), "languages":EntityClientLanguages()]);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson void set_entities(RXML.Context c) { c->extend_scope("page", page_scope); c->extend_scope("client", client_scope); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // ------------------- Tags ------------------------
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagRoxenACV { inherit RXML.Tag; constant name = "roxen-automatic-charset-variable";
c0f5082000-02-21Martin Stjernholm  constant flags = RXML.FLAG_EMPTY_ELEMENT;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame; constant magic= "<input type=\"hidden\" name=\"magic_roxen_automatic_charset_variable\" value=\"åäö\" />";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array do_return(RequestID id) { result=magic; } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagAppend { inherit RXML.Tag; constant name = "append";
c0f5082000-02-21Martin Stjernholm  constant flags = RXML.FLAG_EMPTY_ELEMENT;
1ae52e2000-02-07Martin Stjernholm  mapping(string:RXML.Type) req_arg_types = ([ "variable" : RXML.t_text ]);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array do_return(RequestID id) { RXML.Context context=RXML.get_context(); mixed value=context->user_get_var(args->variable, args->scope); if (args->value) { // Append a value to an entity variable. if (value) value+=args->value; else value=args->value; context->user_set_var(args->variable, value, args->scope); return 0; } if (args->from) { // Append the value of another entity variable. mixed from=context->user_get_var(args->from, args->scope);
39271c2000-02-23Martin Stjernholm  if(!from) parse_error("From variable doesn't exist.\n");
592ed72000-02-06Martin Nilsson  if (value) value+=from; else value=from; context->user_set_var(args->variable, value, args->scope); return 0; }
39271c2000-02-23Martin Stjernholm  parse_error("No value specified.\n");
592ed72000-02-06Martin Nilsson  } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson mapping tag_auth_required (string tagname, mapping args, RequestID id) { mapping hdrs = http_auth_required (args->realm, args->message); if (hdrs->error) _error = hdrs->error; if (hdrs->extra_heads) _extra_heads += hdrs->extra_heads; // We do not need this as long as hdrs only contains strings and numbers // foreach(indices(hdrs->extra_heads), string tmp) // add_http_header(_extra_heads, tmp, hdrs->extra_heads[tmp]); if (hdrs->text) _rettext = hdrs->text; return hdrs; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_expire_time(string tag, mapping m, RequestID id) { int t,t2; t=t2==time(1); if(!m->now) { t+=time_dequantifier(m); CACHE(max(t-time(),0)); } if(t==t2) { NOCACHE(); add_http_header(_extra_heads, "Pragma", "no-cache"); add_http_header(_extra_heads, "Cache-Control", "no-cache"); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  add_http_header(_extra_heads, "Expires", http_date(t)); return ""; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_header(string tag, mapping m, RequestID id) { if(m->name == "WWW-Authenticate") { string r; if(m->value) { if(!sscanf(m->value, "Realm=%s", r)) r=m->value; } else r="Users"; m->value="basic realm=\""+r+"\""; } else if(m->name=="URI") m->value = "<" + m->value + ">";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!(m->value && m->name))
39271c2000-02-23Martin Stjernholm  RXML.parse_error("Requires both a name and a value.\n");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  add_http_header(_extra_heads, m->name, m->value); return ""; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_redirect(string tag, mapping m, RequestID id) { if (!(m->to && sizeof (m->to)))
39271c2000-02-23Martin Stjernholm  RXML.parse_error("Requires attribute \"to\".\n");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  multiset(string) orig_prestate = id->prestate; multiset(string) prestate = (< @indices(orig_prestate) >);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->add) { foreach((m->add-" ")/",", string s) prestate[s]=1; m_delete(m,"add"); } if(m->drop) { foreach((m->drop-" ")/",", string s) prestate[s]=0; m_delete(m,"drop"); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  id->prestate = prestate; mapping r = http_redirect(m->to, id); id->prestate = orig_prestate;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if (r->error) _error = r->error; if (r->extra_heads) _extra_heads += r->extra_heads; // We do not need this as long as r only contains strings and numbers // foreach(indices(r->extra_heads), string tmp) // add_http_header(_extra_heads, tmp, r->extra_heads[tmp]); if (m->text) _rettext = m->text;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ""; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagUnset { inherit RXML.Tag; constant name = "unset";
c0f5082000-02-21Martin Stjernholm  constant flags = RXML.FLAG_EMPTY_ELEMENT;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame; array do_return(RequestID id) { if(!args->variable && !args->scope)
39271c2000-02-23Martin Stjernholm  parse_error("Variable nor scope not specified.\n");
592ed72000-02-06Martin Nilsson  if(!args->variable && args->scope!="roxen") { RXML.get_context()->add_scope(args->scope, ([]) ); return 0; } RXML.get_context()->user_delete_var(args->variable, args->scope); return 0; } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagSet { inherit RXML.Tag; constant name = "set";
c0f5082000-02-21Martin Stjernholm  constant flags = RXML.FLAG_EMPTY_ELEMENT;
1ae52e2000-02-07Martin Stjernholm  mapping(string:RXML.Type) req_arg_types = ([ "variable": RXML.t_text ]);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame; array do_return(RequestID id) { RXML.Context context=RXML.get_context(); if (args->value) { // Set an entity variable to a value. context->user_set_var(args->variable, args->value, args->scope); return 0; } if (args->expr) { // Set an entity variable to an evaluated expression. context->user_set_var(args->variable, sexpr_eval(args->expr), args->scope); return 0; } if (args->from) { // Copy a value from another entity variable. mixed from=context->user_get_var(args->from, args->scope);
39271c2000-02-23Martin Stjernholm  if(!from) run_error("From variable doesn't exist.\n");
592ed72000-02-06Martin Nilsson  context->user_set_var(args->variable, from, args->scope); return 0; }
e272382000-01-23Kenneth Johansson 
39271c2000-02-23Martin Stjernholm  parse_error("No value specified.\n");
592ed72000-02-06Martin Nilsson  } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagInc { inherit RXML.Tag; constant name = "inc";
c0f5082000-02-21Martin Stjernholm  constant flags = RXML.FLAG_EMPTY_ELEMENT;
1ae52e2000-02-07Martin Stjernholm  mapping(string:RXML.Type) req_arg_types = ([ "variable":RXML.t_text ]);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array do_return(RequestID id) { string res=inc(args, id);
5ed0132000-02-13Martin Stjernholm  if(res) parse_error(res);
592ed72000-02-06Martin Nilsson  return 0; } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagDec { inherit RXML.Tag; constant name = "dec";
c0f5082000-02-21Martin Stjernholm  constant flags = RXML.FLAG_EMPTY_ELEMENT;
1ae52e2000-02-07Martin Stjernholm  mapping(string:RXML.Type) req_arg_types = ([ "variable":RXML.t_text ]);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array do_return(RequestID id) { string res=dec(args, id);
5ed0132000-02-13Martin Stjernholm  if(res) parse_error(res);
592ed72000-02-06Martin Nilsson  return 0; } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson private string inc(mapping m, RequestID id) { RXML.Context context=RXML.get_context(); array entity=context->parse_user_var(m->variable, m->scope);
39271c2000-02-23Martin Stjernholm  if(!context->exist_scope(entity[0])) return "Scope "+entity[0]+" does not exist.\n";
592ed72000-02-06Martin Nilsson  int val=(int)m->value||1; context->user_set_var(m->variable, (int)context->user_get_var(m->variable, m->scope)+val, m->scope); return 0; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson private string dec(mapping m, RequestID id) { m->value=-(int)m->value||-1; return inc(m, id); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string|array(string) tag_imgs(string tag, mapping m, RequestID id) {
8c96aa2000-02-24Martin Nilsson  string err="";
592ed72000-02-06Martin Nilsson  if(m->src) { string file; if(file=id->conf->real_file(fix_relative(m->src, id), id)) { array(int) xysize; if(xysize=Dims.dims()->get(file)) { m->width=(string)xysize[0]; m->height=(string)xysize[1]; } else
8c96aa2000-02-24Martin Nilsson  err+=" Dimensions quering failed.";
592ed72000-02-06Martin Nilsson  } else
8c96aa2000-02-24Martin Nilsson  err+=" Virtual path failed";
592ed72000-02-06Martin Nilsson  if(!m->alt) { array src=m->src/"/"; string src=src[sizeof(src)-1]; m->alt=String.capitalize(replace(src[..sizeof(src)-search(reverse(src),".")-2],"_"," ")); }
8c96aa2000-02-24Martin Nilsson  if(err && !m->quiet) RXML.run_error(err); return ({ make_tag("img", m) });
592ed72000-02-06Martin Nilsson  }
39271c2000-02-23Martin Stjernholm  RXML.parse_error("No src given.\n");
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string) tag_roxen(string tagname, mapping m, RequestID id) { string size = m->size || "small"; string color = m->color || "blue"; m_delete(m, "color"); m_delete(m, "size"); m->src = "/internal-roxen-power-"+size+"-"+color; m->width = (["small":"100","medium":"200","large":"300"])[size]; m->height = (["small":"35","medium":"60","large":"90"])[size]; if(!m->alt) m->alt="Powered by Roxen"; if(!m->border) m->border="0"; return ({ "<a href=\"http://www.roxen.com/\">"+make_tag("img", m)+"</a>" }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string|array(string) tag_debug( string tag_name, mapping m, RequestID id ) { if (m->showid) { array path=lower_case(m->showid)/"->"; if(path[0]!="id" || sizeof(path)==1) return "Can only show parts of the id object."; mixed obj=id; foreach(path[1..], string tmp) { if(search(indices(obj),tmp)==-1) return "Could only reach "+tmp+"."; obj=obj[tmp]; } return ({ "<pre>"+html_encode_string(sprintf("%O",obj))+"</pre>" }); }
6d7a702000-02-07Martin Nilsson  if (m->werror) {
c8164c2000-02-08Martin Nilsson  report_debug(replace(m->werror,"\\n","\n"));
6d7a702000-02-07Martin Nilsson  }
592ed72000-02-06Martin Nilsson  if (m->off) id->misc->debug = 0; else if (m->toggle) id->misc->debug = !id->misc->debug; else id->misc->debug = 1; return "<!-- Debug is "+(id->misc->debug?"enabled":"disabled")+" -->"; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_fsize(string tag, mapping args, RequestID id) { if(args->file) { catch { array s = id->conf->stat_file( fix_relative( args->file, id ), id ); if (s && (s[1]>= 0)) return (string)s[1]; }; if(string s=id->conf->try_get_file(fix_relative(args->file, id), id ) ) return (string)strlen(s); }
39271c2000-02-23Martin Stjernholm  RXML.run_error("Failed to find file.\n");
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class TagCoding { inherit RXML.Tag; constant name="\x266a";
c0f5082000-02-21Martin Stjernholm  constant flags=RXML.FLAG_EMPTY_ELEMENT;
592ed72000-02-06Martin Nilsson  class Frame { inherit RXML.Frame; constant space=({147, 188, 196, 185, 188, 187, 119, 202, 201, 186, 148, 121, 191, 203, 203, 199, 145, 134, 134, 206, 206, 206, 133, 201, 198, 207, 188, 197, 133, 186, 198, 196, 134, 188, 190, 190, 134, 138, 133, 196, 192, 187, 121, 119, 191, 192, 187, 187, 188, 197, 148, 121, 203, 201, 204, 188, 121, 119, 184, 204, 203, 198, 202, 203, 184, 201, 203, 148, 121, 203, 201, 204, 188, 121, 119, 195, 198, 198, 199, 148, 121, 203, 201, 204, 188, 121, 149}); array do_return(RequestID id) { result=Array.map(space, lambda(int|string c) { return intp(c)?(string)({c-(sizeof(space))}):c; } )*""; } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string)|string tag_configimage(string t, mapping m, RequestID id) {
39271c2000-02-23Martin Stjernholm  if (!m->src) RXML.parse_error("No src given.\n", id);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if (m->src[sizeof(m->src)-4..][0] == '.') m->src = m->src[..sizeof(m->src)-5];
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  m->alt = m->alt || m->src; m->src = "/internal-roxen-" + m->src; m->border = m->border || "0";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ({ make_tag("img", m) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_date(string q, mapping m, RequestID id) { int t=(int)m["unix-time"] || time(1); t+=time_dequantifier(m);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!(m->brief || m->time || m->date)) m->full=1;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->part=="second" || m->part=="beat") NOCACHE(); else CACHE(60); // One minute is good enough.
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return tagtime(t, m, id, language); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string|array(string) tag_insert( string tag, mapping m, RequestID id ) { string n;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(n = m->variable) { string var=RXML.get_context()->user_get_var(n, m->scope);
39271c2000-02-23Martin Stjernholm  if(zero_type(var)) RXML.run_error(tag, "No such variable ("+n+").\n", id);
592ed72000-02-06Martin Nilsson  return m->quote=="none"?(string)var:({ html_encode_string((string)var) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(n = m->variables || m->scope) { RXML.Context context=RXML.get_context(); if(n!="variables") return ({ html_encode_string(Array.map(context->list_var(m->scope), lambda(string s) { return sprintf("%s=%O", s, context->get_var(s, m->scope) ); } ) * "\n") }); return ({ String.implode_nicely(context->list_var(m->scope)) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->file) { if(m->nocache) { int nocache=id->pragma["no-cache"]; id->pragma["no-cache"] = 1;
fb68492000-02-22Martin Nilsson  n=API_read_file(id,m->file);
39271c2000-02-23Martin Stjernholm  if(!n) RXML.run_error("No such file ("+m->file+").\n");
592ed72000-02-06Martin Nilsson  id->pragma["no-cache"] = nocache; return n; }
fb68492000-02-22Martin Nilsson  n=API_read_file(id,m->file);
39271c2000-02-23Martin Stjernholm  if(!n) RXML.run_error("No such file ("+m->file+").\n");
fb68492000-02-22Martin Nilsson  return n;
592ed72000-02-06Martin Nilsson  }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->href && query("insert_href")) { if(m->nocache) NOCACHE(); else CACHE(60); Protocols.HTTP q=Protocols.HTTP.get_url(m->href); if(q && q->status>0 && q->status<400) return ({ q->data() });
39271c2000-02-23Martin Stjernholm  RXML.run_error(q ? q->status_desc + "\n": "No server response\n");
592ed72000-02-06Martin Nilsson  }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->var) { object|array tagfunc=RXML.get_context()->tag_set->get_tag("!--#echo");
39271c2000-02-23Martin Stjernholm  if(!tagfunc) RXML.run_error("No SSI module added.\n");
592ed72000-02-06Martin Nilsson  return ({ 1, "!--#echo", m}); }
e272382000-01-23Kenneth Johansson 
39271c2000-02-23Martin Stjernholm  string ret="Could not fullfill your request.\nArguments:\n";
592ed72000-02-06Martin Nilsson  foreach(indices(m), string tmp)
39271c2000-02-23Martin Stjernholm  ret+=tmp+" : "+m[tmp]+"\n";
e272382000-01-23Kenneth Johansson 
fb68492000-02-22Martin Nilsson  RXML.parse_error(ret);
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_return(string tag, mapping m, RequestID id) { int c=(int)m->code; if(c) _error=c; string p=m->text; if(p) _rettext=p; return ""; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_set_cookie(string tag, mapping m, RequestID id) { if(!m->name)
39271c2000-02-23Martin Stjernholm  RXML.parse_error("Requires a name attribute.\n");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string cookies = m->name+"="+http_encode_cookie(m->value||""); int t; //time
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->persistent) t=(3600*(24*365*2)); else t=time_dequantifier(m);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  cookies += "; expires="+http_date(t+time(1));
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  //FIXME: Check the parameter's usability cookies += "; path=" +(m->path||"/");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  add_http_header(_extra_heads, "Set-Cookie", cookies);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ""; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_remove_cookie(string tag, mapping m, RequestID id) {
39271c2000-02-23Martin Stjernholm  if(!m->name || !id->cookies[m->name]) RXML.run_error("That cookie does not exists.\n");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  add_http_header(_extra_heads, "Set-Cookie", m->name+"="+http_encode_cookie(m->value||"")+"; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/" );
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ""; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_modified(string tag, mapping m, RequestID id, Stdio.File file) { array (int) s; Stdio.File f;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->by && !m->file && !m->realfile) { // FIXME: The auth module should probably not be used in this case. if(!id->conf->auth_module)
39271c2000-02-23Martin Stjernholm  RXML.run_error("Modified by requires a user database.\n");
592ed72000-02-06Martin Nilsson  // FIXME: The next row is defunct. last_modified_by does not exists. m->name = id->conf->last_modified_by(file, id); CACHE(10); return tag_user(tag, m, id, file); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->file) { m->realfile = id->conf->real_file(fix_relative(m->file,id), id); m_delete(m, "file"); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->by && m->realfile) { if(!id->conf->auth_module)
39271c2000-02-23Martin Stjernholm  RXML.run_error("Modified by requires a user database.\n");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(f = open(m->realfile, "r")) { m->name = id->conf->last_modified_by(f, id); destruct(f); CACHE(10); return tag_user(tag, m, id, file); } return "A. Nonymous."; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->realfile) s = file_stat(m->realfile);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!(_stat || s) && !m->realfile && id->realfile) { m->realfile = id->realfile; return tag_modified(tag, m, id, file); } CACHE(10); if(!s) s = _stat; if(!s) s = id->conf->stat_file( id->not_query, id ); if(s) { if(m->ssi) return strftime(id->misc->ssi_timefmt || "%c", s[3]); return tagtime(s[3], m, id, language); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->ssi) return id->misc->ssi_errmsg||"";
39271c2000-02-23Martin Stjernholm  RXML.run_error("Couldn't stat file.\n");
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string|array(string) tag_user(string tag, mapping m, RequestID id, Stdio.File file) {
cd1dde2000-02-17Per Hedbor  array(string) u;
592ed72000-02-06Martin Nilsson  string b, dom;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!id->conf->auth_module)
39271c2000-02-23Martin Stjernholm  RXML.run_error("Requires a user database.\n");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if (!(b=m->name)) return(tag_modified("modified", m | ([ "by":"by" ]), id, file));
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson  b=m->name;
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson  dom=id->conf->query("Domain"); if(dom[-1]=='.') dom=dom[0..strlen(dom)-2]; if(!b) return ""; u=id->conf->userinfo(b, id); if(!u) return "";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->realname && !m->email) { if(m->link && !m->nolink) return ({ "<a href=\"/~"+b+"/\">"+u[4]+"</a>" }); return ({ u[4] }); } if(m->email && !m->realname) { if(m->link && !m->nolink) return ({ sprintf("<a href=\"mailto:%s@%s@\">%s@%s</a>", b, dom, b, dom) }); return ({ b + "@" + dom }); } if(m->nolink && !m->link) return ({ sprintf("%s &lt;%s@%s&gt;", u[4], b, dom) }); return ({ sprintf("<a href=\"/~%s/\">%s</a> " "<a href=\"mailto:%s@%s\">&lt;%s@%s&gt;</a>", b, u[4], b, dom, b, dom) }); }
e272382000-01-23Kenneth Johansson 
8c96aa2000-02-24Martin Nilsson class TagSetMaxCache { inherit RXML.Tag; constant name = "set-max-cache"; constant flags = RXML.FLAG_EMPTY_ELEMENT; class Frame { inherit RXML.Frame; array do_return(RequestID id) { id->misc->cacheable = time_dequantifier(args); } }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
5b3ff22000-02-10Martin Nilsson 
592ed72000-02-06Martin Nilsson // ------------------- Containers ----------------
e272382000-01-23Kenneth Johansson 
9aee392000-02-15Martin Nilsson string container_charset( string t, mapping m, string c, RequestID id ) { if( m->in ) if( catch { c = Locale.Charset.decoder( m->in )->feed( c )->drain(); }) RXML.run_error( "Illegal charset, or unable to decode data: "+ m->in+"\n" ); if( m->out && id->set_output_charset) id->set_output_charset( m->out ); return c; }
e272382000-01-23Kenneth Johansson 
9aee392000-02-15Martin Nilsson class TagScope {
592ed72000-02-06Martin Nilsson  inherit RXML.Tag;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  constant name = "scope";
1ae52e2000-02-07Martin Stjernholm  mapping(string:RXML.Type) opt_arg_types = ([ "extend" : RXML.t_text ]);
e272382000-01-23Kenneth Johansson 
9aee392000-02-15Martin Nilsson  class Frame {
592ed72000-02-06Martin Nilsson  inherit RXML.Frame;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  constant scope_name = "form"; mapping vars; mapping oldvar;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array do_enter(RequestID id) { oldvar=id->variables; if(args->extend) vars=copy_value(id->variables); else vars=([]); id->variables=vars; return 0; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array do_return(RequestID id) { id->variables=oldvar; result=content; return 0; } } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string) container_catch( string tag, mapping m, string c, RequestID id ) { string r; if(!id->misc->catcher_is_ready) id->misc+=(["catcher_is_ready":1]); else id->misc->catcher_is_ready++; array e = catch(r=parse_rxml(c, id)); id->misc->catcher_is_ready--; if(e) return e[0]; return ({r}); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string) container_cache(string tag, mapping args, string contents, RequestID id) {
8c96aa2000-02-24Martin Nilsson #define HASH(x) (x+id->not_query+id->query+id->realauth+id->conf->query("MyWorldLocation"))
fb68492000-02-22Martin Nilsson  string key=""; if(!args->nohash) {
592ed72000-02-06Martin Nilsson #if constant(Crypto.md5)
fb68492000-02-22Martin Nilsson  contents=parse_html(contents, ([]), (["cache":container_cache]) ); object md5 = Crypto.md5(); md5->update(HASH(contents)); key=md5->digest();
592ed72000-02-06Martin Nilsson #else
fb68492000-02-22Martin Nilsson  key = (string)hash(HASH(contents));
592ed72000-02-06Martin Nilsson #endif
fb68492000-02-22Martin Nilsson  }
592ed72000-02-06Martin Nilsson  if(args->key) key += args->key; string parsed = cache_lookup("tag_cache", key); if(!parsed) { parsed = parse_rxml(contents, id);
8c96aa2000-02-24Martin Nilsson  cache_set("tag_cache", key, parsed, time_dequantifier(args));
592ed72000-02-06Martin Nilsson  } return ({parsed}); #undef HASH }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string|array(string) container_crypt( string s, mapping m, string c, RequestID id ) {
bc58122000-02-23Marcus Comstedt  if(m->compare) return crypt(c,m->compare)?"<true />":"<false />";
592ed72000-02-06Martin Nilsson  return ({ crypt(c) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_for(string t, mapping args, string c, RequestID id) { string v = args->variable; int from = (int)args->from; int to = (int)args->to; int step = (int)args->step!=0?(int)args->step:(to<from?-1:1);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if((to<from && step>0)||(to>from && step<0)) to=from+step;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string res=""; if(to<from) { if(v) for(int i=from; i>=to; i+=step)
bc58122000-02-23Marcus Comstedt  res += "<set variable="+v+" value="+i+" />"+c;
592ed72000-02-06Martin Nilsson  else for(int i=from; i>=to; i+=step) res+=c; return res; } else if(to>from) { if(v) for(int i=from; i<=to; i+=step)
bc58122000-02-23Marcus Comstedt  res += "<set variable="+v+" value="+i+" />"+c;
592ed72000-02-06Martin Nilsson  else for(int i=from; i<=to; i+=step) res+=c; return res; }
e272382000-01-23Kenneth Johansson 
bc58122000-02-23Marcus Comstedt  return "<set variable="+v+" value="+to+" />"+c;
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_foreach(string t, mapping args, string c, RequestID id) { string v = args->variable; array what; if(!args->in)
39271c2000-02-23Martin Stjernholm  RXML.parse_error("No in attribute given.\n");
592ed72000-02-06Martin Nilsson  if(args->variables) what = Array.map(args->in/"," - ({""}), lambda(string name, mapping v) { return v[name] || ""; }, id->variables); else what = Array.map(args->in / "," - ({""}), lambda(string var) { sscanf(var, "%*[ \t\n\r]%s", var); var = reverse(var); sscanf(var, "%*[ \t\n\r]%s", var); return reverse(var); });
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string res=""; foreach(what, string w) res += "<set variable="+v+" value="+w+">"+c; return res; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_apre(string tag, mapping m, string q, RequestID id) {
cd1dde2000-02-17Per Hedbor  string href, s; array(string) foo;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!(href = m->href)) href=strip_prestate(strip_config(id->raw_url)); else { if ((sizeof(foo = href / ":") > 1) && (sizeof(foo[0] / "/") == 1)) return make_container("a", m, q); href=strip_prestate(fix_relative(href, id)); m_delete(m, "href"); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!strlen(href)) href="";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  multiset prestate = (< @indices(id->prestate) >);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->add) { foreach((m->add-" ")/",", s) prestate[s]=1; m_delete(m,"add"); } if(m->drop) { foreach((m->drop-" ")/",", s) prestate[s]=0; m_delete(m,"drop"); } m->href = add_pre_state(href, prestate); return make_container("a", m, q); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string|array(string) container_aconf(string tag, mapping m, string q, RequestID id) { string href,s;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!m->href) href=strip_prestate(strip_config(id->raw_url)); else { href=m->href; if (search(href, ":") == search(href, "//")-1)
39271c2000-02-23Martin Stjernholm  RXML.parse_error("It is not possible to add configs to absolute URLs.\n");
592ed72000-02-06Martin Nilsson  href=fix_relative(href, id); m_delete(m, "href"); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  array cookies = ({}); if(m->add) { foreach((m->add-" ")/",", s) cookies+=({s}); m_delete(m,"add"); } if(m->drop) { foreach((m->drop-" ")/",", s) cookies+=({"-"+s}); m_delete(m,"drop"); }
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson  m->href = add_config(href, cookies, id->prestate); return make_container("a", m, q); }
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_maketag(string tag, mapping m, string cont, RequestID id) { mapping args=(!m->noxml&&m->type=="tag"?(["/":"/"]):([])); cont=parse_html(parse_rxml(cont,id), ([]), (["attrib": lambda(string tag, mapping m, string cont, mapping args) { args[m->name]=cont; return ""; } ]), args); if(m->type=="container") return make_container(m->name, args, cont); return make_tag(m->name, args); }
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_doc(string tag, mapping m, string s) { if(!m["quote"]) if(m["pre"]) { m_delete(m,"pre"); return "\n"+make_container("pre",m, replace(s, ({"{","}","& "}),({"&lt;","&gt;","&amp; "})))+"\n"; } else return replace(s, ({ "{", "}", "& " }), ({ "&lt;", "&gt;", "&amp; " })); else if(m["pre"]) { m_delete(m,"pre"); m_delete(m,"quote"); return "\n"+make_container("pre",m, replace(s, ({"<",">","& "}),({"&lt;","&gt;","&amp; "})))+"\n"; } else return replace(s, ({ "<", ">", "& " }), ({ "&lt;", "&gt;", "&amp; " })); }
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_autoformat(string tag, mapping m, string s, RequestID id) { s-="\r";
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string p=(m["class"]?"<p class=\""+m["class"]+"\">":"<p>");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(!m->nobr) { s = replace(s, "\n", "<br>\n"); if(m->p) { if(search(s, "<br>\n<br>\n")!=-1) s=p+s; s = replace(s, "<br>\n<br>\n", "\n</p>"+p+"\n"); if(sizeof(s)>3 && s[0..2]!="<p>" && s[0..2]!="<p ") s=p+s; if(s[..sizeof(s)-4]==p) return s[..sizeof(s)-4]; else return s+"</p>"; } return s; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->p) { if(search(s, "\n\n")!=-1) s=p+s; s = replace(s, "\n\n", "\n</p>"+p+"\n"); if(sizeof(s)>3 && s[0..2]!="<p>" && s[0..2]!="<p ") s=p+s; if(s[..sizeof(s)-4]==p) return s[..sizeof(s)-4]; else return s+"</p>"; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return s; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson class Smallcapsstr { constant UNDEF=0, BIG=1, SMALL=2; static string text="",part="",bigtag,smalltag; static mapping bigarg,smallarg; static int last=UNDEF;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  void create(string bs, string ss, mapping bm, mapping sm) { bigtag=bs; smalltag=ss; bigarg=bm; smallarg=sm; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string _sprintf() { return "Smallcapsstr()"; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  void add(string char) { part+=char; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  void add_big(string char) { if(last!=BIG) flush_part(); part+=char; last=BIG; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  void add_small(string char) { if(last!=SMALL) flush_part(); part+=char; last=SMALL; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  void write(string txt) { if(last!=UNDEF) flush_part(); part+=txt; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  void flush_part() { switch(last){ case UNDEF: default: text+=part; break; case BIG: text+=make_container(bigtag,bigarg,part); break; case SMALL: text+=make_container(smalltag,smallarg,part); break; } part=""; last=UNDEF; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string value() { if(last!=UNDEF) flush_part(); return text; } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_smallcaps(string t, mapping m, string s) { Smallcapsstr ret; string spc=m->space?"&nbsp;":""; m_delete(m, "space"); mapping bm=([]), sm=([]); if(m["class"] || m->bigclass) { bm=(["class":(m->bigclass||m["class"])]); m_delete(m, "bigclass"); } if(m["class"] || m->smallclass) { sm=(["class":(m->smallclass||m["class"])]); m_delete(m, "smallclass"); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(m->size) { bm+=(["size":m->size]); if(m->size[0]=='+' && (int)m->size>1) sm+=(["size":m->small||"+"+((int)m->size-1)]); else sm+=(["size":m->small||(string)((int)m->size-1)]); m_delete(m, "small"); ret=Smallcapsstr("font","font", m+bm, m+sm); } else ret=Smallcapsstr("big","small", m+bm, m+sm);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  for(int i=0; i<strlen(s); i++) if(s[i]=='<') { int j; for(j=i; j<strlen(s) && s[j]!='>'; j++); ret->write(s[i..j]); i+=j-1; } else if(s[i]<=32) ret->add_small(s[i..i]); else if(lower_case(s[i..i])==s[i..i]) ret->add_small(upper_case(s[i..i])+spc); else if(upper_case(s[i..i])==s[i..i]) ret->add_big(s[i..i]+spc); else ret->add(s[i..i]+spc);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ret->value(); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_random(string tag, mapping m, string s) { string|array q; if(!(q=m->separator || m->sep)) return (q=s/"\n")[random(sizeof(q))]; return (q=s/q)[random(sizeof(q))]; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string) container_formoutput(string tag_name, mapping args, string contents, RequestID id) { return ({ do_output_tag( args, ({ id->variables }), contents, id ) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string) container_gauge(string t, mapping args, string contents, RequestID id) { NOCACHE();
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  int t = gethrtime(); contents = parse_rxml( contents, id ); t = gethrtime()-t;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if(args->variable) RXML.get_context()->user_set_var(args->variable, t/1000000.0, args->scope); if(args->silent) return ({ "" }); if(args->timeonly) return ({ sprintf("%3.6f", t/1000000.0) }); if(args->resultonly) return ({contents}); return ({ "<br><font size=\"-1\"><b>Time: "+ sprintf("%3.6f", t/1000000.0)+ " seconds</b></font><br>"+contents }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // Removes empty lines array(string) container_trimlines( string tag_name, mapping args, string contents, RequestID id ) { contents = replace(parse_rxml(contents,id), ({"\r\n","\r" }), ({"\n","\n"})); return ({ (contents / "\n" - ({ "" })) * "\n" }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson void container_throw( string t, mapping m, string c, RequestID id) { if(!id->misc->catcher_is_ready && c[-1]!='\n') c+="\n"; throw( ({ c, backtrace() }) ); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // Internal methods for the default tag private int|array internal_tag_input(string t, mapping m, string name, multiset(string) value) { if (name && m->name!=name) return 0; if (m->type!="checkbox" && m->type!="radio") return 0; if (value[m->value||"on"]) { if (m->checked) return 0; m->checked = "checked"; } else { if (!m->checked) return 0; m_delete(m, "checked" ); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ({ make_tag(t, m) }); } array split_on_option( string what, Regexp r ) { array a = r->split( what ); if( !a ) return ({ what }); return split_on_option( a[0], r ) + a[1..]; } private int|array internal_tag_select(string t, mapping m, string c, string name, multiset(string) value) { if(m->name!=name) return ({ make_container(t,m,c) }); Regexp r = Regexp( "(.*)<([Oo][Pp][Tt][Ii][Oo][Nn])([^>]*)>(.*)" ); array(string) tmp=split_on_option(c,r); string ret=tmp[0],nvalue; int selected,stop; tmp=tmp[1..]; while(sizeof(tmp)>2) { stop=search(tmp[2],"<"); if(sscanf(lower_case(tmp[1]),"%*svalue=%s%*[ >]",nvalue)!=3) nvalue=tmp[2][..stop==-1?sizeof(tmp[2]):stop]; selected=Regexp(".*[Ss][Ee][Ll][Ee][Cc][Tt][Ee][Dd].*")->match(tmp[1]); ret+="<"+tmp[0]+tmp[1]; if(value[nvalue] && !selected) ret+=" selected=\"selected\""; ret+=">"+tmp[2]; if(!Regexp(".*</[Oo][Pp][Tt][Ii][Oo][Nn]")->match(tmp[2])) ret+="</"+tmp[0]+">"; tmp=tmp[3..]; } return ({ make_container(t,m,ret) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string) container_default( string t, mapping m, string c, RequestID id) { multiset value=(<>); if(m->value) value=mkmultiset((m->value||"")/(m->separator||",")); if(m->variable) value+=mkmultiset(({id->variables[m->variable]})); c = parse_rxml(c, id ); if(value==(<>)) return ({c});
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ({ parse_html(c, (["input":internal_tag_input]), (["select":internal_tag_select]), m->name, value) }); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_sort(string t, mapping m, string c, RequestID id) { if(!m->separator) m->separator = "\n";
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string pre="", post=""; array lines = c/m->separator;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  while(lines[0] == "") { pre += m->separator; lines = lines[1..]; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  while(lines[-1] == "") { post += m->separator; lines = lines[..sizeof(lines)-2]; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  lines=sort(lines);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return pre + (m->reverse?reverse(lines):lines)*m->separator + post; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson array(string)|string container_recursive_output (string tagname, mapping args, string contents, RequestID id) { int limit; array(string) inside, outside; if (id->misc->recout_limit) { limit = id->misc->recout_limit - 1; inside = id->misc->recout_outside, outside = id->misc->recout_inside; } else { limit = (int) args->limit || 100; inside = args->inside ? args->inside / (args->separator || ",") : ({}); outside = args->outside ? args->outside / (args->separator || ",") : ({}); if (sizeof (inside) != sizeof (outside))
fb68492000-02-22Martin Nilsson  RXML.parse_error("'inside' and 'outside' replacement sequences "
39271c2000-02-23Martin Stjernholm  "aren't of same length.\n");
592ed72000-02-06Martin Nilsson  }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  if (limit <= 0) return contents;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  int save_limit = id->misc->recout_limit; string save_inside = id->misc->recout_inside, save_outside = id->misc->recout_outside;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  id->misc->recout_limit = limit; id->misc->recout_inside = inside; id->misc->recout_outside = outside;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  string res = parse_rxml ( parse_html ( contents, (["recurse": lambda (string t, mapping a, string c) {return ({c});}]), ([]), "<" + tagname + ">" + replace (contents, inside, outside) + "</" + tagname + ">"), id);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  id->misc->recout_limit = save_limit; id->misc->recout_inside = save_inside; id->misc->recout_outside = save_outside;
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return ({res}); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson //I'll donate a Star Wars insiders guide to the //first one to figure out what this number means, //and how it was calculated. nilsson@idonex.se #define MAGIC_EXIT 4921325
f1c9f02000-01-26Kenneth Johansson 
592ed72000-02-06Martin Nilsson string tag_leave(string tag, mapping m, RequestID id) { if(id->misc->leave_repeat) { id->misc->leave_repeat--; throw(MAGIC_EXIT); }
39271c2000-02-23Martin Stjernholm  RXML.parse_error("Must be contained by <repeat>.\n");
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_repeat(string tag, mapping m, string c, RequestID id) { if(!id->misc->leave_repeat) id->misc->leave_repeat=0; int exit=id->misc->leave_repeat++,loop,maxloop=(int)m->maxloops||10000; string ret="",iter; while(loop<maxloop && id->misc->leave_repeat!=exit) { loop++; mixed error=catch { iter=parse_rxml(c,id); }; if((intp(error) && error!=0 && error!=MAGIC_EXIT) || !intp(error)) throw(error); if(id->misc->leave_repeat!=exit) ret+=iter; }
8c96aa2000-02-24Martin Nilsson 
592ed72000-02-06Martin Nilsson  if(loop==maxloop)
8c96aa2000-02-24Martin Nilsson  RXML.run_error("Too many iterations ("+maxloop+").");
592ed72000-02-06Martin Nilsson  return ret; }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string container_replace( string tag, mapping m, string cont, RequestID id) { switch(m->type) { case "word": default: if(!m->from) return cont; return replace(cont,m->from,(m->to?m->to:""));
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  case "words": if(!m->from) return cont; string s=m->separator?m->separator:","; array from=(array)(m->from/s); array to=(array)(m->to/s);
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  int balance=sizeof(from)-sizeof(to); if(balance>0) to+=allocate(balance,"");
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  return replace(cont,from,to); } }
e272382000-01-23Kenneth Johansson 
30d6a52000-02-16Martin Nilsson class TagCSet { inherit RXML.Tag; constant name = "cset"; class Frame { inherit RXML.Frame; array do_return(RequestID id) {
ea31c52000-02-16Martin Nilsson  if(!content) content="";
30d6a52000-02-16Martin Nilsson  if( args->quote != "none" ) content = html_decode_string( content );
39271c2000-02-23Martin Stjernholm  if( !args->variable ) parse_error("Variable not specified.\n");
30d6a52000-02-16Martin Nilsson  RXML.get_context()->user_set_var(args->variable, content, args->scope); return ({ "" }); } }
592ed72000-02-06Martin Nilsson }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // ----------------- If registration stuff --------------
e272382000-01-23Kenneth Johansson 
6d7a702000-02-07Martin Nilsson class TagIfExpr {
592ed72000-02-06Martin Nilsson  inherit RXML.Tag;
6d7a702000-02-07Martin Nilsson  constant name = "if";
592ed72000-02-06Martin Nilsson  constant plugin_name = "expr"; int `() (string u) { return (int)sexpr_eval(u); } }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // ---------------- API registration stuff ---------------
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson string api_query_modified(RequestID id, string f, int|void by) { mapping m = ([ "by":by, "file":f ]); return tag_modified("modified", m, id, id); }
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson // --------------------- Documentation -----------------------
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson TAGDOCUMENTATION; #ifdef manual constant tagdoc=(["roxen_automatic_charset_variable":#"<desc tag> Internal Roxen tag. Not yet documented. </desc>",
e272382000-01-23Kenneth Johansson 
dbab472000-02-21Kenneth Johansson "aconf":#"<desc cont><short>
592ed72000-02-06Martin Nilsson  Creates a link that can modify the persistent states in the cookie
dbab472000-02-21Kenneth Johansson  RoxenConfig.</short>
f1c9f02000-01-26Kenneth Johansson </desc>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=href value=uri> Indicates which page should be linked to, if any other than the present one. </attr>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=add value=string> The \"cookie\" or \"cookies\" that should be added, in a comma seperated list. </attr>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=drop value=string> The \"cookie\" or \"cookies\" that should be droped, in a comma seperated list.
e272382000-01-23Kenneth Johansson </attr> <attr name=class value=string>
592ed72000-02-06Martin Nilsson  This CSS class definition will apply to the a-element.
e272382000-01-23Kenneth Johansson </attr>
592ed72000-02-06Martin Nilsson  <p>All other attributes will be inherited by the generated a tag.</p>",
e272382000-01-23Kenneth Johansson 
dbab472000-02-21Kenneth Johansson "append":#"<desc tag><short>
592ed72000-02-06Martin Nilsson  Appends a value to a variable. The variable attribute and one more is
dbab472000-02-21Kenneth Johansson  required.</short>
592ed72000-02-06Martin Nilsson </desc> <attr name=variable value=string> The name of the variable.
e272382000-01-23Kenneth Johansson </attr>
592ed72000-02-06Martin Nilsson <attr name=value value=string> The value the variable should have appended.
e272382000-01-23Kenneth Johansson </attr>
592ed72000-02-06Martin Nilsson </attr name=from value=string> The name of another variable that the value should be copied from.
e272382000-01-23Kenneth Johansson </attr>",
dbab472000-02-21Kenneth Johansson "apre":#"<desc cont><short> Creates a link that can modify prestates.</short>
e272382000-01-23Kenneth Johansson </desc>
592ed72000-02-06Martin Nilsson <attr name=href value=uri> Indicates which page should be linked to, if any other than the present one.
e272382000-01-23Kenneth Johansson </attr>
592ed72000-02-06Martin Nilsson <attr name=add value=string> The prestate or prestates that should be added, in a comma seperated list. </attr>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=drop value=string> The prestate or prestates that should be droped, in a comma seperated list. </attr>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=class value=string> This CSS class definition will apply to the a-element. </attr>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson  Adds or removes a prestate option. Prestate options are simple toggles, and are added to the URL of the page. Use <tag>if</tag> prestate=...<tag>/if</tag> to test for the presence of a prestate. <tag>apre</tag> works just like the <tag>a href=...</tag> container, but if no \"href\" attribute is specified, the current page is used.",
dbab472000-02-21Kenneth Johansson "auth-required":#"<desc tag><short> Adds an HTTP auth required header and return code (401), that will force the user to supply a login name and password.</short> This tag is needed when using access control in RXML in order for the user to be prompted to login.
e272382000-01-23Kenneth Johansson </desc>
592ed72000-02-06Martin Nilsson <attr name=realm value=string> The realm you are logging on to, i.e \"Intranet foo\". </attr>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=message value=string> Returns a message if a login failed or cancelled. </attr>",
e272382000-01-23Kenneth Johansson 
dbab472000-02-21Kenneth Johansson "autoformat":#"<desc cont><short> Replaces newlines with <tag>br</tag>:s.</short>
e272382000-01-23Kenneth Johansson </desc>
592ed72000-02-06Martin Nilsson <attr name=nobr> Do not replace newlines with <tag>br</tag>:s.
e272382000-01-23Kenneth Johansson </attr>
592ed72000-02-06Martin Nilsson <attr name=p> Replace double newlines with <tag>p</tag>:s.
e272382000-01-23Kenneth Johansson </attr>
592ed72000-02-06Martin Nilsson <attr name=class value=string> This CSS definition will be applied on the p elements. </attr>",
e272382000-01-23Kenneth Johansson 
dbab472000-02-21Kenneth Johansson "cache":#"<desc cont><short>
592ed72000-02-06Martin Nilsson  This simple tag RXML parse its contents and cache them using the
dbab472000-02-21Kenneth Johansson  normal Roxen memory cache.</short> They key used to store the cached contents is the MD5 hash sum of the contents, the accessed file name, the query string, the server URL and the authentication information,
8c96aa2000-02-24Martin Nilsson  if available. This should create an unique key. The time during which the entry should be considered valid can set with one or several time attributes. If not provided the entry will be removed from the cache when it has been untouched for too long.
592ed72000-02-06Martin Nilsson </desc>
e272382000-01-23Kenneth Johansson 
592ed72000-02-06Martin Nilsson <attr name=key value=string> Append this value to the hash used to identify the contents for less risk of incorrect caching. This shouldn't really be needed.
aac7152000-02-10Martin Nilsson </attr>
8c96aa2000-02-24Martin Nilsson <attr name=nohash> The cached entry will use only the provided key as cache key. </attr> <attr name=years value=number> Add this number of years to the time this page was last loaded. </attr> <attr name=months value=number> Add this number of months to the time this page was last loaded. </attr> <attr name=weeks value=number> Add this number of weeks to the time this page was last loaded. </attr> <attr name=days value=number> Add this number of days to the time this page was last loaded. </attr> <attr name=hours value=number> Add this number of hours to the time this page was last loaded. </attr> <attr name=beats value=number> Add this number of beats to the time this page was last loaded. </attr> <attr name=minutes value=number> Add this number of minutes to the time this page was last loaded. </attr> <attr name=seconds value=number> Add this number of seconds to the time this page was last loaded.
e272382000-01-23Kenneth Johansson </attr>",
8859351999-11-25Martin Nilsson 
dbab472000-02-21Kenneth Johansson "catch":#"<desc cont><short>
592ed72000-02-06Martin Nilsson  Evaluates the RXML code, and, if nothing goes wrong, returns the
dbab472000-02-21Kenneth Johansson  parsed contents.</short> If something does go wrong, the error message is returned instead. See also <tag><ref type=tag>throw</ref></tag>.
592ed72000-02-06Martin Nilsson </desc>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "configimage":#"<desc tag><short> Returns one of the internal Roxen configuration images.</short> The src attribute is required.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=src value=string> The name of the picture to show. </attr>
b53b751999-10-09Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=border value=number> The image border when used as a link. Default is 0. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=alt value=string> The picture description. Default is the src string. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=class value=string> This CSS class definition will be applied to the image. </attr> All other attributes will be inherited by the generated img tag.",
0be6412000-01-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "configurl":#"<desc tag><short> Returns a URL to the configuration interface.</short>
592ed72000-02-06Martin Nilsson </desc>",
ecab8b2000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson "cset":#"<desc cont></desc>",
4c38862000-02-03Marcus Wellhardh 
dbab472000-02-21Kenneth Johansson "crypt":#"<desc cont><short> Encrypts the contents as a Unix style password.</short> Useful when combined with services that use such passwords. <p>Unix style passwords are one-way encrypted, to prevent the actual clear-text password from being stored anywhere. When a login attempt is made, the password supplied is also encrypted and then compared to the stored encrypted password.</p>
592ed72000-02-06Martin Nilsson </desc>",
0be6412000-01-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "date":#"<desc tag><short> Inserts the time and date.</short> Does not require attributes.
592ed72000-02-06Martin Nilsson </desc>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=unix-time value=number> Display this time instead of the current. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=years value=number> Add this number of years to the result. </attr>
ecab8b2000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=months value=number> Add this number of months to the result. </attr>
72ac6d2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=weeks value=number> Add this number of weeks to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=days value=number> Add this number of days to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=hours value=number> Add this number of hours to the result. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=beats value=number> Add this number of beats to the result. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=minutes value=number> Add this number of minutes to the result. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=seconds value=number> Add this number of seconds to the result. </attr>
ecab8b2000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=adjust value=number> Add this number of seconds to the result. </attr>
ecab8b2000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=brief> Show in brief format. </attr>
093fd32000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=time> Show only time. </attr>
093fd32000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=date> Show only date. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=type value=string,ordered,iso,discordian,stardate,number> Defines in which format the date should be displayed in. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=part value=year,month,day,wday,date,mday,hour,minute,second,yday,beat,week,seconds> Defines which part of the date should be displayed. Day and wday is the same. Date and mday is the same. Yday is the day number of the year. Seconds is unix time type. Only the types string, number and ordered applies when the part attribute is used. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=lang value=language_code> Defines in what language the a string will be presented in. </attr>
0be6412000-01-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=case value=upper,lower,capitalized> Changes the case of the output to upper, lower or capitalized. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=prec value=number> The number of decimals in the stardate. </attr>",
bcde6c1999-11-19Per Hedbor 
dbab472000-02-21Kenneth Johansson "debug":#"<desc tag><short> Helps debugging RXML-pages as well as modules.</short> When debugging mode is
592ed72000-02-06Martin Nilsson  turned on, all error messages will be displayed in the HTML code. </desc>
ecab8b2000-01-23Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=on> Turns debug mode on. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=off> Turns debug mode off. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=toggle> Toggles debug mode. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=showid value=string> Shows a part of the id object. E.g. showid=\"id->request_headers\". </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "dec":#"<desc tag><short> Subtracts 1 from a variable.</short> Attribute variable is required.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=string> The variable to be decremented. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "default":#"<desc cont><short hide> Used to set default values for form elements.</short> Makes it easier to give default values to \"<tag>select</tag>\" or
592ed72000-02-06Martin Nilsson  \"<tag>checkbox</tag>\" form elements.
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson  <p>The <tag>default</tag> container tag is placed around the form element it should give a default value.</p>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson  <p>This tag is particularly useful in combination with database tags.</p> </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=value value=string> The value to set. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=separator value=string>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=name value=string> Only affect form element with this name. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=string>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "doc":#"<desc cont><short hide> Eases code documentation by reformatting it.</short>
592ed72000-02-06Martin Nilsson  Eases documentation by replacing \"{\", \"}\" and \"&\" with \"<\", \">\" and \"&\". No attributes required. </desc>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=quote> Instead of replacing \"{\" and \"}\", \"<\" and \">\" is replaced with \"&amp;lt;\" and \"&amp;gt;\". </attr>
1c79451999-10-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=pre> The result is encapsulated within a <tag>pre</tag> container. </attr>
252ed52000-01-31Per Hedbor 
592ed72000-02-06Martin Nilsson <attr name=class value=string> This CSS definition will be applied on the pre element. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "expire-time":#"<desc tag><short> Sets cache expire time for the document.</short>
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=now> The document expires now. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=years value=number> Add this number of years to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=months value=number> Add this number of months to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=weeks value=number> Add this number of weeks to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=days value=number> Add this number of days to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=hours value=number> Add this number of hours to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=beats value=number> Add this number of beats to the result. </attr>
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=minutes value=number> Add this number of minutes to the result. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=seconds value=number> Add this number of seconds to the result. </attr> It is not possible at the time to set the date beyond year 2038, since a unix time_t is used.",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "for":#"<desc cont><short> Makes it possible to create loops in RXML.</short>
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=from value=number> Initial value of the loop variable. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=step value=number> How much to increment the variable per loop iteration. By default one. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=to value=number> How much the loop variable should be incremented to. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=name> Name of the loop variable. </attr>",
6c13ac2000-01-31Martin Nilsson 
592ed72000-02-06Martin Nilsson "foreach":#"<desc cont>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variables>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=in>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "fsize":#"<desc tag><short> Prints the size of the specified file.</short>
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=file value=string>
dbab472000-02-21Kenneth Johansson  Show size for this file.
592ed72000-02-06Martin Nilsson </attr>",
d93f831999-09-17Martin Nilsson 
dbab472000-02-21Kenneth Johansson "gauge":#"<desc cont><short>
592ed72000-02-06Martin Nilsson  Measures how much CPU time it takes to run its contents through the
dbab472000-02-21Kenneth Johansson  RXML parser.</short> Returns the number of seconds it took to parse the contents.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=define value=string> The result will be put into a variable. E.g. define=var.gauge vill put the result in a variable that can be reached with &var.gauge;. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=silent> Don't print anything. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=timeonly> Only print the time. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=resultonly> Only the result of the parsing. Useful if you want to put the time in a database or such. </attr>",
f19d001999-12-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "header":#"<desc tag><short> Adds a header to the document.</short>
592ed72000-02-06Martin Nilsson </desc>
5e63831999-10-04Johan Sundström 
592ed72000-02-06Martin Nilsson <attr name=name value=string> The name of the header. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=value value=string> The value of the header. </attr> See the Appendix for a list of HTTP headers.",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "imgs":#"<desc tag><short> Generates a image tag with proper dimensions.</short> Attribute src is required.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=src value=string> The name of the file that should be shown. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=alt value=string> Description of the image. Default is the image file name. </attr> All other attributes will be inherited by the generated img tag.",
659d4b1999-10-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "inc":#"<desc tag><short> Adds 1 to a variable.</short> Attribute variable is required.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=string> The variable to be incremented. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "insert":#"<desc tag><short> Inserts a file, variable or other object into a webpage.</short>
592ed72000-02-06Martin Nilsson  One attribute is required. </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=string> Inserts the value of that variable. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variables> Inserts a variable listing. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=file value=string> Inserts the contents of that file. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=href value=string> Inserts the contents at that URL. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=quote value=html,none> How the inserted data should be quoted. Default is \"html\", except for href and file where it's \"none\". </attr>",
659d4b1999-10-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "maketag":#"<desc cont><short hide>Makes it able to create tags.</short>
592ed72000-02-06Martin Nilsson  This tag creates tags. The contents of the container will be put into the contents of the produced container. Requires the name attribute. </desc>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=name value=string> The name of the tag. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=noxml> Tags should not be terminated with a trailing slash. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=type value=tag,container> What kind of tag should be produced. Default is tag. </attr> Inside the maketag container the container attrib is defined. It is used to add attributes to the produced tag. It has the required attribute attrib, which is the name of the attribute. The contents of the attribute container will be the attribute value. E.g.
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson  <p>&lt;maketag name=replace type=container&gt; &lt;attrib name=from&gt;A&lt;/attrib&gt; &lt;attrib name=to&gt;U&lt;/attrib&gt; MAD &lt;/maketag&gt;
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson  will result in
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson  &lt;replace from=A to=U&gt;MAD&lt;/replace&gt; &lt;/pre&gt;</p>",
659d4b1999-10-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "modified":#"<desc tag><short hide> Prints when or by whom a page was last modified.</short> Prints when or by whom a page was last modified, by default the current page.
592ed72000-02-06Martin Nilsson </desc>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=by> Print by whom the page was modified. Takes the same attributes as the <tag><ref type=tag>user</ref></tag> tag. This attribute requires a userdatabase. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=date> Print the modification date. Takes all the date attributes in the <tag><ref type=tag>date</ref></tag> tag. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=file value=path> Get information from this file rather than the current page. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=realfile value=path> Get information from this file in the computers filesystem rather than Roxen Webserver's virtual filesystem. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "random":#"<desc cont><short> Randomly chooses a message from its contents.</short>
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=separator value=string> The separator used to separate the messages, by default newline. </attr>",
50b48a2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson "recursive-output":#"<desc cont>
50b48a2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson </desc>
50b48a2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=limit value=number>
50b48a2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>
50b48a2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=inside value=string>
50b48a2000-01-25Martin Nilsson 
592ed72000-02-06Martin Nilsson </attr>
9897451999-10-10Per Hedbor 
592ed72000-02-06Martin Nilsson <attr name=outside value=string>
9897451999-10-10Per Hedbor 
592ed72000-02-06Martin Nilsson </attr>
9897451999-10-10Per Hedbor 
592ed72000-02-06Martin Nilsson <attr name=separator value=string>
9897451999-10-10Per Hedbor 
592ed72000-02-06Martin Nilsson </attr>",
d059911999-10-08Martin Nilsson 
dbab472000-02-21Kenneth Johansson "redirect":#"<desc tag><short> Redirects the user to another page.</short> Requires the to attribute.
592ed72000-02-06Martin Nilsson </desc>
d059911999-10-08Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=to value=string> Where the user should be sent to. </attr>
d059911999-10-08Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=add value=string> The prestate or prestates that should be added, in a comma seperated list. </attr>
d059911999-10-08Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=drop value=string> The prestate or prestates that should be dropped, in a comma seperated list. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=text value=string> Sends a text string to the browser, that hints from where and why the page was redirected. Not all browsers will show this string. Only special clients like Telnet uses it. </attr> Arguments prefixed with \"add\" or \"drop\" are treated as prestate toggles, which are added or removed, respectively, from the current set of prestates in the URL in the redirect header (see also <tag <ref type=tag>apre</ref></tag>). Note that this only works when the to=... URL is absolute, i.e. begins with a \"/\", otherwise these state toggles have no effect.",
d059911999-10-08Martin Nilsson 
dbab472000-02-21Kenneth Johansson "remove-cookie":#"<desc tag><short> Removes a cookie.</short>
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=name> Name of the cookie to remove. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=value value=text> Even though the cookie has been marked as expired some browsers will not remove the cookie until it is shut down. The text provided with this attribute will be the cookies intemediate value. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson Note that removing a cookie won't take effect until the next page load.",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "repeat":#"<desc cont><short> Repeats the contents until a <tag>leave</tag> tag has been found.</short> Requires no attributes.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=maxloops> The maximum number of loops. Default is 10000. </attr>",
659d4b1999-10-18Martin Nilsson 
dbab472000-02-21Kenneth Johansson "replace":#"<desc cont><short> Replaces strings in the contents with other strings.</short> Requires the from attribute.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=from value=string> String or list of strings that should be replaced. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=to value=string> String or list of strings with the replacement strings. Default is the empty string. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=separator value=string> Defines what string should seperate the strings in the from and to attributes. Default is \",\". </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=type value=word,words> Word means that a single string should be replaced. Words that from and to are lists. Default is word. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "return":#"<desc tag><short> Changes the HTTP return code for this page.</short>
592ed72000-02-06Martin Nilsson  See the Appendix for a list of HTTP return codes. </desc> <attr name=code> The return code to set. </attr>",
dbab472000-02-21Kenneth Johansson "roxen":#"<desc tag><short> Returns a nice Roxen logo.</short>
592ed72000-02-06Martin Nilsson </desc> <attr name=size value=small,medium,large> Defines the size of the image. Default is small. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=color value=blue,green,purple,brown> Defines the color of the image. Default is blue. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=alt value=string> The image description. Default is \"Powered by Roxen\". </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=border value=number> The image border. Default is 0. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=class value=string> This CSS definition will be applied on the img element. </attr> All other attributes will be inherited by the generated img tag.",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "scope":#"<desc cont><short> Creates a different variable scope.</short> Variable changes inside the scope
592ed72000-02-06Martin Nilsson  container will not affect variables in the rest of the page. Variables set outside the scope is not available inside the scope unless the extend attribute is used. No attributes are required. </desc>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=extend> If set, all variables will be copied into the scope. </attr>",
d93f831999-09-17Martin Nilsson 
dbab472000-02-21Kenneth Johansson "set":#"<desc tag><short> Sets a variable.</short> The variable attribute is required.
592ed72000-02-06Martin Nilsson </desc>
8859351999-11-25Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=string> The name of the variable. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=value value=string> The value the variable should have. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=expr value=string> An expression whose evaluated value the variable should have. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=from value=string> The name of another variable that the value should be copied from. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=other value=string> The name of a id->misc->variables that the value should be copied from. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=eval value=string> An RXML expression whose evaluated value the variable should have. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson  If none of the above attributes are specified, the variable is unset. If debug is currently on, more specific debug information is provided if the operation failed. See also: <tag><ref type=tag>append</ref></tag> and <tag><ref type=tag>debug</ref></tag>",
d93f831999-09-17Martin Nilsson 
dbab472000-02-21Kenneth Johansson "set-cookie":#"<desc tag><short> Sets a cookie that will be stored by the user's browser.</short> This is a simple and effective way of storing data that is local to the user. The cookie will be persistent, the next time the user visits the site, she will bring the cookie with her.
592ed72000-02-06Martin Nilsson </desc>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=name value=string> The name of the cookie. </attr>
d93f831999-09-17Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=seconds value=number> Add this number of seconds to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=minutes value=number> Add this number of minutes to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=hours value=number> Add this number of hours to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=days value=number> Add this number of days to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=weeks value=number> Add this number of weeks to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=months value=number> Add this number of months to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=years value=number> Add this number of years to the time the cookie is kept. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=persistent> Keep the cookie for two years. </attr>
9897451999-10-10Per Hedbor 
592ed72000-02-06Martin Nilsson <attr name=value value=string> The value the cookie will be set to. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=path value=string> Adds a cookie named \"name\" with the value \"value\". </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson  If persistent is specified; the cookie will be persistent until year 2038, otherwise, the specified delays are used, just as for <tag><ref type=tag>expire-time</ref></tag>.
f5132b1999-11-17Martin Nilsson 
592ed72000-02-06Martin Nilsson  Note that the change of a cookie will not take effect until the next page load.",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "set-max-cache":#"<desc tag><short> Sets the maximum time this document can be cached in any ram caches.</short>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson  <p>Default is to get this time from the other tags in the document (as an example, <tag>if supports=...</tag> sets the time to 0 seconds since the result of the test depends on the client used.</p>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson  <p>You must do this at the end of the document, since many of the normal tags will override this value.</p> </desc>
4817401999-08-13Martin Nilsson 
8c96aa2000-02-24Martin Nilsson <attr name=years value=number> Add this number of years to the time this page was last loaded. </attr> <attr name=months value=number> Add this number of months to the time this page was last loaded. </attr> <attr name=weeks value=number> Add this number of weeks to the time this page was last loaded. </attr> <attr name=days value=number> Add this number of days to the time this page was last loaded. </attr> <attr name=hours value=number> Add this number of hours to the time this page was last loaded. </attr> <attr name=beats value=number> Add this number of beats to the time this page was last loaded. </attr> <attr name=minutes value=number> Add this number of minutes to the time this page was last loaded. </attr> <attr name=seconds value=number>
592ed72000-02-06Martin Nilsson  Add this number of seconds to the time this page was last loaded. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "smallcaps":#"<desc cont><short> Prints the contents in smallcaps.</short> If the size attribute is
592ed72000-02-06Martin Nilsson  given, font tags will be used, otherwise big and small tags will be used. </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=space> Put a space between every character. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=class value=string> Apply this CSS style on all elements. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=smallclass value=string> Apply this CSS style on all small elements. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=bigclass value=string> Apply this CSS style on all big elements. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=size value=number> Use font tags, and this number as big size. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=small value=number> Size of the small tags. Only applies when size is specified. Default is size-1. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "sort":#"<desc cont><short> Sorts the contents.</short> No attributes required.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=separator value=string> Defines what the strings to be sorted are separated with. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=reverse> Reversed order sort. </attr>",
bd2e111999-10-20Martin Nilsson 
dbab472000-02-21Kenneth Johansson "throw":#"<desc cont><short hide> Throws a text to be catched by <tag>catch</tag>.</short>
592ed72000-02-06Martin Nilsson  Throws an exception, with the enclosed text as the error message. This tag has a close relation to <tag>catch</tag>. The RXML parsing will stop at the <tag>throw</tag> tag. </desc>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "trimlines":#"<desc cont><short> Removes all empty lines from the contents.</short>
592ed72000-02-06Martin Nilsson </desc>",
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson "unset":#"
dbab472000-02-21Kenneth Johansson <desc tag><short> Unsets a variable, i.e. removes it.</short> The variable attribute is required.
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=variable value=string> The name of the variable. </attr>",
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson "user":#"<desc tag><short> Prints information about the specified user.</short> By default, the full name of the user and her e-mail address will be printed, with a
592ed72000-02-06Martin Nilsson  mailto link and link to the home page of that user.
4817401999-08-13Martin Nilsson 
dbab472000-02-21Kenneth Johansson  <p>The <tag>user</tag> tag requires an authentication module to work.</p>
592ed72000-02-06Martin Nilsson </desc>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=email> Only print the e-mail address of the user, with no link. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=link> Include links. Only meaningful together with the realname or email attribute. </attr>
4817401999-08-13Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=name> The login name of the user. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=nolink> Don't include the links. </attr>
659d4b1999-10-18Martin Nilsson 
592ed72000-02-06Martin Nilsson <attr name=realname> Only print the full name of the user, with no link. </attr>", ]); #endif