/**********************************************************************/
/*                                                                    */
/*  WP - some simple macros to do some word-processing thingies.      */
/*     1) Allows you to reformat a paragraph. This means cramming     */
/*        as many words into a line as possible.                      */
/*     2) Allows to to justify those lines so the last char aligns    */
/*        at the right margin.                                        */
/*                                                                    */
/* Kludged together by Marc Adler/Magma Systems                       */
/*                                                                    */
/**********************************************************************/

#define CTRL_C  3
#define ALT_J   164
#define ALT_K   165

init()
{
  assign_key("just_para", ALT_J);
  assign_key("reform",    ALT_K);
  assign_key("center",    CTRL_C);
}

reform()
{
  int len;
  int margin;
  int oldlineno;
  string buf;

  /* prompt the user for the right margin */
  buf = get_tty_str("What is the right margin? ");
  if ((margin = atoi(buf)) <= 0) return;

  oldlineno = currlinenum();    /* save the current line number */

  /* March down till the end of the paragraph */
  while (!is_line_blank(currline()))
  {
    if ((len = strlen(currline())) == 0)        /* no more chars - bye */
      break;

    if (len > margin)                   /* we must split the line */
    {
      setcol(margin);                   /* move to the first word before */
      if (currchar() != ' ')            /*  the right margin */
        prevword();
      if (!is_bol())                     /* move backwards to the first blank */
      {
        left();
        while (!is_bol() && currchar() == ' ')
          left();
        right();
      }
      insert("\n");                     /* split it */
      while (!is_eol() && currchar() == ' ')  /* trim leading blanks */
        delchar();
    }

    else if (len <= margin)     /* too short - join next line if we can */
    {
      if (down() && is_line_blank(currline())) break;  /* no next line */

      /* trim the blanks off the end of the current line */
      up();
      goeol();
      left();
      while (currchar() == ' ' && currcol() > 1)
      {
        delchar();   left();
      }
      
      /* make sure there's a blank between the last word of this line */
      /* and the first word of the joined line */
      goeol();
      insert(" ");
      delchar();                /* join 'em */
    }
  } /* end while */

  /* Go to the original position */
  goline(oldlineno);
  gobol();
}


/* just_para - right justifies all lines downwards until the end */
/*              of the paragraph */
just_para()
{
  while (!is_line_blank(currline()))
  {
    expand();
    down();
  }
}


/* expand() - right-justifies a line by inserting spaces between words */
expand()
{
  string text, new;
  int    margin, nextra, nholes, nb;

  margin = 65;

  squash();                             /* compress multiple blanks */
  text   = currline();
  nholes = wordcount(text) - 1;         /* get the number of gaps   */
  nextra = margin - strlen(text);       /*  and the # of padding blks */

  new = "";                             /* 'new' holds the new line */
  gobol();

  while (!is_eol() && nholes > 0)
  {
    c = currchar();
    new = strcat(new, chr(c));
    if (c == ' ')
    {
      /* pad with the appropriate number of blanks */
      new = strcat(new, repstr(" ", nb = nextra/nholes));
      nextra = nextra - nb;
      nholes = nholes - 1;
    }
    right();
  }

  /* Concat the remainder of the old line to the new line */
  new = strcat(new, substr(text, currcol(), 100));

  /* delete the old line and insert the new one */
  gobol();
  deleol();
  insert(new);
  gobol();
}


/* squash() - compressed sequences of mult. blanks into one blank */
squash()
{
  gobol();                      /* start at the front of the curr line */

  while (!is_eol())
  {
    if (currchar() == ' ')
    {
      right();
      while (!is_eol() && currchar() == ' ')  delchar();    /* compress */
    }
    else
      right();
  }

  gobol();                      /* go back to the front */
}


/* Wordcount() - counts the # of words in the string str. Assumes that   */
/*               the string has no multiple blanks (performed by squash) */
wordcount(str)
  string str;
{
  int count, i, len;

  count = 1;
  len = strlen(str);

  for (i = 1;  i <= len;  i = i + 1)
    if (substr(str, i, 1) == " ")  count = count + 1;
  return count;
}

is_line_blank(str)
  string str;
{
  rtrim(str);
  return (str == "");
}

/* This macro centers the current line */
center()
{
  string text;

  text = currline();
  gobol();         /* get rid of the characters in the line */
  deleol();
  ltrim(text);     /* remove leading & trailing blanks      */
  rtrim(text);
  setcol((80 - strlen(text)) / 2);   /* go to midway point  */
  insert(text);    /* re-insert the text                    */
  gobol();         /* move to the next line down            */
  down();
}

