From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eigenstate.org ([206.124.132.107]) by ewsd; Mon Oct 28 23:34:31 EDT 2019 Received: from eigenstate.org (localhost [127.0.0.1]) by eigenstate.org (OpenSMTPD) with ESMTP id ae85c826 for <9front@9front.org>; Mon, 28 Oct 2019 20:34:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=eigenstate.org; h= message-id:to:subject:date:from:mime-version:content-type :content-transfer-encoding; s=mail; bh=Dbnc1/+DycnZQErerRAW/fIR+ vg=; b=OG0BufheSSYM5IzoNi9rbUO5w8drhxJhhe6w3XYxWzE/wlryFaB8wTeBB /hwG9jozW+5GD/ToKw0Zx3ft/Zlb2uphu+dqn3ucu4CfaJ+NlSKhiiY/yoXvqwQe d3sfBAUmgcKs+EDDIEkD+KrY5KBtL9knwJeaOOZwluoCNBkCFg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=eigenstate.org; h=message-id :to:subject:date:from:mime-version:content-type :content-transfer-encoding; q=dns; s=mail; b=MpN3NSKgxVNTU28U4p1 ghg0VJVVCs5UD+TW67/nZD9lLl5VFMO7t9BKGkEXpvy82pu0b7hcQjS3gy9GD9js QXWFhZSpvbYl37Gkrd2ns+jbtBVvRAeqDZH3hy25U/GKzmMDvANfi7pTnKjxdfOh 4829ZodSklAOATKJDlwuLWPg= Received: from abbatoir.hsd1.ca.comcast.net (c-76-21-119-139.hsd1.ca.comcast.net [76.21.119.139]) by eigenstate.org (OpenSMTPD) with ESMTPSA id 3ea348cf (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO) for <9front@9front.org>; Mon, 28 Oct 2019 20:34:30 -0700 (PDT) Message-ID: <2E7A6A1C7EC2C64348910B4B518151DE@eigenstate.org> To: 9front@9front.org Subject: [Patch] fmt with line prefixes. Date: Mon, 28 Oct 2019 20:34:29 -0700 From: ori@eigenstate.org MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: managed scale-out method-scale SVG over JSON package singleton 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)