Top vs. bottom posting, solution proposal ;-)
Arthur Pemberton
pemboa at gmail.com
Sun Oct 15 20:27:57 UTC 2006
On 10/15/06, Marko Vojinovic <vvmarko at panet.co.yu> wrote:
>
> Hi everybody, :-)
>
> Please, don't hate me for bringing up this topic yet again. I do not wish to
> start another flame, and have no preferences with respect to top/bottom
> posting.
>
> It's just that in several years on this list there were several long
> discussions about that, and I guess we could do without them. :-)
>
> So, I devoted a couple of hours of my time to write down some prototype of
> top/bottom post converter, creatively named top2bottom.c :-) . I didn't even
> bother to google-research for any already existing stuff of the kind, just
> started from scratch and c-ed until it started working... The code is below.
> (Sorry, I don't have a website to upload it and send you a link, it seems the
> easiest way was to post it...) Also, below are some notes about it, for those
> interested.
>
> Try it, and if you like it, send me some feedback to make it better. Or do it
> yourself. Consider this to be my $0.04 to the global benefit of the list.
> Just imagine the scenario: somebody top-posts; he gets a kind reply to not
> top-post; if he continues, top-post-annoyed people filter his messages
> through top2bottom transparently, and there is no discussion about it any
> more. There is peace on Earth, and good will among people... ;-)
>
> Best regards, :-)
> Marko
>
> Still here? Ok. Read on... :-)
>
> A couple of usage notes:
> * This is c code. :-) I prefer it to assembly language, and don't have enough
> skill to do it using bash.
> * Compile it via "gcc top2bottom.c -o top2bottom", should work with any
> version of gcc. Actually, I guess it is compiler/os/platform independent.
> * It reads from stdin and writes to stdout. Feed it with the body of the
> top-posted message to get it bottom-posted.
>
> A couple of features/bugs:
> * Top-posted messages become bottom-posted. By reversing the order of sorting,
> one can make bottom-posted messages get converted to top-posted.
> * "Interspersed" messages are not touched.
> * The "Yesterday Jim wrote:" titles of quotes get from the top of the quote to
> the bottom of it. This may make a message look a bit awkward or confusing,
> but there is no easy way out of it. OTOH, when there are several successive
> quotes, the titles are equally confusing being on the top, also (at least for
> me).
> * ">" is the sole quoting symbol recognized. If there is feedback that this
> thing is useful, i'll be happy to include other quoting symbols, implement a
> bunch of behaviour-changing options, clean up and optimize the code, etc.
>
> A couple of technical notes:
> * I am completely aware that this program is terribly inefficient,
> unoptimized, slow, has insane memory usage, etc..., and that I have broken
> virtually every programming rule that can apply in this case.
> * That said, have in mind that this is just a proof-of-concept code, put
> together in a couple of hours, and I don't want to do any real work on it
> unless I get some feedback that it is useful to the others.
> * That said, note that it works.
> * If it doesn't work, tell me about it. If it segfaults, you probably need to
> enlarge the 5000 characters-per-line limit and/or 5000 lines-per-message
> limit... I know, it's a hack, it's ugly, it's awful, it's crap...
> * If you need to know about licencing etc, consider this to be GNU GPL
> software, although I don't really care. Use it, modify it, whatever...
> * DO NOT learn how to program by looking at this. This is a VERY VERY BAD
> example of code. :-)
> * It's not that I am a bad programmer, I am just being lazy. Have other things
> to do in life, a thesis to work on, etc...
>
> YET STILL HERE??!! Ok, here goes the code. Note that it may look ugly due to
> line wrapping, but it should work nevertheless... :-)
>
> ======== Beginning of the file top2bottom.c ============
> #include <stdio.h>
>
> #define MaxLine 5000 /* Maximum number of characters per line */
> #define MaxMesg 5000 /* Maximum number of lines per file */
> #define EOLN '\n' /* End of line character */
>
> int interspersed; /* indicator to say whether the message is
> interspersed or not */
> int NumberOfLines; /* Counts the total number of lines in a message */
>
> struct MessageStruct {
> int quoteorder; /* The number of leading quote symbols in this
> line */
> int linenumber; /* The initial number of this line */
> char data[MaxLine]; /* The line string */
> } line[MaxMesg]; /* An array of lines, ie. the whole message buffer */
>
> void ReadTheMessage()
> {
> char c;
> int n=0; /* Current line counter */
> int i=0; /* Current character counter */
> int endoffile=0; /* End of file indicator */
>
> NumberOfLines=0; /* Message is empty at this point */
> while((!endoffile)&&((c=getchar())!=EOF)) /* Read in the data from
> stdin */
> {
> line[n].quoteorder=0; /* Initialize the quote order. It will be
> counted later... */
> i=0; /* Reset the character counter */
> while((c!=EOLN)&&(c!=EOF)) /* Read in the current line */
> {
> line[n].data[i] = c; /* Feed the message buffer with the data */
> i++; /* Move to the next character */
> c=getchar(); /* Read it, and repeat */
> }
> line[n].data[i] = EOLN; /* Finish the string */
> line[n].linenumber=n; /* Set the line number */
> n++; /* Move to the next line, and repeat */
> if(c==EOF) endoffile=1; /* Handle the premature end of file */
> }
> NumberOfLines=n; /* Save the number of lines and finish */
> }
>
> void WriteTheMessage()
> {
> int n=0; /* Current line counter */
> int i=0; /* Current character counter */
>
> while(n<NumberOfLines) /* Write the data to stdout */
> {
> i=0; /* Reset the character counter */
> while(line[n].data[i]!=EOLN)
> putchar(line[n].data[i++]); /* Write the current line */
> putchar(EOLN); /* Write the end of line */
> n++; /* Move to the next line, and repeat */
> }
> }
>
> void AnalyzeTheMessage()
> {
> char c;
> int n=0; /* Current line counter */
> int i=0; /* Current character counter */
> int k=0; /* Current quote order counter */
> int orderlessthenk=0; /* Indicator if there is a quoteorder less then k */
> int maxquoteorder=0; /* Maximum value for the quoteorder */
>
> /*
> Ok. First we count the so called "quote order" of each line,
> which amounts to number of leading '>'s per line. In the process,
> we need to account for the famous "From" bug in sendmail, and
> decrement the quoteorder if the text starts with the word
> "From", in order to get it right.
> */
> for(n=0;n<NumberOfLines;n++) /* Go through the each line */
> {
> i=0; /* Reset the character counter */
> c=line[n].data[i]; /* Set the initial data */
> while( ((c=='>')||(c==' ')) &&(c!=EOLN) ) /* Count the leading '>'s, skip
> spaces */
> {
> if (c=='>') line[n].quoteorder++; /* Increment quoteorder for each
> '>' */
> i++; /* Go to the next character */
> c=line[n].data[i]; /* Read it, and repeat */
> }
> if ( (c=='F')&& /* Check if the following string is
> "From" */
> (line[n].data[i+1]=='r')&& /* Now, this is very, very ugly...
> */
> (line[n].data[i+2]=='o')&&
> (line[n].data[i+3]=='m') )
> line[n].quoteorder--; /* If yes, decrease the
> quoteorder... */
> }
> /*
> Now we need to check if the message is interspersed or not. This is tricky,
> as we need to find constructions of the form:
>
> > > >
> >
> > > >
>
> and similar, which amount to quoteorder being 3,1,3 and the like.
> Simoultaneously, we *don't* want to find constrctions of the form:
>
> >
> > > >
> >
>
> because this can happen even if the message is not interspersed.
> But that's life... ;-)
> */
> for(n=0;n<NumberOfLines;n++) /* First find the biggest quote order
> */
> if (line[n].quoteorder>maxquoteorder) maxquoteorder=line[n].quoteorder;
>
> interspersed=0; /* Assume message is not interspersed */
>
> for(k=1;k<maxquoteorder;k++) /* We need to check the above construction for
> all nonzero quote orders */
> {
> n=0; /* Start from the begining of the message */
> while ((line[n].quoteorder!=k)&&(n<NumberOfLines)) n++; /* Get to the
> block of lines of quoteorder k */
> while ((line[n].quoteorder==k)&&(n<NumberOfLines)) n++; /* Go through the
> block */
> /* Now go down the rest ot the lines, and check if some line has
> quoteorder less then k, and another line after it the quoteorder
> equal to k again, which amounts to interspersed construction.
> */
> orderlessthenk=0; /* Assume there are no quotes of order less then k */
> while (n<NumberOfLines) /* For each of the remaining lines */
> {
> if (line[n].quoteorder<k) orderlessthenk = 1; /* alert if there is a
> quote of lesser order */
> if ((line[n].quoteorder==k)&&(orderlessthenk)) interspersed=1; /* We
> found the interspersed construction!! */
> n++; /* Go check the next line */
> }
> }
> /*
> And that's it. If the message has interspersed structure on any level
> of quoteorder, we have the indicator on. Otherwise, it is off.
> */
> }
>
> void SwitchLines(int i, int j)
> {
> int n;
> int tempquoteorder;
> int templinenumber;
> char tempdata[MaxLine];
>
> /* This switches line i with line j, as needed for sorting (sigh)... */
> n=0; /* Copy line i to temp */
> tempquoteorder=line[i].quoteorder;
> templinenumber=line[i].linenumber;
> while(line[i].data[n]!=EOLN)
> tempdata[n]=line[i].data[n++];
> tempdata[n]=EOLN;
> n=0; /* Copy line j to line i */
> line[i].quoteorder=line[j].quoteorder;
> line[i].linenumber=line[j].linenumber;
> while(line[j].data[n]!=EOLN)
> line[i].data[n]=line[j].data[n++];
> line[i].data[n]=EOLN;
> n=0; /* Copy temp to line j */
> line[j].quoteorder=tempquoteorder;
> line[j].linenumber=templinenumber;
> while(tempdata[n]!=EOLN)
> line[j].data[n]=tempdata[n++];
> line[j].data[n]=EOLN;
> }
>
> void SortTheMessage()
> {
> int i,j;
>
> /*
> In order to make the message bottom-posted, we simply need to sort the lines
> by quoteorder
> descending. Further, we need to preserve the order of lines of the same
> quoteorder,
> which amounts in sorting same-quoteorder lines by line number, ascending.
> N.B.: Maybe this can be done in a more clever way, but I am lazy to ponder
> over it... :-)
> */
>
> /* The algorithm is just a simple, stupid and slow bubble-sort, over
> quoteorder and
> linenumber simultaneously... */
> for(i=0;i<NumberOfLines;i++)
> for (j=0;j<=i;j++)
> {
> if(line[i].quoteorder>line[j].quoteorder) SwitchLines(i,j);
>
> if((line[i].quoteorder==line[j].quoteorder)&&(line[i].linenumber<line[j].linenumber))
> SwitchLines(i,j);
> }
> }
>
> int main() /* This is self-explanatory, I hope... :-) */
> {
> ReadTheMessage();
> AnalyzeTheMessage();
> if (!interspersed) SortTheMessage();
> WriteTheMessage();
> }
>
> ======== End of the file top2bottom.c ================
>
Not that this debate really matters to me, lthough I do see the
benifits of bottom posting, I am willing to host this on my site
www.pembo13.com for you if you'd like.
--
Fedora Core 5 and proud
More information about the fedora-list
mailing list