GophHub - kevinboone/epub2txt2/src/main.c


Raw File

    1	/*============================================================================
    2	  epub2txt v2 
    3	  main.c
    4	  Copyright (c)2020-2024 Kevin Boone, GPL v3.0
    5	============================================================================*/
    6	
    7	#include <stdio.h>
    8	#include <stdlib.h>
    9	#include <unistd.h>
   10	#include <string.h>
   11	#include <errno.h>
   12	#include <sys/ioctl.h>
   13	#include <termios.h>
   14	#include <getopt.h>
   15	#include <signal.h>
   16	#include "epub2txt.h" 
   17	#include "defs.h" 
   18	#include "log.h" 
   19	
   20	/*============================================================================
   21	  sig_handler 
   22	============================================================================*/
   23	static void sig_handler (int signo)
   24	  {
   25	  (void)signo;
   26	  epub2txt_cleanup();
   27	  exit (0);
   28	  }
   29	
   30	/*============================================================================
   31	  main
   32	============================================================================*/
   33	int main (int argc, char **argv)
   34	  {
   35	  BOOL show_version = FALSE;
   36	  BOOL show_help = FALSE;
   37	  BOOL ascii = FALSE;
   38	  BOOL is_a_tty = FALSE;
   39	  BOOL noansi = FALSE;
   40	  BOOL raw = FALSE;
   41	  BOOL meta = FALSE;
   42	  BOOL notext = FALSE;
   43	  BOOL calibre = FALSE;
   44	  char *section_separator = NULL;
   45	  int width = 80;
   46	
   47	  static struct option long_options[] =
   48	    {
   49	     {"ascii", no_argument, NULL, 'a'},
   50	     {"calibre", no_argument, NULL, 'c'},
   51	     {"raw", no_argument, NULL, 'r'},
   52	     {"meta", no_argument, NULL, 'm'},
   53	     {"version", no_argument, NULL, 'v'},
   54	     {"noansi", no_argument, NULL, 'n'},
   55	     {"width", required_argument, NULL, 'w'},
   56	     {"log", required_argument, NULL, 'l'},
   57	     {"separator", required_argument, NULL, 's'},
   58	     {"help", no_argument, NULL, 'h'},
   59	     {"notext", no_argument, NULL, 0},
   60	     {0, 0, 0, 0}
   61	    };
   62	
   63	
   64	  log_set_level (WARNING);
   65	  
   66	  // If we have a TTY, try to get the console width in columns. This
   67	  //   may not work on all systems, so we need a fall-back.
   68	  if (isatty (STDOUT_FILENO))
   69	    {
   70	    struct winsize ws;
   71	    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
   72	      {
   73	      width = ws.ws_col;
   74	      }
   75	    is_a_tty = TRUE;
   76	    }
   77	
   78	  // If stdout is not a tty, try stdin. Why? Because if there _is_ a
   79	  //  terminal attached somehow, we want to use its column width,
   80	  //  if we use the "--wrap" option
   81	  if (!is_a_tty)
   82	    {
   83	    if (isatty (STDIN_FILENO))
   84	      {
   85	      struct winsize ws;
   86	      if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
   87	        {
   88	        width = ws.ws_col;
   89	        }
   90	      }
   91	    is_a_tty = TRUE;
   92	    }
   93	
   94	  int opt;
   95	  while (1)
   96	    {
   97	    int option_index = 0;
   98	    opt = getopt_long (argc, argv, "avw:l:nrmchs:",
   99	      long_options, &option_index);
  100	
  101	    if (opt == -1) break;
  102	
  103	    switch (opt)
  104	      {
  105	      case 0:
  106	        if (strcmp (long_options[option_index].name, "version") == 0)
  107	          show_version = TRUE;
  108	        else if (strcmp (long_options[option_index].name, "width") == 0)
  109	          width = atoi (optarg);
  110	        else if (strcmp (long_options[option_index].name, "log") == 0)
  111	          log_set_level (atoi (optarg));
  112	        else if (strcmp (long_options[option_index].name, "help") == 0)
  113	          show_help = TRUE; 
  114	        else if (strcmp (long_options[option_index].name, "raw") == 0)
  115	          raw = TRUE; 
  116	        else if (strcmp (long_options[option_index].name, "ascii") == 0)
  117	          ascii = TRUE; 
  118	        else if (strcmp (long_options[option_index].name, "calibre") == 0)
  119	          calibre = TRUE; 
  120	        else if (strcmp (long_options[option_index].name, "noansi") == 0)
  121	          noansi = TRUE; 
  122	        else if (strcmp (long_options[option_index].name, "meta") == 0)
  123	          meta = TRUE; 
  124	        else if (strcmp (long_options[option_index].name, "notext") == 0)
  125	          notext = TRUE; 
  126	        else if (strcmp 
  127		       (long_options[option_index].name, "separator") == 0)
  128	          section_separator = strdup (optarg); 
  129	        else
  130	          exit (-1);
  131	      case 'a':
  132	        ascii = TRUE; break;
  133	      case 'c':
  134	        calibre = TRUE; break;
  135	      case 'n':
  136	        noansi = TRUE; break;
  137	      case 'h':
  138	        show_help = TRUE; break;
  139	      case 'v':
  140	        show_version = TRUE; break;
  141	      case 'r':
  142	       raw = TRUE; break;
  143	      case 'l':
  144	        log_set_level (atoi(optarg)); break;
  145	      case 'm':
  146	        meta = TRUE; break;
  147	      case 'w':
  148	        width = atoi (optarg); break;
  149	      case 's':
  150	        section_separator = strdup (optarg); break;
  151	      }
  152	    }
  153	
  154	  if (show_version)
  155	    {
  156	    printf (APPNAME " version " VERSION "\n");
  157	    printf ("Copyright (c)2013-2024 Kevin Boone and contributors\n");
  158	    printf ("Distributed under the terms of the GNU Public Licence, v3.0\n");
  159	    exit (0);
  160	    }
  161	
  162	  if (show_help)
  163	    {
  164	    printf ("Usage: %s [options] {files...}\n", argv[0]);
  165	    printf ("  -a,--ascii          try to output ASCII only\n");
  166	    printf ("  -c,--calibre        show Calibre metadata (with -m)\n");
  167	    printf ("  -h,--help           show this message\n");
  168	    printf ("  -l,--log=N          set log level, 0-4\n");
  169	    printf ("  -m,--meta           dump document metadata\n");
  170	    printf ("  -n,--noansi         don't output ANSI terminal codes\n");
  171	    printf ("     --notext         don't output document body\n");
  172	    printf ("  -r,--raw            no formatting at all\n");
  173	    printf ("  -s,--separator=text section separator text\n");
  174	    printf ("  -v,--version        show version\n");
  175	    printf ("  -w,--width=N        set output width\n");
  176	    exit (0);
  177	    }
  178	
  179	  if (optind == argc)
  180	    {
  181	    fprintf (stderr, "%s: no files selected\n", argv[0]); 
  182	    fprintf (stderr, "'%s --help' for usage\n", argv[0]); 
  183	    exit (-1);
  184	    }
  185	
  186	  Epub2TxtOptions options;
  187	  memset (&options, 0, sizeof (options));
  188	  options.width = width;
  189	  options.ascii = ascii;
  190	  options.meta = meta;
  191	  options.notext = notext;
  192	  options.calibre = calibre;
  193	  options.section_separator = section_separator;
  194	
  195	  if (is_a_tty)
  196	    options.ansi = TRUE;
  197	  if (noansi)
  198	    options.ansi = FALSE; 
  199	 
  200	  options.raw = raw;
  201	
  202	  signal (SIGPIPE, sig_handler);
  203	  signal (SIGQUIT, sig_handler);
  204	  signal (SIGINT, sig_handler);
  205	  signal (SIGHUP, sig_handler);
  206	
  207	  int i;
  208	  for (i = optind; i < argc; i++)
  209	    {
  210	    const char *file = argv[i]; 
  211	    char *error = NULL;
  212	    epub2txt_do_file (file, &options, &error); 
  213	    if (error)
  214	      {
  215	      fprintf (stderr, "%s: %s\n", argv[0], error);
  216	      free (error);
  217	      }
  218	    }
  219	
  220	  if (section_separator) free (section_separator);
  221	  exit (0);
  222	  }
  223	
  224	

Generated by GNU Enscript 1.6.6, and GophHub 1.3.