aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--badroff.c78
-rw-r--r--ll.c10
-rw-r--r--ll.h12
4 files changed, 94 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index b08be79..4c782b5 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/badroff.c b/badroff.c
index 2a961b5..c86e29f 100644
--- a/badroff.c
+++ b/badroff.c
@@ -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));
diff --git a/ll.c b/ll.c
new file mode 100644
index 0000000..d929b2f
--- /dev/null
+++ b/ll.c
@@ -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;
+}
diff --git a/ll.h b/ll.h
new file mode 100644
index 0000000..be85ccb
--- /dev/null
+++ b/ll.h
@@ -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