diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | badroff.c | 78 | ||||
-rw-r--r-- | ll.c | 10 | ||||
-rw-r--r-- | ll.h | 12 |
4 files changed, 94 insertions, 11 deletions
@@ -1,7 +1,8 @@ .POSIX: -OBJS = badroff.o buf.o +OBJS = badroff.o buf.o ll.o badroff: $(OBJS) -badroff.o: badroff.c buf.h +badroff.o: badroff.c buf.h ll.h buf.o: buf.c buf.h +ll.o: ll.c ll.h clean: rm -f badroff $(OBJS) @@ -3,6 +3,11 @@ #include <stdlib.h> #include "buf.h" +#include "ll.h" + +char* line(void); +char* wordset(char* txt); +void wsclean(char* txt); typedef enum { false, @@ -101,11 +106,51 @@ char* leader(char* txt){ fin[i] = repeat[i % rptln]; return fin; } +bool endlineset = false; +char* lineset(char* txt){ + llnode *head, *tail; head = tail = appendll(NULL, NULL); + size_t ct, len; ct = len = 0; + while (true){ + tail->next = appendll(tail, line()); + if (endlineset) break; + tail = tail->next; + ct++; + len += strlen(tail->str); + } + free(tail->next->str); free(tail->next); //.ELS cmd + tail = tail->next = head->next; // loop linked list + free(head); + + char *lines, *pos; + lines = malloc((sizeof(char)*(len+1))); + // construct lines + int jmp; + for (pos = lines; pos-lines < len; pos += jmp, tail = tail->next){ + char* str = tail->str + tail->loc; + char* loc = memchr(str, '\n', strlen(str)); + jmp = (loc == NULL) ? 0 : loc-str+1; + memcpy(pos, str, jmp); + tail->loc += jmp; + } + llnode* last = NULL; + /*for (size_t i = 0; i<=ct; i++, last = tail, tail = tail->next){ + free(tail->str); + free(last); + }*/ + endlineset = false; + wsclean(lines); + return lines; +} +char* finlineset(char* txt){ + char* str = malloc(sizeof(char)); str[0] = 0; + endlineset = true; + return str; +} -char* cmds[] = - {"CT ", "FIL ", "LD ", "W "}; // MUST be sorted alphabetically +char* cmds[] = // MUST be sorted alphabetically + {"CT ", "ELS", "FIL ", "LD ", "LS", "W "}; char* (*call[])(char* txt) = - {center, fillline, leader, setwidth}; + {center, finlineset, fillline, leader, lineset, setwidth}; char* cmd(void){ char* dat = popstrbuf(inbuf, chrfill('\n')); @@ -131,24 +176,39 @@ char* cmd(void){ // normal typesetting +void wsclean(char* txt){ + size_t disp = 0; + int firstws; + for (size_t i = 0; i == 0 || txt[i-1] != 0; i++){ + if ( (txt[i] == ' ' || txt[i] == '\n') && txt[i-1] != ' '){ + firstws = i; + } + if (txt[i] == '\n'){ + disp += i-firstws; + } + txt[i-disp] = txt[i]; + } +} + char* wordset(char* txt){ char* orig = txt; - size_t len = strlen(txt); size_t ws = width; - for (size_t i=0; i<len; i++){ + for (size_t i=0; txt[i] != 0; i++){ // turn into a nested loop if (txt[i] == ' ') ws = i; - if (i > width){ + if (i >= width && ws != i){ txt += ws; - txt[0] = '\n'; - len -= ws; + txt[0] = '\n'; ws = width; - i = 0; + i = 0; } } + wsclean(orig); + return orig; } + char* typeset(void){ size_t len = chrfill('\n'); return wordset(popstrbuf(inbuf, len)); @@ -0,0 +1,10 @@ +#include <stdlib.h> +#include "ll.h" + +llnode* appendll(llnode* tail, char* str){ + llnode* new = malloc(sizeof(llnode)); + if (tail != NULL) tail->next = new; + new->str = str; + new->loc = 0; + return new; +} @@ -0,0 +1,12 @@ +#ifndef _LL_INCLUDE +#define _LL_INCLUDE + +typedef struct llnode { + char* str; + int loc; + struct llnode* next; +} llnode; + +llnode* appendll(llnode* tail, char* str); + +#endif |