#include <sys/ioctl.h>
#endif
-void clear_console(){
+int termw, termh;
+
+extern int strcasecmp(const char* s1, const char* s2);
+
+void clear_console() {
#ifdef __MINGW32__
DWORD written = 0;
const char* seq = "\x1b[2J\x1b[1;1H";
#endif
}
-void get_terminal_size(int* width, int* height){
+void get_terminal_size(int* width, int* height) {
#ifdef __MINGW32__
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(winstdout, &csbi);
char* databuf;
int datalen;
+bool isredir;
+
+void status_handler(struct W3* w3, int st) {
+ if(st >= 300 && st < 400) {
+ isredir = true;
+ } else {
+ isredir = false;
+ }
+}
void data_handler(struct W3* w3, char* data, size_t size) {
+ if(isredir) return;
if(databuf == NULL) {
databuf = malloc(size);
datalen = size;
W3_Set_Method(w3, "GET");
W3_Set_Path(w3, u->path);
W3_HTTP_Enable_Redirect(w3);
+ W3_On(w3, "status", (void*)status_handler);
W3_On(w3, "data", (void*)data_handler);
W3_Send_Request(w3);
W3_Free(w3);
}
}
-void html_handler(char* tagname, char* attr){
- printf("<%s> %s\n", tagname, attr != NULL ? attr : "NULL");
+bool title;
+bool italic;
+bool bold;
+bool pre;
+char* titlebuf = NULL;
+
+int nl;
+int start = 0;
+
+void html_handler(char* tagname, char* attr) {
+ if(nl - start > termh - 1) return;
+ if(strcasecmp(tagname, "title") == 0) {
+ title = true;
+ } else if(strcasecmp(tagname, "/title") == 0) {
+ title = false;
+ } else if(strcasecmp(tagname, "i") == 0) {
+ italic = true;
+ } else if(strcasecmp(tagname, "/i") == 0) {
+ italic = false;
+ } else if(strcasecmp(tagname, "pre") == 0) {
+ pre = true;
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/pre") == 0) {
+ pre = false;
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "br") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "h1") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/h1") == 0) {
+ if(nl >= start)
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "h2") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/h2") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "h3") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/h3") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "h4") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/h4") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "h5") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/h5") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "h6") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "/h6") == 0) {
+ if(nl >= start) printf("\n");
+ nl++;
+ } else if(strcasecmp(tagname, "img") == 0) {
+ if(nl >= start) printf("[IMG]");
+ } else if(strcasecmp(tagname, "hr") == 0) {
+ int i;
+ if(nl >= start) printf("\n ");
+ nl++;
+ for(i = 0; i < termw - 2; i++) {
+ if(nl >= start) printf("-");
+ }
+ if(nl >= start) printf("\n");
+ nl++;
+ }
+ fflush(stdout);
}
-void text_handler(char* data){
- printf("<TEXT> %s\n", data);
+void text_handler(char* data) {
+ if(title) {
+ if(titlebuf == NULL) {
+ titlebuf = malloc(1);
+ titlebuf[0] = 0;
+ }
+ char* tmp = titlebuf;
+ titlebuf = __W3_Concat(tmp, data);
+ free(tmp);
+ } else {
+ if(nl - start > termh - 1) return;
+ char* text = malloc(strlen(data) + 64);
+ int i;
+ char* fmt_data = malloc(strlen(data) * 2);
+ if(pre) {
+ free(fmt_data);
+ fmt_data = __W3_Strdup(data);
+ for(i = 0; i < strlen(data); i++) {
+ if(data[i] == '\n') {
+ nl++;
+ }
+ }
+ } else {
+ fmt_data[0] = 0;
+ char* cbuf = malloc(2);
+ cbuf[1] = 0;
+ bool spc = false;
+ bool firstspc = true;
+ for(i = 0; i < strlen(data); i++) {
+ cbuf[0] = data[i];
+ if(data[i] == '\n' || data[i] == '\t') {
+ if(!spc && !firstspc) {
+ spc = true;
+ char* tmp = fmt_data;
+ fmt_data = __W3_Concat(tmp, " ");
+ free(tmp);
+ }
+ } else {
+ firstspc = false;
+ spc = false;
+ char* tmp = fmt_data;
+ fmt_data = __W3_Concat(tmp, cbuf);
+ free(tmp);
+ }
+ }
+ free(cbuf);
+ }
+ sprintf(text, "%s%s%s\x1b[m", italic ? "\x1b[3m" : "", bold ? "\x1b[1m" : "", fmt_data);
+ if(nl >= start) printf("%s", text);
+ fflush(stdout);
+ free(text);
+ free(fmt_data);
+ }
}
-void render_site(){
- if(databuf != NULL){
+void render_site() {
+ if(databuf != NULL) {
+ if(titlebuf != NULL) {
+ free(titlebuf);
+ }
+ title = false;
+ italic = false;
+ bold = false;
+ pre = false;
+ titlebuf = NULL;
+ nl = 0;
W3_Tag_Parse(databuf, datalen, html_handler, text_handler);
+ char* seq = malloc(1024);
+ sprintf(seq, "\x1b[1;%dH", termw - strlen(titlebuf != NULL ? titlebuf : "No title") - 1);
+#ifdef __MINGW32__
+ WriteConsole(winstdout, seq, strlen(seq), &written, NULL);
+#else
+ printf("%s\x1b[7m %s \x1b[m", seq, titlebuf != NULL ? titlebuf : "No title");
+ fflush(stdout);
+#endif
+ free(seq);
}
}
#endif
bool rendered = false;
clear_console();
+ start = 0;
+ get_terminal_size(&termw, &termh);
while(true) { /* Loop */
- if(!rendered){
+ if(!rendered) {
clear_console();
render_site();
rendered = true;
}
if(c != '\n' && c != '\r') {
- printf("(O)pen, (Q)uit");
+ printf("\x1b[%d;1H(O)pen, (Q)uit", termh);
printf("? ");
fflush(stdout);
}
scanf("%s", url);
acc = false;
break;
+ case 'd':
+ rendered = false;
+ start++;
+ break;
case '\n':
case '\r':
break;
break;
}
if(!acc && url != NULL) {
+ start = 0;
access_site(url);
acc = true;
rendered = false;
#include "W3Util.h"
+#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
-void W3_Tag_Parse(char* data, size_t size, void(*tagfunc)(char* tagname, char* attr), void(*textfunc)(char* data)){
+void W3_Tag_Parse(char* data, size_t size, void (*tagfunc)(char* tagname, char* attr), void (*textfunc)(char* data)) {
int i;
int phase = 0;
char* tagn = malloc(1);
char* text = malloc(1);
text[0] = 0;
bool dq = false;
- for(i = 0; i < size; i++){
- if(phase == 1 && data[i] != ' ' && data[i] != '>'){
+ for(i = 0; i < size; i++) {
+ if(phase == 1 && data[i] != ' ' && data[i] != '>') {
cbuf[0] = data[i];
char* tmp = tagn;
tagn = __W3_Concat(tmp, cbuf);
free(tmp);
- }else if(phase == 2 && (dq || data[i] != '>')){
+ } else if(phase == 2 && (dq || data[i] != '>')) {
if(data[i] == '"') dq = !dq;
cbuf[0] = data[i];
char* tmp = attr;
attr = __W3_Concat(tmp, cbuf);
free(tmp);
}
- if(phase == 0 && data[i] == '<'){
- if(strlen(text) > 0){
+ if(phase == 0 && data[i] == '<') {
+ if(strlen(text) > 0) {
textfunc(text);
}
free(text);
free(tagn);
tagn = malloc(1);
tagn[0] = 0;
- }else if(phase == 0){
+ } else if(phase == 0) {
cbuf[0] = data[i];
char* tmp = text;
text = __W3_Concat(tmp, cbuf);
free(tmp);
- }else if(phase == 1 && (data[i] == ' ' || data[i] == '>')){
- if(data[i] == ' '){
+ } else if(phase == 1 && (data[i] == ' ' || data[i] == '>')) {
+ if(data[i] == ' ') {
phase = 2;
free(attr);
attr = malloc(1);
attr[0] = 0;
- }else if(data[i] == '>'){
+ } else if(data[i] == '>') {
tagfunc(tagn, NULL);
phase = 0;
}
- }else if(phase == 2 && data[i] == '>'){
+ } else if(phase == 2 && data[i] == '>') {
tagfunc(tagn, attr);
phase = 0;
}