1 /***************************************************************************
2 cmdlineoptions.cpp - description
3 -------------------
4 begin : Sun Nov 25 2001
5 copyright : (C) 2001-2021 by Andre Simon
6 email : a.simon@mailbox.org
7 ***************************************************************************/
8
9 /*
10 This file is part of Highlight.
11
12 Highlight is free software: you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
16
17 Highlight is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with Highlight. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "cmdlineoptions.h"
27 #include "platform_fs.h"
28 #include "datadir.h"
29 #include <sstream>
30 #include <cstdio>
31 #include <list>
32
33 #include "arg_parser.h"
34
35 using namespace std;
36
37 enum Optcode {
38 S_OPT_ENCLOSE_PRE = 256, S_OPT_FORCE_OUTPUT,
39 S_OPT_INLINE_CSS, S_OPT_KW_CASE,
40 S_OPT_PRINT_CONFIG, S_OPT_TEST_INPUT, S_OPT_NO_NUMBER_WL,
41 S_OPT_SVG_WIDTH, S_OPT_SVG_HEIGHT, S_OPT_CLASSNAME,
42 S_OPT_RTF_CHAR_STYLES, S_OPT_RTF_PAGE_COLOR,
43 S_OPT_SKIP_UNKNOWN,
44 S_OPT_COMPAT_DOC, S_OPT_COMPAT_NODOC, S_OPT_COMPAT_TAB, S_OPT_COMPAT_CSS,
45 S_OPT_COMPAT_OUTDIR, S_OPT_COMPAT_FAILSAFE,
46 S_OPT_COMPAT_SRCLANG, S_OPT_COMPAT_LINENUM, S_OPT_COMPAT_LINEREF,
47 S_OPT_PRETTY_SYMBOLS, S_OPT_EOL_DELIM_CR, S_OPT_START_NESTED,
48 S_OPT_PRINT_STYLE, S_OPT_NO_TRAILING_NL, S_OPT_PLUGIN, S_OPT_ABS_CFG_PATH,
49 S_OPT_PLUGIN_READFILE, S_OPT_PLUGIN_PARAMETER, S_OPT_LIST_SCRIPTS, S_OPT_CANVAS,
50 S_OPT_KEEP_INJECTIONS, S_OPT_FORCE_STDOUT, S_OPT_LATEX_BEAMER, S_OPT_NO_VERSION_INFO,
51 S_OPT_REFORMAT_OPT, S_OPT_RANGE_OPT, S_OPT_BASE16, S_OPT_CATEGORIES, S_OPT_PIPED_FNAME,
52 S_OPT_ISOLATE, S_OPT_MAX_FILE_SIZE, S_OPT_SYNTAX_SUPPORTED,
53 S_OPT_LS_PROFILE, S_OPT_LS_WORKSPACE, S_OPT_LS_EXEC, S_OPT_LS_OPTION, S_OPT_LS_HOVER,
54 S_OPT_LS_SEMANTIC, S_OPT_LS_RAINBOW, S_OPT_LS_SYNTAX, S_OPT_LS_SYNTAX_ERROR, S_OPT_LS_DELAY
55 };
56
57 const Arg_parser::Option options[] = {
58 { 'a', OPT_ANCHORS, Arg_parser::no },
59 { 'b', OPT_LATEX_BABEL, Arg_parser::no },
60 { 'B', OPT_BATCHREC, Arg_parser::yes },
61 { 'c', OPT_STYLE_OUT, Arg_parser::yes },
62 { 'C', OPT_INDEXFILE, Arg_parser::no },
63 { 'd', OPT_OUTDIR, Arg_parser::yes },
64 { 'D', OPT_DATADIR, Arg_parser::yes },
65 { 'e', OPT_STYLE_IN, Arg_parser::yes },
66 { 'f', OPT_FRAGMENT, Arg_parser::no },
67 { 'F', OPT_FORMAT, Arg_parser::yes },
68
69 { 'h', OPT_HELP, Arg_parser::maybe },
70 { 'i', OPT_IN, Arg_parser::yes },
71 { 'I', OPT_INC_STYLE, Arg_parser::no },
72 { 'j', OPT_LNR_LEN, Arg_parser::yes },
73 { 'J', OPT_LINE_LEN, Arg_parser::yes },
74 { 'k', OPT_BASE_FONT, Arg_parser::yes },
75 { 'K', OPT_BASE_FONT_SIZE, Arg_parser::yes },
76 { 'l', OPT_LINENO, Arg_parser::no },
77 { 'm', OPT_LNR_START, Arg_parser::yes },
78 { 'n', OPT_ORDERED_LIST, Arg_parser::no },
79 { 'N', OPT_ANCHOR_FN, Arg_parser::no },
80 { 'o', OPT_OUT, Arg_parser::yes },
81 { 'O', OPT_OUTFORMAT, Arg_parser::yes },
82 { 'P', OPT_PROGRESSBAR, Arg_parser::no },
83 { 'q', OPT_QUIET, Arg_parser::no },
84 { 'Q', OPT_VERSION, Arg_parser::no },
85 { 'r', OPT_REPLACE_QUOTES, Arg_parser::no },
86 { 's', OPT_STYLE, Arg_parser::yes },
87 { 'S', OPT_SYNTAX, Arg_parser::yes },
88 { 't', OPT_DELTABS, Arg_parser::yes },
89 { 'T', OPT_DOC_TITLE, Arg_parser::yes },
90 { 'u', OPT_ENCODING, Arg_parser::yes },
91 { 'v', OPT_VERBOSE, Arg_parser::no },
92 { 'V', OPT_WRAPSIMPLE, Arg_parser::no },
93 { 'W', OPT_WRAP, Arg_parser::no },
94 { 'x', OPT_RTF_PAGE_SIZE, Arg_parser::yes },
95 { 'y', OPT_ANCHOR_PFX, Arg_parser::yes },
96 { 'z', OPT_FILLZEROES, Arg_parser::no },
97
98 { S_OPT_CLASSNAME, OPT_CLASSNAME, Arg_parser::yes },
99 { S_OPT_SVG_WIDTH, OPT_SVG_WIDTH, Arg_parser::yes },
100 { S_OPT_SVG_HEIGHT, OPT_SVG_HEIGHT, Arg_parser::yes },
101 { S_OPT_ENCLOSE_PRE, OPT_ENCLOSE_PRE, Arg_parser::no },
102 { S_OPT_FORCE_OUTPUT, OPT_FORCE_OUTPUT, Arg_parser::maybe },
103 { S_OPT_INLINE_CSS, OPT_INLINE_CSS, Arg_parser::no },
104 { S_OPT_KW_CASE, OPT_KW_CASE, Arg_parser::yes },
105 { S_OPT_PRINT_CONFIG, OPT_PRINT_CONFIG, Arg_parser::no },
106 { S_OPT_TEST_INPUT, OPT_TEST_INPUT, Arg_parser::no },
107 { S_OPT_NO_NUMBER_WL, OPT_NO_NUMBER_WL, Arg_parser::no },
108 { S_OPT_RTF_CHAR_STYLES, OPT_RTF_CHAR_STYLES, Arg_parser::no },
109 { S_OPT_RTF_PAGE_COLOR, OPT_RTF_PAGE_COLOR, Arg_parser::no },
110 { S_OPT_SKIP_UNKNOWN, OPT_SKIP_UNKNOWN, Arg_parser::yes },
111 { S_OPT_START_NESTED, OPT_START_NESTED, Arg_parser::yes },
112 { S_OPT_COMPAT_DOC, OPT_COMPAT_DOC, Arg_parser::no },
113 { S_OPT_COMPAT_NODOC, OPT_COMPAT_NODOC, Arg_parser::no },
114 { S_OPT_COMPAT_TAB, OPT_COMPAT_TAB, Arg_parser::yes },
115 { S_OPT_COMPAT_CSS, OPT_COMPAT_CSS, Arg_parser::yes },
116 { S_OPT_COMPAT_OUTDIR, OPT_COMPAT_OUTDIR, Arg_parser::yes },
117 { S_OPT_COMPAT_FAILSAFE, OPT_COMPAT_FAILSAFE, Arg_parser::no },
118 { S_OPT_COMPAT_SRCLANG, OPT_COMPAT_SRCLANG, Arg_parser::yes },
119 { S_OPT_COMPAT_LINENUM, OPT_COMPAT_LINENUM, Arg_parser::maybe },
120 { S_OPT_COMPAT_LINEREF, OPT_COMPAT_LINEREF, Arg_parser::maybe },
121 { S_OPT_PRETTY_SYMBOLS, OPT_PRETTY_SYMBOLS, Arg_parser::no },
122 { S_OPT_EOL_DELIM_CR, OPT_EOL_DELIM_CR, Arg_parser::no },
123 { S_OPT_PRINT_STYLE, OPT_PRINT_STYLE, Arg_parser::no },
124 { S_OPT_BASE16, OPT_BASE16, Arg_parser::maybe },
125 { S_OPT_NO_TRAILING_NL, OPT_NO_TRAILING_NL, Arg_parser::maybe },
126 { S_OPT_KEEP_INJECTIONS, OPT_KEEP_INJECTIONS, Arg_parser::no },
127 { S_OPT_FORCE_STDOUT, OPT_FORCE_STDOUT, Arg_parser::no },
128 { S_OPT_LATEX_BEAMER, OPT_LATEX_BEAMER, Arg_parser::no },
129 { S_OPT_NO_VERSION_INFO, OPT_NO_VERSION_INFO, Arg_parser::no },
130
131 { S_OPT_PLUGIN, OPT_PLUGIN, Arg_parser::yes },
132 { S_OPT_PLUGIN_READFILE, OPT_PLUGIN_READFILE, Arg_parser::yes },
133 { S_OPT_PLUGIN_PARAMETER, OPT_PLUGIN_PARAMETER, Arg_parser::yes },
134 { S_OPT_ABS_CFG_PATH, OPT_ABS_CFG_PATH, Arg_parser::yes},
135 { S_OPT_LIST_SCRIPTS, OPT_LIST_SCRIPTS, Arg_parser::yes},
136 { S_OPT_CANVAS, OPT_CANVAS, Arg_parser::maybe },
137 { S_OPT_REFORMAT_OPT, OPT_REFORMAT_OPT, Arg_parser::yes },
138 { S_OPT_RANGE_OPT, OPT_RANGE_OPT, Arg_parser::yes },
139 { S_OPT_CATEGORIES, OPT_CATEGORIES, Arg_parser::yes },
140 { S_OPT_PIPED_FNAME, OPT_PIPED_FNAME, Arg_parser::yes },
141 { S_OPT_ISOLATE, OPT_ISOLATE_TAGS, Arg_parser::no },
142 { S_OPT_MAX_FILE_SIZE, OPT_MAX_FILE_SIZE, Arg_parser::yes },
143 { S_OPT_SYNTAX_SUPPORTED, OPT_SYNTAX_SUPPORTED, Arg_parser::no },
144
145 { S_OPT_LS_PROFILE, OPT_LS_PROFILE, Arg_parser::yes },
146 { S_OPT_LS_WORKSPACE, OPT_LS_WORKSPACE, Arg_parser::yes },
147 { S_OPT_LS_EXEC, OPT_LS_EXEC, Arg_parser::yes },
148 { S_OPT_LS_OPTION, OPT_LS_OPTION, Arg_parser::yes },
149 { S_OPT_LS_HOVER, OPT_LS_HOVER, Arg_parser::no },
150 { S_OPT_LS_SEMANTIC, OPT_LS_SEMANTIC, Arg_parser::no },
151 { S_OPT_LS_RAINBOW, OPT_LS_RAINBOW, Arg_parser::no },
152 { S_OPT_LS_SYNTAX_ERROR, OPT_LS_SYNTAX_ERROR, Arg_parser::no },
153
154 { S_OPT_LS_SYNTAX, OPT_LS_SYNTAX, Arg_parser::yes },
155 { S_OPT_LS_DELAY, OPT_LS_DELAY, Arg_parser::yes },
156
157 { 0, 0, Arg_parser::no }
158 };
159
160
161
CmdLineOptions(const int argc,const char * argv[])162 CmdLineOptions::CmdLineOptions ( const int argc, const char *argv[] ) :
163 numberSpaces ( 0 ),
164 lineNrWidth ( 5 ),
165 lineLength ( 80 ),
166 lineNrStart ( 1 ),
167 lineRangeStart( 0 ),
168 lineRangeEnd( 0 ),
169 opt_no_trailing_nl(0),
170 verbosity(0),
171 lsDelay(0),
172 canvasPaddingWidth(0),
173 wrappingStyle ( highlight::WRAP_DISABLED ),
174 outputType ( highlight::HTML ),
175 keywordCase ( StringTools::CASE_UNCHANGED ),
176 baseFontSize("10"),
177 className ( "hl" ),
178 opt_syntax ( false ),
179 opt_include_style ( false ),
180 opt_help ( false ),
181 opt_version ( false ),
182 opt_print_config ( false ),
183 opt_linenumbers ( false ),
184 opt_batch_mode ( false ),
185 opt_fragment ( false ) ,
186 opt_attach_line_anchors ( false ),
187 opt_printindex ( false ),
188 opt_quiet ( false ),
189 opt_replacequotes ( false ),
190 opt_babel ( false ),
191 opt_beamer ( false ),
192 opt_print_progress ( false ),
193 opt_fill_zeroes ( false ),
194 opt_stylepath_explicit ( false ),
195 opt_force_output ( false ),
196 opt_ordered_list ( false ),
197 opt_fnames_as_anchors ( false ),
198 opt_validate ( false ),
199 opt_number_wrapped_lines ( true ),
200 opt_inline_css ( false ),
201 opt_enclose_pre ( false ),
202 opt_char_styles ( false ),
203 opt_page_color(false),
204 opt_pretty_symbols ( false ),
205 opt_delim_CR (false),
206 opt_print_style(false),
207 opt_base16_theme(false),
208 opt_keep_injections(false),
209 opt_force_stdout(false),
210 opt_no_version_info(false),
211 explicit_output_format(false),
212 opt_isolate(false),
213 opt_encoding_explicit(false),
214 opt_syntax_supported_check(false),
215 opt_ls_hover(false),
216 opt_ls_semantic(false),
217 opt_ls_rainbow(false),
218 opt_ls_syntax_error(false),
219 maxFileSize(268435456),
220 fallbackSyntax("txt"),
221 anchorPrefix ( "l" ),
222 helpLang ( "en" ),
223 encodingName ( "ISO-8859-1" )
224 {
225
226 char* hlEnvOptions=getenv("HIGHLIGHT_OPTIONS");
227 if (hlEnvOptions!=NULL) {
228 std::ostringstream envos;
229 envos<<argv[0]<<" "<<hlEnvOptions;
230 std::istringstream ss( envos.str());
231 std::string arg;
232 std::list<std::string> ls;
233 std::vector<char*> options;
234 while (ss >> arg)
235 {
236 ls.push_back(arg);
237 options.push_back(const_cast<char*>(ls.back().c_str()));
238 }
239 options.push_back(0);
240 parseRuntimeOptions(options.size()-1, (const char**) &options[0], false);
241 }
242
243 parseRuntimeOptions(argc, argv);
244
245 if ( skipArg.size() && inputFileNames.size() > 1) {
246 istringstream valueStream;
247 string elem;
248 valueStream.str ( StringTools::change_case ( skipArg,StringTools::CASE_LOWER ) );
249
250 while ( getline ( valueStream, elem, ';' ) ) {
251 ignoredFileTypes.insert ( elem );
252 }
253
254 vector<string>::iterator file=inputFileNames.begin();
255 while ( file!=inputFileNames.end()) {
256 for ( set<string>::iterator ext=ignoredFileTypes.begin(); ext!=ignoredFileTypes.end(); ext++ ) {
257 if (file!=inputFileNames.end() && StringTools::endsWith( *file, *ext )) {
258 file = inputFileNames.erase ( file );
259 break;
260 }
261 }
262 if (file!=inputFileNames.end())
263 file++;
264 }
265 }
266
267 // no batch mode + no explicit format given
268 if (inputFileNames.size()==1 && !explicit_output_format) {
269 int colorOptions = Platform::isColorEscCapable();
270 if (colorOptions) {
271 outputType = colorOptions==2 ? highlight::ESC_TRUECOLOR : highlight::ESC_XTERM256;
272 }
273 }
274 }
275
~CmdLineOptions()276 CmdLineOptions::~CmdLineOptions() {}
277
parseRuntimeOptions(const int argc,const char * argv[],bool readInputFilenames)278 void CmdLineOptions::parseRuntimeOptions( const int argc, const char *argv[], bool readInputFilenames) {
279
280
281 Arg_parser parser ( argc, argv, options );
282 if ( parser.error().size() ) { // bad option
283 cerr << "highlight: "<< parser.error() <<"\n";
284 cerr << "Try 'highlight --help' for more information.\n";
285 exit ( EXIT_FAILURE );
286 }
287
288 int argind = 0;
289 for ( ; argind < parser.arguments(); ++argind ) {
290 const int code = parser.code ( argind );
291 const std::string & arg = parser.argument ( argind );
292 if ( !code ) break; // no more options
293 switch ( code ) {
294 case 'O': {
295 explicit_output_format=true;
296 const string tmp = StringTools::change_case ( arg );
297 if ( tmp == "xhtml" )
298 outputType = highlight::XHTML;
299 else if ( tmp == "tex" )
300 outputType = highlight::TEX;
301 else if ( tmp == "latex" )
302 outputType = highlight::LATEX;
303 else if ( tmp == "rtf" )
304 outputType = highlight::RTF;
305 else if ( tmp == "ansi" || tmp == "esc" ) // gnu source-highlight esc parameter
306 outputType = highlight::ESC_ANSI;
307 else if ( tmp == "xterm256" )
308 outputType = highlight::ESC_XTERM256;
309 else if ( tmp == "truecolor" )
310 outputType = highlight::ESC_TRUECOLOR;
311 else if ( tmp == "svg" )
312 outputType = highlight::SVG;
313 else if ( tmp == "bbcode" )
314 outputType = highlight::BBCODE;
315 else if ( tmp == "pango" )
316 outputType = highlight::PANGO;
317 else if ( tmp == "odt" )
318 outputType = highlight::ODTFLAT;
319 else
320 outputType = highlight::HTML;
321 }
322 break;
323 case 'a':
324 opt_attach_line_anchors = true;
325 break;
326 case 'b':
327 opt_babel=true;
328 break;
329 case 'B':
330 explicit_output_format=true;
331 opt_batch_mode = true;
332 readDirectory ( arg );
333 break;
334
335 case S_OPT_COMPAT_CSS:
336 showDeprecationHint(OPT_COMPAT_CSS, "style-outfile");
337 case 'c':
338 styleOutFilename = arg;
339 opt_stylepath_explicit=true;
340 break;
341 case 'C':
342 opt_printindex=true;
343 break;
344 case 'T':
345 docTitle = arg;
346 break;
347 case 'D':
348 dataDir=validateDirPath ( arg );
349 break;
350 case 'e':
351 styleInFilename = arg;
352 break;
353 case S_OPT_COMPAT_NODOC:
354 showDeprecationHint(OPT_COMPAT_NODOC, "fragment");
355 case 'f':
356 opt_fragment = true;
357 break;
358 case 'F':
359 indentScheme = arg;
360 break;
361 case S_OPT_CLASSNAME:
362 className = arg;
363 break;
364 case 'h':
365 opt_help = true;
366 helpTopic = arg;
367 break;
368 case 'i':
369 inputFileNames.push_back ( arg );
370 break;
371 case 'I':
372 opt_include_style = true;
373 break;
374 case 'j':
375 StringTools::str2num<int> ( lineNrWidth, arg, std::dec );
376 break;
377 case 'J':
378 StringTools::str2num<int> ( lineLength, arg, std::dec );
379 break;
380 case 'k':
381 baseFont = arg;
382 break;
383 case 'K':
384 baseFontSize = arg;
385 break;
386 case S_OPT_COMPAT_LINENUM:
387 if ( arg=="0" ) opt_fill_zeroes=true;
388 /* Falls through */
389 showDeprecationHint(OPT_COMPAT_LINENUM, "line-numbers, zeroes");
390
391 case 'l':
392 opt_linenumbers = true;
393 break;
394 case 'm':
395 StringTools::str2num<int> ( lineNrStart, arg, std::dec );
396 break;
397 case 'M':
398 explicit_output_format=true;
399 outputType=highlight::ESC_XTERM256;
400 break;
401 case 'n':
402 opt_ordered_list = opt_linenumbers = true;
403 break;
404 case 'N':
405 opt_fnames_as_anchors=true;
406 break;
407 case 'o':
408 explicit_output_format=true;
409 outFilename = arg;
410 break;
411 case S_OPT_COMPAT_OUTDIR:
412 showDeprecationHint(OPT_COMPAT_OUTDIR, "outdir");
413 case 'd':
414 explicit_output_format=true;
415 outDirectory = validateDirPath ( arg );
416 break;
417 case 'P':
418 opt_print_progress=true;
419 break;
420 case 'q':
421 opt_quiet = true;
422 break;
423 case 'Q':
424 opt_version = true;
425 break;
426 case 'r':
427 opt_replacequotes=true;
428 break;
429 case 's':
430 styleName = arg;
431 if (Platform::fileExists(styleName)){
432 absThemePath = styleName;
433 }
434 break;
435 case S_OPT_COMPAT_SRCLANG:
436 showDeprecationHint(OPT_COMPAT_SRCLANG, "syntax");
437
438 case 'S':
439 syntax = arg;
440 opt_syntax = true;
441
442 if (Platform::fileExists(arg) && string::npos!=arg.find_last_of('.')){
443 absLangPath = arg;
444 syntax = arg.substr(0, arg.find_last_of('.'));
445 }
446 break;
447 case S_OPT_COMPAT_TAB:
448 showDeprecationHint(OPT_COMPAT_TAB, "replace-tabs");
449
450 case 't':
451 StringTools::str2num<int> ( numberSpaces, arg, std::dec );
452 break;
453 case 'u':
454 encodingName = arg;
455 opt_encoding_explicit=true;
456 break;
457 case 'v':
458 ++verbosity;
459 break;
460 case 'V':
461 wrappingStyle = highlight::WRAP_SIMPLE;
462 break;
463 case 'W':
464 wrappingStyle = highlight::WRAP_DEFAULT;
465 break;
466 case 'x':
467 pageSize = arg;
468 break;
469 case 'y':
470 anchorPrefix = arg;
471 break;
472 case 'z':
473 opt_fill_zeroes=true;
474 break;
475 case S_OPT_SVG_WIDTH:
476 svg_width = arg;
477 break;
478 case S_OPT_SVG_HEIGHT:
479 svg_height = arg;
480 break;
481 case S_OPT_ENCLOSE_PRE:
482 opt_enclose_pre=true;
483 break;
484 case S_OPT_COMPAT_FAILSAFE:
485 showDeprecationHint(OPT_COMPAT_FAILSAFE, OPT_FORCE_OUTPUT);
486
487 case S_OPT_FORCE_OUTPUT:
488 opt_force_output = true;
489 if ( !arg.empty() ) {
490 fallbackSyntax=arg;
491 }
492 break;
493 case S_OPT_INLINE_CSS:
494 opt_inline_css=true;
495 break;
496 case S_OPT_KW_CASE: {
497 const string tmp = StringTools::change_case ( arg );
498 if ( tmp == "upper" )
499 keywordCase = StringTools::CASE_UPPER;
500 else if ( tmp == "lower" )
501 keywordCase = StringTools::CASE_LOWER;
502 else if ( tmp == "capitalize" )
503 keywordCase = StringTools::CASE_CAPITALIZE;
504 else
505 cerr << "highlight: unknown argument " << arg << endl;
506 }
507 break;
508 case S_OPT_PRINT_CONFIG:
509 opt_print_config = true;
510 break;
511 case S_OPT_TEST_INPUT:
512 opt_validate=true;
513 break;
514 case S_OPT_NO_NUMBER_WL:
515 opt_number_wrapped_lines=false;
516 break;
517 case S_OPT_RTF_CHAR_STYLES:
518 opt_char_styles=true;
519 break;
520 case S_OPT_RTF_PAGE_COLOR:
521 opt_page_color=true;
522 break;
523 case S_OPT_SKIP_UNKNOWN:
524 skipArg=arg;
525 break;
526 case S_OPT_PLUGIN:
527 userPlugins.push_back(arg);
528 break;
529 case S_OPT_REFORMAT_OPT:
530 astyleOptions.push_back(arg);
531 break;
532 case S_OPT_LS_OPTION:
533 lsOptions.push_back(arg);
534 break;
535 case S_OPT_PLUGIN_READFILE:
536 showDeprecationHint(OPT_PLUGIN_READFILE, OPT_PLUGIN_PARAMETER);
537
538 case S_OPT_PLUGIN_PARAMETER:
539 pluginParameter=arg;
540 break;
541
542 case S_OPT_PRETTY_SYMBOLS:
543 opt_pretty_symbols = true;
544 break;
545 case S_OPT_LATEX_BEAMER:
546 opt_beamer = true;
547 break;
548 case S_OPT_NO_VERSION_INFO:
549 opt_no_version_info = true;
550 break;
551 case S_OPT_COMPAT_DOC:
552 showDeprecationHint(OPT_COMPAT_DOC, "NONE");
553
554 opt_fragment = false;
555 break;
556 case S_OPT_COMPAT_LINEREF:
557 showDeprecationHint(OPT_COMPAT_LINEREF, "line-numbers, anchors, anchor-prefix");
558
559 opt_linenumbers = true;
560 opt_attach_line_anchors = true;
561 anchorPrefix = ( arg.empty() ) ? "line" : arg;
562 break;
563 case S_OPT_EOL_DELIM_CR:
564 showDeprecationHint(OPT_EOL_DELIM_CR, "NONE");
565
566 opt_delim_CR = true;
567 break;
568 case S_OPT_START_NESTED:
569 showDeprecationHint(OPT_START_NESTED, "NONE");
570
571 startNestedLang=arg;
572 break;
573 case S_OPT_PRINT_STYLE:
574 opt_print_style = true;
575 break;
576 case S_OPT_BASE16:
577 showDeprecationHint(OPT_BASE16, "theme with base16/ prefix");
578
579 opt_base16_theme = true;
580 if (!arg.empty())
581 styleName = arg;
582 break;
583 case S_OPT_NO_TRAILING_NL:
584 opt_no_trailing_nl = 1;
585 if (arg.size()) {
586 if (arg=="empty-file")
587 opt_no_trailing_nl = 2;
588 else
589 cerr << "highlight: unknown argument " << arg << endl;
590 }
591
592 break;
593 case S_OPT_KEEP_INJECTIONS:
594 opt_keep_injections = true;
595 break;
596 case S_OPT_FORCE_STDOUT:
597 opt_force_stdout = true;
598 break;
599 case S_OPT_ABS_CFG_PATH:
600 if (arg.find(".lang")!=string::npos) {
601 absLangPath=arg;
602 syntax = arg.substr(0, arg.find_last_of('.'));
603 opt_syntax = true;
604 } else if (arg.find(".theme")!=string::npos) absThemePath=arg;
605 else cerr << "highlight: unknown config file type" << endl;
606 break;
607
608 case S_OPT_RANGE_OPT: {
609 size_t delimPos=arg.find("-");
610 if (delimPos!=string::npos) {
611 StringTools::str2num<int> ( lineRangeStart, arg.substr(0, delimPos), std::dec );
612 StringTools::str2num<int> ( lineRangeEnd, arg.substr(delimPos+1), std::dec );
613 lineRangeEnd = lineRangeEnd - lineRangeStart + 1;
614 if (lineRangeEnd<=0 || lineRangeStart <=0) {
615 lineRangeStart = lineRangeEnd = 0;
616 }
617 }
618 break;
619 }
620 case S_OPT_LIST_SCRIPTS:
621 listScriptType=arg;
622 break;
623 case S_OPT_CANVAS:
624 canvasPaddingWidth=80;
625 numberSpaces=4; // get around problem with maskWs and tab output
626 if ( !arg.empty() )
627 StringTools::str2num<unsigned int> ( canvasPaddingWidth, arg, std::dec );
628 break;
629
630 case S_OPT_CATEGORIES:
631 listScriptCategory=arg;
632 if (listScriptType.empty()) listScriptType = "langs";
633 break;
634 case S_OPT_PIPED_FNAME:
635 redirectedFilename=arg;
636 opt_syntax=true;
637 break;
638 case S_OPT_ISOLATE:
639 opt_isolate=true;
640 break;
641 case S_OPT_MAX_FILE_SIZE: {
642 StringTools::str2num<off_t> ( maxFileSize, arg, std::dec );
643 switch (arg[arg.size()-1]) {
644 case 'G': maxFileSize *= 1024;
645 case 'M': maxFileSize *= 1024;
646 case 'K': maxFileSize *= 1024;
647 }
648 break;
649 }
650 case S_OPT_SYNTAX_SUPPORTED:
651 opt_syntax_supported_check = true;
652 break;
653
654 case S_OPT_LS_PROFILE:
655 lsProfile = arg;
656 break;
657 case S_OPT_LS_WORKSPACE:
658 lsWorkspace = arg;
659 break;
660 case S_OPT_LS_EXEC:
661 lsExecutable = arg;
662 break;
663 case S_OPT_LS_HOVER:
664 opt_ls_hover = true;
665 break;
666 case S_OPT_LS_SEMANTIC:
667 opt_ls_semantic = true;
668 break;
669 case S_OPT_LS_RAINBOW:
670 opt_ls_rainbow = true;
671 break;
672 case S_OPT_LS_SYNTAX:
673 lsSyntax = arg;
674 break;
675 case S_OPT_LS_SYNTAX_ERROR:
676 opt_ls_syntax_error = true;
677 break;
678 case S_OPT_LS_DELAY:
679 StringTools::str2num<int> ( lsDelay, arg, std::dec );
680 break;
681 default:
682 cerr << "highlight: option parsing failed" << endl;
683 }
684 }
685
686 if (readInputFilenames) {
687 if ( argind < parser.arguments() ) { //still args left
688 if ( inputFileNames.empty() ) {
689 string fName;
690 while ( argind < parser.arguments() ) {
691 fName=parser.argument ( argind++ );
692 if (fName=="-") fName = ""; // handle single "-" as empty arg to trigger reading from stdin
693 inputFileNames.push_back ( fName );
694 }
695 }
696 } else if ( inputFileNames.empty() ) {
697 inputFileNames.push_back ( "" );
698 }
699 }
700 }
701
getSingleOutFilename()702 const string &CmdLineOptions::getSingleOutFilename()
703 {
704 if ( !inputFileNames.empty() && !outDirectory.empty() ) {
705 if ( outFilename.empty() ) {
706 outFilename = outDirectory;
707 int delim = getSingleInFilename().find_last_of ( Platform::pathSeparator ) +1;
708 outFilename += getSingleInFilename().substr ( ( delim>-1 ) ?delim:0 )
709 + getOutFileSuffix();
710 }
711 }
712 return outFilename;
713 }
714
getSingleInFilename() const715 const string &CmdLineOptions::getSingleInFilename() const
716 {
717 return inputFileNames[0];
718 }
719
getOutDirectory()720 const string &CmdLineOptions::getOutDirectory()
721 {
722 if ( !outFilename.empty() && !enableBatchMode() ) {
723 outDirectory=getDirName ( outFilename );
724 }
725 return outDirectory;
726 }
727
getStyleOutFilename() const728 const string CmdLineOptions::getStyleOutFilename() const
729 {
730 if ( !styleOutFilename.empty() ) return styleOutFilename;
731
732 if ( outputType==highlight::TEX || outputType==highlight::LATEX ) {
733 return "highlight.sty";
734 } else {
735 return "highlight.css";
736 }
737 }
getStyleInFilename() const738 const string &CmdLineOptions::getStyleInFilename() const
739 {
740 return styleInFilename;
741 }
getSVGWidth() const742 const string& CmdLineOptions::getSVGWidth() const
743 {
744 return svg_width;
745 }
getSVGHeight() const746 const string& CmdLineOptions::getSVGHeight() const
747 {
748 return svg_height;
749 }
getNumberSpaces() const750 int CmdLineOptions::getNumberSpaces() const
751 {
752 return numberSpaces;
753 }
printVersion() const754 bool CmdLineOptions::printVersion() const
755 {
756 return opt_version;
757 }
printHelp() const758 bool CmdLineOptions::printHelp() const
759 {
760 return opt_help;
761 }
verbosityLevel() const762 int CmdLineOptions::verbosityLevel() const
763 {
764 return verbosity;
765 }
printConfigInfo() const766 bool CmdLineOptions::printConfigInfo() const
767 {
768 return opt_print_config;
769 }
quietMode() const770 bool CmdLineOptions::quietMode() const
771 {
772 return opt_quiet;
773 }
includeStyleDef() const774 bool CmdLineOptions::includeStyleDef() const
775 {
776 return opt_include_style;
777 }
useFNamesAsAnchors() const778 bool CmdLineOptions::useFNamesAsAnchors() const
779 {
780 return opt_fnames_as_anchors;
781 }
782
formatSupportsExtStyle()783 bool CmdLineOptions::formatSupportsExtStyle()
784 {
785 return outputType==highlight::HTML ||
786 outputType==highlight::XHTML ||
787 outputType==highlight::LATEX ||
788 outputType==highlight::TEX ||
789 outputType==highlight::SVG;
790 }
791
printLineNumbers() const792 bool CmdLineOptions::printLineNumbers() const
793 {
794 return opt_linenumbers;
795 }
796
getThemeName() const797 string CmdLineOptions::getThemeName() const
798 {
799 if (!styleName.empty())
800 return styleName+".theme";
801
802 bool isEscOutput = outputType==highlight::ESC_XTERM256 || outputType==highlight::ESC_TRUECOLOR;
803 bool isDarkTerminal = Platform::isDarkTerminal();
804 if (opt_base16_theme)
805 return isEscOutput && isDarkTerminal ? "harmonic-dark.theme" : "harmonic-light.theme";
806
807 return isEscOutput && isDarkTerminal ? "edit-vim-dark.theme" : "edit-kwrite.theme";
808 }
809
enableBatchMode() const810 bool CmdLineOptions::enableBatchMode() const
811 {
812 return inputFileNames.size() >1 || opt_batch_mode;
813 }
814
fragmentOutput() const815 bool CmdLineOptions::fragmentOutput() const
816 {
817 return opt_fragment;
818 }
819
omitVersionInfo() const820 bool CmdLineOptions::omitVersionInfo() const {
821 return opt_no_version_info;
822 }
823
isolateTags() const824 bool CmdLineOptions::isolateTags() const
825 {
826 return opt_isolate;
827 }
828
isSkippedExt(const string & ext) const829 bool CmdLineOptions::isSkippedExt ( const string& ext ) const
830 {
831 return ignoredFileTypes.count ( ext );
832 }
833
checkSyntaxSupport() const834 bool CmdLineOptions::checkSyntaxSupport() const
835 {
836 return opt_syntax_supported_check;
837 }
838
839
getOutFileSuffix() const840 string CmdLineOptions::getOutFileSuffix() const
841 {
842 switch ( outputType ) {
843 case highlight::XHTML:
844 return ".xhtml";
845 case highlight::RTF:
846 return ".rtf";
847 case highlight::TEX:
848 case highlight::LATEX:
849 return ".tex";
850 case highlight::SVG:
851 return ".svg";
852 case highlight::ESC_ANSI:
853 return ".ansi";
854 case highlight::ESC_XTERM256:
855 case highlight::ESC_TRUECOLOR:
856 return ".xterm";
857 case highlight::BBCODE:
858 return ".bbcode";
859 case highlight::ODTFLAT:
860 return ".fodt";
861 default:
862 return ".html";
863 }
864 }
getDirName(const string & path)865 string CmdLineOptions::getDirName ( const string & path )
866 {
867 size_t dirNameLength=path.rfind ( Platform::pathSeparator );
868 return ( dirNameLength==string::npos ) ?string() :path.substr ( 0, dirNameLength+1 );
869 }
attachLineAnchors() const870 bool CmdLineOptions::attachLineAnchors() const
871 {
872 return opt_attach_line_anchors;
873 }
outDirGiven() const874 bool CmdLineOptions::outDirGiven() const
875 {
876 return !outFilename.empty();
877 }
replaceQuotes() const878 bool CmdLineOptions::replaceQuotes() const
879 {
880 return opt_replacequotes;
881 }
disableBabelShorthands() const882 bool CmdLineOptions::disableBabelShorthands() const
883 {
884 return opt_babel;
885 }
enableBeamerMode() const886 bool CmdLineOptions::enableBeamerMode() const
887 {
888 return opt_beamer;
889 }
prettySymbols() const890 bool CmdLineOptions::prettySymbols() const
891 {
892 return opt_pretty_symbols;
893 }
orderedList() const894 bool CmdLineOptions::orderedList() const
895 {
896 return opt_ordered_list;
897 }
useCRDelimiter() const898 bool CmdLineOptions::useCRDelimiter() const
899 {
900 return opt_delim_CR;
901 }
902
isLsRainbow() const903 bool CmdLineOptions::isLsRainbow () const
904 {
905 return opt_ls_rainbow;
906 }
isLsHover() const907 bool CmdLineOptions::isLsHover () const
908 {
909 return opt_ls_hover;
910 }
isLsSemantic() const911 bool CmdLineOptions::isLsSemantic() const
912 {
913 return opt_ls_semantic;
914 }
isLsSyntaxError() const915 bool CmdLineOptions::isLsSyntaxError() const
916 {
917 return opt_ls_syntax_error;
918 }
getDataDir() const919 const string &CmdLineOptions::getDataDir() const
920 {
921 return dataDir;
922 }
getPluginPaths() const923 const vector<string> &CmdLineOptions::getPluginPaths() const
924 {
925 return userPlugins;
926 }
getAStyleOptions() const927 const vector<string> &CmdLineOptions::getAStyleOptions() const
928 {
929 return astyleOptions;
930 }
getLSOptions() const931 const vector<string> &CmdLineOptions::getLSOptions() const
932 {
933 return lsOptions;
934 }
printOnlyStyle() const935 bool CmdLineOptions::printOnlyStyle() const
936 {
937 return opt_print_style;
938 }
useBase16Theme() const939 bool CmdLineOptions::useBase16Theme() const
940 {
941 return opt_base16_theme;
942 }
getMaxFileSize() const943 off_t CmdLineOptions::getMaxFileSize() const
944 {
945 return maxFileSize;
946 }
947
getIndentScheme() const948 string CmdLineOptions::getIndentScheme() const
949 {
950 return StringTools::change_case ( indentScheme );
951 }
952
getSyntax() const953 const string &CmdLineOptions::getSyntax() const
954 {
955 return syntax;
956 }
getEncoding() const957 const string&CmdLineOptions::getEncoding() const
958 {
959 return encodingName;
960 }
961
getAnchorPrefix() const962 const string& CmdLineOptions::getAnchorPrefix() const
963 {
964 return anchorPrefix;
965 }
966
getPageSize() const967 const string &CmdLineOptions::getPageSize() const
968 {
969 return pageSize;
970 }
971
getLsExecutable() const972 const std::string& CmdLineOptions::getLsExecutable() const
973 {
974 return lsExecutable;
975 }
976
getLsWorkspace() const977 const std::string& CmdLineOptions::getLsWorkspace() const
978 {
979 return lsWorkspace;
980 }
981
getLsProfile() const982 const std::string& CmdLineOptions::getLsProfile() const
983 {
984 return lsProfile;
985 }
getLsSyntax() const986 const std::string& CmdLineOptions::getLsSyntax() const
987 {
988 return lsSyntax;
989 }
getLsDelay() const990 const int CmdLineOptions::getLsDelay() const
991 {
992 return lsDelay;
993 }
994
printIndexFile() const995 bool CmdLineOptions::printIndexFile() const
996 {
997 return opt_printindex && ( outputType==highlight::HTML ||
998 outputType==highlight::XHTML );
999 }
printProgress() const1000 bool CmdLineOptions::printProgress() const
1001 {
1002 return opt_print_progress;
1003 }
fillLineNrZeroes() const1004 bool CmdLineOptions::fillLineNrZeroes() const
1005 {
1006 return opt_fill_zeroes;
1007 }
syntaxGiven() const1008 bool CmdLineOptions::syntaxGiven() const
1009 {
1010 return opt_syntax;
1011 }
omitEncoding() const1012 bool CmdLineOptions::omitEncoding() const
1013 {
1014 return StringTools::change_case ( encodingName ) =="none";
1015 }
forceOutput() const1016 bool CmdLineOptions::forceOutput() const
1017 {
1018 return opt_force_output;
1019 }
validateInput() const1020 bool CmdLineOptions::validateInput() const
1021 {
1022 return opt_validate;
1023 }
numberWrappedLines() const1024 bool CmdLineOptions::numberWrappedLines() const
1025 {
1026 return opt_number_wrapped_lines;
1027 }
inlineCSS() const1028 bool CmdLineOptions::inlineCSS() const
1029 {
1030 return opt_inline_css;
1031 }
enclosePreTag() const1032 bool CmdLineOptions::enclosePreTag() const
1033 {
1034 return opt_enclose_pre;
1035 }
includeCharStyles() const1036 bool CmdLineOptions::includeCharStyles() const
1037 {
1038 return opt_char_styles;
1039 }
includePageColor() const1040 bool CmdLineOptions::includePageColor() const
1041 {
1042 return opt_page_color;
1043 }
disableTrailingNL() const1044 int CmdLineOptions::disableTrailingNL() const
1045 {
1046 return opt_no_trailing_nl;
1047 }
keepInjections() const1048 bool CmdLineOptions::keepInjections() const
1049 {
1050 return opt_keep_injections;
1051 }
forceStdout() const1052 bool CmdLineOptions::forceStdout() const
1053 {
1054 return opt_force_stdout;
1055 }
getDocumentTitle() const1056 const string& CmdLineOptions::getDocumentTitle() const
1057 {
1058 return docTitle;
1059 }
getWrappingStyle() const1060 highlight::WrapMode CmdLineOptions::getWrappingStyle() const
1061 {
1062 return wrappingStyle;
1063 }
getInputFileNames() const1064 const vector <string> & CmdLineOptions::getInputFileNames() const
1065 {
1066 return inputFileNames;
1067 }
1068
readDirectory(const string & wildcard)1069 void CmdLineOptions::readDirectory ( const string & wildcard )
1070 {
1071 // get matching files, use recursive search
1072 bool directoryOK=Platform::getDirectoryEntries ( inputFileNames, wildcard, true );
1073 if ( !directoryOK ) {
1074 cerr << "highlight: No files matched the pattern \""
1075 << wildcard << "\"."<< endl;
1076 }
1077 }
1078
validateDirPath(const string & path)1079 string CmdLineOptions::validateDirPath ( const string & path )
1080 {
1081 return ( path[path.length()-1] !=Platform::pathSeparator ) ?
1082 path+Platform::pathSeparator : path;
1083 }
1084
getOutputType() const1085 highlight::OutputType CmdLineOptions::getOutputType() const
1086 {
1087 return outputType;
1088 }
1089
getKeywordCase() const1090 StringTools::KeywordCase CmdLineOptions::getKeywordCase() const
1091 {
1092 return keywordCase;
1093 }
1094
hasBaseFont() const1095 bool CmdLineOptions::hasBaseFont() const
1096 {
1097 return ( ! baseFont.empty() ) ;
1098 }
1099
getBaseFont() const1100 const string& CmdLineOptions::getBaseFont() const
1101 {
1102 return baseFont ;
1103 }
1104
getBaseFontSize() const1105 const string& CmdLineOptions::getBaseFontSize() const
1106 {
1107 return baseFontSize ;
1108 }
1109
getClassName() const1110 const string& CmdLineOptions::getClassName() const
1111 {
1112 return className ;
1113 }
1114
getStartNestedLang() const1115 const string& CmdLineOptions::getStartNestedLang() const
1116 {
1117 return startNestedLang;
1118 }
getAbsThemePath() const1119 const string& CmdLineOptions::getAbsThemePath() const
1120 {
1121 return absThemePath;
1122 }
1123
getAbsLangPath() const1124 const string& CmdLineOptions::getAbsLangPath() const
1125 {
1126 return absLangPath;
1127 }
getPluginParameter() const1128 const string& CmdLineOptions::getPluginParameter() const
1129 {
1130 return pluginParameter;
1131 }
getNumberWidth()1132 int CmdLineOptions::getNumberWidth()
1133 {
1134 return lineNrWidth;
1135 }
1136
getLineLength()1137 int CmdLineOptions::getLineLength()
1138 {
1139 return lineLength;
1140 }
1141
getNumberStart()1142 int CmdLineOptions::getNumberStart()
1143 {
1144 return lineNrStart;
1145 }
1146
getCanvasPadding()1147 int CmdLineOptions::getCanvasPadding()
1148 {
1149 return canvasPaddingWidth;
1150 }
1151
getLineRangeStart()1152 int CmdLineOptions::getLineRangeStart()
1153 {
1154 return lineRangeStart;
1155 }
1156
getLineRangeEnd()1157 int CmdLineOptions::getLineRangeEnd()
1158 {
1159 return lineRangeEnd;
1160 }
1161
getCategories() const1162 const string& CmdLineOptions::getCategories() const {
1163 return listScriptCategory;
1164 }
1165
getHelpTopic() const1166 const string& CmdLineOptions::getHelpTopic() const {
1167 return helpTopic;
1168 }
1169
getSyntaxByFilename() const1170 const string& CmdLineOptions::getSyntaxByFilename() const {
1171 return redirectedFilename;
1172 }
1173
getListScriptKind() const1174 const string& CmdLineOptions::getListScriptKind() const{
1175 return listScriptType;
1176 }
1177
getFallbackSyntax() const1178 const string& CmdLineOptions::getFallbackSyntax() const {
1179 return fallbackSyntax;
1180 }
1181
showDeprecationHint(const std::string & option,const std::string & alt) const1182 void CmdLineOptions::showDeprecationHint ( const std::string & option, const std::string & alt ) const {
1183 cerr << "highlight: deprecated option '"<<option<<"' will be removed in v4.0 stable; valid alternatives: '"<<alt<<"'\n";
1184 }
1185
1186
1187