aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolden Rohrer <hr@hrhr.dev>2020-04-01 13:51:38 -0400
committerDhari Rohrer <DhariRohrer@DhariRorersiMac.hsd1.ga.comcast.net>2020-04-01 15:15:03 -0400
commit539e0bac89012848047e9d69aeee3d2138714928 (patch)
treed68c1e03707dc8b84778ee8128800c942cf84dee
parentef71654b996bcbdb769fe53f63f54afd54b741b7 (diff)
migrated typeset
typeset() now relies on a one line at a time approach; the current version does have some bugs, though (poor handling of large spaces, EOL whitespace)
-rw-r--r--badroff.c58
1 files changed, 21 insertions, 37 deletions
diff --git a/badroff.c b/badroff.c
index c28e153..2a961b5 100644
--- a/badroff.c
+++ b/badroff.c
@@ -1,8 +1,9 @@
#include <stdio.h>
-#include "buf.h"
#include <string.h>
#include <stdlib.h>
+#include "buf.h"
+
typedef enum {
false,
true
@@ -130,44 +131,27 @@ char* cmd(void){
// normal typesetting
-bool cont_typst = false; // communicates with line() for broken lines.
-
-size_t nextws(size_t start){//searches for \n or [^ \n]-1 in buffer
- //starts at `start` (if not whitespace, returns start-1)
- size_t len = buflen(inbuf);
- char* str = peekstrbuf(inbuf, start, len-start);
- size_t i;
- for (i = 0; i<len-start; i++){
- if (str[i] == '\n') return start+i;
- else if (str[i] != ' ') return start+i-1;
+char* wordset(char* txt){
+ char* orig = txt;
+ size_t len = strlen(txt);
+ size_t ws = width;
+ for (size_t i=0; i<len; i++){
+ if (txt[i] == ' ') ws = i;
+ if (i > width){
+ txt += ws;
+ txt[0] = '\n';
+ len -= ws;
+ ws = width;
+ i = 0;
+ }
}
- free(str);
- for (int c = 0; c != '\n' && ( c = addchr() ) != EOF && c == ' ';
- len++); // if this is a newline, exit late (len is last, !(len-1)).
- return len;
+
+ return orig;
}
char* typeset(void){
- size_t len = chrnfill('\n', width+1); //+1 for \n on 81-char lines
- char* next = peekstrbuf(inbuf, 0, len);
- size_t wsend = 0;
- if (next[--len] == '\n'){
- wsend = len;
- } else if (next[len] == ' '){
- wsend = nextws(len);
- }
- else for (wsend = len; next[wsend] != ' '; wsend--);
- // wsend is last index with a piece of whitespace
- for (len = min(wsend,len-1); next[len] == ' '; len--);
- // check, within the string, behind the whitespace for a letter.
- if (next[len] == '\n') len--; // "\n" shouldn't become "\n\n"
- // len should be *index of* last letter
- if (peekchrbuf(inbuf, wsend) == '\n') cont_typst = false;
- else cont_typst = true;
- free(next);
- char* ln = popstrbuf(inbuf, wsend+1);
- ln[len+1] = '\n'; ln[len+2] = 0;
- return ln;
+ size_t len = chrfill('\n');
+ return wordset(popstrbuf(inbuf, len));
}
// a parser to choose when to typeset and when to run a command
@@ -177,7 +161,7 @@ char* line(void){
if ( (sz = fillbuf(2)) == 0)
return "";
char* twobytes = peekstrbuf(inbuf, 0, 2); // .., .\n, or ^.?
- if (sz == 1 || twobytes[1] == '\n' || cont_typst) return typeset();
+ if (sz == 1 || twobytes[1] == '\n') return typeset();
if (twobytes[0] == '.') popchrbuf(inbuf);
if (twobytes[0] == '.' && twobytes[1] != '.'){
char* data = cmd();
@@ -201,7 +185,7 @@ int main(int argc, char** argv){
char* out;
while ( (out = line())[0] != '\0'){
printf("%s",out);
- free(out);
+ // free(out);
}
fclose(in);
return 0;