Rewrite to static site
With a complete reorganisation of the directory structure and most of the content converted to pandoc-flavoured markdown. Some TODO's left before this can go live: - Main page - Atom feeds - Bug tracker
This commit is contained in:
parent
5c85a7d32f
commit
6242b2ee9c
291 changed files with 4346 additions and 6141 deletions
330
pub/download/code/bbcode.c
Normal file
330
pub/download/code/bbcode.c
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* BBCode 2 HTML converter by //YorHel
|
||||
* Copyright 2006 Y.Heling,
|
||||
* License: MIT
|
||||
*
|
||||
* Created just to learn C, probably very ugly piece of code
|
||||
* and probably with a _LOT_ of bugs... But the only way to
|
||||
* learn a programming language is to code something yourself :)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define MAX_ARGH_SIZE 500
|
||||
#define MAX_TAG_SIZE 10
|
||||
#define MAX_NESTED_TAGS 100
|
||||
|
||||
#define TAGCHARS 28
|
||||
#define NUMBER_OF_TAGS 16
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
/* typedefs */
|
||||
typedef enum {
|
||||
B,
|
||||
I,
|
||||
U,
|
||||
SIZE,
|
||||
COLOR,
|
||||
URL,
|
||||
QUOTE,
|
||||
QUOTE2,
|
||||
IMG,
|
||||
IMG2,
|
||||
EMAIL,
|
||||
LIST,
|
||||
LIST2,
|
||||
CODE,
|
||||
HTML,
|
||||
UNDEF, /* hack */
|
||||
} TAGNAME;
|
||||
typedef struct {
|
||||
TAGNAME intags[MAX_NESTED_TAGS];
|
||||
int curtag;
|
||||
char tag[MAX_TAG_SIZE];
|
||||
char argh[MAX_ARGH_SIZE];
|
||||
FILE *dest;
|
||||
int inlist;
|
||||
int liststart;
|
||||
} PARSEINFO; /* just a hack to prevent the use of global variables */
|
||||
typedef struct {
|
||||
char *bb;
|
||||
char *html_s;
|
||||
char *html_e;
|
||||
char arg;
|
||||
} TAGINFO; /* store global information about the tags */
|
||||
|
||||
|
||||
/* functions */
|
||||
void parsebbcode(FILE *, FILE *);
|
||||
void converttag(PARSEINFO *);
|
||||
void formattag(PARSEINFO *);
|
||||
char endtags(PARSEINFO *, TAGNAME);
|
||||
void convertchars(PARSEINFO *, const char *);
|
||||
void convertchar(PARSEINFO *, const int);
|
||||
void convertchararg(char *, int);
|
||||
char istagchar(const int);
|
||||
void err(const char *);
|
||||
|
||||
/* global vars (only consts!) */
|
||||
const char tagchars[TAGCHARS] = "abcdefghijklmnopqrstuvwxyz/*";
|
||||
const TAGINFO taglist[NUMBER_OF_TAGS] = { /* same order as TAGNAME! */
|
||||
{ "b", "<b>", "</b>", FALSE },
|
||||
{ "i", "<i>", "</i>", FALSE },
|
||||
{ "u", "<span style=\"text-decoration: underline\">", "</span>", FALSE },
|
||||
{ "size", "<span style=\"font-size: %spx\">", "</span>", TRUE },
|
||||
{ "color", "<span style=\"color: %s\">", "</span>", TRUE },
|
||||
{ "url", "<a href=\"%s\">", "</a>", TRUE },
|
||||
{ "quote", "<span class=\"bbcode_quote_header\">Quote: <span class=\"bbcode_quote_body\">", "</span></span>", FALSE },
|
||||
{ "quote", "<span class=\"bbcode_quote_header\">%s wrote: <span class=\"bbcode_quote_body\">", "</span></span>", TRUE },
|
||||
{ "img", "<img src=\"", "\" alt=\"\" />", FALSE },
|
||||
{ "img", "<img src=\"%s\" alt=\"", "\" />", TRUE },
|
||||
{ "email", "<a href=\"mailto:%s\">", "</a>", TRUE },
|
||||
{ "list", "<ul>", "</li></ul>", FALSE },
|
||||
{ "list", "<ul style=\"list-style-type: %s\">", "</li></ul>", TRUE },
|
||||
{ "code", "<span class=\"bbcode_code_header\">Code: <span class=\"bbcode_code_body\">", "</span></span>", FALSE },
|
||||
{ "html", "", "", FALSE },
|
||||
{ "", "", "", FALSE },
|
||||
}; /* NOTE: not all characteristics of the BBCodes are defined above, there is also a lot of hard-coded stuff below for a few tags */
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
/* printf("BBCode to HTML converter by //YorHel\n");
|
||||
printf("Copyright 2006 Y. Heling\n\n");
|
||||
|
||||
printf("* Reading & parsing bbcode...\n");
|
||||
while(1) {
|
||||
FILE *file;
|
||||
if((file = fopen(BBFILE, "r")) == NULL) err("Couldn't open BBFILE");
|
||||
parsebbcode(file, stdout);
|
||||
fclose(file);
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
parsebbcode(stdin, stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void parsebbcode(FILE *file, FILE *dest) {
|
||||
PARSEINFO pitemp; /* make sure we allocate the memory */
|
||||
PARSEINFO *pi = &pitemp; /* but we are still going to use a pointer */
|
||||
char intag = pi->inlist = pi->liststart = 0;
|
||||
pi->curtag = 1;
|
||||
pi->intags[0] = UNDEF;
|
||||
sprintf(pi->tag, "");
|
||||
sprintf(pi->argh, "");
|
||||
pi->dest = dest;
|
||||
int c;
|
||||
char tmp[MAX_TAG_SIZE+MAX_ARGH_SIZE+4]; /* temp string, should be able to hold anything necessary */
|
||||
while((c = fgetc(file)) && c != EOF) {
|
||||
if(intag == 0 && c == '[') {
|
||||
intag = 1;
|
||||
}
|
||||
else if(intag == 1 && c == '=')
|
||||
intag = -1;
|
||||
else if(intag != 0 && c == ']') {
|
||||
intag = 0;
|
||||
converttag(pi);
|
||||
sprintf(pi->tag, "");
|
||||
sprintf(pi->argh, "");
|
||||
}
|
||||
else if(intag == 1 && strlen(pi->tag) < sizeof(pi->tag)) {
|
||||
if(istagchar(c)) {
|
||||
sprintf(tmp, "%c", tolower(c));
|
||||
strcat(pi->tag, tmp);
|
||||
} else {
|
||||
sprintf(tmp, "[%s", pi->tag);
|
||||
convertchars(pi, tmp);
|
||||
sprintf(pi->tag, "");
|
||||
}
|
||||
}
|
||||
else if(intag == 1) {
|
||||
intag = 0;
|
||||
sprintf(tmp, "[%s", pi->tag);
|
||||
convertchars(pi, tmp);
|
||||
sprintf(pi->tag, "");
|
||||
}
|
||||
else if(intag == -1 && (strlen(pi->argh)+10) < sizeof(pi->argh)) {
|
||||
convertchararg(tmp, c);
|
||||
strcat(pi->argh, tmp);
|
||||
}
|
||||
else if(intag == -1) {
|
||||
sprintf(tmp, "[%s=%s", pi->tag, pi->argh);
|
||||
convertchars(pi, tmp);
|
||||
sprintf(pi->tag, "");
|
||||
sprintf(pi->argh, "");
|
||||
intag = 0;
|
||||
}
|
||||
else
|
||||
convertchar(pi, c);
|
||||
}
|
||||
/* some stuff left in the buffer */
|
||||
if(strlen(pi->tag) > 0 && strlen(pi->argh) == 0)
|
||||
fprintf(dest, "[%s", pi->tag);
|
||||
else if(strlen(pi->tag) > 0 && strlen(pi->argh) > 0)
|
||||
fprintf(dest, "[%s=%s", pi->tag, pi->argh);
|
||||
/* automatically close opened tags */
|
||||
endtags(pi, UNDEF);
|
||||
}
|
||||
|
||||
void converttag(PARSEINFO *pi) {
|
||||
/* ignore tag if we're not allowed to nest */
|
||||
if((pi->intags[pi->curtag] == CODE && strcmp(pi->tag, "/code") != 0)
|
||||
|| (pi->intags[pi->curtag] == HTML && strcmp(pi->tag, "/html") != 0)
|
||||
|| ((pi->intags[pi->curtag] == IMG || pi->intags[pi->curtag] == IMG2) && strcmp(pi->tag, "/img"))) {
|
||||
formattag(pi);
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse list items */
|
||||
if(!strcmp(pi->tag, "*") && pi->inlist) {
|
||||
endtags(pi, LIST);
|
||||
if(pi->inlist == pi->liststart)
|
||||
fprintf(pi->dest, "</li>");
|
||||
else
|
||||
pi->liststart = pi->inlist;
|
||||
fprintf(pi->dest, "<li>");
|
||||
|
||||
return; /* no need to parse more */
|
||||
}
|
||||
|
||||
/* begin a tag */
|
||||
if(*pi->tag != '/') {
|
||||
int i; int got = -1;
|
||||
for(i=0 ; i<NUMBER_OF_TAGS && got == -1 ; i++)
|
||||
if(!strcmp(pi->tag, taglist[i].bb)) {
|
||||
got = i;
|
||||
if(strlen(pi->argh) == 0 && !taglist[i].arg)
|
||||
fprintf(pi->dest, "%s", taglist[i].html_s);
|
||||
else if(strlen(pi->argh) > 0 && taglist[i].arg) {
|
||||
if(i != LIST2)
|
||||
fprintf(pi->dest, taglist[i].html_s, pi->argh);
|
||||
else
|
||||
fprintf(pi->dest, taglist[i].html_s, strcmp(pi->argh, "1") ? "lower-roman" : "decimal");
|
||||
}
|
||||
else
|
||||
got = -1;
|
||||
};
|
||||
if(got != -1) {
|
||||
pi->intags[++pi->curtag] = got;
|
||||
if(got == LIST || got == LIST2)
|
||||
pi->inlist++;
|
||||
}
|
||||
else
|
||||
formattag(pi);
|
||||
return;
|
||||
}
|
||||
|
||||
/* end a tag */
|
||||
else {
|
||||
char *tag = pi->tag+1; /* strip the '/' */
|
||||
int i;
|
||||
char got = FALSE;
|
||||
for(i=0 ; i<NUMBER_OF_TAGS && got == FALSE ; i++)
|
||||
if(!strcmp(tag, taglist[i].bb) && endtags(pi, i)) {
|
||||
fprintf(pi->dest, "%s", taglist[i].html_e);
|
||||
if(pi->intags[pi->curtag] == LIST || pi->intags[pi->curtag] == LIST2)
|
||||
pi->liststart = --pi->inlist;
|
||||
pi->curtag--;
|
||||
got = TRUE;
|
||||
};
|
||||
if(!got)
|
||||
formattag(pi);
|
||||
}
|
||||
}
|
||||
|
||||
char endtags(PARSEINFO *pi, TAGNAME to) {
|
||||
char s = FALSE;
|
||||
if(to == QUOTE || to == LIST || to == IMG)
|
||||
s = TRUE;
|
||||
else if(to == QUOTE2 || to == LIST2 || to == IMG2) {
|
||||
s = TRUE;
|
||||
to--;
|
||||
}
|
||||
int i = pi->curtag;
|
||||
if(to != UNDEF)
|
||||
while(pi->intags[i] != to && (!s || pi->intags[i] != to+1) && i > 0)
|
||||
i--;
|
||||
if(i) {
|
||||
while(pi->intags[pi->curtag] != to && (!s || pi->intags[pi->curtag] != (to+1)) && pi->curtag > 0) {
|
||||
if(pi->intags[pi->curtag] == LIST || pi->intags[pi->curtag] == LIST2)
|
||||
pi->liststart = --pi->inlist;
|
||||
fprintf(pi->dest, "%s", taglist[pi->intags[pi->curtag--]].html_e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void formattag(PARSEINFO *pi) {
|
||||
char tmp[MAX_TAG_SIZE+MAX_ARGH_SIZE+4];
|
||||
if(strlen(pi->argh) == 0)
|
||||
sprintf(tmp, "[%s]", pi->tag);
|
||||
else
|
||||
sprintf(tmp, "[%s=%s]", pi->tag, pi->argh);
|
||||
convertchars(pi, tmp);
|
||||
}
|
||||
|
||||
void convertchars(PARSEINFO *pi, const char *chars) {
|
||||
int i;
|
||||
for(i=0;i<strlen(chars);i++)
|
||||
convertchar(pi, *(chars+i));
|
||||
}
|
||||
|
||||
void convertchar(PARSEINFO *pi, const int c) {
|
||||
if(pi->inlist && pi->inlist != pi->liststart)
|
||||
return;
|
||||
else if(pi->intags[pi->curtag] == HTML)
|
||||
fprintf(pi->dest, "%c", c);
|
||||
else if(pi->intags[pi->curtag] == IMG || pi->intags[pi->curtag] == IMG2) {
|
||||
char tmp[10];
|
||||
convertchararg(tmp, c);
|
||||
fprintf(pi->dest, tmp);
|
||||
}
|
||||
else if(c == '\n')
|
||||
fprintf(pi->dest, "<br />\n");
|
||||
else if(c == '&')
|
||||
fprintf(pi->dest, "&");
|
||||
else if(c == '<')
|
||||
fprintf(pi->dest, "<");
|
||||
else if(c == '>')
|
||||
fprintf(pi->dest, ">");
|
||||
else
|
||||
fprintf(pi->dest, "%c", c);
|
||||
}
|
||||
|
||||
void convertchararg(char *to, const int c) {
|
||||
switch(c) {
|
||||
case '\n' :
|
||||
sprintf(to, ""); break;
|
||||
case '&' :
|
||||
sprintf(to, "&"); break;
|
||||
case '"' :
|
||||
sprintf(to, """); break;
|
||||
default :
|
||||
sprintf(to, "%c", c);
|
||||
}
|
||||
}
|
||||
|
||||
char istagchar(const int c) {
|
||||
int i;
|
||||
int c2 = tolower(c);
|
||||
for(i=0;i<TAGCHARS;i++)
|
||||
if(c2 == *(tagchars+i))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void err(const char *msg) {
|
||||
fprintf(stderr, "ERROR: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue