spa/gemtext.c

167 lines
4.0 KiB
C

#include <stdio.h>
#include <string.h>
#include "global.h"
#include "db.h"
#include "url.h"
#include <stdlib.h> //exit
extern sUrl base; //the url being rendered
char* skip_to_ws(char* p){
char c;
while((c=*p))
if((' '==c)||('\t'==c)||('\n'==c))
break;
else
p++;
return p;
}
char* skip_ws(char*p){
char c;
while((c=*p))
if((' '==c)||('\t'==c)||('\n'==c))
p++;
else
break;
return p;
}
U32 url_length(char* url){
char* end = skip_to_ws(url);
return end-url;
}
char linebuf[4096];
/*******************************************************************************
render_link_line - Pull out the URL, normalize, and check with the db for the
sigil. Format line for display.
******************************************************************************/
void render_link_line(FILE*out,char*p){
// printf("[%s]\n",p);
char* u = skip_ws(p+2);
U32 ulen = url_length(u);
sUrl url;
if(url_is_full(u)){
sUrl_set(&url,u,ulen);
sUrl_full(&url);
} else {
sUrl_copy(&url,&base);
sUrl_file(&url);
// printf("[r[%*.*s]r]",url_len,url_len,url_start);
//printf("[b[%s]b]",base.buf);
sUrl_rel(&url,u,ulen);
// printf("[[%s]]",url.buf);
}
// make a shortcut!
// printf("[[[%s]]]", url.buf);
if(!sUrl_norm(&url)){
// URL normalized OK. Only spartan urls are databased.
if(!(strncmp("spartan://",url.buf,10))) {
char sigil[5];
U32 idx = URL_idx(url.buf);
idx_sigil(idx,sigil);
//fprintf(out,"\033[33m%s\033[0m ",sigil);
fprintf(out,"\033[33m%s\033[0m ",sigil);
p = skip_ws(u+ulen);
if(*p)
fprintf(out,"\033[92m%s\033[0m",p);
else {
fprintf(out,"\033[92m%*.*s\033[0m\n",ulen,ulen,u);
}
} else { //non-spartan urls are printed as-is
fprintf(out,"\033[95m???? %s\033[0m",u);
}
} else { //an attempt to manipulate a path
fprintf(out,"\033[91mXXXX %s\033[0m",u);
}
}
/*******************************************************************************
render_head - Render a header line, # ## or ###
******************************************************************************/
void render_head(FILE* out, char*p){
int level;
char *q = p;
for(level=0;*q=='#';q++,level++);
switch(level){
case 1: fprintf(out,"\033[93m");break;
case 2: fprintf(out,"\033[94;1m");break;
case 3: fprintf(out,"\033[94m");break;
}
fprintf(out,"%s\033[0m",p);
}
/*******************************************************************************
render_quote - Render a > quote line
******************************************************************************/
void render_quote(FILE* out,char*p){
fprintf(out,"\033[36m%s\033[0m",p);
}
/*******************************************************************************
render_line - dispatch to a proper line handler.
*******************************************************************************/
/*
Return 0 for normal, 1 for block-quote status.
*/
int render_line(FILE* out,char* p, int blockquote){
int backquotes = !strncmp("```",p,3);
if(blockquote){
if(backquotes)
return 0;
else{
fputs(linebuf,out);
return 1;
}
} else {
if(backquotes)
return 1;
else {
switch(*p){
case '=':
if('>'==*(p+1)){
render_link_line(out,p);
return 0;
}
case '#':
render_head(out,p);
return 0;
case '>':
render_quote(out,p);
return 0;
}
fprintf(out,"%s",linebuf);
return 0;
}
}
}
void render_file1(FILE* in,FILE* out){
int bq = 0;
while(fgets(linebuf,4096,in))
bq=render_line(out,linebuf,bq );
}
/*******************************************************************************
render_file - Render the entire in file to out file
******************************************************************************/
void render_file(FILE* in,FILE* out){
int bq = 0; // tracking multiline-quote state
while(fgets(linebuf,4096,in))
bq=render_line(out,linebuf,bq );
}