diff options
-rw-r--r-- | src/frame.c | 97 | ||||
-rw-r--r-- | src/frame.h | 5 | ||||
-rw-r--r-- | src/sc_interp.c | 48 | ||||
-rw-r--r-- | src/sc_parse.c | 47 | ||||
-rw-r--r-- | src/sc_parse.h | 1 |
5 files changed, 101 insertions, 97 deletions
diff --git a/src/frame.c b/src/frame.c index 8f1e3ec..010394f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -51,7 +51,7 @@ struct _paragraph enum para_type type; double height; float space[4]; - int newline_at_end; + SCBlock *newline_at_end; /* For PARA_TYPE_TEXT */ int n_runs; @@ -352,15 +352,15 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w, para->height += para->space[2] + para->space[3]; } -int get_newline_at_end(Paragraph *para) +SCBlock *get_newline_at_end(Paragraph *para) { return para->newline_at_end; } -void set_newline_at_end(Paragraph *para) +void set_newline_at_end(Paragraph *para, SCBlock *bl) { - para->newline_at_end = 1; + para->newline_at_end = bl; } @@ -917,6 +917,27 @@ void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t) return; } + if ( (sc_block_name(run->scblock) != NULL) + && (strcmp(sc_block_name(run->scblock), "newpara") == 0) ) + { + + SCBlock *nnp; + printf("Inserting into newpara block...\n"); + + /* Add a new \newpara block after this one */ + nnp = sc_block_append(run->scblock, "newpara", + NULL, NULL, NULL); + + /* The first \newpara block becomes a normal anonymous block */ + sc_block_set_name(run->scblock, NULL); + + if ( para->newline_at_end == run->scblock ) { + para->newline_at_end = nnp; + printf("Replaced the newpara block\n"); + } + + } + /* Translate paragraph offset for insertion into SCBlock offset */ run_offs = offs - run->para_offs_bytes; scblock_offs = run_offs + run->scblock_offs_bytes; @@ -1214,9 +1235,7 @@ void merge_paragraphs(struct frame *fr, int para) { Paragraph *p1, *p2; struct text_run *runs_new; - int i, j; - size_t offs; - SCBlock *scblock; + int i; SCBlock *n; if ( para >= fr->n_paras-1 ) { @@ -1241,49 +1260,14 @@ void merge_paragraphs(struct frame *fr, int para) } p1->runs = runs_new; - /* Locate the newline which we have just deleted. */ - scblock = p1->runs[p1->n_runs-1].scblock; - n = sc_block_next(scblock); - offs = p1->runs[p1->n_runs-1].scblock_offs_bytes; - offs += p1->runs[p1->n_runs-1].len_bytes; - - if ( sc_block_contents(scblock)[offs] == '\n' ) { - - scblock_delete_text(scblock, offs, offs+1); - - /* Update the SC offset of any run from this SCBlock */ - for ( i=para+1; i<fr->n_paras; i++ ) { - int done = 0; - if ( fr->paras[i]->type != PARA_TYPE_TEXT ) break; - for ( j=0; j<fr->paras[i]->n_runs; j++ ) { - struct text_run *run = &fr->paras[i]->runs[j]; - if ( run->scblock == scblock ) { - run->scblock_offs_bytes -= 1; - } else { - done = 1; - break; - } - } - if ( done ) break; - } - - } else if ( (n!=NULL) && (sc_block_contents(n)[0] == '\n') ) { - - /* It's in the following SCBlock instead */ - - const char *c = sc_block_contents(n); - if ( strlen(c) == 1 ) { - SCBlock *ss = scblock; - sc_block_delete(&scblock, n); - assert(ss == scblock); - } else { - scblock_delete_text(n, 0, 1); - } + /* Delete the \newpara block to unite the paragraphs */ + n = get_newline_at_end(p1); + assert(n != NULL); + sc_block_delete(&fr->scblocks, n); - } else { - printf("Couldn't find newline!\n"); - printf("Have '%s'\n", sc_block_contents(scblock)+offs); - } + /* The end of the united paragraph should now be the end of the + * second one */ + set_newline_at_end(p1, get_newline_at_end(p2)); for ( i=0; i<p2->n_runs; i++ ) { @@ -1308,13 +1292,6 @@ void merge_paragraphs(struct frame *fr, int para) } -static char *s_strdup(const char *a) -{ - if ( a == NULL ) return NULL; - return strdup(a); -} - - static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc) { @@ -1425,10 +1402,10 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, pnew->runs[0].scblock_offs_bytes = 0; } - /* Add a newline after the end of the first paragraph's SC */ - sc_block_append(rr->scblock, s_strdup(sc_block_name(rr->scblock)), - s_strdup(sc_block_options(rr->scblock)), - strdup("\n"), NULL); + /* Add a \newpara after the end of the first paragraph's SC */ + set_newline_at_end(para, + sc_block_append(rr->scblock, strdup("newpara"), + NULL, NULL, NULL)); pnew->open = para->open; para->open = 0; diff --git a/src/frame.h b/src/frame.h index 1e46239..dbe79ef 100644 --- a/src/frame.h +++ b/src/frame.h @@ -131,8 +131,9 @@ extern double paragraph_height(Paragraph *para); extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is, enum is_size isz); -extern int get_newline_at_end(Paragraph *para); -extern void set_newline_at_end(Paragraph *para); +extern SCBlock *get_newline_at_end(Paragraph *para); +extern void set_newline_at_end(Paragraph *para, SCBlock *bl); +extern void check_run(struct frame *fr, int pn); extern void add_run(Paragraph *para, SCBlock *scblock, SCBlock *macro_real, size_t offs_bytes, size_t len_bytes, diff --git a/src/sc_interp.c b/src/sc_interp.c index df559e1..255fe91 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -887,13 +887,6 @@ static int in_macro(SCInterpreter *scin) } -static void set_newline_at_end_last_para(struct frame *fr) -{ - if ( fr->paras == NULL ) return; - set_newline_at_end(fr->paras[fr->n_paras-1]); -} - - /* Add the SCBlock to the text in 'frame', at the end */ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, PangoLanguage *lang, int editable, SCInterpreter *scin) @@ -916,35 +909,12 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, start = 0; do { - char *para_end; - size_t len; - - para_end = strchr(text+start, '\n'); - if ( para_end == NULL ) { - len = strlen(text+start); - } else { - len = para_end - (text+start); - } + size_t len = strlen(text+start); - if ( text[start] == '\n' ) { - if ( !last_para_available_for_text(fr) ) { - /* Add an empty paragraph */ - Paragraph *para = last_open_para(fr); - add_run(para, bl, mrb, start, 0, fontdesc, col); - set_para_spacing(para, st->paraspace); - set_newline_at_end(para); - } - /* Close this paragraph */ - set_newline_at_end_last_para(fr); - close_last_paragraph(fr); - start += 1; - } else { - /* Just add some text */ - Paragraph *para = last_open_para(fr); - add_run(para, bl, mrb, start, len, fontdesc, col); - set_para_spacing(para, st->paraspace); - start += len; - } + Paragraph *para = last_open_para(fr); + add_run(para, bl, mrb, start, len, fontdesc, col); + set_para_spacing(para, st->paraspace); + start += len; } while ( start < len_bytes ); @@ -1001,6 +971,14 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin) set_frame(scin, fr); maybe_recurse_after(scin, child); + } else if ( strcmp(name, "newpara")==0 ) { + struct frame *fr = sc_interp_get_frame(scin); + Paragraph *para = last_open_para(fr); + /* Add a dummy run which we can type into */ + add_run(para, bl, NULL, 0, 0, fr->fontdesc, fr->col); + set_newline_at_end(para, bl); + close_last_paragraph(fr); + } else { return 0; } diff --git a/src/sc_parse.c b/src/sc_parse.c index 56ebcaf..79e59a0 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -296,6 +296,9 @@ char *serialise_sc_block(const SCBlock *bl) if ( bl->name == NULL ) { strcat(a, bl->contents); + } else if ( strcmp(bl->name, "newpara") == 0 ) { + strcat(a, "\n"); + } else { strcat(a, "\\"); @@ -503,6 +506,41 @@ static size_t read_block(const char *sc, char **pname, char **options, } +static void separate_newlines(SCBlock *bl) +{ + while ( bl != NULL ) { + + char *npos; + const char *contents = sc_block_contents(bl); + + if ( contents != NULL ) { + npos = strchr(contents, '\n'); + if ( npos != NULL ) { + SCBlock *nb = NULL; + if ( npos == contents ) { + bl->name = strdup("newpara"); + bl->contents = NULL; + nb = bl; + } else { + sc_block_append(bl, strdup("newpara"), NULL, NULL, &nb); + } + if ( strlen(npos+1) > 0 ) { + sc_block_append(nb, NULL, NULL, strdup(npos+1), &nb); + } + npos[0] = '\0'; + } + } + + if ( sc_block_child(bl) != NULL ) { + separate_newlines(sc_block_child(bl)); + } + + bl = sc_block_next(bl); + + } +} + + SCBlock *sc_parse(const char *sc) { SCBlock *bl; @@ -601,10 +639,19 @@ SCBlock *sc_parse(const char *sc) j = 0; } + separate_newlines(blf); + return blf; } +void sc_block_set_name(SCBlock *bl, char *nam) +{ + free(bl->name); + bl->name = nam; +} + + void sc_block_set_options(SCBlock *bl, char *opt) { free(bl->options); diff --git a/src/sc_parse.h b/src/sc_parse.h index 4775996..41a1112 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -65,6 +65,7 @@ extern void sc_block_unlink(SCBlock **top, SCBlock *deleteme); extern SCBlock *find_last_child(SCBlock *bl); +extern void sc_block_set_name(SCBlock *bl, char *nam); extern void sc_block_set_options(SCBlock *bl, char *opt); extern void sc_block_set_contents(SCBlock *bl, char *con); extern void sc_insert_text(SCBlock *b1, size_t o1, const char *t); |