URI: 
       gramscii.c - gramscii - A simple editor for ASCII box-and-arrow charts
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       gramscii.c (4678B)
       ---
            1 /*
            2 *
            3 * gramscii: a simple editor for ASCII box-and-arrow charts
            4 *
            5 * Copyright (c) 2019 Vincenzo "KatolaZ" Nicosia <katolaz@freaknet.org>
            6 *
            7 * This program is free software: you can redistribute it and/or modify
            8 * it under the terms of the GNU General Public License as published by
            9 * the Free Software Foundation, either version 3 of the License, or
           10 * (at your option) any later version.
           11 *
           12 * This program is distributed in the hope that it will be useful,
           13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
           14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           15 * GNU General Public License for more details.
           16 *
           17 * You should have received a copy of the GNU General Public License
           18 * along with this program. Please see the attached file COPYING. 
           19 * Otherwise, please visit <https://www.gnu.org/licenses/>.
           20 *
           21 */
           22 
           23 #define _POSIX_C_SOURCE 200112L
           24 
           25 #include <stdio.h>
           26 #include <stdlib.h>
           27 #include <signal.h>
           28 
           29 #include "arg.h"
           30 #include "gramscii.h"
           31 
           32 /** global variables **/
           33 
           34 lineset_t screen; /* what is visualised */
           35 lineset_t cutbuf; /* cut/paste buffer */
           36 lineset_t *undo;  /* undo list */
           37 
           38 pos_t marks[26]; /* position marks */
           39 char mark_map[26]; /* marks map */
           40 
           41 int undo_sz;/* allocated size of undo list*/
           42 int undo_cur;/* undo position */
           43 int undo_lst;/* last valid undo position */
           44 
           45 int WIDTH, HEIGHT;
           46 
           47 int mode;/* mode */
           48 int dir;/* line direction */
           49 int x;
           50 int y;
           51 int step;/* current step */
           52 int mult;/* current multiplier */
           53 int force_new;
           54 char corner;
           55 
           56 /* number of available markers for each type */
           57 int hlines_sz;
           58 int vlines_sz;
           59 int corners_sz;
           60 int stmarks_sz;
           61 int endmarks_sz;
           62 /**/
           63 
           64 /* line and arrow markers */
           65 int cur_hl, cur_vl, cur_corn, cur_start, cur_end;
           66 char line_h;
           67 char line_v;
           68 char mark_st;
           69 char mark_end;
           70 /**/
           71 
           72 char modified; /* set to 1 if screen modified since last save */
           73 char fname[256];
           74 
           75 
           76 char script; /* set to 1 in script-mode */
           77 char autoend; /* set to 1 in auto-arrow mode */
           78 
           79 /* Used by draw_arrow to identify the bounding box */
           80 int a_miny;
           81 int a_maxy;
           82 /**/
           83 
           84 struct termios t1, t2, t3;
           85 
           86 /** End of global variables **/
           87 
           88 char *argv0;
           89 
           90 
           91 void cleanup(int s){
           92         
           93         if (!script){
           94                 printf("\033[;H\033[2J");
           95                 tcsetattr(0, TCSANOW, &t1);
           96         }
           97         else
           98                 dump_lines(screen, stdout);
           99         fflush(stdout);
          100         exit(s);
          101 }
          102 
          103 /*** Initialisation ***/
          104 
          105 void init(){
          106 
          107         signal(SIGHUP, cleanup);
          108         signal(SIGINT, cleanup);
          109         signal(SIGTERM, cleanup);
          110         signal(SIGQUIT, cleanup);
          111 
          112         if (!script){
          113                 tcgetattr(0, &t1);
          114                 t2 = t1;
          115                 t2.c_lflag &= ~(ICANON | ECHO);
          116                 tcsetattr(0, TCSANOW, &t2);
          117         }
          118         init_screen();
          119         x = 0;
          120         y = 0;
          121         step = 1;
          122         modified = 0;
          123         fname[0] = '\0';
          124         redraw();
          125 }
          126 
          127 
          128 /*** Commands ***/
          129 
          130 void commands(FILE *fc){
          131 
          132         int c;
          133         while((c=fgetc(fc))!=EOF){
          134                 if (!change_style(c) && !move_around(c, fc, 1)){
          135 #ifdef DEBUG
          136                         fprintf(stderr, "got command: %c\n", c);
          137 #endif
          138                         switch(c){
          139                                 case 'i':
          140                                         mode = TEXT;
          141                                         get_text(fc);
          142                                         break;
          143                                 case 'R':
          144                                         redraw();
          145                                         break;
          146                                 case 'b':
          147                                         mode = BOX;
          148                                         get_box(fc, BOX_RECT);
          149                                         break;
          150                                 case 'A': autoend=1;
          151                                 case 'a':
          152                                         mode = ARROW;
          153                                         get_arrow(fc);
          154                                         autoend = 0;
          155                                         break;
          156                                 case 'W':
          157                                         force_new = 1;/** FALLTHROUGH **/
          158                                 case 'w':
          159                                         write_file(fc);
          160                                         break;
          161                                 case 'e':
          162                                         check_modified(fc);/** FALLTHROUGH **/
          163                                 case 'E':
          164                                         load_file(fc);
          165                                         break;
          166                                 case 'N':
          167                                         new_file(fc);
          168                                         break;
          169                                 case 'x':
          170                                         mode = DEL;
          171                                         erase(fc);
          172                                         break;
          173                                 case 'v':
          174                                         mode = VIS;
          175                                         visual_box(fc);
          176                                         break;
          177                                 case 'C':
          178                                         crop_to_nonblank();
          179                                         break;
          180                                 case 'p':
          181                                         paste();
          182                                         break;
          183                                 case 'u':
          184                                         undo_change();
          185                                         break;
          186                                 case 'U':
          187                                         redo_change();
          188                                         break;
          189                                 case 'r':
          190                                         read_file_at(fc, x, y);
          191                                         break;
          192                                 case 't':
          193                                         mode = TRP;
          194                                         get_box(fc, BOX_TRAP_UC);
          195                                         break;
          196                                 case 'z':
          197                                         mode = PAR;
          198                                         get_box(fc, BOX_PARR);
          199                                         break;
          200                                 case '#':
          201                                         mode = REM;
          202                                         get_comment(fc);
          203                                         break;
          204                                 case 'M':
          205                                         mark_pos(fc);
          206                                         break;
          207                                 case 'q':
          208                                         check_modified(fc);/** FALLTHROUGH **/
          209                                 case 'Q':
          210                                         cleanup(0);
          211                                         break;
          212                         }
          213                 }
          214                 check_bound(&x, &y);
          215                 status_bar();
          216                 show_cursor();
          217                 step = 1;
          218                 force_new = 0;
          219         }
          220 
          221 }
          222 
          223 void usage(){
          224         fprintf(stderr, "Usage: %s [-s] [-h] [file ...]\n", argv0);
          225         exit(1);
          226 }
          227 
          228 
          229 int main(int argc, char *argv[]){
          230         FILE *fc;
          231 
          232         ARGBEGIN {
          233                 case 's':
          234                         script = 1;
          235                         break;
          236                 case 'h': /* FALLTHROUGH */
          237                 default:
          238                         usage();
          239         } ARGEND;        
          240 
          241         init();
          242         while (argc){
          243                 fc = fopen(argv[0], "r");
          244                 if (fc == NULL){
          245                         fprintf(stderr, "Error opening file %s\n", argv[0]);
          246                 }
          247                 else {
          248                         commands(fc);
          249                         fflush(fc);
          250                         fclose(fc);
          251                         redraw();
          252                 }
          253                 argv++;
          254                 argc--;
          255         }
          256         commands(stdin);
          257         cleanup(0);
          258 }