diff options
author | Sebastian Geerken <devnull@localhost> | 2014-07-18 15:58:48 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2014-07-18 15:58:48 +0200 |
commit | 9d9b0c76a3b04a8ea5971e9d9cc8c9cd790b8b49 (patch) | |
tree | 5a92fe13eca24a03189ce8c8a79dc1d26b89336d /src | |
parent | 441370fa67c40a47916b7a44d4fa1d18feadb6dd (diff) | |
parent | 531843c893ae53a61d7278630a5061a63a251ded (diff) |
Merge with main repo.
Diffstat (limited to 'src')
-rw-r--r-- | src/IO/IO.c | 4 | ||||
-rw-r--r-- | src/IO/http.c | 142 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/cache.c | 129 | ||||
-rw-r--r-- | src/cache.h | 3 | ||||
-rw-r--r-- | src/capi.c | 10 | ||||
-rw-r--r-- | src/decode.c | 24 | ||||
-rw-r--r-- | src/decode.h | 16 | ||||
-rw-r--r-- | src/html.cc | 405 | ||||
-rw-r--r-- | src/html_charrefs.h | 2138 | ||||
-rw-r--r-- | src/prefs.c | 1 | ||||
-rw-r--r-- | src/prefs.h | 1 | ||||
-rw-r--r-- | src/prefsparser.cc | 1 | ||||
-rw-r--r-- | src/styleengine.cc | 6 | ||||
-rw-r--r-- | src/styleengine.hh | 1 |
15 files changed, 2590 insertions, 292 deletions
diff --git a/src/IO/IO.c b/src/IO/IO.c index a0a8bba5..43a3ff3a 100644 --- a/src/IO/IO.c +++ b/src/IO/IO.c @@ -350,6 +350,7 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info, switch (Op) { case OpStart: io = IO_new(IOWrite); + io->Info = Info; Info->LocalKey = io; break; case OpSend: @@ -406,9 +407,10 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info, IO_submit(io); } break; + case OpEnd: case OpAbort: io = Info->LocalKey; - IO_close_fd(io, IO_StopRdWr); + IO_close_fd(io, Op == OpEnd ? IO_StopRd : IO_StopRdWr); IO_free(io); dFree(Info); break; diff --git a/src/IO/http.c b/src/IO/http.c index a0021a9e..1be94e0d 100644 --- a/src/IO/http.c +++ b/src/IO/http.c @@ -79,16 +79,18 @@ typedef struct { typedef struct { char *host; - int active_connections; - SocketQueue_t queue; + Dlist *active_fds; + int avail_fd; + SocketQueue_t main_q, image_q; /* imgs have separate lower-priority queue */ } HostConnection_t; static void Http_socket_queue_init(SocketQueue_t *sq); -static void Http_socket_enqueue(SocketQueue_t *sq, SocketData_t* sock); -static SocketData_t* Http_socket_dequeue(SocketQueue_t *sq); +static void Http_socket_enqueue(HostConnection_t *hc, SocketData_t* sock); +static SocketData_t* Http_socket_dequeue(HostConnection_t *hc); static HostConnection_t *Http_host_connection_get(const char *host); static void Http_host_connection_remove(HostConnection_t *hc); static int Http_connect_socket(ChainLink *Info); +static void Http_send_query(ChainLink *Info, SocketData_t *S); static void Http_socket_free(int SKey); /* @@ -160,9 +162,10 @@ static int Http_sock_new(void) static void Http_connect_queued_sockets(HostConnection_t *hc) { + bool_t all_is_well = TRUE; SocketData_t *sd; - while (hc->active_connections < prefs.http_max_conns && - (sd = Http_socket_dequeue(&hc->queue))) { + while (dList_length(hc->active_fds) < prefs.http_max_conns && + (sd = Http_socket_dequeue(hc))) { sd->flags &= ~HTTP_SOCKET_QUEUED; @@ -170,18 +173,30 @@ static void Http_connect_queued_sockets(HostConnection_t *hc) dFree(sd); } else if (a_Web_valid(sd->web)) { /* start connecting the socket */ - if (Http_connect_socket(sd->Info) < 0) { + if (hc->avail_fd != -1) { + sd->SockFD = hc->avail_fd; + hc->avail_fd = -1; + } else if (Http_connect_socket(sd->Info) < 0) { ChainLink *Info = sd->Info; + all_is_well = FALSE; MSG_BW(sd->web, 1, "ERROR: %s", dStrerror(sd->Err)); a_Chain_bfcb(OpAbort, Info, NULL, "Both"); Http_socket_free(VOIDP2INT(Info->LocalKey)); /* free sd */ dFree(Info); - } else { + } + if (all_is_well) { + a_Chain_bcb(OpSend, sd->Info, &sd->SockFD, "FD"); + a_Chain_fcb(OpSend, sd->Info, &sd->SockFD, "FD"); + Http_send_query(sd->Info, sd); sd->connected_to = hc->host; - hc->active_connections++; + dList_append(hc->active_fds, (void *)sd->SockFD); } } } + if (hc->avail_fd != -1) { + dClose(hc->avail_fd); + hc->avail_fd = -1; + } } /* @@ -199,9 +214,9 @@ static void Http_socket_free(int SKey) } else { if (S->connected_to) { HostConnection_t *hc = Http_host_connection_get(S->connected_to); - hc->active_connections--; + dList_remove_fast(hc->active_fds, (void *)S->SockFD); Http_connect_queued_sockets(hc); - if (hc->active_connections == 0) + if (dList_length(hc->active_fds) == 0) Http_host_connection_remove(hc); } dFree(S); @@ -275,6 +290,10 @@ Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester, web_flags & WEB_Stylesheet ? "text/css,*/*;q=0.1" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; + const char *connection_hdr_val = + (prefs.http_persistent_conns == TRUE && + !dStrAsciiCasecmp(URL_SCHEME(url), "http")) ? "keep-alive" : "close"; + if (use_proxy) { dStr_sprintfa(request_uri, "%s%s", URL_STR(url), @@ -309,15 +328,15 @@ Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester, "DNT: 1\r\n" "%s" /* proxy auth */ "%s" /* referer */ - "Connection: close\r\n" + "Connection: %s\r\n" "Content-Type: %s\r\n" "Content-Length: %ld\r\n" "%s" /* cookies */ "\r\n", request_uri->str, URL_AUTHORITY(url), prefs.http_user_agent, accept_hdr_value, HTTP_Language_hdr, auth ? auth : "", - proxy_auth->str, referer, content_type->str, (long)URL_DATA(url)->len, - cookies); + proxy_auth->str, referer, connection_hdr_val, content_type->str, + (long)URL_DATA(url)->len, cookies); dStr_append_l(query, URL_DATA(url)->str, URL_DATA(url)->len); dStr_free(content_type, TRUE); } else { @@ -333,13 +352,13 @@ Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester, "DNT: 1\r\n" "%s" /* proxy auth */ "%s" /* referer */ - "Connection: close\r\n" + "Connection: %s\r\n" "%s" /* cache control */ "%s" /* cookies */ "\r\n", request_uri->str, URL_AUTHORITY(url), prefs.http_user_agent, accept_hdr_value, HTTP_Language_hdr, auth ? auth : "", - proxy_auth->str, referer, + proxy_auth->str, referer, connection_hdr_val, (URL_FLAGS(url) & URL_E2EQuery) ? "Pragma: no-cache\r\nCache-Control: no-cache\r\n" : "", cookies); @@ -447,9 +466,6 @@ static int Http_connect_socket(ChainLink *Info) dClose(S->SockFD); MSG("Http_connect_socket ERROR: %s\n", dStrerror(S->Err)); } else { - a_Chain_bcb(OpSend, Info, &S->SockFD, "FD"); - a_Chain_fcb(OpSend, Info, &S->SockFD, "FD"); - Http_send_query(S->Info, S); return 0; /* Success */ } } @@ -491,7 +507,6 @@ static int Http_must_use_proxy(const DilloUrl *url) /* * Return a new string for the request used to tunnel HTTPS through a proxy. - * As of 2009, the best reference appears to be section 5 of RFC 2817. */ char *a_Http_make_connect_str(const DilloUrl *url) { @@ -565,7 +580,7 @@ static void Http_dns_cb(int Status, Dlist *addr_list, void *data) hc = Http_host_connection_get(URL_HOST(HTTP_Proxy)); else hc = Http_host_connection_get(URL_HOST(S->web->url)); - Http_socket_enqueue(&hc->queue, S); + Http_socket_enqueue(hc, S); Http_connect_queued_sockets(hc); } else { /* DNS wasn't able to resolve the hostname */ @@ -619,6 +634,28 @@ static int Http_get(ChainLink *Info, void *Data1) return 0; } +static void Http_make_fd_available(int fd) +{ + int i, j; + + for (i = 0; i < dList_length(host_connections); i++) { + HostConnection_t *hc = + (HostConnection_t*) dList_nth_data(host_connections, i); + + for (j = 0; j < dList_length(hc->active_fds); j++) { + void *data = dList_nth_data(hc->active_fds, j); + + if (fd == VOIDP2INT(data)) { + _MSG("host %s ", hc->host); + _MSG("Shift fd %d from active to avail\n", fd); + dList_remove_fast (hc->active_fds, data); + hc->avail_fd = fd; + return; + } + } + } +} + /* * CCC function for the HTTP module */ @@ -666,6 +703,51 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info, break; } } + } else if (Branch == 2) { + if (Dir == FWD) { + /* Receiving from server */ + switch (Op) { + case OpSend: + /* Data1 = dbuf */ + a_Chain_fcb(OpSend, Info, Data1, "send_page_2eof"); + break; + case OpEnd: + a_Chain_fcb(OpEnd, Info, NULL, NULL); + dFree(Info); + break; + default: + MSG_WARN("Unused CCC\n"); + break; + } + } else { /* 2 BCK */ + switch (Op) { + case OpStart: + a_Chain_link_new(Info, a_Http_ccc, BCK, a_IO_ccc, 2, 2); + a_Chain_bcb(OpStart, Info, NULL, NULL); /* IORead */ + break; + case OpSend: + if (Data2) { + if (!strcmp(Data2, "FD")) { + Info->LocalKey = (void *)*(int*)Data1; + a_Chain_bcb(OpSend, Info, Data1, Data2); + } else if (!strcmp(Data2, "reply_complete")) { + int fd = VOIDP2INT(Info->LocalKey); + + Http_make_fd_available(fd); + a_Chain_bfcb(OpEnd, Info, NULL, NULL); + dFree(Info); + } + } + break; + case OpAbort: + a_Chain_bcb(OpAbort, Info, NULL, NULL); + dFree(Info); + break; + default: + MSG_WARN("Unused CCC\n"); + break; + } + } } } @@ -676,13 +758,16 @@ static void Http_socket_queue_init(SocketQueue_t *sq) sq->tail = NULL; } -static void Http_socket_enqueue(SocketQueue_t *sq, SocketData_t* sock) +static void Http_socket_enqueue(HostConnection_t *hc, SocketData_t* sock) { + SocketQueue_t *sq; SocketQueueEntry_t *se = dNew(SocketQueueEntry_t, 1); se->sock = sock; se->next = NULL; + sq = sock->web->flags & WEB_Image ? &hc->image_q : &hc->main_q; + if (sq->tail) sq->tail->next = se; sq->tail = se; @@ -691,8 +776,9 @@ static void Http_socket_enqueue(SocketQueue_t *sq, SocketData_t* sock) sq->head = se; } -static SocketData_t* Http_socket_dequeue(SocketQueue_t *sq) +static SocketData_t* Http_socket_dequeue(HostConnection_t *hc) { + SocketQueue_t *sq = hc->main_q.head ? &hc->main_q : &hc->image_q; SocketQueueEntry_t *se = sq->head; SocketData_t *sd = NULL; @@ -720,8 +806,11 @@ static HostConnection_t *Http_host_connection_get(const char *host) } hc = dNew0(HostConnection_t, 1); - Http_socket_queue_init(&hc->queue); + Http_socket_queue_init(&hc->main_q); + Http_socket_queue_init(&hc->image_q); hc->host = dStrdup(host); + hc->active_fds = dList_new(prefs.http_max_conns); + hc->avail_fd = -1; dList_append(host_connections, hc); return hc; @@ -729,9 +818,10 @@ static HostConnection_t *Http_host_connection_get(const char *host) static void Http_host_connection_remove(HostConnection_t *hc) { - assert(hc->queue.head == NULL); + assert(hc->main_q.head == NULL && hc->image_q.head == NULL); dList_remove_fast(host_connections, hc); dFree(hc->host); + dList_free(hc->active_fds); dFree(hc); } @@ -741,7 +831,7 @@ static void Http_host_connection_remove_all() while (dList_length(host_connections) > 0) { hc = (HostConnection_t*) dList_nth_data(host_connections, 0); - while (Http_socket_dequeue(&hc->queue)); + while (Http_socket_dequeue(hc)); Http_host_connection_remove(hc); } dList_free(host_connections); diff --git a/src/Makefile.am b/src/Makefile.am index 16398f21..5abb43dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -98,6 +98,7 @@ dillo_SOURCES = \ plain.cc \ html.cc \ html.hh \ + html_charrefs.h \ html_common.hh \ form.cc \ form.hh \ diff --git a/src/cache.c b/src/cache.c index c4bc1f9b..4b216c55 100644 --- a/src/cache.c +++ b/src/cache.c @@ -55,7 +55,7 @@ typedef struct { Dstr *Data; /* Pointer to raw data */ Dstr *UTF8Data; /* Data after charset translation */ int DataRefcount; /* Reference count */ - Decode *TransferDecoder; /* Transfer decoder (e.g., chunked) */ + DecodeTransfer *TransferDecoder; /* Transfer decoder (e.g., chunked) */ Decode *ContentDecoder; /* Data decoder (e.g., gzip) */ Decode *CharsetDecoder; /* Translates text to UTF-8 encoding */ int ExpectedSize; /* Goal size of the HTTP transfer (0 if unknown)*/ @@ -205,7 +205,7 @@ static void Cache_entry_init(CacheEntry_t *NewEntry, const DilloUrl *Url) NewEntry->CharsetDecoder = NULL; NewEntry->ExpectedSize = 0; NewEntry->TransferSize = 0; - NewEntry->Flags = CA_IsEmpty; + NewEntry->Flags = CA_IsEmpty | CA_KeepAlive; } /* @@ -308,7 +308,7 @@ static void Cache_entry_free(CacheEntry_t *entry) if (entry->CharsetDecoder) a_Decode_free(entry->CharsetDecoder); if (entry->TransferDecoder) - a_Decode_free(entry->TransferDecoder); + a_Decode_transfer_free(entry->TransferDecoder); if (entry->ContentDecoder) a_Decode_free(entry->ContentDecoder); dFree(entry); @@ -652,7 +652,8 @@ static Dlist *Cache_parse_multiple_fields(const char *header, static void Cache_parse_header(CacheEntry_t *entry) { char *header = entry->Header->str; - char *Length, *Type, *location_str, *encoding; + bool_t server1point0 = !strncmp(entry->Header->str, "HTTP/1.0", 8); + char *Length, *Type, *location_str, *encoding, *connection; #ifndef DISABLE_COOKIES Dlist *Cookies; #endif @@ -716,6 +717,17 @@ static void Cache_parse_header(CacheEntry_t *entry) dList_free(warnings); } + if (server1point0) + entry->Flags &= ~CA_KeepAlive; + + if ((connection = Cache_parse_field(header, "Connection"))) { + if (!dStrAsciiCasecmp(connection, "close")) + entry->Flags &= ~CA_KeepAlive; + else if (server1point0 && !dStrAsciiCasecmp(connection, "keep-alive")) + entry->Flags |= CA_KeepAlive; + dFree(connection); + } + /* * Get Transfer-Encoding and initialize decoder */ @@ -834,6 +846,53 @@ static int Cache_get_header(CacheEntry_t *entry, return 0; } +static void Cache_finish_msg(CacheEntry_t *entry) +{ + if (entry->Flags & CA_GotData) { + /* already finished */ + return; + } + + if ((entry->ExpectedSize || entry->TransferSize) && + entry->TypeHdr == NULL) { + MSG_HTTP("Message with a body lacked Content-Type header.\n"); + } + if ((entry->Flags & CA_GotLength) && + (entry->ExpectedSize != entry->TransferSize)) { + MSG_HTTP("Content-Length does NOT match message body at\n" + "%s\n", URL_STR_(entry->Url)); + MSG("Expected size: %d, Transfer size: %d\n", + entry->ExpectedSize, entry->TransferSize); + } + if (!entry->TransferSize && !(entry->Flags & CA_Redirect) && + (entry->Flags & WEB_RootUrl)) { + char *eol = strchr(entry->Header->str, '\n'); + if (eol) { + char *status_line = dStrndup(entry->Header->str, + eol - entry->Header->str); + MSG_HTTP("Body was empty. Server sent status: %s\n", status_line); + dFree(status_line); + } + } + entry->Flags |= CA_GotData; + entry->Flags &= ~CA_Stopped; /* it may catch up! */ + if (entry->TransferDecoder) { + a_Decode_transfer_free(entry->TransferDecoder); + entry->TransferDecoder = NULL; + } + if (entry->ContentDecoder) { + a_Decode_free(entry->ContentDecoder); + entry->ContentDecoder = NULL; + } + dStr_fit(entry->Data); /* fit buffer size! */ + + if ((entry = Cache_process_queue(entry))) { + if (entry->Flags & CA_GotHeader) { + Cache_unref_data(entry); + } + } +} + /* * Receive new data, update the reception buffer (for next read), update the * cache, and service the client queue. @@ -842,16 +901,17 @@ static int Cache_get_header(CacheEntry_t *entry, * 'Op' is the operation to perform * 'VPtr' is a (void) pointer to the IO control structure */ -void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, - const DilloUrl *Url) +bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, + const DilloUrl *Url) { int offset, len; const char *str; Dstr *dstr1, *dstr2, *dstr3; + bool_t done = FALSE; CacheEntry_t *entry = Cache_entry_search(Url); /* Assert a valid entry (not aborted) */ - dReturn_if_fail (entry != NULL); + dReturn_val_if_fail (entry != NULL, FALSE); _MSG("__a_Cache_process_dbuf__\n"); @@ -875,7 +935,8 @@ void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, /* Decode arrived data (<= 3 stages) */ if (entry->TransferDecoder) { - dstr1 = a_Decode_process(entry->TransferDecoder, str, len); + dstr1 = a_Decode_transfer_process(entry->TransferDecoder, str,len); + done = a_Decode_transfer_finished(entry->TransferDecoder); str = dstr1->str; len = dstr1->len; } @@ -896,51 +957,27 @@ void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, if (entry->Data->len) entry->Flags &= ~CA_IsEmpty; - entry = Cache_process_queue(entry); - } - } else if (Op == IOClose) { - if ((entry->ExpectedSize || entry->TransferSize) && - entry->TypeHdr == NULL) { - MSG_HTTP("Message with a body lacked Content-Type header.\n"); - } - if ((entry->Flags & CA_GotLength) && - (entry->ExpectedSize != entry->TransferSize)) { - MSG_HTTP("Content-Length does NOT match message body at\n" - "%s\n", URL_STR_(entry->Url)); - MSG("Expected size: %d, Transfer size: %d\n", - entry->ExpectedSize, entry->TransferSize); - } - if (!entry->TransferSize && !(entry->Flags & CA_Redirect) && - (entry->Flags & WEB_RootUrl)) { - char *eol = strchr(entry->Header->str, '\n'); - if (eol) { - char *status_line = dStrndup(entry->Header->str, - eol - entry->Header->str); - MSG_HTTP("Body was empty. Server sent status: %s\n", status_line); - dFree(status_line); + if ((entry->Flags & CA_GotLength) && + (entry->TransferSize >= entry->ExpectedSize)) { + done = TRUE; } - } - entry->Flags |= CA_GotData; - entry->Flags &= ~CA_Stopped; /* it may catch up! */ - if (entry->TransferDecoder) { - a_Decode_free(entry->TransferDecoder); - entry->TransferDecoder = NULL; - } - if (entry->ContentDecoder) { - a_Decode_free(entry->ContentDecoder); - entry->ContentDecoder = NULL; - } - dStr_fit(entry->Data); /* fit buffer size! */ - - if ((entry = Cache_process_queue(entry))) { - if (entry->Flags & CA_GotHeader) { - Cache_unref_data(entry); + if (!(entry->Flags & CA_KeepAlive)) { + /* Let IOClose finish it later */ + done = FALSE; } + + entry = Cache_process_queue(entry); + + if (entry && done) + Cache_finish_msg(entry); } + } else if (Op == IOClose) { + Cache_finish_msg(entry); } else if (Op == IOAbort) { /* unused */ MSG("a_Cache_process_dbuf Op = IOAbort; not implemented!\n"); } + return done; } /* diff --git a/src/cache.h b/src/cache.h index c39e4600..f3b064f2 100644 --- a/src/cache.h +++ b/src/cache.h @@ -33,6 +33,7 @@ extern "C" { #define CA_InternalUrl 0x800 /* URL content is generated by dillo */ #define CA_HugeFile 0x1000 /* URL content is too big */ #define CA_IsEmpty 0x2000 /* True until a byte of content arrives */ +#define CA_KeepAlive 0x4000 typedef struct CacheClient CacheClient_t; @@ -67,7 +68,7 @@ const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype, const char *from); uint_t a_Cache_get_flags(const DilloUrl *url); uint_t a_Cache_get_flags_with_redirection(const DilloUrl *url); -void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, +bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, const DilloUrl *Url); int a_Cache_download_enabled(const DilloUrl *url); void a_Cache_entry_remove_by_url(DilloUrl *url); @@ -714,7 +714,10 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info, Capi_conn_ref(conn); Info->LocalKey = conn; conn->InfoRecv = Info; - a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 2, 2); + if (strcmp(conn->server, "http") == 0) + a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Http_ccc, 2, 2); + else + a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 2, 2); a_Chain_bcb(OpStart, Info, NULL, Data2); break; case OpSend: @@ -744,7 +747,10 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info, if (strcmp(Data2, "send_page_2eof") == 0) { /* Data1 = dbuf */ DataBuf *dbuf = Data1; - a_Cache_process_dbuf(IORead, dbuf->Buf, dbuf->Size, conn->url); + bool_t finished = a_Cache_process_dbuf(IORead, dbuf->Buf, + dbuf->Size, conn->url); + if (finished) + a_Chain_bcb(OpSend, Info, NULL, "reply_complete"); } else if (strcmp(Data2, "send_status_message") == 0) { a_UIcmd_set_msg(conn->bw, "%s", Data1); } else if (strcmp(Data2, "chat") == 0) { diff --git a/src/decode.c b/src/decode.c index 53a0d621..76dd6ef7 100644 --- a/src/decode.c +++ b/src/decode.c @@ -21,9 +21,10 @@ static const int bufsize = 8*1024; /* - * Decode chunked data + * Decode 'Transfer-Encoding: chunked' data */ -static Dstr *Decode_chunked(Decode *dc, const char *instr, int inlen) +Dstr *a_Decode_transfer_process(DecodeTransfer *dc, const char *instr, + int inlen) { char *inputPtr, *eol; int inputRemaining; @@ -66,6 +67,7 @@ static Dstr *Decode_chunked(Decode *dc, const char *instr, int inlen) } if (!(chunkRemaining = strtol(inputPtr, NULL, 0x10))) { + dc->finished = TRUE; break; /* A chunk length of 0 means we're done! */ } inputRemaining -= (eol - inputPtr) + 1; @@ -80,10 +82,16 @@ static Dstr *Decode_chunked(Decode *dc, const char *instr, int inlen) return output; } -static void Decode_chunked_free(Decode *dc) +bool_t a_Decode_transfer_finished(DecodeTransfer *dc) +{ + return dc->finished; +} + +void a_Decode_transfer_free(DecodeTransfer *dc) { dFree(dc->state); dStr_free(dc->leftover, 1); + dFree(dc); } static void Decode_compression_free(Decode *dc) @@ -280,19 +288,17 @@ static void Decode_charset_free(Decode *dc) /* * Initialize transfer decoder. Currently handles "chunked". */ -Decode *a_Decode_transfer_init(const char *format) +DecodeTransfer *a_Decode_transfer_init(const char *format) { - Decode *dc = NULL; + DecodeTransfer *dc = NULL; if (format && !dStrAsciiCasecmp(format, "chunked")) { int *chunk_remaining = dNew(int, 1); *chunk_remaining = 0; - dc = dNew(Decode, 1); + dc = dNew(DecodeTransfer, 1); dc->leftover = dStr_new(""); dc->state = chunk_remaining; - dc->decode = Decode_chunked; - dc->free = Decode_chunked_free; - dc->buffer = NULL; /* not used */ + dc->finished = FALSE; _MSG("chunked!\n"); } return dc; diff --git a/src/decode.h b/src/decode.h index 279807a6..06c987f6 100644 --- a/src/decode.h +++ b/src/decode.h @@ -15,7 +15,21 @@ typedef struct Decode { void (*free) (struct Decode *dc); } Decode; -Decode *a_Decode_transfer_init(const char *format); +/* I'm not going to shoehorn the decoders into the same form anymore. They + * can evolve independently. + */ +typedef struct DecodeTransfer { + Dstr *leftover; + void *state; + bool_t finished; /* has the terminating chunk been seen? */ +} DecodeTransfer; + +DecodeTransfer *a_Decode_transfer_init(const char *format); +Dstr *a_Decode_transfer_process(DecodeTransfer *dc, const char *instr, + int inlen); +bool_t a_Decode_transfer_finished(DecodeTransfer *dc); +void a_Decode_transfer_free(DecodeTransfer *dc); + Decode *a_Decode_content_init(const char *format); Decode *a_Decode_charset_init(const char *format); Dstr *a_Decode_process(Decode *dc, const char *instr, int inlen); diff --git a/src/html.cc b/src/html.cc index f465f888..9fe8715f 100644 --- a/src/html.cc +++ b/src/html.cc @@ -26,6 +26,7 @@ #include "msg.h" #include "binaryconst.h" #include "colors.h" +#include "html_charrefs.h" #include "utf8.hh" #include "misc.h" @@ -787,113 +788,16 @@ void a_Html_stash_init(DilloHtml *html) dStr_truncate(html->Stash, 0); } -/* Entities list from the HTML 4.01 DTD */ -typedef struct { - const char *entity; - int isocode; -} Ent_t; - -#define NumEnt 252 -static const Ent_t Entities[NumEnt] = { - {"AElig",0306}, {"Aacute",0301}, {"Acirc",0302}, {"Agrave",0300}, - {"Alpha",01621},{"Aring",0305}, {"Atilde",0303}, {"Auml",0304}, - {"Beta",01622}, {"Ccedil",0307}, {"Chi",01647}, {"Dagger",020041}, - {"Delta",01624},{"ETH",0320}, {"Eacute",0311}, {"Ecirc",0312}, - {"Egrave",0310},{"Epsilon",01625},{"Eta",01627}, {"Euml",0313}, - {"Gamma",01623},{"Iacute",0315}, {"Icirc",0316}, {"Igrave",0314}, - {"Iota",01631}, {"Iuml",0317}, {"Kappa",01632}, {"Lambda",01633}, - {"Mu",01634}, {"Ntilde",0321}, {"Nu",01635}, {"OElig",0522}, - {"Oacute",0323},{"Ocirc",0324}, {"Ograve",0322}, {"Omega",01651}, - {"Omicron",01637},{"Oslash",0330},{"Otilde",0325},{"Ouml",0326}, - {"Phi",01646}, {"Pi",01640}, {"Prime",020063},{"Psi",01650}, - {"Rho",01641}, {"Scaron",0540}, {"Sigma",01643}, {"THORN",0336}, - {"Tau",01644}, {"Theta",01630}, {"Uacute",0332}, {"Ucirc",0333}, - {"Ugrave",0331},{"Upsilon",01645},{"Uuml",0334}, {"Xi",01636}, - {"Yacute",0335},{"Yuml",0570}, {"Zeta",01626}, {"aacute",0341}, - {"acirc",0342}, {"acute",0264}, {"aelig",0346}, {"agrave",0340}, - {"alefsym",020465},{"alpha",01661},{"amp",38}, {"and",021047}, - {"ang",021040}, {"aring",0345}, {"asymp",021110},{"atilde",0343}, - {"auml",0344}, {"bdquo",020036},{"beta",01662}, {"brvbar",0246}, - {"bull",020042},{"cap",021051}, {"ccedil",0347}, {"cedil",0270}, - {"cent",0242}, {"chi",01707}, {"circ",01306}, {"clubs",023143}, - {"cong",021105},{"copy",0251}, {"crarr",020665},{"cup",021052}, - {"curren",0244},{"dArr",020723}, {"dagger",020040},{"darr",020623}, - {"deg",0260}, {"delta",01664}, {"diams",023146},{"divide",0367}, - {"eacute",0351},{"ecirc",0352}, {"egrave",0350}, {"empty",021005}, - {"emsp",020003},{"ensp",020002}, {"epsilon",01665},{"equiv",021141}, - {"eta",01667}, {"eth",0360}, {"euml",0353}, {"euro",020254}, - {"exist",021003},{"fnof",0622}, {"forall",021000},{"frac12",0275}, - {"frac14",0274},{"frac34",0276}, {"frasl",020104},{"gamma",01663}, - {"ge",021145}, {"gt",62}, {"hArr",020724}, {"harr",020624}, - {"hearts",023145},{"hellip",020046},{"iacute",0355},{"icirc",0356}, - {"iexcl",0241}, {"igrave",0354}, {"image",020421},{"infin",021036}, - {"int",021053}, {"iota",01671}, {"iquest",0277}, {"isin",021010}, - {"iuml",0357}, {"kappa",01672}, {"lArr",020720}, {"lambda",01673}, - {"lang",021451},{"laquo",0253}, {"larr",020620}, {"lceil",021410}, - {"ldquo",020034},{"le",021144}, {"lfloor",021412},{"lowast",021027}, - {"loz",022712}, {"lrm",020016}, {"lsaquo",020071},{"lsquo",020030}, - {"lt",60}, {"macr",0257}, {"mdash",020024},{"micro",0265}, - {"middot",0267},{"minus",021022},{"mu",01674}, {"nabla",021007}, - {"nbsp",0240}, {"ndash",020023},{"ne",021140}, {"ni",021013}, - {"not",0254}, {"notin",021011},{"nsub",021204}, {"ntilde",0361}, - {"nu",01675}, {"oacute",0363}, {"ocirc",0364}, {"oelig",0523}, - {"ograve",0362},{"oline",020076},{"omega",01711}, {"omicron",01677}, - {"oplus",021225},{"or",021050}, {"ordf",0252}, {"ordm",0272}, - {"oslash",0370},{"otilde",0365}, {"otimes",021227},{"ouml",0366}, - {"para",0266}, {"part",021002}, {"permil",020060},{"perp",021245}, - {"phi",01706}, {"pi",01700}, {"piv",01726}, {"plusmn",0261}, - {"pound",0243}, {"prime",020062},{"prod",021017}, {"prop",021035}, - {"psi",01710}, {"quot",34}, {"rArr",020722}, {"radic",021032}, - {"rang",021452},{"raquo",0273}, {"rarr",020622}, {"rceil",021411}, - {"rdquo",020035},{"real",020434},{"reg",0256}, {"rfloor",021413}, - {"rho",01701}, {"rlm",020017}, {"rsaquo",020072},{"rsquo",020031}, - {"sbquo",020032},{"scaron",0541},{"sdot",021305}, {"sect",0247}, - {"shy",0255}, {"sigma",01703}, {"sigmaf",01702},{"sim",021074}, - {"spades",023140},{"sub",021202},{"sube",021206}, {"sum",021021}, - {"sup",021203}, {"sup1",0271}, {"sup2",0262}, {"sup3",0263}, - {"supe",021207},{"szlig",0337}, {"tau",01704}, {"there4",021064}, - {"theta",01670},{"thetasym",01721},{"thinsp",020011},{"thorn",0376}, - {"tilde",01334},{"times",0327}, {"trade",020442},{"uArr",020721}, - {"uacute",0372},{"uarr",020621}, {"ucirc",0373}, {"ugrave",0371}, - {"uml",0250}, {"upsih",01722}, {"upsilon",01705},{"uuml",0374}, - {"weierp",020430},{"xi",01676}, {"yacute",0375}, {"yen",0245}, - {"yuml",0377}, {"zeta",01666}, {"zwj",020015}, {"zwnj",020014} -}; - - -/* - * Comparison function for binary search - */ -static int Html_entity_comp(const void *a, const void *b) -{ - return strcmp(((Ent_t *)a)->entity, ((Ent_t *)b)->entity); -} - -/* - * Binary search of 'key' in entity list - */ -static int Html_entity_search(char *key) -{ - Ent_t *res, EntKey; - - EntKey.entity = key; - res = (Ent_t*) bsearch(&EntKey, Entities, NumEnt, - sizeof(Ent_t), Html_entity_comp); - if (res) - return (res - Entities); - return -1; -} - /* * This is M$ non-standard "smart quotes" (w1252). Now even deprecated by them! * * SGML for HTML4.01 defines c >= 128 and c <= 159 as UNUSED. - * TODO: Probably I should remove this hack, and add a HTML warning. --Jcid + * TODO: Probably I should remove this hack. --Jcid */ -static int Html_ms_stupid_quotes_2ucs(int isocode) +static int Html_ms_stupid_quotes_2ucs(int codepoint) { int ret; - switch (isocode) { + switch (codepoint) { case 145: case 146: ret = '\''; break; case 147: @@ -901,130 +805,233 @@ static int Html_ms_stupid_quotes_2ucs(int isocode) case 149: ret = 176; break; case 150: case 151: ret = '-'; break; - default: ret = isocode; break; + default: ret = codepoint; break; } return ret; } /* - * Given an entity, return the UCS character code. - * Returns a negative value (error code) if not a valid entity. - * - * The first character *token is assumed to be == '&' - * - * For valid entities, *entsize is set to the length of the parsed entity. + * Parse a numeric character reference (e.g., "/" or "/"). + * The "&#" has already been consumed. */ -static int Html_parse_entity(DilloHtml *html, const char *token, - int toksize, int *entsize) +static const char *Html_parse_numeric_charref(DilloHtml *html, char *tok, + bool_t is_attr, int *entsize) { - int isocode, i; - char *tok, *s, c; + static char buf[5]; + char *s = tok; + int n, codepoint = -1; - token++; - tok = s = toksize ? dStrndup(token, (uint_t)toksize) : dStrdup(token); - - isocode = -1; - - if (*s == '#') { - /* numeric character reference */ - errno = 0; - if (*++s == 'x' || *s == 'X') { - if (isxdigit(*++s)) { - /* strtol with base 16 accepts leading "0x" - we don't */ - if (*s == '0' && s[1] == 'x') { - s++; - isocode = 0; - } else { - isocode = strtol(s, &s, 16); - } + errno = 0; + + if (*s == 'x' || *s == 'X') { + if (isxdigit(*++s)) { + /* strtol with base 16 accepts leading "0x" - we don't */ + if (*s == '0' && s[1] == 'x') { + s++; + codepoint = 0; + } else { + codepoint = strtol(s, &s, 16); } - } else if (isdigit(*s)) { - isocode = strtol(s, &s, 10); } + } else if (isdigit(*s)) { + codepoint = strtol(s, &s, 10); + } + if (errno) + codepoint = -1; - if (!isocode || errno || isocode > 0xffff) { - /* this catches null bytes, errors and codes >= 0xFFFF */ - BUG_MSG("numeric character reference \"%s\" out of range\n", tok); - isocode = -2; + if (*s == ';') + s++; + else { + if (prefs.show_extra_warnings && (html->DocType == DT_XHTML || + (html->DocType == DT_HTML && html->DocTypeVersion <= 4.01f))) { + char c = *s; + *s = '\0'; + BUG_MSG("character reference '&#%s' lacks ';'\n", tok); + *s = c; } - - if (isocode != -1) { - if (*s == ';') - s++; - else if (prefs.show_extra_warnings) - BUG_MSG("numeric character reference without trailing ';'\n"); + /* Don't require ';' for old HTML, except that our current heuristic + * is to require it in attributes to avoid cases like "©=1" found + * in URLs. + */ + if (is_attr || html->DocType == DT_XHTML || + (html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f)) { + return NULL; } - } else if (isalpha(*s)) { - /* character entity reference */ - while (*++s && (isalnum(*s) || strchr(":_.-", *s))) ; - c = *s; - *s = 0; + } + if ((codepoint < 0x20 && codepoint != '\t' && codepoint != '\n' && + codepoint != '\f') || + (codepoint >= 0x7f && codepoint <= 0x9f) || + (codepoint >= 0xd800 && codepoint <= 0xdfff) || codepoint > 0x10ffff || + ((codepoint & 0xfffe) == 0xfffe) || + (!(html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f) && + codepoint > 0xffff)) { + /* this catches null bytes, errors, codes out of range, disallowed + * control chars, permanently undefined chars, and surrogates. + */ + char c = *s; + *s = '\0'; + BUG_MSG("numeric character reference '&#%s' is not valid.\n", tok); + *s = c; - if ((i = Html_entity_search(tok)) >= 0) { - isocode = Entities[i].isocode; + codepoint = (codepoint >= 145 && codepoint <= 151) ? + Html_ms_stupid_quotes_2ucs(codepoint) : -1; + } + if (codepoint != -1) { + if (codepoint >= 128) { + n = a_Utf8_encode(codepoint, buf); } else { - if (html->DocType == DT_XHTML && !strcmp(tok, "apos")) { - isocode = 0x27; - } else { - if ((html->DocType == DT_HTML && html->DocTypeVersion == 4.01f) || - html->DocType == DT_XHTML) - BUG_MSG("undefined character entity '%s'\n", tok); - isocode = -3; - } + n = 1; + buf[0] = (char) codepoint; } - if (c == ';') - s++; - else if (prefs.show_extra_warnings) - BUG_MSG("character entity reference without trailing ';'\n"); + assert(n < 5); + buf[n] = '\0'; + *entsize = s-tok+2; + return buf; + } else { + return NULL; } +} +/* + * Comparison function for binary search + */ +static int Html_charref_comp(const void *a, const void *b) +{ + return strcmp(((Charref_t *)a)->ref, ((Charref_t *)b)->ref); +} + +/* + * Binary search of 'key' in charref list + */ +static Charref_t *Html_charref_search(char *key) +{ + Charref_t RefKey; + + RefKey.ref = key; + return (Charref_t*) bsearch(&RefKey, Charrefs, NumRef, + sizeof(Charref_t), Html_charref_comp); +} + +/* + * Parse a named character reference (e.g., "&" or "…"). + * The "&" has already been consumed. + */ +static const char *Html_parse_named_charref(DilloHtml *html, char *tok, + bool_t is_attr, int *entsize) +{ + Charref_t *p; + char c; + char *s = tok; + const char *ret = NULL; + + while (*++s && (isalnum(*s) || strchr(":_.-", *s))) ; + c = *s; + *s = '\0'; + if (c != ';') { + if (prefs.show_extra_warnings && (html->DocType == DT_XHTML || + (html->DocType == DT_HTML && html->DocTypeVersion <= 4.01f))) + BUG_MSG("character reference '&%s' lacks ';'\n", tok); + + /* Don't require ';' for old HTML, except that our current heuristic + * is to require it in attributes to avoid cases like "©=1" found + * in URLs. + */ + if (is_attr || html->DocType == DT_XHTML || + (html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f)) { + return ret; + } + } + + if ((p = Html_charref_search(tok))) { + ret = (html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f) ? + p->html5_str : p->html4_str; + } + + if (!ret && html->DocType == DT_XHTML && !strcmp(tok, "apos")) + ret = "'"; + + *s = c; + if (c == ';') + s++; + + if (!ret) { + c = *s; + *s = '\0'; + BUG_MSG("undefined character reference &%s\n", tok); + *s = c; + } *entsize = s-tok+1; - dFree(tok); + return ret; +} - if (isocode >= 145 && isocode <= 151) { - /* TODO: remove this hack. */ - isocode = Html_ms_stupid_quotes_2ucs(isocode); - } else if (isocode == -1 && prefs.show_extra_warnings) +/* + * Given an entity, return the corresponding string. + * Returns NULL if not a valid entity. + * + * The first character *token is assumed to be == '&' + * + * For valid entities, *entsize is set to the length of the parsed entity. + */ +static const char *Html_parse_entity(DilloHtml *html, const char *token, + int toksize, int *entsize, bool_t is_attr) +{ + const char *ret = NULL; + char *tok; + + token++; + tok = dStrndup(token, (uint_t)toksize); + + if (*tok == '#') { + ret = Html_parse_numeric_charref(html, tok+1, is_attr, entsize); + } else if (isalpha(*tok)) { + ret = Html_parse_named_charref(html, tok, is_attr, entsize); + } else if (prefs.show_extra_warnings && + (!(html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f))) { + // HTML5 doesn't mind literal '&'s. BUG_MSG("literal '&'\n"); + } + dFree(tok); - return isocode; + return ret; } /* - * Convert all the entities in a token to utf8 encoding. Takes - * a token and its length, and returns a newly allocated string. + * Parse all the entities in a token. Takes the token and its length, and + * returns a newly allocated string. */ char *a_Html_parse_entities(DilloHtml *html, const char *token, int toksize) { const char *esc_set = "&"; - char *new_str, buf[4]; - int i, j, k, n, s, isocode, entsize; - - new_str = dStrndup(token, toksize); - s = strcspn(new_str, esc_set); - if (new_str[s] == 0) - return new_str; - - for (i = j = s; i < toksize; i++) { - if (token[i] == '&' && - (isocode = Html_parse_entity(html, token+i, - toksize-i, &entsize)) >= 0) { - if (isocode >= 128) { - /* multibyte encoding */ - n = a_Utf8_encode(isocode, buf); - for (k = 0; k < n; ++k) - new_str[j++] = buf[k]; + int i, s, entsize; + char *str; + + s = strcspn(token, esc_set); + if (s >= toksize) { + /* no ampersands */ + str = dStrndup(token, toksize); + } else { + Dstr *ds = dStr_sized_new(toksize); + + dStr_append_l(ds, token, s); + + for (i = s; i < toksize; i++) { + const char *entstr; + const bool_t is_attr = FALSE; + + if (token[i] == '&' && + (entstr = Html_parse_entity(html, token+i, toksize-i, &entsize, + is_attr))) { + dStr_append(ds, entstr); + i += entsize-1; } else { - new_str[j++] = (char) isocode; + dStr_append_c(ds, token[i]); } - i += entsize-1; - } else { - new_str[j++] = token[i]; } + str = ds->str; + dStr_free(ds, 0); } - new_str[j] = '\0'; - return new_str; + return str; } /* @@ -4014,7 +4021,7 @@ static const char *Html_get_attr2(DilloHtml *html, const char *attrname, int tag_parsing_flags) { - int i, isocode, entsize, Found = 0, delimiter = 0, attr_pos = 0; + int i, entsize, Found = 0, delimiter = 0, attr_pos = 0; Dstr *Buf = html->attr_data; DilloHtmlTagParsingState state = SEEK_ATTR_START; @@ -4073,16 +4080,12 @@ static const char *Html_get_attr2(DilloHtml *html, state = FINISHED; } else if (tag[i] == '&' && (tag_parsing_flags & HTML_ParseEntities)) { - if ((isocode = Html_parse_entity(html, tag+i, - tagsize-i, &entsize)) >= 0) { - if (isocode >= 128) { - char buf[4]; - int k, n = a_Utf8_encode(isocode, buf); - for (k = 0; k < n; ++k) - dStr_append_c(Buf, buf[k]); - } else { - dStr_append_c(Buf, (char) isocode); - } + const char *entstr; + const bool_t is_attr = TRUE; + + if ((entstr = Html_parse_entity(html, tag+i, tagsize-i, &entsize, + is_attr))) { + dStr_append(Buf, entstr); i += entsize-1; } else { dStr_append_c(Buf, tag[i]); diff --git a/src/html_charrefs.h b/src/html_charrefs.h new file mode 100644 index 00000000..b9a47b7b --- /dev/null +++ b/src/html_charrefs.h @@ -0,0 +1,2138 @@ +#ifndef HTML_CHARREFS_H +#define HTML_CHARREFS_H + +typedef struct { + const char *ref; + const char *html5_str; + const char *html4_str; +} Charref_t; + +#define NumRef 2125 +static const Charref_t Charrefs[NumRef] = { +{"AElig", "Æ", "Æ"}, +{"AMP", "&", NULL}, +{"Aacute", "Á", "Á"}, +{"Abreve", "Ă", NULL}, +{"Acirc", "Â", "Â"}, +{"Acy", "А", NULL}, +{"Afr", "", NULL}, +{"Agrave", "À", "À"}, +{"Alpha", "Α", "Α"}, +{"Amacr", "Ā", NULL}, +{"And", "⩓", NULL}, +{"Aogon", "Ą", NULL}, +{"Aopf", "", NULL}, +{"ApplyFunction", "", NULL}, +{"Aring", "Å", "Å"}, +{"Ascr", "", NULL}, +{"Assign", "≔", NULL}, +{"Atilde", "Ã", "Ã"}, +{"Auml", "Ä", "Ä"}, +{"Backslash", "∖", NULL}, +{"Barv", "⫧", NULL}, +{"Barwed", "⌆", NULL}, +{"Bcy", "Б", NULL}, +{"Because", "∵", NULL}, +{"Bernoullis", "ℬ", NULL}, +{"Beta", "Β", "Β"}, +{"Bfr", "", NULL}, +{"Bopf", "", NULL}, +{"Breve", "˘", NULL}, +{"Bscr", "ℬ", NULL}, +{"Bumpeq", "≎", NULL}, +{"CHcy", "Ч", NULL}, +{"COPY", "©", NULL}, +{"Cacute", "Ć", NULL}, +{"Cap", "⋒", NULL}, +{"CapitalDifferentialD", "ⅅ", NULL}, +{"Cayleys", "ℭ", NULL}, +{"Ccaron", "Č", NULL}, +{"Ccedil", "Ç", "Ç"}, +{"Ccirc", "Ĉ", NULL}, +{"Cconint", "∰", NULL}, +{"Cdot", "Ċ", NULL}, +{"Cedilla", "¸", NULL}, +{"CenterDot", "·", NULL}, +{"Cfr", "ℭ", NULL}, +{"Chi", "Χ", "Χ"}, +{"CircleDot", "⊙", NULL}, +{"CircleMinus", "⊖", NULL}, +{"CirclePlus", "⊕", NULL}, +{"CircleTimes", "⊗", NULL}, +{"ClockwiseContourIntegral", "∲", NULL}, +{"CloseCurlyDoubleQuote", "”", NULL}, +{"CloseCurlyQuote", "’", NULL}, +{"Colon", "∷", NULL}, +{"Colone", "⩴", NULL}, +{"Congruent", "≡", NULL}, +{"Conint", "∯", NULL}, +{"ContourIntegral", "∮", NULL}, +{"Copf", "ℂ", NULL}, +{"Coproduct", "∐", NULL}, +{"CounterClockwiseContourIntegral", "∳", NULL}, +{"Cross", "⨯", NULL}, +{"Cscr", "", NULL}, +{"Cup", "⋓", NULL}, +{"CupCap", "≍", NULL}, +{"DD", "ⅅ", NULL}, +{"DDotrahd", "⤑", NULL}, +{"DJcy", "Ђ", NULL}, +{"DScy", "Ѕ", NULL}, +{"DZcy", "Џ", NULL}, +{"Dagger", "‡", "‡"}, +{"Darr", "↡", NULL}, +{"Dashv", "⫤", NULL}, +{"Dcaron", "Ď", NULL}, +{"Dcy", "Д", NULL}, +{"Del", "∇", NULL}, +{"Delta", "Δ", "Δ"}, +{"Dfr", "", NULL}, +{"DiacriticalAcute", "´", NULL}, +{"DiacriticalDot", "˙", NULL}, +{"DiacriticalDoubleAcute", "˝", NULL}, +{"DiacriticalGrave", "`", NULL}, +{"DiacriticalTilde", "˜", NULL}, +{"Diamond", "⋄", NULL}, +{"DifferentialD", "ⅆ", NULL}, +{"Dopf", "", NULL}, +{"Dot", "¨", NULL}, +{"DotDot", "⃜", NULL}, +{"DotEqual", "≐", NULL}, +{"DoubleContourIntegral", "∯", NULL}, +{"DoubleDot", "¨", NULL}, +{"DoubleDownArrow", "⇓", NULL}, +{"DoubleLeftArrow", "⇐", NULL}, +{"DoubleLeftRightArrow", "⇔", NULL}, +{"DoubleLeftTee", "⫤", NULL}, +{"DoubleLongLeftArrow", "⟸", NULL}, +{"DoubleLongLeftRightArrow", "⟺", NULL}, +{"DoubleLongRightArrow", "⟹", NULL}, +{"DoubleRightArrow", "⇒", NULL}, +{"DoubleRightTee", "⊨", NULL}, +{"DoubleUpArrow", "⇑", NULL}, +{"DoubleUpDownArrow", "⇕", NULL}, +{"DoubleVerticalBar", "∥", NULL}, +{"DownArrow", "↓", NULL}, +{"DownArrowBar", "⤓", NULL}, +{"DownArrowUpArrow", "⇵", NULL}, +{"DownBreve", "̑", NULL}, +{"DownLeftRightVector", "⥐", NULL}, +{"DownLeftTeeVector", "⥞", NULL}, +{"DownLeftVector", "↽", NULL}, +{"DownLeftVectorBar", "⥖", NULL}, +{"DownRightTeeVector", "⥟", NULL}, +{"DownRightVector", "⇁", NULL}, +{"DownRightVectorBar", "⥗", NULL}, +{"DownTee", "⊤", NULL}, +{"DownTeeArrow", "↧", NULL}, +{"Downarrow", "⇓", NULL}, +{"Dscr", "", NULL}, +{"Dstrok", "Đ", NULL}, +{"ENG", "Ŋ", NULL}, +{"ETH", "Ð", "Ð"}, +{"Eacute", "É", "É"}, +{"Ecaron", "Ě", NULL}, +{"Ecirc", "Ê", "Ê"}, +{"Ecy", "Э", NULL}, +{"Edot", "Ė", NULL}, +{"Efr", "", NULL}, +{"Egrave", "È", "È"}, +{"Element", "∈", NULL}, +{"Emacr", "Ē", NULL}, +{"EmptySmallSquare", "◻", NULL}, +{"EmptyVerySmallSquare", "▫", NULL}, +{"Eogon", "Ę", NULL}, +{"Eopf", "", NULL}, +{"Epsilon", "Ε", "Ε"}, +{"Equal", "⩵", NULL}, +{"EqualTilde", "≂", NULL}, +{"Equilibrium", "⇌", NULL}, +{"Escr", "ℰ", NULL}, +{"Esim", "⩳", NULL}, +{"Eta", "Η", "Η"}, +{"Euml", "Ë", "Ë"}, +{"Exists", "∃", NULL}, +{"ExponentialE", "ⅇ", NULL}, +{"Fcy", "Ф", NULL}, +{"Ffr", "", NULL}, +{"FilledSmallSquare", "◼", NULL}, +{"FilledVerySmallSquare", "▪", NULL}, +{"Fopf", "", NULL}, +{"ForAll", "∀", NULL}, +{"Fouriertrf", "ℱ", NULL}, +{"Fscr", "ℱ", NULL}, +{"GJcy", "Ѓ", NULL}, +{"GT", ">", NULL}, +{"Gamma", "Γ", "Γ"}, +{"Gammad", "Ϝ", NULL}, +{"Gbreve", "Ğ", NULL}, +{"Gcedil", "Ģ", NULL}, +{"Gcirc", "Ĝ", NULL}, +{"Gcy", "Г", NULL}, +{"Gdot", "Ġ", NULL}, +{"Gfr", "", NULL}, +{"Gg", "⋙", NULL}, +{"Gopf", "", NULL}, +{"GreaterEqual", "≥", NULL}, +{"GreaterEqualLess", "⋛", NULL}, +{"GreaterFullEqual", "≧", NULL}, +{"GreaterGreater", "⪢", NULL}, +{"GreaterLess", "≷", NULL}, +{"GreaterSlantEqual", "⩾", NULL}, +{"GreaterTilde", "≳", NULL}, +{"Gscr", "", NULL}, +{"Gt", "≫", NULL}, +{"HARDcy", "Ъ", NULL}, +{"Hacek", "ˇ", NULL}, +{"Hat", "^", NULL}, +{"Hcirc", "Ĥ", NULL}, +{"Hfr", "ℌ", NULL}, +{"HilbertSpace", "ℋ", NULL}, +{"Hopf", "ℍ", NULL}, +{"HorizontalLine", "─", NULL}, +{"Hscr", "ℋ", NULL}, +{"Hstrok", "Ħ", NULL}, +{"HumpDownHump", "≎", NULL}, +{"HumpEqual", "≏", NULL}, +{"IEcy", "Е", NULL}, +{"IJlig", "IJ", NULL}, +{"IOcy", "Ё", NULL}, +{"Iacute", "Í", "Í"}, +{"Icirc", "Î", "Î"}, +{"Icy", "И", NULL}, +{"Idot", "İ", NULL}, +{"Ifr", "ℑ", NULL}, +{"Igrave", "Ì", "Ì"}, +{"Im", "ℑ", NULL}, +{"Imacr", "Ī", NULL}, +{"ImaginaryI", "ⅈ", NULL}, +{"Implies", "⇒", NULL}, +{"Int", "∬", NULL}, +{"Integral", "∫", NULL}, +{"Intersection", "⋂", NULL}, +{"InvisibleComma", "", NULL}, +{"InvisibleTimes", "", NULL}, +{"Iogon", "Į", NULL}, +{"Iopf", "", NULL}, +{"Iota", "Ι", "Ι"}, +{"Iscr", "ℐ", NULL}, +{"Itilde", "Ĩ", NULL}, +{"Iukcy", "І", NULL}, +{"Iuml", "Ï", "Ï"}, +{"Jcirc", "Ĵ", NULL}, +{"Jcy", "Й", NULL}, +{"Jfr", "", NULL}, +{"Jopf", "", NULL}, +{"Jscr", "", NULL}, +{"Jsercy", "Ј", NULL}, +{"Jukcy", "Є", NULL}, +{"KHcy", "Х", NULL}, +{"KJcy", "Ќ", NULL}, +{"Kappa", "Κ", "Κ"}, +{"Kcedil", "Ķ", NULL}, +{"Kcy", "К", NULL}, +{"Kfr", "", NULL}, +{"Kopf", "", NULL}, +{"Kscr", "", NULL}, +{"LJcy", "Љ", NULL}, +{"LT", "<", NULL}, +{"Lacute", "Ĺ", NULL}, +{"Lambda", "Λ", "Λ"}, +{"Lang", "⟪", NULL}, +{"Laplacetrf", "ℒ", NULL}, +{"Larr", "↞", NULL}, +{"Lcaron", "Ľ", NULL}, +{"Lcedil", "Ļ", NULL}, +{"Lcy", "Л", NULL}, +{"LeftAngleBracket", "⟨", NULL}, +{"LeftArrow", "←", NULL}, +{"LeftArrowBar", "⇤", NULL}, +{"LeftArrowRightArrow", "⇆", NULL}, +{"LeftCeiling", "⌈", NULL}, +{"LeftDoubleBracket", "⟦", NULL}, +{"LeftDownTeeVector", "⥡", NULL}, +{"LeftDownVector", "⇃", NULL}, +{"LeftDownVectorBar", "⥙", NULL}, +{"LeftFloor", "⌊", NULL}, +{"LeftRightArrow", "↔", NULL}, +{"LeftRightVector", "⥎", NULL}, +{"LeftTee", "⊣", NULL}, +{"LeftTeeArrow", "↤", NULL}, +{"LeftTeeVector", "⥚", NULL}, +{"LeftTriangle", "⊲", NULL}, +{"LeftTriangleBar", "⧏", NULL}, +{"LeftTriangleEqual", "⊴", NULL}, +{"LeftUpDownVector", "⥑", NULL}, +{"LeftUpTeeVector", "⥠", NULL}, +{"LeftUpVector", "↿", NULL}, +{"LeftUpVectorBar", "⥘", NULL}, +{"LeftVector", "↼", NULL}, +{"LeftVectorBar", "⥒", NULL}, +{"Leftarrow", "⇐", NULL}, +{"Leftrightarrow", "⇔", NULL}, +{"LessEqualGreater", "⋚", NULL}, +{"LessFullEqual", "≦", NULL}, +{"LessGreater", "≶", NULL}, +{"LessLess", "⪡", NULL}, +{"LessSlantEqual", "⩽", NULL}, +{"LessTilde", "≲", NULL}, +{"Lfr", "", NULL}, +{"Ll", "⋘", NULL}, +{"Lleftarrow", "⇚", NULL}, +{"Lmidot", "Ŀ", NULL}, +{"LongLeftArrow", "⟵", NULL}, +{"LongLeftRightArrow", "⟷", NULL}, +{"LongRightArrow", "⟶", NULL}, +{"Longleftarrow", "⟸", NULL}, +{"Longleftrightarrow", "⟺", NULL}, +{"Longrightarrow", "⟹", NULL}, +{"Lopf", "", NULL}, +{"LowerLeftArrow", "↙", NULL}, +{"LowerRightArrow", "↘", NULL}, +{"Lscr", "ℒ", NULL}, +{"Lsh", "↰", NULL}, +{"Lstrok", "Ł", NULL}, +{"Lt", "≪", NULL}, +{"Map", "⤅", NULL}, +{"Mcy", "М", NULL}, +{"MediumSpace", " ", NULL}, +{"Mellintrf", "ℳ", NULL}, +{"Mfr", "", NULL}, +{"MinusPlus", "∓", NULL}, +{"Mopf", "", NULL}, +{"Mscr", "ℳ", NULL}, +{"Mu", "Μ", "Μ"}, +{"NJcy", "Њ", NULL}, +{"Nacute", "Ń", NULL}, +{"Ncaron", "Ň", NULL}, +{"Ncedil", "Ņ", NULL}, +{"Ncy", "Н", NULL}, +{"NegativeMediumSpace", "", NULL}, +{"NegativeThickSpace", "", NULL}, +{"NegativeThinSpace", "", NULL}, +{"NegativeVeryThinSpace", "", NULL}, +{"NestedGreaterGreater", "≫", NULL}, +{"NestedLessLess", "≪", NULL}, +{"NewLine", "\n", NULL}, +{"Nfr", "", NULL}, +{"NoBreak", "", NULL}, +{"NonBreakingSpace", " ", NULL}, +{"Nopf", "ℕ", NULL}, +{"Not", "⫬", NULL}, +{"NotCongruent", "≢", NULL}, +{"NotCupCap", "≭", NULL}, +{"NotDoubleVerticalBar", "∦", NULL}, +{"NotElement", "∉", NULL}, +{"NotEqual", "≠", NULL}, +{"NotEqualTilde", "≂̸", NULL}, +{"NotExists", "∄", NULL}, +{"NotGreater", "≯", NULL}, +{"NotGreaterEqual", "≱", NULL}, +{"NotGreaterFullEqual", "≧̸", NULL}, +{"NotGreaterGreater", "≫̸", NULL}, +{"NotGreaterLess", "≹", NULL}, +{"NotGreaterSlantEqual", "⩾̸", NULL}, +{"NotGreaterTilde", "≵", NULL}, +{"NotHumpDownHump", "≎̸", NULL}, +{"NotHumpEqual", "≏̸", NULL}, +{"NotLeftTriangle", "⋪", NULL}, +{"NotLeftTriangleBar", "⧏̸", NULL}, +{"NotLeftTriangleEqual", "⋬", NULL}, +{"NotLess", "≮", NULL}, +{"NotLessEqual", "≰", NULL}, +{"NotLessGreater", "≸", NULL}, +{"NotLessLess", "≪̸", NULL}, +{"NotLessSlantEqual", "⩽̸", NULL}, +{"NotLessTilde", "≴", NULL}, +{"NotNestedGreaterGreater", "⪢̸", NULL}, +{"NotNestedLessLess", "⪡̸", NULL}, +{"NotPrecedes", "⊀", NULL}, +{"NotPrecedesEqual", "⪯̸", NULL}, +{"NotPrecedesSlantEqual", "⋠", NULL}, +{"NotReverseElement", "∌", NULL}, +{"NotRightTriangle", "⋫", NULL}, +{"NotRightTriangleBar", "⧐̸", NULL}, +{"NotRightTriangleEqual", "⋭", NULL}, +{"NotSquareSubset", "⊏̸", NULL}, +{"NotSquareSubsetEqual", "⋢", NULL}, +{"NotSquareSuperset", "⊐̸", NULL}, +{"NotSquareSupersetEqual", "⋣", NULL}, +{"NotSubset", "⊂⃒", NULL}, +{"NotSubsetEqual", "⊈", NULL}, +{"NotSucceeds", "⊁", NULL}, +{"NotSucceedsEqual", "⪰̸", NULL}, +{"NotSucceedsSlantEqual", "⋡", NULL}, +{"NotSucceedsTilde", "≿̸", NULL}, +{"NotSuperset", "⊃⃒", NULL}, +{"NotSupersetEqual", "⊉", NULL}, +{"NotTilde", "≁", NULL}, +{"NotTildeEqual", "≄", NULL}, +{"NotTildeFullEqual", "≇", NULL}, +{"NotTildeTilde", "≉", NULL}, +{"NotVerticalBar", "∤", NULL}, +{"Nscr", "", NULL}, +{"Ntilde", "Ñ", "Ñ"}, +{"Nu", "Ν", "Ν"}, +{"OElig", "Œ", "Œ"}, +{"Oacute", "Ó", "Ó"}, +{"Ocirc", "Ô", "Ô"}, +{"Ocy", "О", NULL}, +{"Odblac", "Ő", NULL}, +{"Ofr", "", NULL}, +{"Ograve", "Ò", "Ò"}, +{"Omacr", "Ō", NULL}, +{"Omega", "Ω", "Ω"}, +{"Omicron", "Ο", "Ο"}, +{"Oopf", "", NULL}, +{"OpenCurlyDoubleQuote", "“", NULL}, +{"OpenCurlyQuote", "‘", NULL}, +{"Or", "⩔", NULL}, +{"Oscr", "", NULL}, +{"Oslash", "Ø", "Ø"}, +{"Otilde", "Õ", "Õ"}, +{"Otimes", "⨷", NULL}, +{"Ouml", "Ö", "Ö"}, +{"OverBar", "‾", NULL}, +{"OverBrace", "⏞", NULL}, +{"OverBracket", "⎴", NULL}, +{"OverParenthesis", "⏜", NULL}, +{"PartialD", "∂", NULL}, +{"Pcy", "П", NULL}, +{"Pfr", "", NULL}, +{"Phi", "Φ", "Φ"}, +{"Pi", "Π", "Π"}, +{"PlusMinus", "±", NULL}, +{"Poincareplane", "ℌ", NULL}, +{"Popf", "ℙ", NULL}, +{"Pr", "⪻", NULL}, +{"Precedes", "≺", NULL}, +{"PrecedesEqual", "⪯", NULL}, +{"PrecedesSlantEqual", "≼", NULL}, +{"PrecedesTilde", "≾", NULL}, +{"Prime", "″", "″"}, +{"Product", "∏", NULL}, +{"Proportion", "∷", NULL}, +{"Proportional", "∝", NULL}, +{"Pscr", "", NULL}, +{"Psi", "Ψ", "Ψ"}, +{"QUOT", "\"", NULL}, +{"Qfr", "", NULL}, +{"Qopf", "ℚ", NULL}, +{"Qscr", "", NULL}, +{"RBarr", "⤐", NULL}, +{"REG", "®", NULL}, +{"Racute", "Ŕ", NULL}, +{"Rang", "⟫", NULL}, +{"Rarr", "↠", NULL}, +{"Rarrtl", "⤖", NULL}, +{"Rcaron", "Ř", NULL}, +{"Rcedil", "Ŗ", NULL}, +{"Rcy", "Р", NULL}, +{"Re", "ℜ", NULL}, +{"ReverseElement", "∋", NULL}, +{"ReverseEquilibrium", "⇋", NULL}, +{"ReverseUpEquilibrium", "⥯", NULL}, +{"Rfr", "ℜ", NULL}, +{"Rho", "Ρ", "Ρ"}, +{"RightAngleBracket", "⟩", NULL}, +{"RightArrow", "→", NULL}, +{"RightArrowBar", "⇥", NULL}, +{"RightArrowLeftArrow", "⇄", NULL}, +{"RightCeiling", "⌉", NULL}, +{"RightDoubleBracket", "⟧", NULL}, +{"RightDownTeeVector", "⥝", NULL}, +{"RightDownVector", "⇂", NULL}, +{"RightDownVectorBar", "⥕", NULL}, +{"RightFloor", "⌋", NULL}, +{"RightTee", "⊢", NULL}, +{"RightTeeArrow", "↦", NULL}, +{"RightTeeVector", "⥛", NULL}, +{"RightTriangle", "⊳", NULL}, +{"RightTriangleBar", "⧐", NULL}, +{"RightTriangleEqual", "⊵", NULL}, +{"RightUpDownVector", "⥏", NULL}, +{"RightUpTeeVector", "⥜", NULL}, +{"RightUpVector", "↾", NULL}, +{"RightUpVectorBar", "⥔", NULL}, +{"RightVector", "⇀", NULL}, +{"RightVectorBar", "⥓", NULL}, +{"Rightarrow", "⇒", NULL}, +{"Ropf", "ℝ", NULL}, +{"RoundImplies", "⥰", NULL}, +{"Rrightarrow", "⇛", NULL}, +{"Rscr", "ℛ", NULL}, +{"Rsh", "↱", NULL}, +{"RuleDelayed", "⧴", NULL}, +{"SHCHcy", "Щ", NULL}, +{"SHcy", "Ш", NULL}, +{"SOFTcy", "Ь", NULL}, +{"Sacute", "Ś", NULL}, +{"Sc", "⪼", NULL}, +{"Scaron", "Š", "Š"}, +{"Scedil", "Ş", NULL}, +{"Scirc", "Ŝ", NULL}, +{"Scy", "С", NULL}, +{"Sfr", "", NULL}, +{"ShortDownArrow", "↓", NULL}, +{"ShortLeftArrow", "←", NULL}, +{"ShortRightArrow", "→", NULL}, +{"ShortUpArrow", "↑", NULL}, +{"Sigma", "Σ", "Σ"}, +{"SmallCircle", "∘", NULL}, +{"Sopf", "", NULL}, +{"Sqrt", "√", NULL}, +{"Square", "□", NULL}, +{"SquareIntersection", "⊓", NULL}, +{"SquareSubset", "⊏", NULL}, +{"SquareSubsetEqual", "⊑", NULL}, +{"SquareSuperset", "⊐", NULL}, +{"SquareSupersetEqual", "⊒", NULL}, +{"SquareUnion", "⊔", NULL}, +{"Sscr", "", NULL}, +{"Star", "⋆", NULL}, +{"Sub", "⋐", NULL}, +{"Subset", "⋐", NULL}, +{"SubsetEqual", "⊆", NULL}, +{"Succeeds", "≻", NULL}, +{"SucceedsEqual", "⪰", NULL}, +{"SucceedsSlantEqual", "≽", NULL}, +{"SucceedsTilde", "≿", NULL}, +{"SuchThat", "∋", NULL}, +{"Sum", "∑", NULL}, +{"Sup", "⋑", NULL}, +{"Superset", "⊃", NULL}, +{"SupersetEqual", "⊇", NULL}, +{"Supset", "⋑", NULL}, +{"THORN", "Þ", "Þ"}, +{"TRADE", "™", NULL}, +{"TSHcy", "Ћ", NULL}, +{"TScy", "Ц", NULL}, +{"Tab", "\t", NULL}, +{"Tau", "Τ", "Τ"}, +{"Tcaron", "Ť", NULL}, +{"Tcedil", "Ţ", NULL}, +{"Tcy", "Т", NULL}, +{"Tfr", "", NULL}, +{"Therefore", "∴", NULL}, +{"Theta", "Θ", "Θ"}, +{"ThickSpace", " ", NULL}, +{"ThinSpace", " ", NULL}, +{"Tilde", "∼", NULL}, +{"TildeEqual", "≃", NULL}, +{"TildeFullEqual", "≅", NULL}, +{"TildeTilde", "≈", NULL}, +{"Topf", "", NULL}, +{"TripleDot", "⃛", NULL}, +{"Tscr", "", NULL}, +{"Tstrok", "Ŧ", NULL}, +{"Uacute", "Ú", "Ú"}, +{"Uarr", "↟", NULL}, +{"Uarrocir", "⥉", NULL}, +{"Ubrcy", "Ў", NULL}, +{"Ubreve", "Ŭ", NULL}, +{"Ucirc", "Û", "Û"}, +{"Ucy", "У", NULL}, +{"Udblac", "Ű", NULL}, +{"Ufr", "", NULL}, +{"Ugrave", "Ù", "Ù"}, +{"Umacr", "Ū", NULL}, +{"UnderBar", "_", NULL}, +{"UnderBrace", "⏟", NULL}, +{"UnderBracket", "⎵", NULL}, +{"UnderParenthesis", "⏝", NULL}, +{"Union", "⋃", NULL}, +{"UnionPlus", "⊎", NULL}, +{"Uogon", "Ų", NULL}, +{"Uopf", "", NULL}, +{"UpArrow", "↑", NULL}, +{"UpArrowBar", "⤒", NULL}, +{"UpArrowDownArrow", "⇅", NULL}, +{"UpDownArrow", "↕", NULL}, +{"UpEquilibrium", "⥮", NULL}, +{"UpTee", "⊥", NULL}, +{"UpTeeArrow", "↥", NULL}, +{"Uparrow", "⇑", NULL}, +{"Updownarrow", "⇕", NULL}, +{"UpperLeftArrow", "↖", NULL}, +{"UpperRightArrow", "↗", NULL}, +{"Upsi", "ϒ", NULL}, +{"Upsilon", "Υ", "Υ"}, +{"Uring", "Ů", NULL}, +{"Uscr", "", NULL}, +{"Utilde", "Ũ", NULL}, +{"Uuml", "Ü", "Ü"}, +{"VDash", "⊫", NULL}, +{"Vbar", "⫫", NULL}, +{"Vcy", "В", NULL}, +{"Vdash", "⊩", NULL}, +{"Vdashl", "⫦", NULL}, +{"Vee", "⋁", NULL}, +{"Verbar", "‖", NULL}, +{"Vert", "‖", NULL}, +{"VerticalBar", "∣", NULL}, +{"VerticalLine", "|", NULL}, +{"VerticalSeparator", "❘", NULL}, +{"VerticalTilde", "≀", NULL}, +{"VeryThinSpace", " ", NULL}, +{"Vfr", "", NULL}, +{"Vopf", "", NULL}, +{"Vscr", "", NULL}, +{"Vvdash", "⊪", NULL}, +{"Wcirc", "Ŵ", NULL}, +{"Wedge", "⋀", NULL}, +{"Wfr", "", NULL}, +{"Wopf", "", NULL}, +{"Wscr", "", NULL}, +{"Xfr", "", NULL}, +{"Xi", "Ξ", "Ξ"}, +{"Xopf", "", NULL}, +{"Xscr", "", NULL}, +{"YAcy", "Я", NULL}, +{"YIcy", "Ї", NULL}, +{"YUcy", "Ю", NULL}, +{"Yacute", "Ý", "Ý"}, +{"Ycirc", "Ŷ", NULL}, +{"Ycy", "Ы", NULL}, +{"Yfr", "", NULL}, +{"Yopf", "", NULL}, +{"Yscr", "", NULL}, +{"Yuml", "Ÿ", "Ÿ"}, +{"ZHcy", "Ж", NULL}, +{"Zacute", "Ź", NULL}, +{"Zcaron", "Ž", NULL}, +{"Zcy", "З", NULL}, +{"Zdot", "Ż", NULL}, +{"ZeroWidthSpace", "", NULL}, +{"Zeta", "Ζ", "Ζ"}, +{"Zfr", "ℨ", NULL}, +{"Zopf", "ℤ", NULL}, +{"Zscr", "", NULL}, +{"aacute", "á", "á"}, +{"abreve", "ă", NULL}, +{"ac", "∾", NULL}, +{"acE", "∾̳", NULL}, +{"acd", "∿", NULL}, +{"acirc", "â", "â"}, +{"acute", "´", "´"}, +{"acy", "а", NULL}, +{"aelig", "æ", "æ"}, +{"af", "", NULL}, +{"afr", "", NULL}, +{"agrave", "à", "à"}, +{"alefsym", "ℵ", "ℵ"}, +{"aleph", "ℵ", NULL}, +{"alpha", "α", "α"}, +{"amacr", "ā", NULL}, +{"amalg", "⨿", NULL}, +{"amp", "&", "&"}, +{"and", "∧", "∧"}, +{"andand", "⩕", NULL}, +{"andd", "⩜", NULL}, +{"andslope", "⩘", NULL}, +{"andv", "⩚", NULL}, +{"ang", "∠", "∠"}, +{"ange", "⦤", NULL}, +{"angle", "∠", NULL}, +{"angmsd", "∡", NULL}, +{"angmsdaa", "⦨", NULL}, +{"angmsdab", "⦩", NULL}, +{"angmsdac", "⦪", NULL}, +{"angmsdad", "⦫", NULL}, +{"angmsdae", "⦬", NULL}, +{"angmsdaf", "⦭", NULL}, +{"angmsdag", "⦮", NULL}, +{"angmsdah", "⦯", NULL}, +{"angrt", "∟", NULL}, +{"angrtvb", "⊾", NULL}, +{"angrtvbd", "⦝", NULL}, +{"angsph", "∢", NULL}, +{"angst", "Å", NULL}, +{"angzarr", "⍼", NULL}, +{"aogon", "ą", NULL}, +{"aopf", "", NULL}, +{"ap", "≈", NULL}, +{"apE", "⩰", NULL}, +{"apacir", "⩯", NULL}, +{"ape", "≊", NULL}, +{"apid", "≋", NULL}, +{"apos", "'", NULL}, +{"approx", "≈", NULL}, +{"approxeq", "≊", NULL}, +{"aring", "å", "å"}, +{"ascr", "", NULL}, +{"ast", "*", NULL}, +{"asymp", "≈", "≈"}, +{"asympeq", "≍", NULL}, +{"atilde", "ã", "ã"}, +{"auml", "ä", "ä"}, +{"awconint", "∳", NULL}, +{"awint", "⨑", NULL}, +{"bNot", "⫭", NULL}, +{"backcong", "≌", NULL}, +{"backepsilon", "϶", NULL}, +{"backprime", "‵", NULL}, +{"backsim", "∽", NULL}, +{"backsimeq", "⋍", NULL}, +{"barvee", "⊽", NULL}, +{"barwed", "⌅", NULL}, +{"barwedge", "⌅", NULL}, +{"bbrk", "⎵", NULL}, +{"bbrktbrk", "⎶", NULL}, +{"bcong", "≌", NULL}, +{"bcy", "б", NULL}, +{"bdquo", "„", "„"}, +{"becaus", "∵", NULL}, +{"because", "∵", NULL}, +{"bemptyv", "⦰", NULL}, +{"bepsi", "϶", NULL}, +{"bernou", "ℬ", NULL}, +{"beta", "β", "β"}, +{"beth", "ℶ", NULL}, +{"between", "≬", NULL}, +{"bfr", "", NULL}, +{"bigcap", "⋂", NULL}, +{"bigcirc", "◯", NULL}, +{"bigcup", "⋃", NULL}, +{"bigodot", "⨀", NULL}, +{"bigoplus", "⨁", NULL}, +{"bigotimes", "⨂", NULL}, +{"bigsqcup", "⨆", NULL}, +{"bigstar", "★", NULL}, +{"bigtriangledown", "▽", NULL}, +{"bigtriangleup", "△", NULL}, +{"biguplus", "⨄", NULL}, +{"bigvee", "⋁", NULL}, +{"bigwedge", "⋀", NULL}, +{"bkarow", "⤍", NULL}, +{"blacklozenge", "⧫", NULL}, +{"blacksquare", "▪", NULL}, +{"blacktriangle", "▴", NULL}, +{"blacktriangledown", "▾", NULL}, +{"blacktriangleleft", "◂", NULL}, +{"blacktriangleright", "▸", NULL}, +{"blank", "␣", NULL}, +{"blk12", "▒", NULL}, +{"blk14", "░", NULL}, +{"blk34", "▓", NULL}, +{"block", "█", NULL}, +{"bne", "=⃥", NULL}, +{"bnequiv", "≡⃥", NULL}, +{"bnot", "⌐", NULL}, +{"bopf", "", NULL}, +{"bot", "⊥", NULL}, +{"bottom", "⊥", NULL}, +{"bowtie", "⋈", NULL}, +{"boxDL", "╗", NULL}, +{"boxDR", "╔", NULL}, +{"boxDl", "╖", NULL}, +{"boxDr", "╓", NULL}, +{"boxH", "═", NULL}, +{"boxHD", "╦", NULL}, +{"boxHU", "╩", NULL}, +{"boxHd", "╤", NULL}, +{"boxHu", "╧", NULL}, +{"boxUL", "╝", NULL}, +{"boxUR", "╚", NULL}, +{"boxUl", "╜", NULL}, +{"boxUr", "╙", NULL}, +{"boxV", "║", NULL}, +{"boxVH", "╬", NULL}, +{"boxVL", "╣", NULL}, +{"boxVR", "╠", NULL}, +{"boxVh", "╫", NULL}, +{"boxVl", "╢", NULL}, +{"boxVr", "╟", NULL}, +{"boxbox", "⧉", NULL}, +{"boxdL", "╕", NULL}, +{"boxdR", "╒", NULL}, +{"boxdl", "┐", NULL}, +{"boxdr", "┌", NULL}, +{"boxh", "─", NULL}, +{"boxhD", "╥", NULL}, +{"boxhU", "╨", NULL}, +{"boxhd", "┬", NULL}, +{"boxhu", "┴", NULL}, +{"boxminus", "⊟", NULL}, +{"boxplus", "⊞", NULL}, +{"boxtimes", "⊠", NULL}, +{"boxuL", "╛", NULL}, +{"boxuR", "╘", NULL}, +{"boxul", "┘", NULL}, +{"boxur", "└", NULL}, +{"boxv", "│", NULL}, +{"boxvH", "╪", NULL}, +{"boxvL", "╡", NULL}, +{"boxvR", "╞", NULL}, +{"boxvh", "┼", NULL}, +{"boxvl", "┤", NULL}, +{"boxvr", "├", NULL}, +{"bprime", "‵", NULL}, +{"breve", "˘", NULL}, +{"brvbar", "¦", "¦"}, +{"bscr", "", NULL}, +{"bsemi", "⁏", NULL}, +{"bsim", "∽", NULL}, +{"bsime", "⋍", NULL}, +{"bsol", "\\", NULL}, +{"bsolb", "⧅", NULL}, +{"bsolhsub", "⟈", NULL}, +{"bull", "•", "•"}, +{"bullet", "•", NULL}, +{"bump", "≎", NULL}, +{"bumpE", "⪮", NULL}, +{"bumpe", "≏", NULL}, +{"bumpeq", "≏", NULL}, +{"cacute", "ć", NULL}, +{"cap", "∩", "∩"}, +{"capand", "⩄", NULL}, +{"capbrcup", "⩉", NULL}, +{"capcap", "⩋", NULL}, +{"capcup", "⩇", NULL}, +{"capdot", "⩀", NULL}, +{"caps", "∩︀", NULL}, +{"caret", "⁁", NULL}, +{"caron", "ˇ", NULL}, +{"ccaps", "⩍", NULL}, +{"ccaron", "č", NULL}, +{"ccedil", "ç", "ç"}, +{"ccirc", "ĉ", NULL}, +{"ccups", "⩌", NULL}, +{"ccupssm", "⩐", NULL}, +{"cdot", "ċ", NULL}, +{"cedil", "¸", "¸"}, +{"cemptyv", "⦲", NULL}, +{"cent", "¢", "¢"}, +{"centerdot", "·", NULL}, +{"cfr", "", NULL}, +{"chcy", "ч", NULL}, +{"check", "✓", NULL}, +{"checkmark", "✓", NULL}, +{"chi", "χ", "χ"}, +{"cir", "○", NULL}, +{"cirE", "⧃", NULL}, +{"circ", "ˆ", "ˆ"}, +{"circeq", "≗", NULL}, +{"circlearrowleft", "↺", NULL}, +{"circlearrowright", "↻", NULL}, +{"circledR", "®", NULL}, +{"circledS", "Ⓢ", NULL}, +{"circledast", "⊛", NULL}, +{"circledcirc", "⊚", NULL}, +{"circleddash", "⊝", NULL}, +{"cire", "≗", NULL}, +{"cirfnint", "⨐", NULL}, +{"cirmid", "⫯", NULL}, +{"cirscir", "⧂", NULL}, +{"clubs", "♣", "♣"}, +{"clubsuit", "♣", NULL}, +{"colon", ":", NULL}, +{"colone", "≔", NULL}, +{"coloneq", "≔", NULL}, +{"comma", ",", NULL}, +{"commat", "@", NULL}, +{"comp", "∁", NULL}, +{"compfn", "∘", NULL}, +{"complement", "∁", NULL}, +{"complexes", "ℂ", NULL}, +{"cong", "≅", "≅"}, +{"congdot", "⩭", NULL}, +{"conint", "∮", NULL}, +{"copf", "", NULL}, +{"coprod", "∐", NULL}, +{"copy", "©", "©"}, +{"copysr", "℗", NULL}, +{"crarr", "↵", "↵"}, +{"cross", "✗", NULL}, +{"cscr", "", NULL}, +{"csub", "⫏", NULL}, +{"csube", "⫑", NULL}, +{"csup", "⫐", NULL}, +{"csupe", "⫒", NULL}, +{"ctdot", "⋯", NULL}, +{"cudarrl", "⤸", NULL}, +{"cudarrr", "⤵", NULL}, +{"cuepr", "⋞", NULL}, +{"cuesc", "⋟", NULL}, +{"cularr", "↶", NULL}, +{"cularrp", "⤽", NULL}, +{"cup", "∪", "∪"}, +{"cupbrcap", "⩈", NULL}, +{"cupcap", "⩆", NULL}, +{"cupcup", "⩊", NULL}, +{"cupdot", "⊍", NULL}, +{"cupor", "⩅", NULL}, +{"cups", "∪︀", NULL}, +{"curarr", "↷", NULL}, +{"curarrm", "⤼", NULL}, +{"curlyeqprec", "⋞", NULL}, +{"curlyeqsucc", "⋟", NULL}, +{"curlyvee", "⋎", NULL}, +{"curlywedge", "⋏", NULL}, +{"curren", "¤", "¤"}, +{"curvearrowleft", "↶", NULL}, +{"curvearrowright", "↷", NULL}, +{"cuvee", "⋎", NULL}, +{"cuwed", "⋏", NULL}, +{"cwconint", "∲", NULL}, +{"cwint", "∱", NULL}, +{"cylcty", "⌭", NULL}, +{"dArr", "⇓", "⇓"}, +{"dHar", "⥥", NULL}, +{"dagger", "†", "†"}, +{"daleth", "ℸ", NULL}, +{"darr", "↓", "↓"}, +{"dash", "‐", NULL}, +{"dashv", "⊣", NULL}, +{"dbkarow", "⤏", NULL}, +{"dblac", "˝", NULL}, +{"dcaron", "ď", NULL}, +{"dcy", "д", NULL}, +{"dd", "ⅆ", NULL}, +{"ddagger", "‡", NULL}, +{"ddarr", "⇊", NULL}, +{"ddotseq", "⩷", NULL}, +{"deg", "°", "°"}, +{"delta", "δ", "δ"}, +{"demptyv", "⦱", NULL}, +{"dfisht", "⥿", NULL}, +{"dfr", "", NULL}, +{"dharl", "⇃", NULL}, +{"dharr", "⇂", NULL}, +{"diam", "⋄", NULL}, +{"diamond", "⋄", NULL}, +{"diamondsuit", "♦", NULL}, +{"diams", "♦", "♦"}, +{"die", "¨", NULL}, +{"digamma", "ϝ", NULL}, +{"disin", "⋲", NULL}, +{"div", "÷", NULL}, +{"divide", "÷", "÷"}, +{"divideontimes", "⋇", NULL}, +{"divonx", "⋇", NULL}, +{"djcy", "ђ", NULL}, +{"dlcorn", "⌞", NULL}, +{"dlcrop", "⌍", NULL}, +{"dollar", "$", NULL}, +{"dopf", "", NULL}, +{"dot", "˙", NULL}, +{"doteq", "≐", NULL}, +{"doteqdot", "≑", NULL}, +{"dotminus", "∸", NULL}, +{"dotplus", "∔", NULL}, +{"dotsquare", "⊡", NULL}, +{"doublebarwedge", "⌆", NULL}, +{"downarrow", "↓", NULL}, +{"downdownarrows", "⇊", NULL}, +{"downharpoonleft", "⇃", NULL}, +{"downharpoonright", "⇂", NULL}, +{"drbkarow", "⤐", NULL}, +{"drcorn", "⌟", NULL}, +{"drcrop", "⌌", NULL}, +{"dscr", "", NULL}, +{"dscy", "ѕ", NULL}, +{"dsol", "⧶", NULL}, +{"dstrok", "đ", NULL}, +{"dtdot", "⋱", NULL}, +{"dtri", "▿", NULL}, +{"dtrif", "▾", NULL}, +{"duarr", "⇵", NULL}, +{"duhar", "⥯", NULL}, +{"dwangle", "⦦", NULL}, +{"dzcy", "џ", NULL}, +{"dzigrarr", "⟿", NULL}, +{"eDDot", "⩷", NULL}, +{"eDot", "≑", NULL}, +{"eacute", "é", "é"}, +{"easter", "⩮", NULL}, +{"ecaron", "ě", NULL}, +{"ecir", "≖", NULL}, +{"ecirc", "ê", "ê"}, +{"ecolon", "≕", NULL}, +{"ecy", "э", NULL}, +{"edot", "ė", NULL}, +{"ee", "ⅇ", NULL}, +{"efDot", "≒", NULL}, +{"efr", "", NULL}, +{"eg", "⪚", NULL}, +{"egrave", "è", "è"}, +{"egs", "⪖", NULL}, +{"egsdot", "⪘", NULL}, +{"el", "⪙", NULL}, +{"elinters", "⏧", NULL}, +{"ell", "ℓ", NULL}, +{"els", "⪕", NULL}, +{"elsdot", "⪗", NULL}, +{"emacr", "ē", NULL}, +{"empty", "∅", "∅"}, +{"emptyset", "∅", NULL}, +{"emptyv", "∅", NULL}, +{"emsp", " ", " "}, +{"emsp13", " ", NULL}, +{"emsp14", " ", NULL}, +{"eng", "ŋ", NULL}, +{"ensp", " ", " "}, +{"eogon", "ę", NULL}, +{"eopf", "", NULL}, +{"epar", "⋕", NULL}, +{"eparsl", "⧣", NULL}, +{"eplus", "⩱", NULL}, +{"epsi", "ε", NULL}, +{"epsilon", "ε", "ε"}, +{"epsiv", "ϵ", NULL}, +{"eqcirc", "≖", NULL}, +{"eqcolon", "≕", NULL}, +{"eqsim", "≂", NULL}, +{"eqslantgtr", "⪖", NULL}, +{"eqslantless", "⪕", NULL}, +{"equals", "=", NULL}, +{"equest", "≟", NULL}, +{"equiv", "≡", "≡"}, +{"equivDD", "⩸", NULL}, +{"eqvparsl", "⧥", NULL}, +{"erDot", "≓", NULL}, +{"erarr", "⥱", NULL}, +{"escr", "ℯ", NULL}, +{"esdot", "≐", NULL}, +{"esim", "≂", NULL}, +{"eta", "η", "η"}, +{"eth", "ð", "ð"}, +{"euml", "ë", "ë"}, +{"euro", "€", "€"}, +{"excl", "!", NULL}, +{"exist", "∃", "∃"}, +{"expectation", "ℰ", NULL}, +{"exponentiale", "ⅇ", NULL}, +{"fallingdotseq", "≒", NULL}, +{"fcy", "ф", NULL}, +{"female", "♀", NULL}, +{"ffilig", "ffi", NULL}, +{"fflig", "ff", NULL}, +{"ffllig", "ffl", NULL}, +{"ffr", "", NULL}, +{"filig", "fi", NULL}, +{"fjlig", "fj", NULL}, +{"flat", "♭", NULL}, +{"fllig", "fl", NULL}, +{"fltns", "▱", NULL}, +{"fnof", "ƒ", "ƒ"}, +{"fopf", "", NULL}, +{"forall", "∀", "∀"}, +{"fork", "⋔", NULL}, +{"forkv", "⫙", NULL}, +{"fpartint", "⨍", NULL}, +{"frac12", "½", "½"}, +{"frac13", "⅓", NULL}, +{"frac14", "¼", "¼"}, +{"frac15", "⅕", NULL}, +{"frac16", "⅙", NULL}, +{"frac18", "⅛", NULL}, +{"frac23", "⅔", NULL}, +{"frac25", "⅖", NULL}, +{"frac34", "¾", "¾"}, +{"frac35", "⅗", NULL}, +{"frac38", "⅜", NULL}, +{"frac45", "⅘", NULL}, +{"frac56", "⅚", NULL}, +{"frac58", "⅝", NULL}, +{"frac78", "⅞", NULL}, +{"frasl", "⁄", "⁄"}, +{"frown", "⌢", NULL}, +{"fscr", "", NULL}, +{"gE", "≧", NULL}, +{"gEl", "⪌", NULL}, +{"gacute", "ǵ", NULL}, +{"gamma", "γ", "γ"}, +{"gammad", "ϝ", NULL}, +{"gap", "⪆", NULL}, +{"gbreve", "ğ", NULL}, +{"gcirc", "ĝ", NULL}, +{"gcy", "г", NULL}, +{"gdot", "ġ", NULL}, +{"ge", "≥", "≥"}, +{"gel", "⋛", NULL}, +{"geq", "≥", NULL}, +{"geqq", "≧", NULL}, +{"geqslant", "⩾", NULL}, +{"ges", "⩾", NULL}, +{"gescc", "⪩", NULL}, +{"gesdot", "⪀", NULL}, +{"gesdoto", "⪂", NULL}, +{"gesdotol", "⪄", NULL}, +{"gesl", "⋛︀", NULL}, +{"gesles", "⪔", NULL}, +{"gfr", "", NULL}, +{"gg", "≫", NULL}, +{"ggg", "⋙", NULL}, +{"gimel", "ℷ", NULL}, +{"gjcy", "ѓ", NULL}, +{"gl", "≷", NULL}, +{"glE", "⪒", NULL}, +{"gla", "⪥", NULL}, +{"glj", "⪤", NULL}, +{"gnE", "≩", NULL}, +{"gnap", "⪊", NULL}, +{"gnapprox", "⪊", NULL}, +{"gne", "⪈", NULL}, +{"gneq", "⪈", NULL}, +{"gneqq", "≩", NULL}, +{"gnsim", "⋧", NULL}, +{"gopf", "", NULL}, +{"grave", "`", NULL}, +{"gscr", "ℊ", NULL}, +{"gsim", "≳", NULL}, +{"gsime", "⪎", NULL}, +{"gsiml", "⪐", NULL}, +{"gt", ">", ">"}, +{"gtcc", "⪧", NULL}, +{"gtcir", "⩺", NULL}, +{"gtdot", "⋗", NULL}, +{"gtlPar", "⦕", NULL}, +{"gtquest", "⩼", NULL}, +{"gtrapprox", "⪆", NULL}, +{"gtrarr", "⥸", NULL}, +{"gtrdot", "⋗", NULL}, +{"gtreqless", "⋛", NULL}, +{"gtreqqless", "⪌", NULL}, +{"gtrless", "≷", NULL}, +{"gtrsim", "≳", NULL}, +{"gvertneqq", "≩︀", NULL}, +{"gvnE", "≩︀", NULL}, +{"hArr", "⇔", "⇔"}, +{"hairsp", " ", NULL}, +{"half", "½", NULL}, +{"hamilt", "ℋ", NULL}, +{"hardcy", "ъ", NULL}, +{"harr", "↔", "↔"}, +{"harrcir", "⥈", NULL}, +{"harrw", "↭", NULL}, +{"hbar", "ℏ", NULL}, +{"hcirc", "ĥ", NULL}, +{"hearts", "♥", "♥"}, +{"heartsuit", "♥", NULL}, +{"hellip", "…", "…"}, +{"hercon", "⊹", NULL}, +{"hfr", "", NULL}, +{"hksearow", "⤥", NULL}, +{"hkswarow", "⤦", NULL}, +{"hoarr", "⇿", NULL}, +{"homtht", "∻", NULL}, +{"hookleftarrow", "↩", NULL}, +{"hookrightarrow", "↪", NULL}, +{"hopf", "", NULL}, +{"horbar", "―", NULL}, +{"hscr", "", NULL}, +{"hslash", "ℏ", NULL}, +{"hstrok", "ħ", NULL}, +{"hybull", "⁃", NULL}, +{"hyphen", "‐", NULL}, +{"iacute", "í", "í"}, +{"ic", "", NULL}, +{"icirc", "î", "î"}, +{"icy", "и", NULL}, +{"iecy", "е", NULL}, +{"iexcl", "¡", "¡"}, +{"iff", "⇔", NULL}, +{"ifr", "", NULL}, +{"igrave", "ì", "ì"}, +{"ii", "ⅈ", NULL}, +{"iiiint", "⨌", NULL}, +{"iiint", "∭", NULL}, +{"iinfin", "⧜", NULL}, +{"iiota", "℩", NULL}, +{"ijlig", "ij", NULL}, +{"imacr", "ī", NULL}, +{"image", "ℑ", "ℑ"}, +{"imagline", "ℐ", NULL}, +{"imagpart", "ℑ", NULL}, +{"imath", "ı", NULL}, +{"imof", "⊷", NULL}, +{"imped", "Ƶ", NULL}, +{"in", "∈", NULL}, +{"incare", "℅", NULL}, +{"infin", "∞", "∞"}, +{"infintie", "⧝", NULL}, +{"inodot", "ı", NULL}, +{"int", "∫", "∫"}, +{"intcal", "⊺", NULL}, +{"integers", "ℤ", NULL}, +{"intercal", "⊺", NULL}, +{"intlarhk", "⨗", NULL}, +{"intprod", "⨼", NULL}, +{"iocy", "ё", NULL}, +{"iogon", "į", NULL}, +{"iopf", "", NULL}, +{"iota", "ι", "ι"}, +{"iprod", "⨼", NULL}, +{"iquest", "¿", "¿"}, +{"iscr", "", NULL}, +{"isin", "∈", "∈"}, +{"isinE", "⋹", NULL}, +{"isindot", "⋵", NULL}, +{"isins", "⋴", NULL}, +{"isinsv", "⋳", NULL}, +{"isinv", "∈", NULL}, +{"it", "", NULL}, +{"itilde", "ĩ", NULL}, +{"iukcy", "і", NULL}, +{"iuml", "ï", "ï"}, +{"jcirc", "ĵ", NULL}, +{"jcy", "й", NULL}, +{"jfr", "", NULL}, +{"jmath", "ȷ", NULL}, +{"jopf", "", NULL}, +{"jscr", "", NULL}, +{"jsercy", "ј", NULL}, +{"jukcy", "є", NULL}, +{"kappa", "κ", "κ"}, +{"kappav", "ϰ", NULL}, +{"kcedil", "ķ", NULL}, +{"kcy", "к", NULL}, +{"kfr", "", NULL}, +{"kgreen", "ĸ", NULL}, +{"khcy", "х", NULL}, +{"kjcy", "ќ", NULL}, +{"kopf", "", NULL}, +{"kscr", "", NULL}, +{"lAarr", "⇚", NULL}, +{"lArr", "⇐", "⇐"}, +{"lAtail", "⤛", NULL}, +{"lBarr", "⤎", NULL}, +{"lE", "≦", NULL}, +{"lEg", "⪋", NULL}, +{"lHar", "⥢", NULL}, +{"lacute", "ĺ", NULL}, +{"laemptyv", "⦴", NULL}, +{"lagran", "ℒ", NULL}, +{"lambda", "λ", "λ"}, +{"lang", "⟨", "〈"}, +{"langd", "⦑", NULL}, +{"langle", "⟨", NULL}, +{"lap", "⪅", NULL}, +{"laquo", "«", "«"}, +{"larr", "←", "←"}, +{"larrb", "⇤", NULL}, +{"larrbfs", "⤟", NULL}, +{"larrfs", "⤝", NULL}, +{"larrhk", "↩", NULL}, +{"larrlp", "↫", NULL}, +{"larrpl", "⤹", NULL}, +{"larrsim", "⥳", NULL}, +{"larrtl", "↢", NULL}, +{"lat", "⪫", NULL}, +{"latail", "⤙", NULL}, +{"late", "⪭", NULL}, +{"lates", "⪭︀", NULL}, +{"lbarr", "⤌", NULL}, +{"lbbrk", "❲", NULL}, +{"lbrace", "{", NULL}, +{"lbrack", "[", NULL}, +{"lbrke", "⦋", NULL}, +{"lbrksld", "⦏", NULL}, +{"lbrkslu", "⦍", NULL}, +{"lcaron", "ľ", NULL}, +{"lcedil", "ļ", NULL}, +{"lceil", "⌈", "⌈"}, +{"lcub", "{", NULL}, +{"lcy", "л", NULL}, +{"ldca", "⤶", NULL}, +{"ldquo", "“", "“"}, +{"ldquor", "„", NULL}, +{"ldrdhar", "⥧", NULL}, +{"ldrushar", "⥋", NULL}, +{"ldsh", "↲", NULL}, +{"le", "≤", "≤"}, +{"leftarrow", "←", NULL}, +{"leftarrowtail", "↢", NULL}, +{"leftharpoondown", "↽", NULL}, +{"leftharpoonup", "↼", NULL}, +{"leftleftarrows", "⇇", NULL}, +{"leftrightarrow", "↔", NULL}, +{"leftrightarrows", "⇆", NULL}, +{"leftrightharpoons", "⇋", NULL}, +{"leftrightsquigarrow", "↭", NULL}, +{"leftthreetimes", "⋋", NULL}, +{"leg", "⋚", NULL}, +{"leq", "≤", NULL}, +{"leqq", "≦", NULL}, +{"leqslant", "⩽", NULL}, +{"les", "⩽", NULL}, +{"lescc", "⪨", NULL}, +{"lesdot", "⩿", NULL}, +{"lesdoto", "⪁", NULL}, +{"lesdotor", "⪃", NULL}, +{"lesg", "⋚︀", NULL}, +{"lesges", "⪓", NULL}, +{"lessapprox", "⪅", NULL}, +{"lessdot", "⋖", NULL}, +{"lesseqgtr", "⋚", NULL}, +{"lesseqqgtr", "⪋", NULL}, +{"lessgtr", "≶", NULL}, +{"lesssim", "≲", NULL}, +{"lfisht", "⥼", NULL}, +{"lfloor", "⌊", "⌊"}, +{"lfr", "", NULL}, +{"lg", "≶", NULL}, +{"lgE", "⪑", NULL}, +{"lhard", "↽", NULL}, +{"lharu", "↼", NULL}, +{"lharul", "⥪", NULL}, +{"lhblk", "▄", NULL}, +{"ljcy", "љ", NULL}, +{"ll", "≪", NULL}, +{"llarr", "⇇", NULL}, +{"llcorner", "⌞", NULL}, +{"llhard", "⥫", NULL}, +{"lltri", "◺", NULL}, +{"lmidot", "ŀ", NULL}, +{"lmoust", "⎰", NULL}, +{"lmoustache", "⎰", NULL}, +{"lnE", "≨", NULL}, +{"lnap", "⪉", NULL}, +{"lnapprox", "⪉", NULL}, +{"lne", "⪇", NULL}, +{"lneq", "⪇", NULL}, +{"lneqq", "≨", NULL}, +{"lnsim", "⋦", NULL}, +{"loang", "⟬", NULL}, +{"loarr", "⇽", NULL}, +{"lobrk", "⟦", NULL}, +{"longleftarrow", "⟵", NULL}, +{"longleftrightarrow", "⟷", NULL}, +{"longmapsto", "⟼", NULL}, +{"longrightarrow", "⟶", NULL}, +{"looparrowleft", "↫", NULL}, +{"looparrowright", "↬", NULL}, +{"lopar", "⦅", NULL}, +{"lopf", "", NULL}, +{"loplus", "⨭", NULL}, +{"lotimes", "⨴", NULL}, +{"lowast", "∗", "∗"}, +{"lowbar", "_", NULL}, +{"loz", "◊", "◊"}, +{"lozenge", "◊", NULL}, +{"lozf", "⧫", NULL}, +{"lpar", "(", NULL}, +{"lparlt", "⦓", NULL}, +{"lrarr", "⇆", NULL}, +{"lrcorner", "⌟", NULL}, +{"lrhar", "⇋", NULL}, +{"lrhard", "⥭", NULL}, +{"lrm", "", ""}, +{"lrtri", "⊿", NULL}, +{"lsaquo", "‹", "‹"}, +{"lscr", "", NULL}, +{"lsh", "↰", NULL}, +{"lsim", "≲", NULL}, +{"lsime", "⪍", NULL}, +{"lsimg", "⪏", NULL}, +{"lsqb", "[", NULL}, +{"lsquo", "‘", "‘"}, +{"lsquor", "‚", NULL}, +{"lstrok", "ł", NULL}, +{"lt", "<", "<"}, +{"ltcc", "⪦", NULL}, +{"ltcir", "⩹", NULL}, +{"ltdot", "⋖", NULL}, +{"lthree", "⋋", NULL}, +{"ltimes", "⋉", NULL}, +{"ltlarr", "⥶", NULL}, +{"ltquest", "⩻", NULL}, +{"ltrPar", "⦖", NULL}, +{"ltri", "◃", NULL}, +{"ltrie", "⊴", NULL}, +{"ltrif", "◂", NULL}, +{"lurdshar", "⥊", NULL}, +{"luruhar", "⥦", NULL}, +{"lvertneqq", "≨︀", NULL}, +{"lvnE", "≨︀", NULL}, +{"mDDot", "∺", NULL}, +{"macr", "¯", "¯"}, +{"male", "♂", NULL}, +{"malt", "✠", NULL}, +{"maltese", "✠", NULL}, +{"map", "↦", NULL}, +{"mapsto", "↦", NULL}, +{"mapstodown", "↧", NULL}, +{"mapstoleft", "↤", NULL}, +{"mapstoup", "↥", NULL}, +{"marker", "▮", NULL}, +{"mcomma", "⨩", NULL}, +{"mcy", "м", NULL}, +{"mdash", "—", "—"}, +{"measuredangle", "∡", NULL}, +{"mfr", "", NULL}, +{"mho", "℧", NULL}, +{"micro", "µ", "µ"}, +{"mid", "∣", NULL}, +{"midast", "*", NULL}, +{"midcir", "⫰", NULL}, +{"middot", "·", "·"}, +{"minus", "−", "−"}, +{"minusb", "⊟", NULL}, +{"minusd", "∸", NULL}, +{"minusdu", "⨪", NULL}, +{"mlcp", "⫛", NULL}, +{"mldr", "…", NULL}, +{"mnplus", "∓", NULL}, +{"models", "⊧", NULL}, +{"mopf", "", NULL}, +{"mp", "∓", NULL}, +{"mscr", "", NULL}, +{"mstpos", "∾", NULL}, +{"mu", "μ", "μ"}, +{"multimap", "⊸", NULL}, +{"mumap", "⊸", NULL}, +{"nGg", "⋙̸", NULL}, +{"nGt", "≫⃒", NULL}, +{"nGtv", "≫̸", NULL}, +{"nLeftarrow", "⇍", NULL}, +{"nLeftrightarrow", "⇎", NULL}, +{"nLl", "⋘̸", NULL}, +{"nLt", "≪⃒", NULL}, +{"nLtv", "≪̸", NULL}, +{"nRightarrow", "⇏", NULL}, +{"nVDash", "⊯", NULL}, +{"nVdash", "⊮", NULL}, +{"nabla", "∇", "∇"}, +{"nacute", "ń", NULL}, +{"nang", "∠⃒", NULL}, +{"nap", "≉", NULL}, +{"napE", "⩰̸", NULL}, +{"napid", "≋̸", NULL}, +{"napos", "ʼn", NULL}, +{"napprox", "≉", NULL}, +{"natur", "♮", NULL}, +{"natural", "♮", NULL}, +{"naturals", "ℕ", NULL}, +{"nbsp", " ", " "}, +{"nbump", "≎̸", NULL}, +{"nbumpe", "≏̸", NULL}, +{"ncap", "⩃", NULL}, +{"ncaron", "ň", NULL}, +{"ncedil", "ņ", NULL}, +{"ncong", "≇", NULL}, +{"ncongdot", "⩭̸", NULL}, +{"ncup", "⩂", NULL}, +{"ncy", "н", NULL}, +{"ndash", "–", "–"}, +{"ne", "≠", "≠"}, +{"neArr", "⇗", NULL}, +{"nearhk", "⤤", NULL}, +{"nearr", "↗", NULL}, +{"nearrow", "↗", NULL}, +{"nedot", "≐̸", NULL}, +{"nequiv", "≢", NULL}, +{"nesear", "⤨", NULL}, +{"nesim", "≂̸", NULL}, +{"nexist", "∄", NULL}, +{"nexists", "∄", NULL}, +{"nfr", "", NULL}, +{"ngE", "≧̸", NULL}, +{"nge", "≱", NULL}, +{"ngeq", "≱", NULL}, +{"ngeqq", "≧̸", NULL}, +{"ngeqslant", "⩾̸", NULL}, +{"nges", "⩾̸", NULL}, +{"ngsim", "≵", NULL}, +{"ngt", "≯", NULL}, +{"ngtr", "≯", NULL}, +{"nhArr", "⇎", NULL}, +{"nharr", "↮", NULL}, +{"nhpar", "⫲", NULL}, +{"ni", "∋", "∋"}, +{"nis", "⋼", NULL}, +{"nisd", "⋺", NULL}, +{"niv", "∋", NULL}, +{"njcy", "њ", NULL}, +{"nlArr", "⇍", NULL}, +{"nlE", "≦̸", NULL}, +{"nlarr", "↚", NULL}, +{"nldr", "‥", NULL}, +{"nle", "≰", NULL}, +{"nleftarrow", "↚", NULL}, +{"nleftrightarrow", "↮", NULL}, +{"nleq", "≰", NULL}, +{"nleqq", "≦̸", NULL}, +{"nleqslant", "⩽̸", NULL}, +{"nles", "⩽̸", NULL}, +{"nless", "≮", NULL}, +{"nlsim", "≴", NULL}, +{"nlt", "≮", NULL}, +{"nltri", "⋪", NULL}, +{"nltrie", "⋬", NULL}, +{"nmid", "∤", NULL}, +{"nopf", "", NULL}, +{"not", "¬", "¬"}, +{"notin", "∉", "∉"}, +{"notinE", "⋹̸", NULL}, +{"notindot", "⋵̸", NULL}, +{"notinva", "∉", NULL}, +{"notinvb", "⋷", NULL}, +{"notinvc", "⋶", NULL}, +{"notni", "∌", NULL}, +{"notniva", "∌", NULL}, +{"notnivb", "⋾", NULL}, +{"notnivc", "⋽", NULL}, +{"npar", "∦", NULL}, +{"nparallel", "∦", NULL}, +{"nparsl", "⫽⃥", NULL}, +{"npart", "∂̸", NULL}, +{"npolint", "⨔", NULL}, +{"npr", "⊀", NULL}, +{"nprcue", "⋠", NULL}, +{"npre", "⪯̸", NULL}, +{"nprec", "⊀", NULL}, +{"npreceq", "⪯̸", NULL}, +{"nrArr", "⇏", NULL}, +{"nrarr", "↛", NULL}, +{"nrarrc", "⤳̸", NULL}, +{"nrarrw", "↝̸", NULL}, +{"nrightarrow", "↛", NULL}, +{"nrtri", "⋫", NULL}, +{"nrtrie", "⋭", NULL}, +{"nsc", "⊁", NULL}, +{"nsccue", "⋡", NULL}, +{"nsce", "⪰̸", NULL}, +{"nscr", "", NULL}, +{"nshortmid", "∤", NULL}, +{"nshortparallel", "∦", NULL}, +{"nsim", "≁", NULL}, +{"nsime", "≄", NULL}, +{"nsimeq", "≄", NULL}, +{"nsmid", "∤", NULL}, +{"nspar", "∦", NULL}, +{"nsqsube", "⋢", NULL}, +{"nsqsupe", "⋣", NULL}, +{"nsub", "⊄", "⊄"}, +{"nsubE", "⫅̸", NULL}, +{"nsube", "⊈", NULL}, +{"nsubset", "⊂⃒", NULL}, +{"nsubseteq", "⊈", NULL}, +{"nsubseteqq", "⫅̸", NULL}, +{"nsucc", "⊁", NULL}, +{"nsucceq", "⪰̸", NULL}, +{"nsup", "⊅", NULL}, +{"nsupE", "⫆̸", NULL}, +{"nsupe", "⊉", NULL}, +{"nsupset", "⊃⃒", NULL}, +{"nsupseteq", "⊉", NULL}, +{"nsupseteqq", "⫆̸", NULL}, +{"ntgl", "≹", NULL}, +{"ntilde", "ñ", "ñ"}, +{"ntlg", "≸", NULL}, +{"ntriangleleft", "⋪", NULL}, +{"ntrianglelefteq", "⋬", NULL}, +{"ntriangleright", "⋫", NULL}, +{"ntrianglerighteq", "⋭", NULL}, +{"nu", "ν", "ν"}, +{"num", "#", NULL}, +{"numero", "№", NULL}, +{"numsp", " ", NULL}, +{"nvDash", "⊭", NULL}, +{"nvHarr", "⤄", NULL}, +{"nvap", "≍⃒", NULL}, +{"nvdash", "⊬", NULL}, +{"nvge", "≥⃒", NULL}, +{"nvgt", ">⃒", NULL}, +{"nvinfin", "⧞", NULL}, +{"nvlArr", "⤂", NULL}, +{"nvle", "≤⃒", NULL}, +{"nvlt", "<⃒", NULL}, +{"nvltrie", "⊴⃒", NULL}, +{"nvrArr", "⤃", NULL}, +{"nvrtrie", "⊵⃒", NULL}, +{"nvsim", "∼⃒", NULL}, +{"nwArr", "⇖", NULL}, +{"nwarhk", "⤣", NULL}, +{"nwarr", "↖", NULL}, +{"nwarrow", "↖", NULL}, +{"nwnear", "⤧", NULL}, +{"oS", "Ⓢ", NULL}, +{"oacute", "ó", "ó"}, +{"oast", "⊛", NULL}, +{"ocir", "⊚", NULL}, +{"ocirc", "ô", "ô"}, +{"ocy", "о", NULL}, +{"odash", "⊝", NULL}, +{"odblac", "ő", NULL}, +{"odiv", "⨸", NULL}, +{"odot", "⊙", NULL}, +{"odsold", "⦼", NULL}, +{"oelig", "œ", "œ"}, +{"ofcir", "⦿", NULL}, +{"ofr", "", NULL}, +{"ogon", "˛", NULL}, +{"ograve", "ò", "ò"}, +{"ogt", "⧁", NULL}, +{"ohbar", "⦵", NULL}, +{"ohm", "Ω", NULL}, +{"oint", "∮", NULL}, +{"olarr", "↺", NULL}, +{"olcir", "⦾", NULL}, +{"olcross", "⦻", NULL}, +{"oline", "‾", "‾"}, +{"olt", "⧀", NULL}, +{"omacr", "ō", NULL}, +{"omega", "ω", "ω"}, +{"omicron", "ο", "ο"}, +{"omid", "⦶", NULL}, +{"ominus", "⊖", NULL}, +{"oopf", "", NULL}, +{"opar", "⦷", NULL}, +{"operp", "⦹", NULL}, +{"oplus", "⊕", "⊕"}, +{"or", "∨", "∨"}, +{"orarr", "↻", NULL}, +{"ord", "⩝", NULL}, +{"order", "ℴ", NULL}, +{"orderof", "ℴ", NULL}, +{"ordf", "ª", "ª"}, +{"ordm", "º", "º"}, +{"origof", "⊶", NULL}, +{"oror", "⩖", NULL}, +{"orslope", "⩗", NULL}, +{"orv", "⩛", NULL}, +{"oscr", "ℴ", NULL}, +{"oslash", "ø", "ø"}, +{"osol", "⊘", NULL}, +{"otilde", "õ", "õ"}, +{"otimes", "⊗", "⊗"}, +{"otimesas", "⨶", NULL}, +{"ouml", "ö", "ö"}, +{"ovbar", "⌽", NULL}, +{"par", "∥", NULL}, +{"para", "¶", "¶"}, +{"parallel", "∥", NULL}, +{"parsim", "⫳", NULL}, +{"parsl", "⫽", NULL}, +{"part", "∂", "∂"}, +{"pcy", "п", NULL}, +{"percnt", "%", NULL}, +{"period", ".", NULL}, +{"permil", "‰", "‰"}, +{"perp", "⊥", "⊥"}, +{"pertenk", "‱", NULL}, +{"pfr", "", NULL}, +{"phi", "φ", "φ"}, +{"phiv", "ϕ", NULL}, +{"phmmat", "ℳ", NULL}, +{"phone", "☎", NULL}, +{"pi", "π", "π"}, +{"pitchfork", "⋔", NULL}, +{"piv", "ϖ", "ϖ"}, +{"planck", "ℏ", NULL}, +{"planckh", "ℎ", NULL}, +{"plankv", "ℏ", NULL}, +{"plus", "+", NULL}, +{"plusacir", "⨣", NULL}, +{"plusb", "⊞", NULL}, +{"pluscir", "⨢", NULL}, +{"plusdo", "∔", NULL}, +{"plusdu", "⨥", NULL}, +{"pluse", "⩲", NULL}, +{"plusmn", "±", "±"}, +{"plussim", "⨦", NULL}, +{"plustwo", "⨧", NULL}, +{"pm", "±", NULL}, +{"pointint", "⨕", NULL}, +{"popf", "", NULL}, +{"pound", "£", "£"}, +{"pr", "≺", NULL}, +{"prE", "⪳", NULL}, +{"prap", "⪷", NULL}, +{"prcue", "≼", NULL}, +{"pre", "⪯", NULL}, +{"prec", "≺", NULL}, +{"precapprox", "⪷", NULL}, +{"preccurlyeq", "≼", NULL}, +{"preceq", "⪯", NULL}, +{"precnapprox", "⪹", NULL}, +{"precneqq", "⪵", NULL}, +{"precnsim", "⋨", NULL}, +{"precsim", "≾", NULL}, +{"prime", "′", "′"}, +{"primes", "ℙ", NULL}, +{"prnE", "⪵", NULL}, +{"prnap", "⪹", NULL}, +{"prnsim", "⋨", NULL}, +{"prod", "∏", "∏"}, +{"profalar", "⌮", NULL}, +{"profline", "⌒", NULL}, +{"profsurf", "⌓", NULL}, +{"prop", "∝", "∝"}, +{"propto", "∝", NULL}, +{"prsim", "≾", NULL}, +{"prurel", "⊰", NULL}, +{"pscr", "", NULL}, +{"psi", "ψ", "ψ"}, +{"puncsp", " ", NULL}, +{"qfr", "", NULL}, +{"qint", "⨌", NULL}, +{"qopf", "", NULL}, +{"qprime", "⁗", NULL}, +{"qscr", "", NULL}, +{"quaternions", "ℍ", NULL}, +{"quatint", "⨖", NULL}, +{"quest", "?", NULL}, +{"questeq", "≟", NULL}, +{"quot", "\"", "\""}, +{"rAarr", "⇛", NULL}, +{"rArr", "⇒", "⇒"}, +{"rAtail", "⤜", NULL}, +{"rBarr", "⤏", NULL}, +{"rHar", "⥤", NULL}, +{"race", "∽̱", NULL}, +{"racute", "ŕ", NULL}, +{"radic", "√", "√"}, +{"raemptyv", "⦳", NULL}, +{"rang", "⟩", "〉"}, +{"rangd", "⦒", NULL}, +{"range", "⦥", NULL}, +{"rangle", "⟩", NULL}, +{"raquo", "»", "»"}, +{"rarr", "→", "→"}, +{"rarrap", "⥵", NULL}, +{"rarrb", "⇥", NULL}, +{"rarrbfs", "⤠", NULL}, +{"rarrc", "⤳", NULL}, +{"rarrfs", "⤞", NULL}, +{"rarrhk", "↪", NULL}, +{"rarrlp", "↬", NULL}, +{"rarrpl", "⥅", NULL}, +{"rarrsim", "⥴", NULL}, +{"rarrtl", "↣", NULL}, +{"rarrw", "↝", NULL}, +{"ratail", "⤚", NULL}, +{"ratio", "∶", NULL}, +{"rationals", "ℚ", NULL}, +{"rbarr", "⤍", NULL}, +{"rbbrk", "❳", NULL}, +{"rbrace", "}", NULL}, +{"rbrack", "]", NULL}, +{"rbrke", "⦌", NULL}, +{"rbrksld", "⦎", NULL}, +{"rbrkslu", "⦐", NULL}, +{"rcaron", "ř", NULL}, +{"rcedil", "ŗ", NULL}, +{"rceil", "⌉", "⌉"}, +{"rcub", "}", NULL}, +{"rcy", "р", NULL}, +{"rdca", "⤷", NULL}, +{"rdldhar", "⥩", NULL}, +{"rdquo", "”", "”"}, +{"rdquor", "”", NULL}, +{"rdsh", "↳", NULL}, +{"real", "ℜ", "ℜ"}, +{"realine", "ℛ", NULL}, +{"realpart", "ℜ", NULL}, +{"reals", "ℝ", NULL}, +{"rect", "▭", NULL}, +{"reg", "®", "®"}, +{"rfisht", "⥽", NULL}, +{"rfloor", "⌋", "⌋"}, +{"rfr", "", NULL}, +{"rhard", "⇁", NULL}, +{"rharu", "⇀", NULL}, +{"rharul", "⥬", NULL}, +{"rho", "ρ", "ρ"}, +{"rhov", "ϱ", NULL}, +{"rightarrow", "→", NULL}, +{"rightarrowtail", "↣", NULL}, +{"rightharpoondown", "⇁", NULL}, +{"rightharpoonup", "⇀", NULL}, +{"rightleftarrows", "⇄", NULL}, +{"rightleftharpoons", "⇌", NULL}, +{"rightrightarrows", "⇉", NULL}, +{"rightsquigarrow", "↝", NULL}, +{"rightthreetimes", "⋌", NULL}, +{"ring", "˚", NULL}, +{"risingdotseq", "≓", NULL}, +{"rlarr", "⇄", NULL}, +{"rlhar", "⇌", NULL}, +{"rlm", "", ""}, +{"rmoust", "⎱", NULL}, +{"rmoustache", "⎱", NULL}, +{"rnmid", "⫮", NULL}, +{"roang", "⟭", NULL}, +{"roarr", "⇾", NULL}, +{"robrk", "⟧", NULL}, +{"ropar", "⦆", NULL}, +{"ropf", "", NULL}, +{"roplus", "⨮", NULL}, +{"rotimes", "⨵", NULL}, +{"rpar", ")", NULL}, +{"rpargt", "⦔", NULL}, +{"rppolint", "⨒", NULL}, +{"rrarr", "⇉", NULL}, +{"rsaquo", "›", "›"}, +{"rscr", "", NULL}, +{"rsh", "↱", NULL}, +{"rsqb", "]", NULL}, +{"rsquo", "’", "’"}, +{"rsquor", "’", NULL}, +{"rthree", "⋌", NULL}, +{"rtimes", "⋊", NULL}, +{"rtri", "▹", NULL}, +{"rtrie", "⊵", NULL}, +{"rtrif", "▸", NULL}, +{"rtriltri", "⧎", NULL}, +{"ruluhar", "⥨", NULL}, +{"rx", "℞", NULL}, +{"sacute", "ś", NULL}, +{"sbquo", "‚", "‚"}, +{"sc", "≻", NULL}, +{"scE", "⪴", NULL}, +{"scap", "⪸", NULL}, +{"scaron", "š", "š"}, +{"sccue", "≽", NULL}, +{"sce", "⪰", NULL}, +{"scedil", "ş", NULL}, +{"scirc", "ŝ", NULL}, +{"scnE", "⪶", NULL}, +{"scnap", "⪺", NULL}, +{"scnsim", "⋩", NULL}, +{"scpolint", "⨓", NULL}, +{"scsim", "≿", NULL}, +{"scy", "с", NULL}, +{"sdot", "⋅", "⋅"}, +{"sdotb", "⊡", NULL}, +{"sdote", "⩦", NULL}, +{"seArr", "⇘", NULL}, +{"searhk", "⤥", NULL}, +{"searr", "↘", NULL}, +{"searrow", "↘", NULL}, +{"sect", "§", "§"}, +{"semi", ";", NULL}, +{"seswar", "⤩", NULL}, +{"setminus", "∖", NULL}, +{"setmn", "∖", NULL}, +{"sext", "✶", NULL}, +{"sfr", "", NULL}, +{"sfrown", "⌢", NULL}, +{"sharp", "♯", NULL}, +{"shchcy", "щ", NULL}, +{"shcy", "ш", NULL}, +{"shortmid", "∣", NULL}, +{"shortparallel", "∥", NULL}, +{"shy", "", ""}, +{"sigma", "σ", "σ"}, +{"sigmaf", "ς", "ς"}, +{"sigmav", "ς", NULL}, +{"sim", "∼", "∼"}, +{"simdot", "⩪", NULL}, +{"sime", "≃", NULL}, +{"simeq", "≃", NULL}, +{"simg", "⪞", NULL}, +{"simgE", "⪠", NULL}, +{"siml", "⪝", NULL}, +{"simlE", "⪟", NULL}, +{"simne", "≆", NULL}, +{"simplus", "⨤", NULL}, +{"simrarr", "⥲", NULL}, +{"slarr", "←", NULL}, +{"smallsetminus", "∖", NULL}, +{"smashp", "⨳", NULL}, +{"smeparsl", "⧤", NULL}, +{"smid", "∣", NULL}, +{"smile", "⌣", NULL}, +{"smt", "⪪", NULL}, +{"smte", "⪬", NULL}, +{"smtes", "⪬︀", NULL}, +{"softcy", "ь", NULL}, +{"sol", "/", NULL}, +{"solb", "⧄", NULL}, +{"solbar", "⌿", NULL}, +{"sopf", "", NULL}, +{"spades", "♠", "♠"}, +{"spadesuit", "♠", NULL}, +{"spar", "∥", NULL}, +{"sqcap", "⊓", NULL}, +{"sqcaps", "⊓︀", NULL}, +{"sqcup", "⊔", NULL}, +{"sqcups", "⊔︀", NULL}, +{"sqsub", "⊏", NULL}, +{"sqsube", "⊑", NULL}, +{"sqsubset", "⊏", NULL}, +{"sqsubseteq", "⊑", NULL}, +{"sqsup", "⊐", NULL}, +{"sqsupe", "⊒", NULL}, +{"sqsupset", "⊐", NULL}, +{"sqsupseteq", "⊒", NULL}, +{"squ", "□", NULL}, +{"square", "□", NULL}, +{"squarf", "▪", NULL}, +{"squf", "▪", NULL}, +{"srarr", "→", NULL}, +{"sscr", "", NULL}, +{"ssetmn", "∖", NULL}, +{"ssmile", "⌣", NULL}, +{"sstarf", "⋆", NULL}, +{"star", "☆", NULL}, +{"starf", "★", NULL}, +{"straightepsilon", "ϵ", NULL}, +{"straightphi", "ϕ", NULL}, +{"strns", "¯", NULL}, +{"sub", "⊂", "⊂"}, +{"subE", "⫅", NULL}, +{"subdot", "⪽", NULL}, +{"sube", "⊆", "⊆"}, +{"subedot", "⫃", NULL}, +{"submult", "⫁", NULL}, +{"subnE", "⫋", NULL}, +{"subne", "⊊", NULL}, +{"subplus", "⪿", NULL}, +{"subrarr", "⥹", NULL}, +{"subset", "⊂", NULL}, +{"subseteq", "⊆", NULL}, +{"subseteqq", "⫅", NULL}, +{"subsetneq", "⊊", NULL}, +{"subsetneqq", "⫋", NULL}, +{"subsim", "⫇", NULL}, +{"subsub", "⫕", NULL}, +{"subsup", "⫓", NULL}, +{"succ", "≻", NULL}, +{"succapprox", "⪸", NULL}, +{"succcurlyeq", "≽", NULL}, +{"succeq", "⪰", NULL}, +{"succnapprox", "⪺", NULL}, +{"succneqq", "⪶", NULL}, +{"succnsim", "⋩", NULL}, +{"succsim", "≿", NULL}, +{"sum", "∑", "∑"}, +{"sung", "♪", NULL}, +{"sup", "⊃", "⊃"}, +{"sup1", "¹", "¹"}, +{"sup2", "²", "²"}, +{"sup3", "³", "³"}, +{"supE", "⫆", NULL}, +{"supdot", "⪾", NULL}, +{"supdsub", "⫘", NULL}, +{"supe", "⊇", "⊇"}, +{"supedot", "⫄", NULL}, +{"suphsol", "⟉", NULL}, +{"suphsub", "⫗", NULL}, +{"suplarr", "⥻", NULL}, +{"supmult", "⫂", NULL}, +{"supnE", "⫌", NULL}, +{"supne", "⊋", NULL}, +{"supplus", "⫀", NULL}, +{"supset", "⊃", NULL}, +{"supseteq", "⊇", NULL}, +{"supseteqq", "⫆", NULL}, +{"supsetneq", "⊋", NULL}, +{"supsetneqq", "⫌", NULL}, +{"supsim", "⫈", NULL}, +{"supsub", "⫔", NULL}, +{"supsup", "⫖", NULL}, +{"swArr", "⇙", NULL}, +{"swarhk", "⤦", NULL}, +{"swarr", "↙", NULL}, +{"swarrow", "↙", NULL}, +{"swnwar", "⤪", NULL}, +{"szlig", "ß", "ß"}, +{"target", "⌖", NULL}, +{"tau", "τ", "τ"}, +{"tbrk", "⎴", NULL}, +{"tcaron", "ť", NULL}, +{"tcedil", "ţ", NULL}, +{"tcy", "т", NULL}, +{"tdot", "⃛", NULL}, +{"telrec", "⌕", NULL}, +{"tfr", "", NULL}, +{"there4", "∴", "∴"}, +{"therefore", "∴", NULL}, +{"theta", "θ", "θ"}, +{"thetasym", "ϑ", "ϑ"}, +{"thetav", "ϑ", NULL}, +{"thickapprox", "≈", NULL}, +{"thicksim", "∼", NULL}, +{"thinsp", " ", " "}, +{"thkap", "≈", NULL}, +{"thksim", "∼", NULL}, +{"thorn", "þ", "þ"}, +{"tilde", "˜", "˜"}, +{"times", "×", "×"}, +{"timesb", "⊠", NULL}, +{"timesbar", "⨱", NULL}, +{"timesd", "⨰", NULL}, +{"tint", "∭", NULL}, +{"toea", "⤨", NULL}, +{"top", "⊤", NULL}, +{"topbot", "⌶", NULL}, +{"topcir", "⫱", NULL}, +{"topf", "", NULL}, +{"topfork", "⫚", NULL}, +{"tosa", "⤩", NULL}, +{"tprime", "‴", NULL}, +{"trade", "™", "™"}, +{"triangle", "▵", NULL}, +{"triangledown", "▿", NULL}, +{"triangleleft", "◃", NULL}, +{"trianglelefteq", "⊴", NULL}, +{"triangleq", "≜", NULL}, +{"triangleright", "▹", NULL}, +{"trianglerighteq", "⊵", NULL}, +{"tridot", "◬", NULL}, +{"trie", "≜", NULL}, +{"triminus", "⨺", NULL}, +{"triplus", "⨹", NULL}, +{"trisb", "⧍", NULL}, +{"tritime", "⨻", NULL}, +{"trpezium", "⏢", NULL}, +{"tscr", "", NULL}, +{"tscy", "ц", NULL}, +{"tshcy", "ћ", NULL}, +{"tstrok", "ŧ", NULL}, +{"twixt", "≬", NULL}, +{"twoheadleftarrow", "↞", NULL}, +{"twoheadrightarrow", "↠", NULL}, +{"uArr", "⇑", "⇑"}, +{"uHar", "⥣", NULL}, +{"uacute", "ú", "ú"}, +{"uarr", "↑", "↑"}, +{"ubrcy", "ў", NULL}, +{"ubreve", "ŭ", NULL}, +{"ucirc", "û", "û"}, +{"ucy", "у", NULL}, +{"udarr", "⇅", NULL}, +{"udblac", "ű", NULL}, +{"udhar", "⥮", NULL}, +{"ufisht", "⥾", NULL}, +{"ufr", "", NULL}, +{"ugrave", "ù", "ù"}, +{"uharl", "↿", NULL}, +{"uharr", "↾", NULL}, +{"uhblk", "▀", NULL}, +{"ulcorn", "⌜", NULL}, +{"ulcorner", "⌜", NULL}, +{"ulcrop", "⌏", NULL}, +{"ultri", "◸", NULL}, +{"umacr", "ū", NULL}, +{"uml", "¨", "¨"}, +{"uogon", "ų", NULL}, +{"uopf", "", NULL}, +{"uparrow", "↑", NULL}, +{"updownarrow", "↕", NULL}, +{"upharpoonleft", "↿", NULL}, +{"upharpoonright", "↾", NULL}, +{"uplus", "⊎", NULL}, +{"upsi", "υ", NULL}, +{"upsih", "ϒ", "ϒ"}, +{"upsilon", "υ", "υ"}, +{"upuparrows", "⇈", NULL}, +{"urcorn", "⌝", NULL}, +{"urcorner", "⌝", NULL}, +{"urcrop", "⌎", NULL}, +{"uring", "ů", NULL}, +{"urtri", "◹", NULL}, +{"uscr", "", NULL}, +{"utdot", "⋰", NULL}, +{"utilde", "ũ", NULL}, +{"utri", "▵", NULL}, +{"utrif", "▴", NULL}, +{"uuarr", "⇈", NULL}, +{"uuml", "ü", "ü"}, +{"uwangle", "⦧", NULL}, +{"vArr", "⇕", NULL}, +{"vBar", "⫨", NULL}, +{"vBarv", "⫩", NULL}, +{"vDash", "⊨", NULL}, +{"vangrt", "⦜", NULL}, +{"varepsilon", "ϵ", NULL}, +{"varkappa", "ϰ", NULL}, +{"varnothing", "∅", NULL}, +{"varphi", "ϕ", NULL}, +{"varpi", "ϖ", NULL}, +{"varpropto", "∝", NULL}, +{"varr", "↕", NULL}, +{"varrho", "ϱ", NULL}, +{"varsigma", "ς", NULL}, +{"varsubsetneq", "⊊︀", NULL}, +{"varsubsetneqq", "⫋︀", NULL}, +{"varsupsetneq", "⊋︀", NULL}, +{"varsupsetneqq", "⫌︀", NULL}, +{"vartheta", "ϑ", NULL}, +{"vartriangleleft", "⊲", NULL}, +{"vartriangleright", "⊳", NULL}, +{"vcy", "в", NULL}, +{"vdash", "⊢", NULL}, +{"vee", "∨", NULL}, +{"veebar", "⊻", NULL}, +{"veeeq", "≚", NULL}, +{"vellip", "⋮", NULL}, +{"verbar", "|", NULL}, +{"vert", "|", NULL}, +{"vfr", "", NULL}, +{"vltri", "⊲", NULL}, +{"vnsub", "⊂⃒", NULL}, +{"vnsup", "⊃⃒", NULL}, +{"vopf", "", NULL}, +{"vprop", "∝", NULL}, +{"vrtri", "⊳", NULL}, +{"vscr", "", NULL}, +{"vsubnE", "⫋︀", NULL}, +{"vsubne", "⊊︀", NULL}, +{"vsupnE", "⫌︀", NULL}, +{"vsupne", "⊋︀", NULL}, +{"vzigzag", "⦚", NULL}, +{"wcirc", "ŵ", NULL}, +{"wedbar", "⩟", NULL}, +{"wedge", "∧", NULL}, +{"wedgeq", "≙", NULL}, +{"weierp", "℘", "℘"}, +{"wfr", "", NULL}, +{"wopf", "", NULL}, +{"wp", "℘", NULL}, +{"wr", "≀", NULL}, +{"wreath", "≀", NULL}, +{"wscr", "", NULL}, +{"xcap", "⋂", NULL}, +{"xcirc", "◯", NULL}, +{"xcup", "⋃", NULL}, +{"xdtri", "▽", NULL}, +{"xfr", "", NULL}, +{"xhArr", "⟺", NULL}, +{"xharr", "⟷", NULL}, +{"xi", "ξ", "ξ"}, +{"xlArr", "⟸", NULL}, +{"xlarr", "⟵", NULL}, +{"xmap", "⟼", NULL}, +{"xnis", "⋻", NULL}, +{"xodot", "⨀", NULL}, +{"xopf", "", NULL}, +{"xoplus", "⨁", NULL}, +{"xotime", "⨂", NULL}, +{"xrArr", "⟹", NULL}, +{"xrarr", "⟶", NULL}, +{"xscr", "", NULL}, +{"xsqcup", "⨆", NULL}, +{"xuplus", "⨄", NULL}, +{"xutri", "△", NULL}, +{"xvee", "⋁", NULL}, +{"xwedge", "⋀", NULL}, +{"yacute", "ý", "ý"}, +{"yacy", "я", NULL}, +{"ycirc", "ŷ", NULL}, +{"ycy", "ы", NULL}, +{"yen", "¥", "¥"}, +{"yfr", "", NULL}, +{"yicy", "ї", NULL}, +{"yopf", "", NULL}, +{"yscr", "", NULL}, +{"yucy", "ю", NULL}, +{"yuml", "ÿ", "ÿ"}, +{"zacute", "ź", NULL}, +{"zcaron", "ž", NULL}, +{"zcy", "з", NULL}, +{"zdot", "ż", NULL}, +{"zeetrf", "ℨ", NULL}, +{"zeta", "ζ", "ζ"}, +{"zfr", "", NULL}, +{"zhcy", "ж", NULL}, +{"zigrarr", "⇝", NULL}, +{"zopf", "", NULL}, +{"zscr", "", NULL}, +{"zwj", "", ""}, +{"zwnj", "", ""}, +}; +#endif /* HTML_CHARREFS_H */ diff --git a/src/prefs.c b/src/prefs.c index cd13aac8..56e02006 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -63,6 +63,7 @@ void a_Prefs_init(void) prefs.http_language = NULL; prefs.http_proxy = NULL; prefs.http_max_conns = 6; + prefs.http_persistent_conns = FALSE; prefs.http_proxyuser = NULL; prefs.http_referer = dStrdup(PREFS_HTTP_REFERER); prefs.http_user_agent = dStrdup(PREFS_HTTP_USER_AGENT); diff --git a/src/prefs.h b/src/prefs.h index bb97651e..0e54e0fc 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -91,6 +91,7 @@ typedef struct { bool_t load_background_images; bool_t load_stylesheets; bool_t parse_embedded_css; + bool_t http_persistent_conns; int32_t buffered_drawing; char *font_serif; char *font_sans_serif; diff --git a/src/prefsparser.cc b/src/prefsparser.cc index 81b097e7..ce420eac 100644 --- a/src/prefsparser.cc +++ b/src/prefsparser.cc @@ -73,6 +73,7 @@ int PrefsParser::parseOption(char *name, char *value) { "home", &prefs.home, PREFS_URL }, { "http_language", &prefs.http_language, PREFS_STRING }, { "http_max_conns", &prefs.http_max_conns, PREFS_INT32 }, + { "http_persistent_conns", &prefs.http_persistent_conns, PREFS_BOOL }, { "http_proxy", &prefs.http_proxy, PREFS_URL }, { "http_proxyuser", &prefs.http_proxyuser, PREFS_STRING }, { "http_referer", &prefs.http_referer, PREFS_STRING }, diff --git a/src/styleengine.cc b/src/styleengine.cc index 024ef56d..f92cccf8 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -71,6 +71,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout, this->pageUrl = pageUrl ? a_Url_dup(pageUrl) : NULL; this->baseUrl = baseUrl ? a_Url_dup(baseUrl) : NULL; importDepth = 0; + dpmm = layout->dpiX () / 25.4; /* assume dpiX == dpiY */ stackPush (); Node *n = stack->getLastRef (); @@ -760,11 +761,6 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, * \brief Resolve relative lengths to absolute values. */ bool StyleEngine::computeValue (int *dest, CssLength value, Font *font) { - static float dpmm; - - if (dpmm == 0.0) - dpmm = layout->dpiX () / 25.4; /* assume dpiX == dpiY */ - switch (CSS_LENGTH_TYPE (value)) { case CSS_LENGTH_TYPE_PX: *dest = (int) CSS_LENGTH_VALUE (value); diff --git a/src/styleengine.hh b/src/styleengine.hh index 41f892d7..772e7f63 100644 --- a/src/styleengine.hh +++ b/src/styleengine.hh @@ -35,6 +35,7 @@ class StyleEngine { CssContext *cssContext; Doctree *doctree; int importDepth; + float dpmm; DilloUrl *pageUrl, *baseUrl; void stackPush (); |