first working version with minimal syntax (check test.nhtml)
This commit is contained in:
		
							parent
							
								
									7a9a3ca64a
								
							
						
					
					
						commit
						a4674d7eee
					
				
							
								
								
									
										8
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								Makefile
									
									
									
									
									
								
							@ -1,8 +1,10 @@
 | 
				
			|||||||
OBJ:= main.o
 | 
					OBJ:= html.o main.o
 | 
				
			||||||
OUTPUT:=nhtmlc
 | 
					OUTPUT:=nhtmlc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
debug: CXXFLAGS = -g 
 | 
					all: debug
 | 
				
			||||||
debug: CFLAGS = -g 
 | 
					
 | 
				
			||||||
 | 
					debug: CXXFLAGS = -g -DDEBUG
 | 
				
			||||||
 | 
					debug: CFLAGS = -g -DDEBUG
 | 
				
			||||||
debug: $(OBJ)
 | 
					debug: $(OBJ)
 | 
				
			||||||
	gcc $(OBJ) -g -o $(OUTPUT)
 | 
						gcc $(OBJ) -g -o $(OUTPUT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										216
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								main.c
									
									
									
									
									
								
							@ -2,6 +2,12 @@
 | 
				
			|||||||
#include <stdlib.h> // needs: realloc, malloc, free
 | 
					#include <stdlib.h> // needs: realloc, malloc, free
 | 
				
			||||||
#include <string.h> // needs: strcmp, memcpy
 | 
					#include <string.h> // needs: strcmp, memcpy
 | 
				
			||||||
#include <errno.h> 
 | 
					#include <errno.h> 
 | 
				
			||||||
 | 
					#include <ctype.h> // needs: isspace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <getopt.h> // needs: getopt_long
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "html.h" // needs: html_escaped
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	char * c_str;
 | 
						char * c_str;
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
@ -23,6 +29,7 @@ int string_append(string_t *str, char c) {
 | 
				
			|||||||
	str->c_str[str->len-1] = c;
 | 
						str->c_str[str->len-1] = c;
 | 
				
			||||||
	str->c_str[str->len] = 0; // make sure
 | 
						str->c_str[str->len] = 0; // make sure
 | 
				
			||||||
	str->len++;
 | 
						str->len++;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void string_destroy(string_t s) {
 | 
					void string_destroy(string_t s) {
 | 
				
			||||||
@ -62,6 +69,8 @@ attr_t * attr_set_find(attr_set_t *set, const char * name) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Append new Attribute to set
 | 
					// Append new Attribute to set
 | 
				
			||||||
int attr_set_append(attr_set_t * set, attr_t *new_entry) {
 | 
					int attr_set_append(attr_set_t * set, attr_t *new_entry) {
 | 
				
			||||||
 | 
						if (new_entry->name.c_str== NULL) return -1; // reject empty entries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// search first
 | 
						// search first
 | 
				
			||||||
	attr_t * new_ptr = attr_set_find(set, new_entry->name.c_str);
 | 
						attr_t * new_ptr = attr_set_find(set, new_entry->name.c_str);
 | 
				
			||||||
	if (new_ptr != NULL) {
 | 
						if (new_ptr != NULL) {
 | 
				
			||||||
@ -84,15 +93,90 @@ int attr_set_append(attr_set_t * set, attr_t *new_entry) {
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void attr_reset(attr_t * attr) {
 | 
				
			||||||
 | 
						memset(attr, 0, sizeof(attr_t));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int strip(FILE * stream) {
 | 
				
			||||||
 | 
						int current = 0;
 | 
				
			||||||
 | 
						while((current = fgetc(stream)) != EOF) {
 | 
				
			||||||
 | 
							if (!isspace(current))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return current;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int parse_attr(FILE * stream, attr_set_t * output) {
 | 
					int parse_attr(FILE * stream, attr_set_t * output) {
 | 
				
			||||||
	fprintf(stderr, "stub: parse_attr\n");
 | 
						attr_t current_attr = {};
 | 
				
			||||||
	return 0;
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
						printf("parse_attr\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						int buffer = 0;
 | 
				
			||||||
 | 
						unsigned char isKey = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while((buffer = fgetc(stream)) != EOF) {
 | 
				
			||||||
 | 
							// parse key=value pairs
 | 
				
			||||||
 | 
							// check for delim
 | 
				
			||||||
 | 
							//if (buffer == ' ' || buffer == '\t' || buffer == '\n'){
 | 
				
			||||||
 | 
							if (isspace(buffer)) {
 | 
				
			||||||
 | 
								attr_set_append(output, ¤t_attr);
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
								printf("parsed attr: %s=%s\n", current_attr.name.c_str, current_attr.value);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								// reset attribute
 | 
				
			||||||
 | 
								attr_reset(¤t_attr);
 | 
				
			||||||
 | 
								isKey = 1;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (buffer == '=') {
 | 
				
			||||||
 | 
								isKey = 0;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
							if (buffer == ']') {
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (isKey) {
 | 
				
			||||||
 | 
								string_append(¤t_attr.name, buffer);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								string_append(¤t_attr.value, buffer);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// append last attribute
 | 
				
			||||||
 | 
						attr_set_append(output, ¤t_attr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//memset(output, 0, sizeof(attr_set_t));
 | 
				
			||||||
 | 
						return strip(stream);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int parse_text(FILE * stream, FILE * output) {
 | 
					int parse_text(FILE * stream, FILE * output) {
 | 
				
			||||||
	// STUB
 | 
					#ifdef DEBUG
 | 
				
			||||||
	fprintf(stderr, "stub: parse_text\n");
 | 
						printf("parse text\n");
 | 
				
			||||||
	return 0;
 | 
					#endif
 | 
				
			||||||
 | 
						int buffer = 0;
 | 
				
			||||||
 | 
						char escaped = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while((buffer = fgetc(stream)) != EOF) {
 | 
				
			||||||
 | 
							if (!escaped && buffer == '\\') {
 | 
				
			||||||
 | 
								escaped = 1;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!escaped && buffer == '"') {
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							escaped = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (html_escape(buffer, output)) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fputc(buffer, output);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//fprintf(stderr, "stub: parse_text\n");
 | 
				
			||||||
 | 
						return strip(stream);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct node {
 | 
					typedef struct node {
 | 
				
			||||||
@ -102,7 +186,10 @@ typedef struct node {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// write out node
 | 
					// write out node
 | 
				
			||||||
void print_node(node_t * node, FILE * output) {
 | 
					void open_node(node_t * node, FILE * output) {
 | 
				
			||||||
 | 
						// check for empty node (text mostly)
 | 
				
			||||||
 | 
						if (!node->name.c_str)  return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// start by writing tag
 | 
						// start by writing tag
 | 
				
			||||||
	fputc('<', output);
 | 
						fputc('<', output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -113,43 +200,99 @@ void print_node(node_t * node, FILE * output) {
 | 
				
			|||||||
	size_t i = 0;
 | 
						size_t i = 0;
 | 
				
			||||||
	attr_t * current = node->attributes.arr;
 | 
						attr_t * current = node->attributes.arr;
 | 
				
			||||||
	for (; i < node->attributes.len; i++,current++) {
 | 
						for (; i < node->attributes.len; i++,current++) {
 | 
				
			||||||
		fprintf(output, " %s=\"%s\"", current->name.c_str, current->value.c_str);
 | 
							if (current->value.c_str)
 | 
				
			||||||
 | 
								fprintf(output, " %s=\"%s\"", current->name.c_str, current->value.c_str);
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								fputc(' ', output);
 | 
				
			||||||
 | 
								fputs(current->name.c_str, output);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// close tag
 | 
						// close tag
 | 
				
			||||||
	fputc('>', output);
 | 
						fputc('>', output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					void close_node(node_t * node, FILE * output) {
 | 
				
			||||||
 | 
						if (node->name.c_str) {
 | 
				
			||||||
 | 
							fprintf(output, "</%s>", node->name.c_str);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int print_tag(FILE * stream, FILE * output) {
 | 
					int readName(FILE *stream, node_t *node) {
 | 
				
			||||||
	node_t new_node;
 | 
						int current = strip(stream);
 | 
				
			||||||
	int buffer = 0;
 | 
						if (current == EOF) {
 | 
				
			||||||
 | 
							return current;
 | 
				
			||||||
	while ((buffer = fgetc(stream)) != EOF) {
 | 
					 | 
				
			||||||
		switch(buffer) {
 | 
					 | 
				
			||||||
		case '[': // parse attributes
 | 
					 | 
				
			||||||
			if (parse_attr(stream, &new_node.attributes) != -1) {
 | 
					 | 
				
			||||||
				fprintf(stderr, "could not parse attributes: %d", -1);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case '"':
 | 
					 | 
				
			||||||
			// raw text
 | 
					 | 
				
			||||||
			parse_text(stream, output);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			if (buffer != ' ' && buffer != '\t' && buffer != '\n') {
 | 
					 | 
				
			||||||
				string_append(&new_node.name, buffer);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							if (current == '{' || current == '[') {
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
							if (current == ' ' || current == '\t' || current == '\n') {
 | 
				
			||||||
 | 
								current = strip(stream);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							string_append(&node->name, current);
 | 
				
			||||||
 | 
						} while((current = fgetc(stream)) != EOF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return current;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum node_type {
 | 
				
			||||||
 | 
						NODE_SELFCLOSING,
 | 
				
			||||||
 | 
						NODE_TEXT,
 | 
				
			||||||
 | 
						NODE_TAG
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int parse_node(int current, FILE * stream, FILE * output) {
 | 
				
			||||||
 | 
						if (current == '"') {
 | 
				
			||||||
 | 
							return parse_text(stream, output);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// normal node
 | 
				
			||||||
 | 
						node_t current_node = {};
 | 
				
			||||||
 | 
						string_append(¤t_node.name, current);
 | 
				
			||||||
 | 
						current = readName(stream, ¤t_node);
 | 
				
			||||||
 | 
						if (current == EOF) {
 | 
				
			||||||
 | 
							goto done;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
						printf("parse_node: %s\n", current_node.name.c_str);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						if (current == '[') {
 | 
				
			||||||
 | 
							current = parse_attr(stream, ¤t_node.attributes);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (current != '{') {
 | 
				
			||||||
 | 
							// tag is selfclosing
 | 
				
			||||||
 | 
							open_node(¤t_node, output);
 | 
				
			||||||
 | 
							return current;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						current = strip(stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						open_node(¤t_node, output);
 | 
				
			||||||
 | 
						while(current != '}' && current != EOF) {
 | 
				
			||||||
 | 
							current = parse_node(current, stream, output);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						close_node(¤t_node, output);
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
						return strip(stream);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char ** args) {
 | 
					int main(int argc, char ** args) {
 | 
				
			||||||
 | 
						//getopt_long(argc, args, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char * filename= NULL;
 | 
						char * filename= NULL;
 | 
				
			||||||
	for(;argc != 1; --argc) {
 | 
						FILE * output = fopen("a.html", "w");
 | 
				
			||||||
 | 
						if (output == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "could not create output file\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(;argc > 1; --argc) {
 | 
				
			||||||
		filename = args[argc-1];
 | 
							filename = args[argc-1];
 | 
				
			||||||
		printf("starting conversion of %s\n", filename);
 | 
							printf("starting conversion of %s\n", filename);
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
@ -160,16 +303,19 @@ int main(int argc, char ** args) {
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		while(!feof(handle)) {
 | 
							int current = strip(handle);
 | 
				
			||||||
			if (print_tag(handle, stdout) != 0) {
 | 
					
 | 
				
			||||||
				fprintf(stderr, "error during parsing of node\n");
 | 
							while((current = parse_node(current, handle, output)) != EOF) {
 | 
				
			||||||
				break;
 | 
					//			if () {
 | 
				
			||||||
			}
 | 
					//				fprintf(stderr, "error during parsing of node\n");
 | 
				
			||||||
 | 
					//				break;
 | 
				
			||||||
 | 
					//			}
 | 
				
			||||||
		}	
 | 
							}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fclose(handle);
 | 
							fclose(handle);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fclose(output);
 | 
				
			||||||
	printf("done compiling\n");
 | 
						printf("done compiling\n");
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										36
									
								
								test.nhtml
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								test.nhtml
									
									
									
									
									
								
							@ -1,12 +1,28 @@
 | 
				
			|||||||
div {
 | 
					!DOCTYPE[html]
 | 
				
			||||||
	"hi i'm raw text"
 | 
					head {
 | 
				
			||||||
	"I'm raw text too :)" 
 | 
						title { "was geht" }
 | 
				
			||||||
	"Including \"escaping\""
 | 
						meta[charset=utf-8]
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
h1 {
 | 
					 | 
				
			||||||
div {
 | 
					 | 
				
			||||||
	"Another, but bigger font"
 | 
					 | 
				
			||||||
	"Adding a 
 | 
					 | 
				
			||||||
	new line adds a <br/> :)" 
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
						h1 { "Alle Meine Endchen schwimmen auf dem See" }
 | 
				
			||||||
 | 
						p {
 | 
				
			||||||
 | 
							"Alle meine Entchen schwimmen auf dem See,
 | 
				
			||||||
 | 
							schwimmen auf dem See,
 | 
				
			||||||
 | 
							Köpfchen in das Wasser, Schwänzchen in die Höh'." 
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p {
 | 
				
			||||||
 | 
							"Alle meine Täubchen gurren auf dem Dach,
 | 
				
			||||||
 | 
							gurren auf dem Dach,
 | 
				
			||||||
 | 
							eins fliegt in die Lüfte, fliegen alle nach." 
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p {
 | 
				
			||||||
 | 
							"Alle meine Hühner scharren in dem Stroh,
 | 
				
			||||||
 | 
							scharren in dem Stroh,
 | 
				
			||||||
 | 
							finden sie ein Körnchen, sind sie alle froh."
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p {
 | 
				
			||||||
 | 
							"Alle meine Gänschen watscheln durch den Grund,
 | 
				
			||||||
 | 
							watscheln durch den Grund,
 | 
				
			||||||
 | 
							suchen in dem Tümpel, werden kugelrund."
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user