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).