From e855e14baa0c00bb0da4da1aef4d120f10c7a65e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 3 Sep 2012 09:02:31 +0200 Subject: "Finished" parser --- Makefile.am | 7 +- src/presentation.h | 1 + src/storycode.c | 341 +++++++++++++++++++++++++++++++++++++++++------- src/storycode.h | 2 + tests/.gitignore | 1 + tests/render_test_sc1.c | 95 ++++++++++++++ tests/storycode_test.c | 28 +++- 7 files changed, 427 insertions(+), 48 deletions(-) create mode 100644 tests/render_test_sc1.c diff --git a/Makefile.am b/Makefile.am index 30d789a..a6003a8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,10 +25,13 @@ icons_DATA = data/colloquium-select.svg data/colloquium-text.svg \ EXTRA_DIST += $(colloquium_DATA) -noinst_PROGRAMS = tests/storycode_test tests/render_test -TESTS = tests/storycode_test tests/render_test +noinst_PROGRAMS = tests/storycode_test tests/render_test tests/render_test_sc1 +TESTS = tests/storycode_test tests/render_test tests/render_test_sc1 tests_storycode_test_SOURCES = tests/storycode_test.c src/storycode.c tests_render_test_SOURCES = tests/render_test.c src/storycode.c src/render.c \ src/layout.c + +tests_render_test_sc1_SOURCES = tests/render_test_sc1.c src/storycode.c \ + src/render.c src/layout.c diff --git a/src/presentation.h b/src/presentation.h index 64e6d79..73eb5b3 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -57,6 +57,7 @@ struct frame struct frame **rendering_order; int num_ro; + int max_ro; char *sc; /* Storycode */ diff --git a/src/storycode.c b/src/storycode.c index b9dfb20..d843128 100644 --- a/src/storycode.c +++ b/src/storycode.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "storycode.h" #include "presentation.h" @@ -136,91 +137,343 @@ static int sc_block_list_add(SCBlockList *bl, bl->blocks[bl->n_blocks].options = options; bl->blocks[bl->n_blocks].contents = contents; bl->n_blocks++; + return 0; } -SCBlockList *sc_find_blocks(const char *sc, const char *blockname) +static int get_subexpr(const char *sc, char *bk, char **pcontents, int *err) { - SCBlockList *bl; - const char *pos; - char label[1024]; + size_t ml; + int i; + int bct = 1; + int found = 0; + char *contents; - bl = sc_block_list_new(); - if ( bl == NULL ) return NULL; + *err = 0; - if ( strlen(blockname) > 1021 ) { - fprintf(stderr, "Block name '%s' too long.\n", blockname); - return NULL; + ml = strlen(sc); + contents = malloc(ml+1); + if ( contents == NULL ) { + *err = -1; + return 0; } + *pcontents = contents; + + for ( i=0; iname == NULL ) { + strcat(out, b->contents); + } else { + + if ( strcmp(blockname, b->name) != 0 ) { + strcat(out, "\\"); + strcat(out, b->name); + if ( b->options != NULL ) { + strcat(out, "["); + strcat(out, b->options); + strcat(out, "]"); + } + if ( b->contents != NULL ) { + strcat(out, "{"); + strcat(out, b->contents); + strcat(out, "}"); + } + + if ( (b->options == NULL) + && (b->contents == NULL) ) { + strcat(out, " "); + } + + } + + } + } + sc_block_list_free(bl); + + return out; +} + + +static int alloc_ro(struct frame *fr) +{ + struct frame **new_ro; + + new_ro = realloc(fr->rendering_order, + fr->max_ro*sizeof(struct frame *)); + if ( new_ro == NULL ) return 1; + + fr->rendering_order = new_ro; + + return 0; +} + + +static struct frame *frame_new() +{ + struct frame *n; + + n = calloc(1, sizeof(struct frame)); + if ( n == NULL ) return NULL; + + n->rendering_order = NULL; + n->max_ro = 32; + alloc_ro(n); + + n->num_ro = 1; + n->rendering_order[0] = n; + + return n; +} + + +static struct frame *add_subframe(struct frame *fr, char *sc) +{ + struct frame *n; + + n = frame_new(); + if ( n == NULL ) return NULL; + + if ( fr->num_ro == fr->max_ro ) { + fr->max_ro += 32; + if ( alloc_ro(fr) ) return NULL; + } + + fr->rendering_order[fr->num_ro++] = fr; + + return fr; +} + + +static void recursive_unpack(struct frame *fr, const char *sc) +{ + SCBlockList *bl; + SCBlockListIterator *iter; + struct scblock *b; + + bl = sc_find_blocks(sc, "f"); + + for ( b = sc_block_list_first(bl, &iter); + b != NULL; + b = sc_block_list_next(bl, iter) ) + { + struct frame *sfr; + sfr = add_subframe(fr, remove_blocks(sc, "f")); + recursive_unpack(sfr, b->contents); + } + sc_block_list_free(bl); +} + + /* Unpack level 2 StoryCode (content + subframes) into frames */ struct frame *sc_unpack(const char *sc) { struct frame *fr; - fr = calloc(1, sizeof(struct frame)); + fr = frame_new(); if ( fr == NULL ) return NULL; - + fr->sc = remove_blocks(sc, "f"); + printf("Top frame: '%s'\n", fr->sc); + recursive_unpack(fr, sc); return fr; } diff --git a/src/storycode.h b/src/storycode.h index 6ba5e45..97d22f8 100644 --- a/src/storycode.h +++ b/src/storycode.h @@ -44,4 +44,6 @@ struct scblock *sc_block_list_next(SCBlockList *bl, SCBlockListIterator *iter); extern SCBlockList *sc_find_blocks(const char *sc, const char *blockname); extern void sc_block_list_free(SCBlockList *bl); +extern struct frame *sc_unpack(const char *sc); + #endif /* STORYCODE_H */ diff --git a/tests/.gitignore b/tests/.gitignore index 5549a63..b352eb3 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -3,3 +3,4 @@ .dirstamp storycode_test render_test +render_test_sc1 diff --git a/tests/render_test_sc1.c b/tests/render_test_sc1.c new file mode 100644 index 0000000..9cbf042 --- /dev/null +++ b/tests/render_test_sc1.c @@ -0,0 +1,95 @@ +/* + * render_test_sc1.c + * + * Colloquium - A tiny presentation program + * + * Copyright (c) 2012 Thomas White + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "../src/storycode.h" +#include "../src/render.h" +#include "../src/layout.h" +#include "../src/stylesheet.h" + + +static gint mw_destroy(GtkWidget *w, void *p) +{ + exit(0); +} + +static gboolean draw_sig(GtkWidget *da, cairo_t *cr, struct frame *fr) +{ + PangoContext *pc; + GtkAllocation allocation; + gint w, h; + + w = gtk_widget_get_allocated_width(da); + h = gtk_widget_get_allocated_height(da); + + /* Overall background */ + cairo_rectangle(cr, 0.0, 0.0, w, h); + cairo_set_source_rgb(cr, 0.9, 0.9, 0.9); + cairo_fill(cr); + + pc = gtk_widget_get_pango_context(da); + + gtk_widget_get_allocation(da, &allocation); + + layout_frame(fr, allocation.width, allocation.height); + render_frame(fr, cr, pc); + + return FALSE; +} + + +int main(int argc, char *argv[]) +{ + GtkWidget *window; + GtkWidget *drawingarea; + struct frame *fr; + + gtk_init(&argc, &argv); + + fr = sc_unpack("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.\\f{Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.} Wibble Wobble."); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + drawingarea = gtk_drawing_area_new(); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(drawingarea)); + gtk_widget_set_size_request(GTK_WIDGET(drawingarea), 320, 200); + + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(mw_destroy), + NULL); + + g_signal_connect(G_OBJECT(drawingarea), "draw", + G_CALLBACK(draw_sig), fr); + + gtk_widget_show_all(window); + gtk_main(); + + return 0; +} diff --git a/tests/storycode_test.c b/tests/storycode_test.c index a39fa72..e9987ef 100644 --- a/tests/storycode_test.c +++ b/tests/storycode_test.c @@ -35,14 +35,38 @@ int main(int argc, char *argv[]) SCBlockList *bl; SCBlockListIterator *iter; struct scblock *b; + const char *tt = "\\bg[a=b]{wibble \\f{wobble}}\\bg{rwawr}Wobble" + "\\f{wibble \\bg[muhu]{wobble}}"; - bl = sc_find_blocks("\\bg{wibble \\f{wobble}}\\bg{rwawr}Wobble", "bg"); + printf("'%s' ->\n", tt); + bl = sc_find_blocks(tt, "bg"); + + if ( bl == NULL ) { + printf("Failed to find blocks.\n"); + return 1; + } + + for ( b = sc_block_list_first(bl, &iter); + b != NULL; + b = sc_block_list_next(bl, iter) ) + { + printf(" \\%s [%s] {%s}\n", b->name, b->options, b->contents); + } + sc_block_list_free(bl); + + printf("->\n"); + bl = sc_find_blocks(tt, NULL); + + if ( bl == NULL ) { + printf("Failed to find blocks.\n"); + return 1; + } for ( b = sc_block_list_first(bl, &iter); b != NULL; b = sc_block_list_next(bl, iter) ) { - printf("'%s'\n", b->contents); + printf(" \\%s [%s] {%s}\n", b->name, b->options, b->contents); } sc_block_list_free(bl); -- cgit v1.2.3