9front - general discussion about 9front
 help / color / mirror / Atom feed
From: ori@eigenstate.org
To: 9front@9front.org
Subject: [Patch] fmt with line prefixes.
Date: Mon, 28 Oct 2019 20:34:29 -0700	[thread overview]
Message-ID: <2E7A6A1C7EC2C64348910B4B518151DE@eigenstate.org> (raw)

I' use fmt to reflow emails, and I've found it useful to teach fmt to
reflow lines with quote prefixes, like

	> > quote a long line
	> and a response

into

	> > quote a
	> > long line
	> and a
	> response

Below is a patch that does it.  I'm not sure if there's a better or
more general way to handle it (regex prefixes?), or whether it's
useful enough to commit.

Ideally, someone would be able to give me a clever script to do this
without touching fmt, but I haven't been able to think of a way of
doing it.

Thoughts, improvements, or better ideas?


diff -r fe8aefb6ab34 sys/src/cmd/fmt.c
--- a/sys/src/cmd/fmt.c	Mon Oct 28 14:12:44 2019 -0700
+++ b/sys/src/cmd/fmt.c	Mon Oct 28 20:19:24 2019 -0700
@@ -7,8 +7,10 @@
  * block up paragraphs, possibly with indentation
  */
 
+char *lineprefix = "";		/* what prefix can lines have? */
 int extraindent = 0;		/* how many spaces to indent all lines */
 int indent = 0;			/* current value of indent, before extra indent */
+int prefix = 0;			/* current count of prefixes */
 int length = 70;		/* how many columns per output line */
 int join = 1;			/* can lines be joined? */
 int maxtab = 8;
@@ -21,6 +23,7 @@
 {
 	Word	*next;
 
+	int	prefix;
 	int	indent;
 	int	length;
 	char	bol;
@@ -46,6 +49,9 @@
 	case 'i':
 		extraindent = atoi(EARGF(usage()));
 		break;
+	case 'p':
+		lineprefix = EARGF(usage());
+		break;
 	case 'j':
 		join = 0;
 		break;
@@ -57,7 +63,7 @@
 		usage();
 	}ARGEND
 
-	if(length <= indent){
+	if(length <= extraindent){
 		fprint(2, "%s: line length<=indentation\n", argv0);
 		exits("length");
 	}
@@ -89,11 +95,25 @@
 }
 
 int
+prefixof(char **s)
+{
+	int pfx, np;
+
+	if(!*lineprefix)
+		return 0;
+
+	np = strlen(lineprefix);
+	for(pfx = 0; strncmp(*s, lineprefix, np) == 0; pfx++)
+		*s += strlen(lineprefix);
+	return pfx;
+}
+
+int
 indentof(char *s)
 {
 	int ind;
 
-	ind = 0;
+	ind = 0;		
 	for(; *s != '\0'; s++)
 		switch(*s){
 		default:
@@ -112,13 +132,14 @@
 }
 
 Word*
-newword(char *s, int n, int ind, int bol)
+newword(char *s, int n, int ind, int pfx, int bol)
 {
 	Word *w;
 
 	w = malloc(sizeof(Word) + n+1);
 	w->next = nil;
 	w->indent = ind;
+	w->prefix = pfx;
 	w->bol = bol;
 	memmove(w->text, s, n);
 	w->text[n] = 0;
@@ -142,20 +163,21 @@
 	if(line == nil)
 		return nil;
 	tail = nil;
+	prefix = prefixof(&line);
 	indent = indentof(line);
 	for(;;){
 		while(*line == ' ' || *line == '\t')
 			line++;
 		if(*line == '\0'){
 			if(head == nil)
-				return newword("", 0, -1, 1);
+				return newword("", 0, -1, -1, 1);
 			break;
 		}
 		/* how long is this word? */
 		for(s=line++; *line != '\0'; line++)
 			if(*line==' ' || *line=='\t')
 				break;
-		w = newword(s, line-s, indent, head==nil);
+		w = newword(s, line-s, indent, prefix, head==nil);
 		if(head == nil)
 			head = w;
 		else
@@ -167,9 +189,26 @@
 	return w;
 }
 
-void
-printindent(int w)
+int
+printprefix(int p)
 {
+	int l, i, np;
+
+	l = 0;
+	np = strlen(lineprefix);
+	for(i = 0; i < p; i++){
+		Bprint(&bout, lineprefix);
+		l += np;
+	}
+	return l;
+}
+
+int
+printindent(int ind)
+{
+	int w;
+
+	w = ind;
 	while(w >= maxtab){
 		Bputc(&bout, '\t');
 		w -= maxtab;
@@ -178,6 +217,7 @@
 		Bputc(&bout, ' ');
 		w--;
 	}
+	return ind;
 }
 
 /* give extra space if word ends with period, etc. */
@@ -211,8 +251,10 @@
 			if(w == nil)
 				break;
 		}
-		col = w->indent;
-		printindent(extraindent+col);
+		col = 0;
+		col += printindent(extraindent);
+		col += printprefix(w->prefix);
+		col += printindent(w->indent);
 		/* emit words until overflow; always emit at least one word */
 		for(;;){
 			Bprint(&bout, "%s", w->text);
@@ -221,7 +263,7 @@
 			w = getword();
 			if(w == nil)
 				break;
-			if(w->indent != o->indent)
+			if(w->indent != o->indent || w->prefix != o->prefix)
 				break;	/* indent change */
 			nsp = nspaceafter(o->text);
 			if(col+nsp+w->length > length)



                 reply	other threads:[~2019-10-29  3:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2E7A6A1C7EC2C64348910B4B518151DE@eigenstate.org \
    --to=ori@eigenstate.org \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).