TagAttributes GetAttributes () { int token; TagAttributes attributes; string id; bool wellFormedForServer = true; attributes = new TagAttributes (); while ((token = tokenizer.get_token ()) != Token.EOF){ if (token == '<' && Eat ('%')) { tokenizer.Verbatim = true; attributes.Add ("", "<%" + GetVerbatim (tokenizer.get_token (), "%>") + "%>"); tokenizer.Verbatim = false; tokenizer.InTag = true; continue; } if (token != Token.IDENTIFIER) break; id = tokenizer.Value; if (Eat ('=')){ if (Eat (Token.ATTVALUE)){ attributes.Add (id, tokenizer.Value); wellFormedForServer &= tokenizer.AlternatingQuotes; } else if (Eat ('<') && Eat ('%')) { tokenizer.Verbatim = true; attributes.Add (id, "<%" + GetVerbatim (tokenizer.get_token (), "%>") + "%>"); tokenizer.Verbatim = false; tokenizer.InTag = true; } else { OnError ("expected ATTVALUE"); return null; } } else { attributes.Add (id, null); } } tokenizer.put_back (); if (attributes.IsRunAtServer () && !wellFormedForServer) { OnError ("The server tag is not well formed."); return null; } return attributes; }
void GetTag (out TagType tagtype, out string id, out TagAttributes attributes) { int token = tokenizer.get_token (); tagtype = TagType.ServerComment; id = null; attributes = null; switch (token){ case '%': GetServerTag (out tagtype, out id, out attributes); break; case '/': if (!Eat (Token.IDENTIFIER)) OnError ("expecting TAGNAME"); id = tokenizer.Value; if (!Eat ('>')) OnError ("expecting '>'. Got '" + id + "'"); tagtype = TagType.Close; break; case '!': bool double_dash = Eat (Token.DOUBLEDASH); if (double_dash) tokenizer.put_back (); tokenizer.Verbatim = true; string end = double_dash ? "-->" : ">"; string comment = GetVerbatim (tokenizer.get_token (), end); tokenizer.Verbatim = false; if (comment == null) OnError ("Unfinished HTML comment/DTD"); string pathType, filename; if (double_dash && GetInclude (comment, out pathType, out filename)) { tagtype = TagType.Include; attributes = new TagAttributes (); attributes.Add (pathType, filename); } else { tagtype = TagType.Text; id = "<!" + comment + end; } break; case Token.IDENTIFIER: if (this.filename == "@@inner_string@@") { // Actually not tag but "xxx < yyy" stuff in inner_string! tagtype = TagType.Text; tokenizer.InTag = false; id = "<" + tokenizer.Odds + tokenizer.Value; } else { id = tokenizer.Value; try { attributes = GetAttributes (); } catch (Exception e) { OnError (e.Message); break; } tagtype = TagType.Tag; if (Eat ('/') && Eat ('>')) { tagtype = TagType.SelfClosing; } else if (!Eat ('>')) { if (attributes.IsRunAtServer ()) { OnError ("The server tag is not well formed."); break; } tokenizer.Verbatim = true; attributes.Add ("", GetVerbatim (tokenizer.get_token (), ">") + ">"); tokenizer.Verbatim = false; } } break; default: tagtype = TagType.Text; tokenizer.InTag = false; id = "<" + tokenizer.Value; break; } }