aboutsummaryrefslogtreecommitdiff
path: root/src/sc_interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sc_interp.c')
-rw-r--r--src/sc_interp.c727
1 files changed, 142 insertions, 585 deletions
diff --git a/src/sc_interp.c b/src/sc_interp.c
index dea8446..7bbfeeb 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -38,21 +38,6 @@
#include "utils.h"
-struct macro
-{
- char *name;
- SCBlock *bl;
- struct macro *prev; /* Previous declaration, or NULL */
-};
-
-
-struct template
-{
- char *name;
- SCBlock *bl;
-};
-
-
struct sc_state
{
PangoFontDescription *fontdesc;
@@ -71,25 +56,8 @@ struct sc_state
double slide_height;
struct frame *fr; /* The current frame */
-
- int n_macros;
- int max_macros;
- struct macro *macros; /* Contents need to be copied on push */
-
- int n_styles;
- int max_styles;
- struct macro *styles; /* Contents need to be copied on push */
-
- int n_templates;
- int max_templates;
- struct template *templates;
-
- SCBlock *macro_contents; /* If running a macro, the child block of the caller */
- SCBlock *macro_real_block; /* If running a macro, the block which called the macro */
- int macro_editable; /* If running a macro, whether this bit can be edited or not */
};
-
struct _scinterp
{
PangoContext *pc;
@@ -118,6 +86,17 @@ struct _sccallbacklist
};
+static int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss)
+{
+ while ( bl != NULL ) {
+ if ( sc_interp_add_block(scin, bl, ss) ) return 1;
+ bl = sc_block_next(bl);
+ }
+
+ return 0;
+}
+
+
SCCallbackList *sc_callback_list_new()
{
SCCallbackList *cbl;
@@ -242,12 +221,6 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl)
double w, h;
int r;
void *bvp;
- SCBlock *rbl;
-
- rbl = bl;
- if ( sc_interp_get_macro_real_block(scin) != NULL ) {
- bl = sc_interp_get_macro_real_block(scin);
- }
if ( strcmp(cbl->names[i], name) != 0 ) continue;
r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]);
@@ -255,7 +228,7 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl)
struct sc_state *st = &scin->state[scin->j];
Paragraph *pnew;
pnew = add_callback_para(sc_interp_get_frame(scin),
- bl, rbl, w, h,
+ bl, w, h,
cbl->draw_funcs[i],
cbl->click_funcs[i],
bvp, cbl->vps[i]);
@@ -293,41 +266,6 @@ double *sc_interp_get_fgcol(SCInterpreter *scin)
}
-double *sc_interp_get_bgcol(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->bgcol;
-}
-
-
-double *sc_interp_get_bgcol2(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->bgcol2;
-}
-
-
-GradientType sc_interp_get_bggrad(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->bggrad;
-}
-
-
-int sc_interp_get_ascent(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->ascent;
-}
-
-
-int sc_interp_get_height(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->height;
-}
-
-
static void set_frame_default_style(struct frame *fr, SCInterpreter *scin)
{
if ( fr == NULL ) return;
@@ -526,38 +464,22 @@ static void set_bggrad(SCInterpreter *scin, const char *options,
{
struct sc_state *st = &scin->state[scin->j];
GdkRGBA col1, col2;
- char *n2;
- char *optcopy = strdup(options);
- if ( options == NULL ) {
- fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), options);
- return;
- }
-
- n2 = strchr(optcopy, ',');
- if ( n2 == NULL ) {
- fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), options);
- return;
- }
+ if ( parse_colour_duo(options, &col1, &col2) == 0 ) {
- n2[0] = '\0';
+ st->bgcol[0] = col1.red;
+ st->bgcol[1] = col1.green;
+ st->bgcol[2] = col1.blue;
+ st->bgcol[3] = col1.alpha;
- gdk_rgba_parse(&col1, optcopy);
- gdk_rgba_parse(&col2, &n2[1]);
+ st->bgcol2[0] = col2.red;
+ st->bgcol2[1] = col2.green;
+ st->bgcol2[2] = col2.blue;
+ st->bgcol2[3] = col2.alpha;
- st->bgcol[0] = col1.red;
- st->bgcol[1] = col1.green;
- st->bgcol[2] = col1.blue;
- st->bgcol[3] = col1.alpha;
+ st->bggrad = grad;
- st->bgcol2[0] = col2.red;
- st->bgcol2[1] = col2.green;
- st->bgcol2[2] = col2.blue;
- st->bgcol2[3] = col2.alpha;
-
- st->bggrad = grad;
-
- free(optcopy);
+ }
}
@@ -611,13 +533,6 @@ struct frame *sc_interp_get_frame(SCInterpreter *scin)
}
-SCBlock *sc_interp_get_macro_real_block(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->macro_real_block;
-}
-
-
static void set_frame(SCInterpreter *scin, struct frame *fr)
{
struct sc_state *st = &scin->state[scin->j];
@@ -649,33 +564,6 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
scin->cbl = NULL;
st = &scin->state[0];
- st->n_macros = 0;
- st->max_macros = 16;
- st->macros = malloc(16*sizeof(struct macro));
- if ( st->macros == NULL ) {
- free(scin->state);
- free(scin);
- return NULL;
- }
- st->n_styles = 0;
- st->max_styles = 16;
- st->styles = malloc(16*sizeof(struct macro));
- if ( st->styles == NULL ) {
- free(scin->state);
- free(scin);
- return NULL;
- }
- st->n_templates = 0;
- st->max_templates = 16;
- st->templates = malloc(16*sizeof(struct template));
- if ( st->templates == NULL ) {
- free(scin->state);
- free(scin);
- return NULL;
- }
- st->macro_contents = NULL;
- st->macro_real_block = NULL;
- st->macro_editable = 0;
st->fr = NULL;
st->paraspace[0] = 0.0;
st->paraspace[1] = 0.0;
@@ -696,7 +584,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
st->bgcol2[1] = 1.0;
st->bgcol2[2] = 1.0;
st->bgcol2[3] = 1.0;
- st->bggrad = GRAD_NOBG;
+ st->bggrad = GRAD_NONE;
scin->lang = lang;
/* The "ultimate" default font */
@@ -713,8 +601,6 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
void sc_interp_destroy(SCInterpreter *scin)
{
- /* FIXME: Free all templates and macros */
-
/* Empty the stack */
while ( scin->j > 0 ) {
sc_interp_restore(scin);
@@ -729,34 +615,6 @@ void sc_interp_destroy(SCInterpreter *scin)
}
-static int parse_double(const char *a, float v[2])
-{
- int nn;
-
- nn = sscanf(a, "%fx%f", &v[0], &v[1]);
- if ( nn != 2 ) {
- fprintf(stderr, _("Invalid size '%s'\n"), a);
- return 1;
- }
-
- return 0;
-}
-
-
-static int parse_tuple(const char *a, float v[4])
-{
- int nn;
-
- nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]);
- if ( nn != 4 ) {
- fprintf(stderr, _("Invalid tuple '%s'\n"), a);
- return 1;
- }
-
- return 0;
-}
-
-
static void set_padding(struct frame *fr, const char *opts)
{
float p[4];
@@ -788,19 +646,6 @@ static void set_paraspace(SCInterpreter *scin, const char *opts)
}
-static void set_slide_size(SCInterpreter *scin, const char *opts)
-{
- float p[2];
- struct sc_state *st = &scin->state[scin->j];
-
- if ( parse_double(opts, p) ) return;
-
- st->slide_width = p[0];
- st->slide_height = p[1];
- st->have_size = 1;
-}
-
-
void update_geom(struct frame *fr)
{
char geom[256];
@@ -1015,24 +860,17 @@ static void maybe_recurse_before(SCInterpreter *scin, SCBlock *child)
}
-static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child)
+static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child,
+ Stylesheet *ss)
{
if ( child == NULL ) return;
- sc_interp_add_blocks(scin, child);
+ sc_interp_add_blocks(scin, child, ss);
sc_interp_restore(scin);
}
-static int in_macro(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- if ( st->macro_contents == NULL ) return 0;
- return 1;
-}
-
-
-static void add_newpara(struct frame *fr, SCBlock *bl, SCBlock *mrb)
+static void add_newpara(struct frame *fr, SCBlock *bl)
{
Paragraph *last_para;
@@ -1043,7 +881,7 @@ static void add_newpara(struct frame *fr, SCBlock *bl, SCBlock *mrb)
/* The block after the \newpara will always be the first one of the
* next paragraph, by definition, even if it's \f or another \newpara */
- create_paragraph(fr, sc_block_next(mrb), sc_block_next(bl));
+ create_paragraph(fr, sc_block_next(bl));
}
@@ -1055,7 +893,6 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl,
PangoFontDescription *fontdesc;
double *col;
struct sc_state *st = &scin->state[scin->j];
- SCBlock *rbl;
Paragraph *para;
/* Empty block? */
@@ -1064,47 +901,113 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl,
fontdesc = sc_interp_get_fontdesc(scin);
col = sc_interp_get_fgcol(scin);
- rbl = bl;
- if ( st->macro_real_block != NULL ) {
- bl = st->macro_real_block;
- }
-
para = last_para(fr);
if ( (para == NULL) || (para_type(para) != PARA_TYPE_TEXT) ) {
/* Last paragraph is not text.
* or: no paragraphs yet.
* Either way: Create the first one */
- para = create_paragraph(fr, bl, rbl);
+ para = create_paragraph(fr, bl);
}
set_para_alignment(para, st->alignment);
- add_run(para, bl, rbl, fontdesc, col);
+ add_run(para, bl, fontdesc, col);
set_para_spacing(para, st->paraspace);
return 0;
}
-void sc_interp_run_style(SCInterpreter *scin, const char *sname)
+static void apply_style(SCInterpreter *scin, Stylesheet *ss, const char *path)
{
- int i;
- struct sc_state *st = &scin->state[scin->j];
+ char *result;
- for ( i=0; i<st->n_styles; i++ ) {
- if ( strcmp(sname, st->styles[i].name) == 0 ) {
- sc_interp_add_blocks(scin, st->styles[i].bl);
- return;
+ if ( ss == NULL ) return;
+
+ /* Font */
+ result = stylesheet_lookup(ss, path, "font");
+ if ( result != NULL ) set_font(scin, result);
+
+ /* Foreground colour */
+ result = stylesheet_lookup(ss, path, "fgcol");
+ if ( result != NULL ) set_colour(scin, result);
+
+ /* Background (vertical gradient) */
+ result = stylesheet_lookup(ss, path, "bggradv");
+ if ( result != NULL ) set_bggrad(scin, result, GRAD_VERT);
+
+ /* Background (horizontal gradient) */
+ result = stylesheet_lookup(ss, path, "bggradh");
+ if ( result != NULL ) set_bggrad(scin, result, GRAD_HORIZ);
+
+ /* Background (solid colour) */
+ result = stylesheet_lookup(ss, path, "bgcol");
+ if ( result != NULL ) set_bgcol(scin, result);
+
+ /* Padding */
+ result = stylesheet_lookup(ss, path, "pad");
+ if ( result != NULL ) set_padding(sc_interp_get_frame(scin), result);
+
+ /* Paragraph spacing */
+ result = stylesheet_lookup(ss, path, "paraspace");
+ if ( result != NULL ) set_paraspace(scin, result);
+
+ /* Alignment */
+ result = stylesheet_lookup(ss, path, "alignment");
+ if ( result != NULL ) {
+ if ( strcmp(result, "center") == 0 ) {
+ set_alignment(scin, PANGO_ALIGN_CENTER);
}
+ if ( strcmp(result, "left") == 0 ) {
+ set_alignment(scin, PANGO_ALIGN_LEFT);
+ }
+ if ( strcmp(result, "right") == 0 ) {
+ set_alignment(scin, PANGO_ALIGN_RIGHT);
+ }
+ }
+
+ update_bg(scin);
+}
+
+
+static void output_frame(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss,
+ const char *stylename)
+{
+ struct frame *fr;
+ SCBlock *child = sc_block_child(bl);
+ const char *options = sc_block_options(bl);
+ char *result;
+
+ fr = add_subframe(sc_interp_get_frame(scin));
+ fr->scblocks = bl;
+ fr->resizable = 1;
+ if ( fr == NULL ) {
+ fprintf(stderr, _("Failed to add frame.\n"));
+ return;
+ }
+
+ /* Lowest priority: current state of interpreter */
+ set_frame_default_style(fr, scin);
+
+ /* Next priority: geometry from stylesheet */
+ result = stylesheet_lookup(ss, stylename, "geometry");
+ if ( result != NULL ) {
+ parse_frame_options(fr, sc_interp_get_frame(scin), result);
}
+
+ /* Highest priority: parameters to \f (or \slidetitle etc) */
+ parse_frame_options(fr, sc_interp_get_frame(scin), options);
+
+ maybe_recurse_before(scin, child);
+ set_frame(scin, fr);
+ apply_style(scin, ss, stylename);
+ maybe_recurse_after(scin, child, ss);
}
-static int check_outputs(SCBlock *bl, SCInterpreter *scin)
+static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss)
{
const char *name = sc_block_name(bl);
const char *options = sc_block_options(bl);
- SCBlock *child = sc_block_child(bl);
- struct sc_state *st = &scin->state[scin->j];
if ( name == NULL ) {
add_text(sc_interp_get_frame(scin),
@@ -1116,11 +1019,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
if ( parse_image_options(options, sc_interp_get_frame(scin),
&w, &h, &filename) == 0 )
{
- SCBlock *rbl = bl;
- if ( st->macro_real_block != NULL ) {
- bl = st->macro_real_block;
- }
- add_image_para(sc_interp_get_frame(scin), bl, rbl,
+ add_image_para(sc_interp_get_frame(scin), bl,
filename, scin->is, w, h, 1);
free(filename);
} else {
@@ -1129,38 +1028,20 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
}
} else if ( strcmp(name, "f")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.frame");
- struct frame *fr;
+ } else if ( strcmp(name, "slidetitle")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.slidetitle");
- fr = add_subframe(sc_interp_get_frame(scin));
- fr->scblocks = bl;
- if ( in_macro(scin) ) {
- fr->resizable = 0;
- } else {
- fr->resizable = 1;
- }
- if ( fr == NULL ) {
- fprintf(stderr, _("Failed to add frame.\n"));
- return 1;
- }
-
- set_frame_default_style(fr, scin);
+ } else if ( strcmp(name, "prestitle")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.prestitle");
- parse_frame_options(fr, sc_interp_get_frame(scin), options);
-
- maybe_recurse_before(scin, child);
- set_frame(scin, fr);
- sc_interp_run_style(scin, "frame");
- maybe_recurse_after(scin, child);
+ } else if ( strcmp(name, "author")==0 ) {
+ output_frame(scin, bl, ss, "$.slide.author");
} else if ( strcmp(name, "newpara")==0 ) {
-
struct frame *fr = sc_interp_get_frame(scin);
- SCBlock *rbl = bl;
- if ( st->macro_real_block != NULL ) {
- bl = st->macro_real_block;
- }
- add_newpara(fr, bl, rbl);
+ add_newpara(fr, bl);
} else {
return 0;
@@ -1170,68 +1051,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
}
-static int check_macro(const char *name, SCInterpreter *scin)
-{
- int i;
- struct sc_state *st = &scin->state[scin->j];
-
- if ( name == NULL ) return 0;
-
- for ( i=0; i<st->n_macros; i++ ) {
- if ( strcmp(st->macros[i].name, name) == 0 ) {
- return 1;
- }
- }
-
- return 0;
-}
-
-
-static void exec_macro(SCBlock *bl, SCInterpreter *scin, SCBlock *child)
-{
- struct sc_state *st = &scin->state[scin->j];
- int i;
- const char *name;
-
- name = sc_block_name(bl);
- for ( i=0; i<st->n_macros; i++ ) {
- if ( strcmp(st->macros[i].name, name) == 0 ) {
- sc_interp_save(scin);
- scin->state[scin->j].macro_real_block = bl;
- scin->state[scin->j].macro_contents = child;
- sc_interp_add_blocks(scin, scin->state[scin->j].macros[i].bl);
- sc_interp_restore(scin);
- break; /* Stop iterating, because "st" is now invalid */
- }
- }
-}
-
-
-static void run_macro_contents(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- SCBlock *contents = st->macro_contents;
-
- sc_interp_save(scin);
- scin->state[scin->j].macro_real_block = NULL;
- sc_interp_add_blocks(scin, contents);
- sc_interp_restore(scin);
-}
-
-
-static void run_editable(SCInterpreter *scin, SCBlock *contents)
-{
- //struct sc_state *st = &scin->state[scin->j];
-
- sc_interp_save(scin);
- //scin->state[scin->j].macro_real_block = NULL;
- scin->state[scin->j].macro_editable = 1;
- sc_interp_add_blocks(scin, contents);
- sc_interp_restore(scin);
-}
-
-
-int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
+int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss)
{
const char *name = sc_block_name(bl);
const char *options = sc_block_options(bl);
@@ -1241,16 +1061,11 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
//show_sc_blocks(bl);
//printf("<------------\n");
- if ( check_macro(name, scin) ) {
- sc_interp_save(scin);
- exec_macro(bl, scin, child);
- sc_interp_restore(scin);
-
- } else if ( check_callback(scin, bl) ) {
+ if ( check_callback(scin, bl) ) {
/* Handled in check_callback, don't do anything else */
} else if ((sc_interp_get_frame(scin) != NULL)
- && check_outputs(bl, scin) ) {
+ && check_outputs(bl, scin, ss) ) {
/* Block handled as output thing */
} else if ( name == NULL ) {
@@ -1258,95 +1073,86 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
} else if ( strcmp(name, "presentation") == 0 ) {
maybe_recurse_before(scin, child);
- sc_interp_run_style(scin, "narrative");
- maybe_recurse_after(scin, child);
-
- } else if ( strcmp(name, "stylesheet") == 0 ) {
- /* Ignore (see sc_interp_run_stylesheet) */
+ apply_style(scin, ss, "$.narrative");
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "slide") == 0 ) {
maybe_recurse_before(scin, child);
- sc_interp_run_style(scin, "slide");
- maybe_recurse_after(scin, child);
+ apply_style(scin, ss, "$.slide");
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "font") == 0 ) {
maybe_recurse_before(scin, child);
set_font(scin, options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "fontsize") == 0 ) {
maybe_recurse_before(scin, child);
set_fontsize(scin, options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bold") == 0 ) {
maybe_recurse_before(scin, child);
set_bold(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "oblique") == 0 ) {
maybe_recurse_before(scin, child);
set_oblique(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "italic") == 0 ) {
maybe_recurse_before(scin, child);
set_italic(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "lalign") == 0 ) {
maybe_recurse_before(scin, child);
set_alignment(scin, PANGO_ALIGN_LEFT);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "ralign") == 0 ) {
maybe_recurse_before(scin, child);
set_alignment(scin, PANGO_ALIGN_RIGHT);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "center") == 0 ) {
maybe_recurse_before(scin, child);
set_alignment(scin, PANGO_ALIGN_CENTER);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "fgcol") == 0 ) {
maybe_recurse_before(scin, child);
set_colour(scin, options);
- maybe_recurse_after(scin, child);
-
- } else if ( strcmp(name, "contents") == 0 ) {
- run_macro_contents(scin);
-
- } else if ( strcmp(name, "editable") == 0 ) {
- run_editable(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "pad") == 0 ) {
maybe_recurse_before(scin, child);
set_padding(sc_interp_get_frame(scin), options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bgcol") == 0 ) {
maybe_recurse_before(scin, child);
set_bgcol(scin, options);
update_bg(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bggradh") == 0 ) {
maybe_recurse_before(scin, child);
set_bggrad(scin, options, GRAD_HORIZ);
update_bg(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "bggradv") == 0 ) {
maybe_recurse_before(scin, child);
set_bggrad(scin, options, GRAD_VERT);
update_bg(scin);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else if ( strcmp(name, "paraspace") == 0 ) {
maybe_recurse_before(scin, child);
set_paraspace(scin, options);
- maybe_recurse_after(scin, child);
+ maybe_recurse_after(scin, child, ss);
} else {
@@ -1358,252 +1164,3 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl)
return 0;
}
-
-int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
-{
- while ( bl != NULL ) {
- if ( sc_interp_add_block(scin, bl) ) return 1;
- bl = sc_block_next(bl);
- }
-
- return 0;
-}
-
-
-static int try_add_style(SCInterpreter *scin, const char *options, SCBlock *bl)
-{
- struct sc_state *st = &scin->state[scin->j];
- char *nn;
- char *comma;
- int i;
-
- nn = strdup(options);
- comma = strchr(nn, ',');
- if ( comma != NULL ) {
- comma[0] = '\0';
- }
-
- for ( i=0; i<st->n_styles; i++ ) {
- if ( strcmp(st->styles[i].name, nn) == 0 ) {
- st->styles[i].name = nn;
- st->styles[i].bl = bl;
- st->styles[i].prev = NULL; /* FIXME: Stacking */
- return 0;
- }
- }
-
- if ( st->max_styles == st->n_styles ) {
-
- struct macro *styles_new;
-
- styles_new = realloc(st->styles, sizeof(struct macro)
- * (st->max_styles+16));
- if ( styles_new == NULL ) {
- fprintf(stderr, _("Failed to add style.\n"));
- return 1;
- }
-
- st->styles = styles_new;
- st->max_styles += 16;
-
- }
-
- i = st->n_styles++;
-
- st->styles[i].name = nn;
- st->styles[i].bl = bl;
- st->styles[i].prev = NULL; /* FIXME: Stacking */
-
- return 0;
-}
-
-
-static int try_add_macro(SCInterpreter *scin, const char *options, SCBlock *bl)
-{
- struct sc_state *st = &scin->state[scin->j];
- char *nn;
- char *comma;
- int i;
-
- nn = strdup(options);
- comma = strchr(nn, ',');
- if ( comma != NULL ) {
- comma[0] = '\0';
- }
-
- for ( i=0; i<st->n_macros; i++ ) {
- if ( strcmp(st->macros[i].name, nn) == 0 ) {
- st->macros[i].name = nn;
- st->macros[i].bl = bl;
- st->macros[i].prev = NULL; /* FIXME: Stacking */
- return 0;
- }
- }
-
- if ( st->max_macros == st->n_macros ) {
-
- struct macro *macros_new;
-
- macros_new = realloc(st->macros, sizeof(struct macro)
- * (st->max_macros+16));
- if ( macros_new == NULL ) {
- fprintf(stderr, _("Failed to add macro.\n"));
- return 1;
- }
-
- st->macros = macros_new;
- st->max_macros += 16;
-
- }
-
- i = st->n_macros++;
-
- st->macros[i].name = nn;
- st->macros[i].bl = bl;
- st->macros[i].prev = NULL; /* FIXME: Stacking */
-
- return 0;
-}
-
-
-static int try_add_template(SCInterpreter *scin, const char *options, SCBlock *bl)
-{
- struct sc_state *st = &scin->state[scin->j];
- char *nn;
- char *comma;
- int i;
-
- nn = strdup(options);
- comma = strchr(nn, ',');
- if ( comma != NULL ) {
- comma[0] = '\0';
- }
-
- for ( i=0; i<st->n_templates; i++ ) {
- if ( strcmp(st->templates[i].name, nn) == 0 ) {
- fprintf(stderr, _("Duplicate template '%s'\n"), nn);
- return 0;
- }
- }
-
- if ( st->max_templates == st->n_templates ) {
-
- struct template *templates_new;
-
- templates_new = realloc(st->templates, sizeof(struct template)
- * (st->max_templates+16));
- if ( templates_new == NULL ) {
- fprintf(stderr, _("Failed to add templates\n"));
- return 1;
- }
-
- st->templates = templates_new;
- st->max_templates += 16;
-
- }
-
- i = st->n_templates++;
-
- st->templates[i].name = nn;
- st->templates[i].bl = bl;
-
- return 0;
-}
-
-void add_macro(SCInterpreter *scin, const char *mname, const char *contents)
-{
- SCBlock *bl = sc_parse(contents);
- try_add_macro(scin, mname, bl);
-}
-
-
-void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl)
-{
- if ( bl == NULL ) return;
-
- if ( strcmp(sc_block_name(bl), "stylesheet") != 0 ) {
- fprintf(stderr, _("Style sheet isn't a style sheet.\n"));
- return;
- }
-
- bl = sc_block_child(bl);
-
- while ( bl != NULL ) {
-
- const char *name = sc_block_name(bl);
- const char *options = sc_block_options(bl);
-
- if ( name == NULL ) {
-
- /* Do nothing */
-
- } else if ( strcmp(name, "def") == 0 ) {
- try_add_macro(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "ss") == 0 ) { /* Backward compatibility */
- try_add_macro(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "style") == 0 ) {
- try_add_style(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "template") == 0 ) {
- try_add_template(scin, options, sc_block_child(bl));
-
- } else if ( strcmp(name, "font") == 0 ) {
- set_font(scin, options);
-
- } else if ( strcmp(name, "fgcol") == 0 ) {
- set_colour(scin, options);
-
- } else if ( strcmp(name, "bgcol") == 0 ) {
- set_bgcol(scin, options);
- update_bg(scin);
-
- } else if ( strcmp(name, "bggradh") == 0 ) {
- set_bggrad(scin, options, GRAD_HORIZ);
- update_bg(scin);
-
- } else if ( strcmp(name, "bggradv") == 0 ) {
- set_bggrad(scin, options, GRAD_VERT);
- update_bg(scin);
-
- } else if ( strcmp(name, "paraspace") == 0 ) {
- set_paraspace(scin, options);
-
- } else if ( strcmp(name, "slidesize") == 0 ) {
- set_slide_size(scin, options);
-
- }
-
- bl = sc_block_next(bl);
-
- }
-}
-
-
-int sc_interp_get_slide_size(SCInterpreter *scin, double *w, double *h)
-{
- if ( !scin->state->have_size ) return 1;
- *w = scin->state->slide_width;
- *h = scin->state->slide_height;
- return 0;
-}
-
-
-struct template_id *sc_interp_get_templates(SCInterpreter *scin, int *np)
-{
- struct template_id *list;
- int i;
-
- list = malloc(sizeof(struct template_id)*scin->state->n_templates);
- if ( list == NULL ) return NULL;
-
- for ( i=0; i<scin->state->n_templates; i++ ) {
- list[i].name = strdup(scin->state->templates[i].name);
- list[i].friendlyname = strdup(scin->state->templates[i].name);
- list[i].scblock = sc_block_copy(scin->state->templates[i].bl);
- }
-
- *np = scin->state->n_templates;
- return list;
-}