#include <u.h>#include <libc.h>#include <draw.h>#include <ctype.h>#include <html.h>#include "impl.h" typedef struct TokenSource TokenSource;struct TokenSource{ int i; // index of next byte to use uchar* data; // all the data int edata; // data[0:edata] is valid int chset; // one of US_Ascii, etc. int mtype; // TextHtml or TextPlain}; enum { EOF = -2, EOB = -1}; #define ISNAMCHAR(c) ((c)<256 && (isalpha(c) || isdigit(c) || (c) == '-' || (c) == '.')) #define SMALLBUFSIZE 240#define BIGBUFSIZE 2000 // HTML 4.0 tag names.// Keep sorted, and in correspondence with enum in iparse.h.Rune* tagnames[] = { L" ", L"!", L"a", L"abbr", L"acronym", L"address", L"applet", L"area", L"b", L"base", L"basefont", L"bdo", L"big", L"blink", L"blockquote", L"body", L"bq", L"br", L"button", L"caption", L"center", L"cite", L"code", L"col", L"colgroup", L"dd", L"del", L"dfn", L"dir", L"div", L"dl", L"dt", L"em", L"fieldset", L"font", L"form", L"frame", L"frameset", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"head", L"hr", L"html", L"i", L"iframe", L"img", L"input", L"ins", L"isindex", L"kbd", L"label", L"legend", L"li", L"link", L"map", L"menu", L"meta", L"nobr", L"noframes", L"noscript", L"object", L"ol", L"optgroup", L"option", L"p", L"param", L"pre", L"q", L"s", L"samp", L"script", L"select", L"small", L"span", L"strike", L"strong", L"style", L"sub", L"sup", L"table", L"tbody", L"td", L"textarea", L"tfoot", L"th", L"thead", L"title", L"tr", L"tt", L"u", L"ul", L"var"}; // HTML 4.0 attribute names.// Keep sorted, and in correspondence with enum in i.h.Rune* attrnames[] = { L"abbr", L"accept-charset", L"access-key", L"action", L"align", L"alink", L"alt", L"archive", L"axis", L"background", L"bgcolor", L"border", L"cellpadding", L"cellspacing", L"char", L"charoff", L"charset", L"checked", L"cite", L"class", L"classid", L"clear", L"code", L"codebase", L"codetype", L"color", L"cols", L"colspan", L"compact", L"content", L"coords", L"data", L"datetime", L"declare", L"defer", L"dir", L"disabled", L"enctype", L"face", L"for", L"frame", L"frameborder", L"headers", L"height", L"href", L"hreflang", L"hspace", L"http-equiv", L"id", L"ismap", L"label", L"lang", L"link", L"longdesc", L"marginheight", L"marginwidth", L"maxlength", L"media", L"method", L"multiple", L"name", L"nohref", L"noresize", L"noshade", L"nowrap", L"object", L"onblur", L"onchange", L"onclick", L"ondblclick", L"onfocus", L"onkeypress", L"onkeyup", L"onload", L"onmousedown", L"onmousemove", L"onmouseout", L"onmouseover", L"onmouseup", L"onreset", L"onselect", L"onsubmit", L"onunload", L"profile", L"prompt", L"readonly", L"rel", L"rev", L"rows", L"rowspan", L"rules", L"scheme", L"scope", L"scrolling", L"selected", L"shape", L"size", L"span", L"src", L"standby", L"start", L"style", L"summary", L"tabindex", L"target", L"text", L"title", L"type", L"usemap", L"valign", L"value", L"valuetype", L"version", L"vlink", L"vspace", L"width"}; // Character entity to unicode character number map.// Keep sorted by name.StringInt chartab[142]= { {L"AElig", 198}, {L"Aacute", 193}, {L"Acirc", 194}, {L"Agrave", 192}, {L"Aring", 197}, {L"Atilde", 195}, {L"Auml", 196}, {L"Ccedil", 199}, {L"ETH", 208}, {L"Eacute", 201}, {L"Ecirc", 202}, {L"Egrave", 200}, {L"Euml", 203}, {L"Iacute", 205}, {L"Icirc", 206}, {L"Igrave", 204}, {L"Iuml", 207}, {L"Ntilde", 209}, {L"Oacute", 211}, {L"Ocirc", 212}, {L"Ograve", 210}, {L"Oslash", 216}, {L"Otilde", 213}, {L"Ouml", 214}, {L"THORN", 222}, {L"Uacute", 218}, {L"Ucirc", 219}, {L"Ugrave", 217}, {L"Uuml", 220}, {L"Yacute", 221}, {L"aacute", 225}, {L"acirc", 226}, {L"acute", 180}, {L"aelig", 230}, {L"agrave", 224}, {L"alpha", 945}, {L"amp", 38}, {L"aring", 229}, {L"atilde", 227}, {L"auml", 228}, {L"beta", 946}, {L"brvbar", 166}, {L"ccedil", 231}, {L"cdots", 8943}, {L"cedil", 184}, {L"cent", 162}, {L"chi", 967}, {L"copy", 169}, {L"curren", 164}, {L"ddots", 8945}, {L"deg", 176}, {L"delta", 948}, {L"divide", 247}, {L"eacute", 233}, {L"ecirc", 234}, {L"egrave", 232}, {L"emdash", 8212}, {L"emsp", 8195}, {L"endash", 8211}, {L"ensp", 8194}, {L"epsilon", 949}, {L"eta", 951}, {L"eth", 240}, {L"euml", 235}, {L"frac12", 189}, {L"frac14", 188}, {L"frac34", 190}, {L"gamma", 947}, {L"gt", 62}, {L"iacute", 237}, {L"icirc", 238}, {L"iexcl", 161}, {L"igrave", 236}, {L"iota", 953}, {L"iquest", 191}, {L"iuml", 239}, {L"kappa", 954}, {L"lambda", 955}, {L"laquo", 171}, {L"ldots", 8230}, {L"lt", 60}, {L"macr", 175}, {L"micro", 181}, {L"middot", 183}, {L"mu", 956}, {L"nbsp", 160}, {L"not", 172}, {L"ntilde", 241}, {L"nu", 957}, {L"oacute", 243}, {L"ocirc", 244}, {L"ograve", 242}, {L"omega", 969}, {L"omicron", 959}, {L"ordf", 170}, {L"ordm", 186}, {L"oslash", 248}, {L"otilde", 245}, {L"ouml", 246}, {L"para", 182}, {L"phi", 966}, {L"pi", 960}, {L"plusmn", 177}, {L"pound", 163}, {L"psi", 968}, {L"quad", 8193}, {L"quot", 34}, {L"raquo", 187}, {L"reg", 174}, {L"rho", 961}, {L"sect", 167}, {L"shy", 173}, {L"sigma", 963}, {L"sp", 8194}, {L"sup1", 185}, {L"sup2", 178}, {L"sup3", 179}, {L"szlig", 223}, {L"tau", 964}, {L"theta", 952}, {L"thinsp", 8201}, {L"thorn", 254}, {L"times", 215}, {L"trade", 8482}, {L"uacute", 250}, {L"ucirc", 251}, {L"ugrave", 249}, {L"uml", 168}, {L"upsilon", 965}, {L"uuml", 252}, {L"varepsilon", 8712}, {L"varphi", 981}, {L"varpi", 982}, {L"varrho", 1009}, {L"vdots", 8942}, {L"vsigma", 962}, {L"vtheta", 977}, {L"xi", 958}, {L"yacute", 253}, {L"yen", 165}, {L"yuml", 255}, {L"zeta", 950}};#define NCHARTAB (sizeof(chartab)/sizeof(chartab[0])) // Characters Winstart..Winend are those that Windows// uses interpolated into the Latin1 set.// They aren't supposed to appear in HTML, but they do....enum { Winstart = 127, Winend = 159}; static int winchars[]= { 8226, // 8226 is a bullet 8226, 8226, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 8226, 8226, 8226, 8226, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 8226, 8226, 376}; static StringInt* tagtable; // initialized from tagnamesstatic StringInt* attrtable; // initialized from attrnames static void lexinit();static int getplaindata(TokenSource* ts, Token* a, int* pai);static int getdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai);static int getscriptdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai);static int gettag(TokenSource* ts, int starti, Token* a, int* pai);static Rune* buftostr(Rune* s, Rune* buf, int j);static int comment(TokenSource* ts);static int findstr(TokenSource* ts, Rune* s);static int ampersand(TokenSource* ts);static int lowerc(int c);static int getchar(TokenSource* ts);static void ungetchar(TokenSource* ts, int c);static void backup(TokenSource* ts, int savei);static void freeinsidetoken(Token* t);static void freeattrs(Attr* ahead);static Attr* newattr(int attid, Rune* value, Attr* link);static int Tconv(Fmt* f); int dbglex = 0;static int lexinited = 0; static voidlexinit(void){ tagtable = _makestrinttab(tagnames, Numtags); attrtable = _makestrinttab(attrnames, Numattrs); fmtinstall('T', Tconv); lexinited = 1;} static TokenSource*newtokensource(uchar* data, int edata, int chset, int mtype){ TokenSource* ans; assert(chset == US_Ascii || chset == ISO_8859_1 || chset == UTF_8 || chset == Unicode); ans = (TokenSource*)emalloc(sizeof(TokenSource)); ans->i = 0; ans->data = data; ans->edata = edata; ans->chset = chset; ans->mtype = mtype; return ans;} enum { ToksChunk = 500}; // Call this to get the tokens.// The number of returned tokens is returned in *plen.Token*_gettoks(uchar* data, int datalen, int chset, int mtype, int* plen){ TokenSource* ts; Token* a; int alen; int ai; int starti; int c; int tag; if(!lexinited) lexinit(); ts = newtokensource(data, datalen, chset, mtype); alen = ToksChunk; a = (Token*)emalloc(alen * sizeof(Token)); ai = 0; if(dbglex) fprint(2, "_gettoks starts, ts.i=%d, ts.edata=%d\n", ts->i, ts->edata); if(ts->mtype == TextHtml) { for(;;) { if(ai == alen) { a = (Token*)erealloc(a, (alen+ToksChunk)*sizeof(Token)); alen += ToksChunk; } starti = ts->i; c = getchar(ts); if(c < 0) break; if(c == '<') { tag = gettag(ts, starti, a, &ai); if(tag == Tscript) { // special rules for getting Data after....Lines 1–500 of 1378. Load more
#include <u.h> #include <libc.h> #include <draw.h> #include <ctype.h> #include <html.h> #include "impl.h" typedef struct TokenSource TokenSource; struct TokenSource { int i; // index of next byte to use uchar* data; // all the data int edata; // data[0:edata] is valid int chset; // one of US_Ascii, etc. int mtype; // TextHtml or TextPlain }; enum { EOF = -2, EOB = -1 }; #define ISNAMCHAR(c) ((c)<256 && (isalpha(c) || isdigit(c) || (c) == '-' || (c) == '.')) #define SMALLBUFSIZE 240 #define BIGBUFSIZE 2000 // HTML 4.0 tag names. // Keep sorted, and in correspondence with enum in iparse.h. Rune* tagnames[] = { L" ", L"!", L"a", L"abbr", L"acronym", L"address", L"applet", L"area", L"b", L"base", L"basefont", L"bdo", L"big", L"blink", L"blockquote", L"body", L"bq", L"br", L"button", L"caption", L"center", L"cite", L"code", L"col", L"colgroup", L"dd", L"del", L"dfn", L"dir", L"div", L"dl", L"dt", L"em", L"fieldset", L"font", L"form", L"frame", L"frameset", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"head", L"hr", L"html", L"i", L"iframe", L"img", L"input", L"ins", L"isindex", L"kbd", L"label", L"legend", L"li", L"link", L"map", L"menu", L"meta", L"nobr", L"noframes", L"noscript", L"object", L"ol", L"optgroup", L"option", L"p", L"param", L"pre", L"q", L"s", L"samp", L"script", L"select", L"small", L"span", L"strike", L"strong", L"style", L"sub", L"sup", L"table", L"tbody", L"td", L"textarea", L"tfoot", L"th", L"thead", L"title", L"tr", L"tt", L"u", L"ul", L"var" }; // HTML 4.0 attribute names. // Keep sorted, and in correspondence with enum in i.h. Rune* attrnames[] = { L"abbr", L"accept-charset", L"access-key", L"action", L"align", L"alink", L"alt", L"archive", L"axis", L"background", L"bgcolor", L"border", L"cellpadding", L"cellspacing", L"char", L"charoff", L"charset", L"checked", L"cite", L"class", L"classid", L"clear", L"code", L"codebase", L"codetype", L"color", L"cols", L"colspan", L"compact", L"content", L"coords", L"data", L"datetime", L"declare", L"defer", L"dir", L"disabled", L"enctype", L"face", L"for", L"frame", L"frameborder", L"headers", L"height", L"href", L"hreflang", L"hspace", L"http-equiv", L"id", L"ismap", L"label", L"lang", L"link", L"longdesc", L"marginheight", L"marginwidth", L"maxlength", L"media", L"method", L"multiple", L"name", L"nohref", L"noresize", L"noshade", L"nowrap", L"object", L"onblur", L"onchange", L"onclick", L"ondblclick", L"onfocus", L"onkeypress", L"onkeyup", L"onload", L"onmousedown", L"onmousemove", L"onmouseout", L"onmouseover", L"onmouseup", L"onreset", L"onselect", L"onsubmit", L"onunload", L"profile", L"prompt", L"readonly", L"rel", L"rev", L"rows", L"rowspan", L"rules", L"scheme", L"scope", L"scrolling", L"selected", L"shape", L"size", L"span", L"src", L"standby", L"start", L"style", L"summary", L"tabindex", L"target", L"text", L"title", L"type", L"usemap", L"valign", L"value", L"valuetype", L"version", L"vlink", L"vspace", L"width" }; // Character entity to unicode character number map. // Keep sorted by name. StringInt chartab[142]= { {L"AElig", 198}, {L"Aacute", 193}, {L"Acirc", 194}, {L"Agrave", 192}, {L"Aring", 197}, {L"Atilde", 195}, {L"Auml", 196}, {L"Ccedil", 199}, {L"ETH", 208}, {L"Eacute", 201}, {L"Ecirc", 202}, {L"Egrave", 200}, {L"Euml", 203}, {L"Iacute", 205}, {L"Icirc", 206}, {L"Igrave", 204}, {L"Iuml", 207}, {L"Ntilde", 209}, {L"Oacute", 211}, {L"Ocirc", 212}, {L"Ograve", 210}, {L"Oslash", 216}, {L"Otilde", 213}, {L"Ouml", 214}, {L"THORN", 222}, {L"Uacute", 218}, {L"Ucirc", 219}, {L"Ugrave", 217}, {L"Uuml", 220}, {L"Yacute", 221}, {L"aacute", 225}, {L"acirc", 226}, {L"acute", 180}, {L"aelig", 230}, {L"agrave", 224}, {L"alpha", 945}, {L"amp", 38}, {L"aring", 229}, {L"atilde", 227}, {L"auml", 228}, {L"beta", 946}, {L"brvbar", 166}, {L"ccedil", 231}, {L"cdots", 8943}, {L"cedil", 184}, {L"cent", 162}, {L"chi", 967}, {L"copy", 169}, {L"curren", 164}, {L"ddots", 8945}, {L"deg", 176}, {L"delta", 948}, {L"divide", 247}, {L"eacute", 233}, {L"ecirc", 234}, {L"egrave", 232}, {L"emdash", 8212}, {L"emsp", 8195}, {L"endash", 8211}, {L"ensp", 8194}, {L"epsilon", 949}, {L"eta", 951}, {L"eth", 240}, {L"euml", 235}, {L"frac12", 189}, {L"frac14", 188}, {L"frac34", 190}, {L"gamma", 947}, {L"gt", 62}, {L"iacute", 237}, {L"icirc", 238}, {L"iexcl", 161}, {L"igrave", 236}, {L"iota", 953}, {L"iquest", 191}, {L"iuml", 239}, {L"kappa", 954}, {L"lambda", 955}, {L"laquo", 171}, {L"ldots", 8230}, {L"lt", 60}, {L"macr", 175}, {L"micro", 181}, {L"middot", 183}, {L"mu", 956}, {L"nbsp", 160}, {L"not", 172}, {L"ntilde", 241}, {L"nu", 957}, {L"oacute", 243}, {L"ocirc", 244}, {L"ograve", 242}, {L"omega", 969}, {L"omicron", 959}, {L"ordf", 170}, {L"ordm", 186}, {L"oslash", 248}, {L"otilde", 245}, {L"ouml", 246}, {L"para", 182}, {L"phi", 966}, {L"pi", 960}, {L"plusmn", 177}, {L"pound", 163}, {L"psi", 968}, {L"quad", 8193}, {L"quot", 34}, {L"raquo", 187}, {L"reg", 174}, {L"rho", 961}, {L"sect", 167}, {L"shy", 173}, {L"sigma", 963}, {L"sp", 8194}, {L"sup1", 185}, {L"sup2", 178}, {L"sup3", 179}, {L"szlig", 223}, {L"tau", 964}, {L"theta", 952}, {L"thinsp", 8201}, {L"thorn", 254}, {L"times", 215}, {L"trade", 8482}, {L"uacute", 250}, {L"ucirc", 251}, {L"ugrave", 249}, {L"uml", 168}, {L"upsilon", 965}, {L"uuml", 252}, {L"varepsilon", 8712}, {L"varphi", 981}, {L"varpi", 982}, {L"varrho", 1009}, {L"vdots", 8942}, {L"vsigma", 962}, {L"vtheta", 977}, {L"xi", 958}, {L"yacute", 253}, {L"yen", 165}, {L"yuml", 255}, {L"zeta", 950} }; #define NCHARTAB (sizeof(chartab)/sizeof(chartab[0])) // Characters Winstart..Winend are those that Windows // uses interpolated into the Latin1 set. // They aren't supposed to appear in HTML, but they do.... enum { Winstart = 127, Winend = 159 }; static int winchars[]= { 8226, // 8226 is a bullet 8226, 8226, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 8226, 8226, 8226, 8226, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 8226, 8226, 376}; static StringInt* tagtable; // initialized from tagnames static StringInt* attrtable; // initialized from attrnames static void lexinit(); static int getplaindata(TokenSource* ts, Token* a, int* pai); static int getdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai); static int getscriptdata(TokenSource* ts, int firstc, int starti, Token* a, int* pai); static int gettag(TokenSource* ts, int starti, Token* a, int* pai); static Rune* buftostr(Rune* s, Rune* buf, int j); static int comment(TokenSource* ts); static int findstr(TokenSource* ts, Rune* s); static int ampersand(TokenSource* ts); static int lowerc(int c); static int getchar(TokenSource* ts); static void ungetchar(TokenSource* ts, int c); static void backup(TokenSource* ts, int savei); static void freeinsidetoken(Token* t); static void freeattrs(Attr* ahead); static Attr* newattr(int attid, Rune* value, Attr* link); static int Tconv(Fmt* f); int dbglex = 0; static int lexinited = 0; static void lexinit(void) { tagtable = _makestrinttab(tagnames, Numtags); attrtable = _makestrinttab(attrnames, Numattrs); fmtinstall('T', Tconv); lexinited = 1; } static TokenSource* newtokensource(uchar* data, int edata, int chset, int mtype) { TokenSource* ans; assert(chset == US_Ascii || chset == ISO_8859_1 || chset == UTF_8 || chset == Unicode); ans = (TokenSource*)emalloc(sizeof(TokenSource)); ans->i = 0; ans->data = data; ans->edata = edata; ans->chset = chset; ans->mtype = mtype; return ans; } enum { ToksChunk = 500 }; // Call this to get the tokens. // The number of returned tokens is returned in *plen. Token* _gettoks(uchar* data, int datalen, int chset, int mtype, int* plen) { TokenSource* ts; Token* a; int alen; int ai; int starti; int c; int tag; if(!lexinited) lexinit(); ts = newtokensource(data, datalen, chset, mtype); alen = ToksChunk; a = (Token*)emalloc(alen * sizeof(Token)); ai = 0; if(dbglex) fprint(2, "_gettoks starts, ts.i=%d, ts.edata=%d\n", ts->i, ts->edata); if(ts->mtype == TextHtml) { for(;;) { if(ai == alen) { a = (Token*)erealloc(a, (alen+ToksChunk)*sizeof(Token)); alen += ToksChunk; } starti = ts->i; c = getchar(ts); if(c < 0) break; if(c == '<') { tag = gettag(ts, starti, a, &ai); if(tag == Tscript) { // special rules for getting Data after....