diff options
Diffstat (limited to 'badroff.c')
-rw-r--r-- | badroff.c | 78 |
1 files changed, 69 insertions, 9 deletions
@@ -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)); |