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.