Top vs. bottom posting, solution proposal ;-)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 ================

-- 
fedora-list mailing list
fedora-list@xxxxxxxxxx
To unsubscribe: https://www.redhat.com/mailman/listinfo/fedora-list
[Index of Archives]     [Older Fedora Users]     [Fedora Announce]     [Fedora Package Announce]     [EPEL Announce]     [Fedora Magazine]     [Fedora News]     [Fedora Summer Coding]     [Fedora Laptop]     [Fedora Cloud]     [Fedora Advisory Board]     [Fedora Education]     [Fedora Security]     [Fedora Scitech]     [Fedora Robotics]     [Fedora Maintainers]     [Fedora Infrastructure]     [Fedora Websites]     [Anaconda Devel]     [Fedora Devel Java]     [Fedora Legacy]     [Fedora Desktop]     [Fedora Fonts]     [ATA RAID]     [Fedora Marketing]     [Fedora Management Tools]     [Fedora Mentors]     [SSH]     [Fedora Package Review]     [Fedora R Devel]     [Fedora PHP Devel]     [Kickstart]     [Fedora Music]     [Fedora Packaging]     [Centos]     [Fedora SELinux]     [Fedora Legal]     [Fedora Kernel]     [Fedora OCaml]     [Coolkey]     [Virtualization Tools]     [ET Management Tools]     [Yum Users]     [Tux]     [Yosemite News]     [Gnome Users]     [KDE Users]     [Fedora Art]     [Fedora Docs]     [Asterisk PBX]     [Fedora Sparc]     [Fedora Universal Network Connector]     [Libvirt Users]     [Fedora ARM]

  Powered by Linux