home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 019 / text.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  7KB  |  380 lines

  1. /*
  2.  *  Copyright (c) 1992 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include "buffer.h"
  9. #include "ins.h"
  10. #include "ledit.h"
  11. #include "text.h"
  12. #include "screen.h"
  13. #include "cmds.h"
  14. #include "paste.h"
  15. #include "misc.h"
  16. #include "slang.h"
  17.  
  18. /* This routine deletes multiple spaces except those following a period, '?'
  19.    or a '!'.
  20.  
  21.    Returns the address of beginning of non whitespace */
  22. unsigned char *text_format_line(void)
  23. {
  24.     unsigned char *p, *p1;
  25.     int min;
  26.  
  27.     p = CLine->data;
  28.     Point = 0;
  29.  
  30.     while(((*p == '\t') || (*p == ' ')) && (Point < CLine->len)) p++, Point++;
  31.     min = Point;
  32.  
  33.     Point = CLine->len - 1;
  34.     if (Point < 0) Point = 0;
  35.     p = CLine->data + Point;
  36.  
  37.     while (Point > min)
  38.       {
  39.           if ((*p == ' ') || (*p == '\t'))
  40.             {
  41.            Point--; p--;
  42.            p1 = p - 1;
  43.            if (((*p == ' ') || (*p == '\t')) && (Point > min)
  44.            && (*p1 != '.') && (*p1 != '?') && (*p1 != '!'))
  45.          {
  46.             del();
  47.             if (*p == '\t') *p = ' ';
  48.          }
  49.         }
  50.           else
  51.             {
  52.                 Point--; p--;
  53.             }
  54.       }
  55.    return(CLine->data + min);
  56. }
  57.  
  58. int wrap_line1(int format)
  59. {
  60.    unsigned char *p, *pmin;
  61.    int col;
  62.  
  63.    if (format) pmin = text_format_line(); else pmin = CLine->data;
  64.    eol();
  65.    col = calculate_column();
  66.    if (col < User_Vars.wrap_column)
  67.      {
  68.     return(0);
  69.      }
  70.  
  71.    point_column(User_Vars.wrap_column - 1);
  72.    p = CLine->data + Point;
  73.  
  74.    while(p > pmin)
  75.      {
  76.     if ((*p == ' ') || (*p == '\t')) break;
  77.     p--;
  78.      }
  79.  
  80.    if (p == pmin)
  81.      {
  82.     /* that failed, so go the other way */
  83.     p = CLine->data + CLine->len;
  84.     while(pmin < p)
  85.       {
  86.          if ((*pmin == ' ') || (*pmin == '\t')) break;
  87.          pmin++;
  88.       }
  89.     if (p == pmin) return(0);
  90.     p = pmin;
  91.      }
  92.  
  93.    Point = (int) (p - CLine->data);
  94.    trim_whitespace();
  95.    newline();
  96.    CLine = CLine->prev;
  97.    return(1);
  98. }
  99.  
  100. void wrap_line(int format)
  101. {
  102.     push_spot();
  103.     wrap_line1(format);
  104.     pop_spot();
  105. }
  106.  
  107. /* Here a paragraph follows either an indentation, a '\\' char or two
  108.    '\n' chars.  or a '%' char since tex uses this */
  109.  
  110. static int paragraph_sep_hook;
  111.  
  112. int is_paragraph_sep(void)
  113. {
  114.    unsigned char *p;
  115.    int ret;
  116.    p = CLine->data;
  117.    
  118.    if (paragraph_sep_hook && 
  119.        (0 != (paragraph_sep_hook = lang_run_hooks("is_paragraph_separator", NULL))))
  120.      {
  121.     if (!lang_pop_integer(&ret)) ret = 1;
  122.     return ret;
  123.      }
  124.  
  125.    if ((*p == '\n') || (*p == '\\') || (*p == '%')) return(1);
  126.    return(0);
  127. }
  128.  
  129. int backward_paragraph(void)
  130. {
  131.    paragraph_sep_hook = 1;
  132.    while(1)
  133.      {
  134.     eol();
  135.     trim_whitespace();
  136.  
  137.     if (is_paragraph_sep()) return(1);
  138.     if (CLine->prev == NULL) break;
  139.     CLine = CLine->prev;
  140.      }
  141.    return(1);
  142. }
  143.  
  144. int forward_paragraph(void)
  145. {
  146.    paragraph_sep_hook = 1;
  147.    while(1)
  148.      {
  149.     eol();
  150.     trim_whitespace();
  151.     if (is_paragraph_sep()) return(1);
  152.     if (CLine->next == NULL) break;
  153.     CLine = CLine->next;
  154.      }
  155.    return(1);
  156. }
  157.  
  158. int text_format_paragraph()
  159. {
  160.    unsigned char *p;
  161.    int n, col;
  162.    Line *end, *beg, *next;
  163.  
  164.    if (CBuf->modes != WRAP_MODE) return(0);
  165.    push_spot();
  166.  
  167.    get_current_indent(&n);
  168.  
  169.    /* find paragraph start */
  170.    backward_paragraph();
  171.    if (is_paragraph_sep() && (CLine->next != NULL)) CLine = CLine->next;
  172.    beg = CLine;
  173.  
  174.    forward_paragraph();
  175.    if (CLine->next == NULL) end = NULL; else end = CLine;
  176.  
  177.    CLine = beg;
  178.    Point = 0;
  179.    /* Now loop formatting as we go until the end is reached */
  180.    while(CLine != end)
  181.      {
  182.     eol();
  183.     if (CLine != beg) indent_to(n);
  184.     if (wrap_line1(1))
  185.       {
  186.          CLine = CLine->next;
  187.          indent_to(n);
  188.          continue;
  189.       }
  190.     else if (CLine->next == end) break;
  191.  
  192.     next = CLine->next;
  193.     if (next != end)
  194.       {
  195.          /* Now count the length of the word on the next line. */
  196.          CLine = next;
  197.          Point = 0;
  198.          trim_whitespace();
  199.          p = CLine->data;
  200.          while((*p > ' ') && (p - CLine->data < CLine->len)) p++;
  201.  
  202.          CLine = CLine->prev;
  203.          eol();
  204.  
  205.          col = calculate_column();
  206.          if ((p - next->data) + col < User_Vars.wrap_column - 1)
  207.            {
  208.           del();
  209.           ins(' ');
  210.            }
  211.          else CLine = CLine->next;
  212.       }
  213.      }
  214.    pop_spot();
  215.    return(1);
  216. }
  217.  
  218. int narrow_paragraph(void)
  219. {
  220.    int wrap, n;
  221.    if (CBuf->modes != WRAP_MODE) return(0);
  222.    get_current_indent(&n);
  223.    wrap = User_Vars.wrap_column;
  224.    if (wrap - n <= wrap/2) return(0);
  225.    User_Vars.wrap_column -= n;
  226.    text_format_paragraph();
  227.    User_Vars.wrap_column = wrap;
  228.    return(1);
  229. }
  230.  
  231. int center_line(void)
  232. {
  233.    unsigned char *p, *pmax;
  234.    int len;
  235.  
  236.    push_spot();
  237.    (void) eol_cmd();
  238.    p = CLine->data;
  239.    pmax = p + CLine->len;
  240.  
  241.    while(p < pmax)
  242.      {
  243.     if (*p > ' ') break;
  244.     p++;
  245.      }
  246.    if ((len = (int)(pmax - p)) < 0) len = 0;
  247.    if ((len = (User_Vars.wrap_column - len) / 2) < 0) len = 0;
  248.    indent_to(len);
  249.    pop_spot();
  250.    return(1);
  251. }
  252.  
  253. int text_smart_quote(void)
  254. {
  255.    char c, last;
  256.    int upd;
  257.  
  258.    if (Point) c = (char ) *(CLine->data + (Point - 1)); else c = 0;
  259.    if (!(CBuf->modes & TEXT_MODE) || (c == '\\')) return ins_char_cmd();
  260.  
  261.    last = Last_Command_Char;
  262.    if ((c == '(') || (c == '[') || (c == '{') || (c <= ' ') || !Point)
  263.      Last_Command_Char = '`';
  264.    else
  265.      Last_Command_Char = '\'';
  266.  
  267.    upd = ins_char_cmd();
  268.    if (last == '"') upd = ins_char_cmd();
  269.    Last_Command_Char = last;
  270.    return(upd);
  271. }
  272.  
  273. #define upcase(ch) ((ch) &= 0xDF)
  274. #define downcase(ch) ((ch) |= 0x20)
  275.  
  276. static char Word[60];
  277.  
  278. void define_word(char *w)
  279. {
  280.    strcpy(Word, w);
  281. }
  282.  
  283.  
  284. int forward_word()
  285. {
  286.    if (eolp()) return nextline(&Number_One);
  287.    skip_whitespace();
  288.    if (!skip_chars1(Word, 0)) skip_chars1(Word, 1);
  289.    return(1);
  290. }
  291.  
  292. int backward_word()
  293. {
  294.    if (!Point) return prevline(&Number_One);
  295.    
  296.    if (!bskip_chars1(Word, 0)) bskip_chars1(Word, 1);
  297.    return(1);
  298. }
  299.  
  300. void transform_region(char *what)
  301. {
  302.    int pnt, cap, tmpm;
  303.    Line *line;
  304.    unsigned char *p, *pmax;
  305.  
  306.    if (!check_region(&Number_One)) return;    /* spot pushed */
  307.  
  308.    pnt = Point;
  309.    line = CLine;
  310.    tmpm = 1; pop_mark(&tmpm);
  311.    cap = 0;
  312.    while(1)
  313.      {
  314.     p = CLine->data + Point;
  315.     if (line != CLine) pmax = CLine->data + CLine->len;
  316.     else pmax = CLine->data + pnt;
  317.     while (p < pmax)
  318.       {
  319.          if (isalpha(*p))
  320.          switch(*what)
  321.            {
  322.           case 'u': if (*p > 'Z') upcase(*p); break;
  323.           case 'c': if (!cap)
  324.                       {
  325.                  cap = 1;
  326.                  if (*p > 'Z') upcase(*p);
  327.                  break;
  328.                   }
  329.  
  330.           case 'd': if (*p < 'a') downcase(*p); break;
  331.           default: if (*p < 'a') downcase(*p); else upcase(*p);
  332.            }
  333.          p++;
  334.       }
  335.     register_change(0);
  336.     if (line == CLine) break;
  337.     CLine = CLine->next;
  338.      }
  339.    pop_spot();
  340.    mark_buffer_modified(&Number_One);
  341. }
  342.  
  343. void mark_word(void)
  344. {
  345.    push_mark();
  346.    forward_word();
  347. }
  348.  
  349. static void do_xword(char ch)
  350. {
  351.    mark_word();
  352.    transform_region(&ch);
  353. }
  354.  
  355. int upcase_word(void)
  356. {
  357.    do_xword('u');
  358.    return(1);
  359. }
  360.  
  361. int downcase_word(void)
  362. {
  363.    do_xword('d');
  364.    return(1);
  365. }
  366.  
  367. int capitalize_word(void)
  368. {
  369.    do_xword('c');
  370.    return(1);
  371. }
  372.  
  373. int delete_word(void)
  374. {
  375.    mark_word();
  376.    delete_region();
  377.    return(1);
  378. }
  379.  
  380.